[Twisted-Python] Lazily adding Identities in new cred

Jp Calderone exarkun at twistedmatrix.com
Fri Jul 11 22:37:26 MDT 2003


On Sat, Jul 12, 2003 at 12:09:12AM -0400, David Ripton wrote:
> Hi,
> 
> I'm working on a turn-based game, with a server and N untrusted clients, 
> using PB.
> 
> So far I just have a few hardcoded test users and passwords.  Now I'd 
> like to add lazy user registration.  If a username is already known, 
> then you need the password to log in.  If it's not known, you can claim 
> that username by attempting to login, and your password should be 
> immediately set to whatever you just used.
> 
> (I'm not saying this is the generally ideal way to add new users and 
> assign their passwords, but it should definitely be doable in any 
> reasonably flexible authentication framework.)
> 
> It appears that cred was not really designed to support this, because 
> the password that the user entered is not passed to 
> Authorizer.getIdentityRequest, which seems like the obvious place to 
> lazily add an Identity.
> 
> Getting it there by patching Twisted would be easy enough: pass it from 
> pb.authIdentity through AuthServ.remote_username into the call to 
> getIdentityRequest.  The callers would always need to pass the password, 
> but only a small percentage of Authorizers would actually use it, so 
> this doesn't seem perfectly clean.  But I don't see a better alternative.
> 
> Suggestions?

  The best solution would seem to be to get PB working with the new cred
code -- which doesn't use Authorizers, Identities, or any of that confusion.

  Here's a simple credentials checker that adds all unrecognized usernames
that are requested (untested):

    from twisted import cred
    import twisted.cred.credentials
    import twisted.cred.checkers
    import twisted.cred.error

    from twisted.python.components import implements

    class LazyCredentialsChecker:
        __implements__ = (cred.checkers.ICredentialsChecker,)

        credentialInterfaces = (cred.credentials.IUsernamePassword,)

        def userExists(self, username):
            # Return true if username exists, false otherwise

        def getPassword(self, username):
            # Implement appropriately

        def addUser(self, username, password):
            # Here, too

        def requestAvatarId(self, creds):
            if implements(creds, cred.credentials.IUsernamePassword):
                if self.userExists(creds.username):
                    if self.getPassword(creds.username) == creds.password:
                        return creds.username
                    raise cred.error.UnauthorizedLogin()
                self.addUser(creds.username, creds.password)
                return creds.username
            raise NotImplementedError()

  An even nicer way to do this would be to create an interface for creating
a new user, (eg, IChargen), have requestAvatarId check for this interface,
and create the required entries in its database, rather than relying on the
non-existence of a username to create a new one (what if the user mistypes
their user?)

  Hope this helps,

  Jp

-- 
"The problem is, of course, that not only is economics bankrupt but it has
 always been nothing more than politics in disguise ... economics is a form
 of brain damage."  -- Hazel Henderson
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: </pipermail/twisted-python/attachments/20030712/5057f979/attachment.sig>


More information about the Twisted-Python mailing list