# Path: txcas/exceptions.py
# class CASError(Exception):
#     pass
# 
# class InvalidTicket(CASError):
#     pass
# 
# class InvalidService(CASError):
#     pass
# 
# class NotSSOService(CASError):
#     pass
# 
# class InvalidTicketSpec(InvalidTicket):
#     pass
# 
# Path: txcas/http.py
# def createNonVerifyingHTTPClient(reactor, agent_kwds=None, **kwds):
#     agent_kwds = normalizeDict_(agent_kwds)
#     agent_kwds['contextFactory'] = NonVerifyingContextFactory()
#     return HTTPClient(Agent(reactor, **agent_kwds), **kwds)
# 
# def createVerifyingHTTPClient(
#         reactor, 
#         agent_kwds=None, 
#         policy_factory=BrowserLikePolicyForHTTPS, 
#         **kwds):
#     agent_kwds = normalizeDict_(agent_kwds)
#     agent_kwds['contextFactory'] = policy_factory()
#     return HTTPClient(Agent(reactor, **agent_kwds), **kwds)
# 
# Path: txcas/interface.py
# class ITicketStore(Interface):
#     
#     lt_lifespan = Attribute('LT lifespan in seconds.')
#     st_lifespan = Attribute('ST lifespan in seconds.')
#     pt_lifespan = Attribute('PT lifespan in seconds.')
#     tgt_lifespan = Attribute('TGC lifespan in seconds.')
#     pgt_lifespan = Attribute('PGT lifespan in seconds.')
#     ticket_size = Attribute('Size of ticket ID in characters.')
#     
#     isSSOService = Attribute(
#                             'Function that accepts a service and returns True if' \
#                             'the service may participate in SSO.')
#     
#     def mkLoginTicket(service):
#         """
#         Make a login ticket.
#         
#         @type service: C{string}
#         @param service: The service URL.
#         
#         @rtpe: C{string}
#         @return: ticket ID
#         """
#         
#     def useLoginTicket(ticket, service):
#         """
#         Consume a login ticket.
#         Returns a dict with key `service`.
#         """
#         
#     def mkServiceTicket(service, tgt, primaryCredentials):
#         """
#         """
#         
#     def useServiceTicket(ticket, service, requirePrimaryCredentials=False):
#         """
#         """
#         
#     def mkProxyTicket(service, pgt):
#         """
#         """
#         
#     def useServiceOrProxyTicket(ticket, service, requirePrimaryCredentials=False):
#         """
#         """
#         
#     def mkProxyGrantingTicket(service, ticket, tgt, pgturl, proxy_chain=None):
#         """
#         """
#         
#     def mkTicketGrantingCookie(avatar_id):
#         """
#         """
#         
#     def useTicketGrantingCookie(tgt, service):
#         """
#         """
#         
#     def expireTGT(tgt):
#         """
#         """
#         
#     def register_ticket_expiration_callback(callback):
#         """
#         Register a function to be called when a ticket is expired.
#         The function should take 3 arguments, (ticket, data, explicit).
#         `ticket` is the ticket ID, `data` is a dict of the ticket data,
#         and `explicit` is a boolean that indicates whether the ticket
#         was explicitly expired (e.g. /logout, ST/PT validation) or
#         implicitly expired (e.g. timeout or parent ticket expired).
#         """
# 
# class ITicketStoreFactory(Interface):
# 
#     tag = Attribute('String used to identify the plugin factory.')
#     opt_help = Attribute('String description of the plugin.')
#     opt_usage = Attribute('String describes how to provide arguments for factory.')
# 
#     def generateTicketStore(argstring=""):
#         """
#         Create an object that implements ITicketStore.
#         """
# 
# class IServiceManagerAcceptor(Interface):
#     
#     service_manager = Attribute('None or a reference to the current service manager plugin.')
# 
# Path: txcas/urls.py
# def are_urls_equal(url0, url1):
#     p0 = urlparse(url0)
#     p1 = urlparse(url1)
#     scheme0 = p0.scheme.lower()
#     scheme1 = p1.scheme.lower()
#     if scheme0 != scheme1:
#         return False
#     netloc0 = normalize_netloc(scheme0, p0.netloc)
#     netloc1 = normalize_netloc(scheme1, p1.netloc)
#     if netloc0 != netloc1:
#         return False
#     if p0.path != p1.path:
#         return False
#     if p0.params != p1.params:
#         return False
#     if p0.fragment != p1.fragment:
#         return False
#     qs0 = set(parse_qsl(p0.query))
#     qs1 = set(parse_qsl(p1.query))
#     if qs0 != qs1:
#         return False
#     return True


