Skip to content

Instantly share code, notes, and snippets.

@minskmaz
Last active July 13, 2018 00:06
Show Gist options
  • Save minskmaz/ab218d7b137b24ede8ffc7e3ea6e2392 to your computer and use it in GitHub Desktop.
Save minskmaz/ab218d7b137b24ede8ffc7e3ea6e2392 to your computer and use it in GitHub Desktop.

Revisions

  1. minskmaz revised this gist Jul 13, 2018. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions credentialChecker.py
    Original file line number Diff line number Diff line change
    @@ -24,4 +24,5 @@ def process(matched):
    stmnt = "SELECT * FROM Principal WHERE username = '{}'".format(username)
    d = self.db().Registry.DBPOOL.runQuery(stmnt)
    d.addCallback(process)
    return d # <----- this fixed it!
    checkers.PasswordCredentialChecker = PasswordCredentialChecker
  2. minskmaz revised this gist Jul 11, 2018. 1 changed file with 0 additions and 33 deletions.
    33 changes: 0 additions & 33 deletions WebAuthSessionWrapper.py
    Original file line number Diff line number Diff line change
    @@ -73,36 +73,3 @@ def getChild(self, path, request):
    request.postpath.insert(0, request.prepath.pop())
    return self._authorizedResource(request)

    class IFormCredentialFactory(Interface):
    """
    A credential factory defines a way to generate a particular kind of
    authentication challenge and a way to interpret the responses to these
    challenges. It creates L{ICredentials} providers from responses. These
    objects will be used with L{twisted.cred} to authenticate an authorize
    requests.
    """
    scheme = Attribute(
    "A C{str} giving the name of the authentication scheme with which "
    "this factory is associated. For example, C{'basic'} or C{'digest'}.")


    def getChallenge(request):
    """
    Generate a new challenge to be sent to a client. Same as the existing
    iweb.ICredentialFactory, except that getChallenge should return a URL
    that refers to login form
    """


    def decode(response, request):
    """
    Create a credentials object from the given response.
    @type response: C{str}
    @param response: scheme specific response string
    @type request: L{twisted.web.http.Request}
    @param request: The request being processed (from which the response
    was taken).
    @raise twisted.cred.error.LoginFailed: If the response is invalid.
    @rtype: L{twisted.cred.credentials.ICredentials} provider
    @return: The credentials represented by the given response.
    """
  3. minskmaz revised this gist Jul 11, 2018. 1 changed file with 1 addition and 33 deletions.
    34 changes: 1 addition & 33 deletions WebAuthSessionWrapper.py
    Original file line number Diff line number Diff line change
    @@ -105,36 +105,4 @@ def decode(response, request):
    @raise twisted.cred.error.LoginFailed: If the response is invalid.
    @rtype: L{twisted.cred.credentials.ICredentials} provider
    @return: The credentials represented by the given response.
    """


    class FormCredentialFactory(object):
    """
    Credential Factory for XHTML form authentication
    @type authenticationRealm: C{str}
    @ivar authenticationRealm: The HTTP authentication realm which will be issued in
    challenges.
    """
    implements(IFormCredentialFactory)

    scheme = 'txmetrc.form_based_login'

    def __init__(self, authenticationRealm):
    self.authenticationRealm = authenticationRealm
    self.url = '/{}/login'.format(self.scheme)

    def getChallenge(self, request):
    return self.url

    def decode(self, request):
    """
    Extract the credentials from the POST body. Support
    'decode method so as not to break the interface'
    """
    args = request.args
    try:
    creds = (args['login'][0], args['password'][0])
    except KeyError:
    raise error.LoginFailed('Invalid credentials')
    else:
    return credentials.UsernamePassword(*creds)
    """
  4. minskmaz renamed this gist Jul 11, 2018. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  5. minskmaz revised this gist Jul 11, 2018. 1 changed file with 140 additions and 0 deletions.
    140 changes: 140 additions & 0 deletions AutheSessionWrapper.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,140 @@
    class WebAuthSessionWrapper(resource.Resource):
    """
    Wrap a twisted.cred.portal, requiring authN/authZ via various providers.
    """

    isLeaf = False

    def __init__(self, portal, credentialFactories, *children):
    """
    Initialize a session wrapper.
    """
    resource.Resource.__init__(self)
    self._portal = portal
    self._credentialFactories = credentialFactories
    for path, child in children:
    self.putChild(path, child)

    def _authorizedResource(self, request):
    """
    Get the twisted.web.resource.IResource which the given request is
    authorized to receive. If the proper credentials are present, the
    resource will be requested from the portal.
    """
    authProvider = None
    session = request.getSession()
    if session.avatar is not None:
    return session.avatar
    else:
    userCredentials = credentials.Anonymous()
    if request.method == 'POST':
    authProvider = request.args['scheme'][0]
    for credentialFactory in self._credentialFactories:
    if credentialFactory.scheme == authProvider:
    userCredentials = credentialFactory.decode(request)
    break
    return DeferredResource(self._login(userCredentials, request))

    def _login(self, credentials, request):
    """
    Get the twisted.web.resource.IResource avatar for the given credentials.
    Returns a twisted.internet.defer.Deferred which will be called back with
    a twisted.web.resource.IResource avatar or which will errback if
    authentication fails.
    """
    d = self._portal.login(credentials, request, resource.IResource)
    d.addCallbacks(self._loginSucceeded, self._loginFailed)
    return d

    def _loginSucceeded(self, (interface, avatar, logout)):
    #print "_loginSucceeded", interface, avatar, logout
    return avatar

    def _loginFailed(self, result):
    """
    Handle login failure by presenting either another challenge (for
    expected authentication/authorization-related failures) or a server
    error page (for anything else).
    """
    errorMessage = result.getErrorMessage()
    if result.check(credError.Unauthorized, credError.LoginFailed):
    log.msg('txsocmob.cred.HTTPSessionWrapper._loginFailed: ' + errorMessage)
    return Redirect('/')
    else:
    return resource.ErrorPage(500, 'Server error.', errorMessage)

    def getChild(self, path, request):
    """
    TBD.
    """
    # Don't consume any segments of the request - this class should be
    # transparent!
    log.msg('getChild: ' + path)
    request.postpath.insert(0, request.prepath.pop())
    return self._authorizedResource(request)

    class IFormCredentialFactory(Interface):
    """
    A credential factory defines a way to generate a particular kind of
    authentication challenge and a way to interpret the responses to these
    challenges. It creates L{ICredentials} providers from responses. These
    objects will be used with L{twisted.cred} to authenticate an authorize
    requests.
    """
    scheme = Attribute(
    "A C{str} giving the name of the authentication scheme with which "
    "this factory is associated. For example, C{'basic'} or C{'digest'}.")


    def getChallenge(request):
    """
    Generate a new challenge to be sent to a client. Same as the existing
    iweb.ICredentialFactory, except that getChallenge should return a URL
    that refers to login form
    """


    def decode(response, request):
    """
    Create a credentials object from the given response.
    @type response: C{str}
    @param response: scheme specific response string
    @type request: L{twisted.web.http.Request}
    @param request: The request being processed (from which the response
    was taken).
    @raise twisted.cred.error.LoginFailed: If the response is invalid.
    @rtype: L{twisted.cred.credentials.ICredentials} provider
    @return: The credentials represented by the given response.
    """


    class FormCredentialFactory(object):
    """
    Credential Factory for XHTML form authentication
    @type authenticationRealm: C{str}
    @ivar authenticationRealm: The HTTP authentication realm which will be issued in
    challenges.
    """
    implements(IFormCredentialFactory)

    scheme = 'txmetrc.form_based_login'

    def __init__(self, authenticationRealm):
    self.authenticationRealm = authenticationRealm
    self.url = '/{}/login'.format(self.scheme)

    def getChallenge(self, request):
    return self.url

    def decode(self, request):
    """
    Extract the credentials from the POST body. Support
    'decode method so as not to break the interface'
    """
    args = request.args
    try:
    creds = (args['login'][0], args['password'][0])
    except KeyError:
    raise error.LoginFailed('Invalid credentials')
    else:
    return credentials.UsernamePassword(*creds)
  6. minskmaz renamed this gist Jul 11, 2018. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  7. minskmaz revised this gist Jul 11, 2018. 1 changed file with 35 additions and 0 deletions.
    35 changes: 35 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,35 @@
    class WebAuthenticatedRealm(object):
    interface.implements(IRealm)

    def __init__(self, anonymousRoot, authorizedRoot):
    self.anonymousRoot = anonymousRoot
    self.authorizedRoot = authorizedRoot

    def requestAvatar(self, avatarId, request, *interfaces):
    """
    Called after the user has successfully authenticated, returning an
    IResource instance representing the user's HTTP interface to an app.
    """
    print "####################################################"
    ##### HERE'S WHERE IT BREAKS DOWN, avatarId comes is as None
    print "requestAvatar", avatarId, request, interfaces
    print "####################################################"
    if resource.IResource in interfaces:
    if not avatarId:
    return (
    resource.IResource,
    self.anonymousRoot(),
    logout)
    else:
    avatar = self.authorizedRoot()
    session = request.getSession()
    session.avatar = avatar
    if not session.expireCallbacks:
    session.notifyOnExpire(lambda: sessionExpired(session))
    return (
    resource.IResource,
    avatar,
    logout
    )
    log.msg('requestAvatar: Realm not implemented.')
    raise NotImplementedError()
  8. minskmaz created this gist Jul 11, 2018.
    27 changes: 27 additions & 0 deletions credentialChecker.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,27 @@
    class PasswordCredentialChecker(object):
    implements(ICredentialsChecker)
    credentialInterfaces = (IUsernamePassword,)

    def __init__(self):
    print("INSTANTIATED PasswordCredentialChecker")
    self.crud = getUtility(ITraceCrud, 'trace_crud')()
    self.db = getUtility(ITwistarConnectionPool, 'twistar')

    def requestAvatarId(self, credentials):
    def process(matched):
    if len(matched) == 1:
    if matched[0][2] == credentials.password:
    print "MATCHING PASSWORDS"
    print credentials.username
    return defer.succeed(credentials.username)#succeed(credentials.username)
    else:
    return fail(credError.UnauthorizedLogin("Bad password"))
    else:
    return fail(credError.UnauthorizedLogin("No such user"))

    username = credentials.username
    if username:
    stmnt = "SELECT * FROM Principal WHERE username = '{}'".format(username)
    d = self.db().Registry.DBPOOL.runQuery(stmnt)
    d.addCallback(process)
    checkers.PasswordCredentialChecker = PasswordCredentialChecker