[Twisted-Python] Lazily adding Identities in new cred

Jp Calderone exarkun at twistedmatrix.com
Sat Jul 12 00:37:26 EDT 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,


"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 : http://twistedmatrix.com/pipermail/twisted-python/attachments/20030712/5057f979/attachment.pgp 

More information about the Twisted-Python mailing list