import datetime
import random
import string
import sys
import uuid
import txcas.settings
import treq
from textwrap import dedent
from xml.sax.saxutils import escape as xml_escape
from txcas.exceptions import (
    CASError, InvalidTicket, InvalidService,
    NotSSOService, InvalidTicketSpec)
from txcas.http import (
    createNonVerifyingHTTPClient, createVerifyingHTTPClient)
from txcas.interface import (
    ITicketStore, ITicketStoreFactory, IServiceManagerAcceptor)
from txcas.urls import are_urls_equal
from twisted.internet import defer
from twisted.plugin import IPlugin
from twisted.python import log
from twisted.web.http_headers import Headers
from zope.interface import implements
            from twisted.internet import reactor
        self._delays = {}
        self._debug = _debug
        self._expire_callback = (lambda ticket, data, explicit: None)
        if verify_cert:
            self.httpClientFactory = createVerifyingHTTPClient
        else:
            self.httpClientFactory = createNonVerifyingHTTPClient

    def _getServiceValidator(self):
        service_mgr = self.service_manager
        if service_mgr is None:
            return (lambda x: True)
        else:
            return service_mgr.isValidService

    def _getServiceSSOPredicate(self):
        service_mgr = self.service_manager
        if service_mgr is None:
            return (lambda x: True)
        else:
            return service_mgr.isSSOService
        
    def debug(self, msg):
        if self._debug:
            log.msg(msg)

    def _validService(self, service):

        def cb(result):
            if not result:

