# Path: txcas/casuser.py
# class User(object):
# 
#     implements(ICASUser)
# 
#     username = None
#     attribs = None
#     
#     def __init__(self, username, attribs):
#         self.username = username
#         self.attribs = attribs
#    
#     def logout(self):
#         pass
# 
# Path: txcas/interface.py
# class ICASUser(Interface):
# 
#     username = Attribute('String username')
#     attribs = Attribute('List of (attribute, value) tuples.')
# 
# class IRealmFactory(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 generateRealm(argstring=""):
#         """
#         Create an object that implements IRealm.
#         """
# 
# class IServiceManagerAcceptor(Interface):
#     
#     service_manager = Attribute('None or a reference to the current service manager plugin.')
# 
# Path: txcas/settings.py
# def get_bool(value, default=False):
#     if value is None:
#         return False
#     value = str(value).strip().lower()
#     if value in ('y', '1', 't', 'yes', 'true'):
#         return True
#     elif value in ('n', '0', 'f', 'no', 'false'):
#         return False
#     else:
#         return default
# 
# def export_settings_to_dict(scp):
#     settings = {}
#     for section in scp.sections():
#         for option in scp.options(section):
#             settings.setdefault(section, {})[option] = scp.get(section, option)
#     return settings
# 
# def load_settings(config_basename, defaults=None, syspath=None, appdir=None):
#     """
#     Load settings.
#     """
#     if defaults is None:
#         defaults = {}
#     scp = load_defaults(defaults)
#     if appdir is None:
#         appdir = os.path.dirname(os.path.dirname(__file__))
#     paths = []
#     if syspath is not None:
#         paths.append(os.path.join(syspath, "%s.cfg" % config_basename))
#     paths.append(os.path.expanduser("~/%src" % config_basename))
#     paths.append(os.path.join(appdir, "%s.cfg" % config_basename))
#     scp.read(paths)
#     return scp


from textwrap import dedent
from txcas.casuser import User
from txcas.interface import ICASUser, IRealmFactory, IServiceManagerAcceptor
from txcas.settings import get_bool, export_settings_to_dict, load_settings
from ldaptor.protocols.ldap.ldapclient import LDAPClient
from ldaptor.protocols.ldap import ldapsyntax
from ldaptor.protocols.ldap.ldaperrors import LDAPInvalidCredentials
from twisted.cred.portal import IRealm
from twisted.internet import defer, reactor
from twisted.internet.endpoints import clientFromString, connectProtocol
from twisted.internet.ssl import Certificate, optionsForClientTLS, platformTrust
from twisted.plugin import IPlugin
from zope.interface import implements
import sys
import txcas.utils
import pem
        else:
            attributes = self._attribs
        e = clientFromString(reactor, self._endpointstr)
        client = yield connectProtocol(e, LDAPClient())
        startTls = self._startTls
        startTlsHostName = self._startTlsHostName
        startTlsAuthority = self._startTlsAuthority
        if startTls:
            startTlsArgs = []
            if startTlsHostName is not None:
                if startTlsAuthority is not None:
                    ctx = optionsForClientTLS(unicode(startTlsHostName), startTlsAuthority)
                else:
                    ctx = optionsForClientTLS(unicode(startTlsHostName), platformTrust())
                startTlsArgs.append(ctx)
            client = yield client.startTLS(*startTlsArgs)
        yield client.bind(binddn, bindpw)
        o = ldapsyntax.LDAPEntry(client, basedn)
        results = yield o.search(filterText=query, attributes=attributes.keys())
        yield client.unbind()
        if len(results) != 1:
            raise Exception("No unique account found for '%s'." % avatarId)
        entry = results[0]
        _attribs = attributes
        attribs = []
        for key, alias in _attribs.iteritems():
            if key in entry:
                valuelist = entry[key]
                for value in valuelist:
                    attribs.append((alias, value))

