Files
Hippolyzer/pyogp/lib/base/tests/credentials.txt

123 lines
5.3 KiB
Plaintext

Introduction
============
At the beginning of every application you need to login or you need to verify if a user is the user he claims to be.
This is where credentials come into play. The Open Grid Protocol defines two possible types right now
(see http://wiki.secondlife.com/wiki/Open_Grid_Protocol#Agent_Authentication_.28Resource_Class.29)::
{ credential: credential , first_name: string , last_name: string }
::Note: Currently deployed protocol requires the following arguments: { firstname: string , lastname: string , password: string }
Note: Alternatively, this can be used: { firstname: string , lastname: string , md5-password: md5sum string }
What we need to implement right now is the current deployed protocol. The problem is that no field defines
what type of credential it is, except the md5-password or password variant.
Creating serialized credentials
===============================
When you want to login to an agent domain you need to send one of these two variants. You can do it like this::
>>> from pyogp.lib.base.credentials import PlainPasswordCredential
>>> credential = PlainPasswordCredential('firstname', 'lastname', 'secret')
Now we can serialize it like this::
>>> from pyogp.lib.base.credentials import LLSDSerializer
>>> serializer = LLSDSerializer(credential)
>>> serializer.serialize()
'<?xml version="1.0" ?><llsd><map><key>lastname</key><string>lastname</string><key>password</key><string>secret</string><key>firstname</key><string>firstname</string></map></llsd>'
>>> serializer.content_type
'application/llsd+xml'
Let's try the MD5 version::
>>> from pyogp.lib.base.credentials import MD5PasswordCredential
>>> credential = MD5PasswordCredential('firstname', 'lastname', plainpw = 'secret')
Note that you either can pass ``plainpw`` or ``md5pw`` as a password. If ``plainpw`` is given then it will get converted
to MD5 automatically. Note that the md5 password used in the protocol has no $1$ prepended! If both options are given, ``md5pw``
takes precedence.
Let's try to serialize this::
>>> from pyogp.lib.base.credentials import MD5PasswordLLSDSerializer
>>> serializer = MD5PasswordLLSDSerializer(credential)
>>> serializer.serialize()
'<?xml version="1.0" ?><llsd><map><key>lastname</key><string>lastname</string><key>md5-password</key><string>5ebe2294ecd0e0f08eab7690d2a6ee69</string><key>firstname</key><string>firstname</string></map></llsd>'
>>> serializer.content_type
'application/llsd+xml'
Let's try it with ``md5pw``::
>>> credential = MD5PasswordCredential('firstname', 'lastname', md5pw = 'secret')
>>> serializer = MD5PasswordLLSDSerializer(credential)
>>> serializer.serialize()
'<?xml version="1.0" ?><llsd><map><key>lastname</key><string>lastname</string><key>md5-password</key><string>secret</string><key>firstname</key><string>firstname</string></map></llsd>'
>>> serializer.content_type
'application/llsd+xml'
Deserializing a credential
==========================
If you want to implement an Agent Domain you also need to deserialize the credential to check it's validity. Unfortunately both types
of credentials are just XML to the outside. We use a utility which knows about the internals and returns the appropriate credential instance.
Let's try it with a plain password credential::
>>> s='<?xml version="1.0" ?><llsd><map><key>lastname</key><string>lastname</string><key>password</key><string>secret</string><key>firstname</key><string>firstname</string></map></llsd>'
We get the utility for it like this::
>>> from pyogp.lib.base.credentials import CredentialLLSDDeserializer
>>> deserializer = CredentialLLSDDeserializer()
Now let's use this utility::
>>> credential = deserializer.deserialize(s)
>>> credential.__class__.__name__
'PlainPasswordCredential'
>>> credential
PlainPasswordCredential for 'firstname lastname'
>>> credential.password
'secret'
Let's try the same for the md5 based version::
>>> s='<?xml version="1.0" ?><llsd><map><key>lastname</key><string>lastname</string><key>md5-password</key><string>5ebe2294ecd0e0f08eab7690d2a6ee69</string><key>firstname</key><string>firstname</string></map></llsd>'
>>> credential = deserializer.deserialize(s)
>>> credential.__class__.__name__
'MD5PasswordCredential'
>>> credential
MD5PasswordCredential for 'firstname lastname'
>>> credential.password
'5ebe2294ecd0e0f08eab7690d2a6ee69'
Possible errors
===============
Just for the fun of it let's test what happens if we pass a string which neither has password or md5-password::
>>> s='<?xml version="1.0" ?><llsd><map><key>lastname</key><string>lastname</string><key>firstname</key><string>firstname</string></map></llsd>'
>>> credential = deserializer.deserialize(s)
Traceback (most recent call last):
...
CredentialDeserializerNotFound: deserialization for payload '{'lastname': 'lastname', 'firstname': 'firstname'}' not supported
And what if no firstname and lastname was given::
>>> s='<?xml version="1.0" ?><llsd><map><key>password</key><string>secret</string></map></llsd>'
>>> credential = deserializer.deserialize(s)
Traceback (most recent call last):
...
CredentialDeserializerNotFound: deserialization for payload '{'password': 'secret'}' not supported