# Path: txcas/exceptions.py
# class CASError(Exception):
#     pass
# 
# class InvalidTicket(CASError):
#     pass
# 
# class InvalidService(CASError):
#     pass
# 
# class NotSSOService(CASError):
#     pass
# 
# class InvalidTicketSpec(InvalidTicket):
#     pass
# 
# Path: txcas/http.py
# def createNonVerifyingHTTPClient(reactor, agent_kwds=None, **kwds):
#     agent_kwds = normalizeDict_(agent_kwds)
#     agent_kwds['contextFactory'] = NonVerifyingContextFactory()
#     return HTTPClient(Agent(reactor, **agent_kwds), **kwds)
# 
# def createVerifyingHTTPClient(
#         reactor, 
#         agent_kwds=None, 
#         policy_factory=BrowserLikePolicyForHTTPS, 
#         **kwds):
#     agent_kwds = normalizeDict_(agent_kwds)
#     agent_kwds['contextFactory'] = policy_factory()
#     return HTTPClient(Agent(reactor, **agent_kwds), **kwds)
# 
# Path: txcas/interface.py
# class ITicketStore(Interface):
#     
#     lt_lifespan = Attribute('LT lifespan in seconds.')
#     st_lifespan = Attribute('ST lifespan in seconds.')
#     pt_lifespan = Attribute('PT lifespan in seconds.')
#     tgt_lifespan = Attribute('TGC lifespan in seconds.')
#     pgt_lifespan = Attribute('PGT lifespan in seconds.')
#     ticket_size = Attribute('Size of ticket ID in characters.')
#     
#     isSSOService = Attribute(
#                             'Function that accepts a service and returns True if' \
#                             'the service may participate in SSO.')
#     
#     def mkLoginTicket(service):
#         """
#         Make a login ticket.
#         
#         @type service: C{string}
#         @param service: The service URL.
#         
#         @rtpe: C{string}
#         @return: ticket ID
#         """
#         
#     def useLoginTicket(ticket, service):
#         """
#         Consume a login ticket.
#         Returns a dict with key `service`.
#         """
#         
#     def mkServiceTicket(service, tgt, primaryCredentials):
#         """
#         """
#         
#     def useServiceTicket(ticket, service, requirePrimaryCredentials=False):
#         """
#         """
#         
#     def mkProxyTicket(service, pgt):
#         """
#         """
#         
#     def useServiceOrProxyTicket(ticket, service, requirePrimaryCredentials=False):
#         """
#         """
#         
#     def mkProxyGrantingTicket(service, ticket, tgt, pgturl, proxy_chain=None):
#         """
#         """
#         
#     def mkTicketGrantingCookie(avatar_id):
#         """
#         """
#         
#     def useTicketGrantingCookie(tgt, service):
#         """
#         """
#         
#     def expireTGT(tgt):
#         """
#         """
#         
#     def register_ticket_expiration_callback(callback):
#         """
#         Register a function to be called when a ticket is expired.
#         The function should take 3 arguments, (ticket, data, explicit).
#         `ticket` is the ticket ID, `data` is a dict of the ticket data,
#         and `explicit` is a boolean that indicates whether the ticket
#         was explicitly expired (e.g. /logout, ST/PT validation) or
#         implicitly expired (e.g. timeout or parent ticket expired).
#         """
# 
# class ITicketStoreFactory(Interface):
# 
#     tag = Attribute('String used to identify the plugin factory.')
#     opt_help = Attribute('String description of the plugin.')
#     opt_usage = Attribute('String describes how to provide arguments for factory.')
# 
#     def generateTicketStore(argstring=""):
#         """
#         Create an object that implements ITicketStore.
#         """
# 
# class IServiceManagerAcceptor(Interface):
#     
#     service_manager = Attribute('None or a reference to the current service manager plugin.')
# 
# Path: txcas/urls.py
# def are_urls_equal(url0, url1):
#     p0 = urlparse(url0)
#     p1 = urlparse(url1)
#     scheme0 = p0.scheme.lower()
#     scheme1 = p1.scheme.lower()
#     if scheme0 != scheme1:
#         return False
#     netloc0 = normalize_netloc(scheme0, p0.netloc)
#     netloc1 = normalize_netloc(scheme1, p1.netloc)
#     if netloc0 != netloc1:
#         return False
#     if p0.path != p1.path:
#         return False
#     if p0.params != p1.params:
#         return False
#     if p0.fragment != p1.fragment:
#         return False
#     qs0 = set(parse_qsl(p0.query))
#     qs1 = set(parse_qsl(p1.query))
#     if qs0 != qs1:
#         return False
#     return True


# Path: txcas/in_memory_ticket_store.py
import datetime
import random
import string
import sys
import uuid
import txcas.settings
import treq
from textwrap import dedent
from xml.sax.saxutils import escape as xml_escape
from txcas.exceptions import (
    CASError, InvalidTicket, InvalidService,
    NotSSOService, InvalidTicketSpec)
from txcas.http import (
    createNonVerifyingHTTPClient, createVerifyingHTTPClient)
from txcas.interface import (
    ITicketStore, ITicketStoreFactory, IServiceManagerAcceptor)
from txcas.urls import are_urls_equal
from twisted.internet import defer
from twisted.plugin import IPlugin
from twisted.python import log
from twisted.web.http_headers import Headers
from zope.interface import implements
            from twisted.internet import reactor

        self._delays = {}
        self._debug = _debug
        self._expire_callback = (lambda ticket, data, explicit: None)
        if verify_cert:
            self.httpClientFactory = createVerifyingHTTPClient
        else:
            self.httpClientFactory = createNonVerifyingHTTPClient

    def _getServiceValidator(self):
        service_mgr = self.service_manager
        if service_mgr is None:
            return (lambda x: True)
        else:
            return service_mgr.isValidService

    def _getServiceSSOPredicate(self):
        service_mgr = self.service_manager
        if service_mgr is None:
            return (lambda x: True)
        else:
            return service_mgr.isSSOService
        
    def debug(self, msg):
        if self._debug:
            log.msg(msg)

    def _validService(self, service):

        def cb(result):
            if not result:

                return defer.fail(InvalidService(