# Path: txcas/casuser.py
# class User(object):
# 
#     implements(ICASUser)
# 
#     username = None
#     attribs = None
#     
#     def __init__(self, username, attribs):
#         self.username = username
#         self.attribs = attribs
#    
#     def logout(self):
#         pass
# 
# Path: txcas/interface.py
# class ICASUser(Interface):
# 
#     username = Attribute('String username')
#     attribs = Attribute('List of (attribute, value) tuples.')
# 
# class IRealmFactory(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 generateRealm(argstring=""):
#         """
#         Create an object that implements IRealm.
#         """
# 
# class IServiceManagerAcceptor(Interface):
#     
#     service_manager = Attribute('None or a reference to the current service manager plugin.')
# 
# Path: txcas/settings.py
# def get_bool(value, default=False):
#     if value is None:
#         return False
#     value = str(value).strip().lower()
#     if value in ('y', '1', 't', 'yes', 'true'):
#         return True
#     elif value in ('n', '0', 'f', 'no', 'false'):
#         return False
#     else:
#         return default
# 
# def export_settings_to_dict(scp):
#     settings = {}
#     for section in scp.sections():
#         for option in scp.options(section):
#             settings.setdefault(section, {})[option] = scp.get(section, option)
#     return settings
# 
# def load_settings(config_basename, defaults=None, syspath=None, appdir=None):
#     """
#     Load settings.
#     """
#     if defaults is None:
#         defaults = {}
#     scp = load_defaults(defaults)
#     if appdir is None:
#         appdir = os.path.dirname(os.path.dirname(__file__))
#     paths = []
#     if syspath is not None:
#         paths.append(os.path.join(syspath, "%s.cfg" % config_basename))
#     paths.append(os.path.expanduser("~/%src" % config_basename))
#     paths.append(os.path.join(appdir, "%s.cfg" % config_basename))
#     scp.read(paths)
#     return scp


# Path: txcas/ldap_realm.py
from textwrap import dedent
from txcas.casuser import User
from txcas.interface import ICASUser, IRealmFactory, IServiceManagerAcceptor
from txcas.settings import get_bool, export_settings_to_dict, load_settings
from ldaptor.protocols.ldap.ldapclient import LDAPClient
from ldaptor.protocols.ldap import ldapsyntax
from ldaptor.protocols.ldap.ldaperrors import LDAPInvalidCredentials
from twisted.cred.portal import IRealm
from twisted.internet import defer, reactor
from twisted.internet.endpoints import clientFromString, connectProtocol
from twisted.internet.ssl import Certificate, optionsForClientTLS, platformTrust
from twisted.plugin import IPlugin
from zope.interface import implements
import sys
import txcas.utils
import pem

        else:
            attributes = self._attribs
        e = clientFromString(reactor, self._endpointstr)
        client = yield connectProtocol(e, LDAPClient())
        startTls = self._startTls
        startTlsHostName = self._startTlsHostName
        startTlsAuthority = self._startTlsAuthority
        if startTls:
            startTlsArgs = []
            if startTlsHostName is not None:
                if startTlsAuthority is not None:
                    ctx = optionsForClientTLS(unicode(startTlsHostName), startTlsAuthority)
                else:
                    ctx = optionsForClientTLS(unicode(startTlsHostName), platformTrust())
                startTlsArgs.append(ctx)
            client = yield client.startTLS(*startTlsArgs)
        yield client.bind(binddn, bindpw)
        o = ldapsyntax.LDAPEntry(client, basedn)
        results = yield o.search(filterText=query, attributes=attributes.keys())
        yield client.unbind()
        if len(results) != 1:
            raise Exception("No unique account found for '%s'." % avatarId)
        entry = results[0]
        _attribs = attributes
        attribs = []
        for key, alias in _attribs.iteritems():
            if key in entry:
                valuelist = entry[key]
                for value in valuelist:
                    attribs.append((alias, value))

        user = User(avatarId, attribs)