From 67bcfb4b1b632bf8f1d0cb81284086c832c33909 Mon Sep 17 00:00:00 2001 From: "tao.takashi" Date: Sun, 27 Jul 2008 19:54:54 +0000 Subject: [PATCH] added deserializer for credentials plus a test for it (and the serializer as well). Also cleaned up unused interfaces. --- pyogp/lib/base/agentdomain.py | 2 +- pyogp/lib/base/credentials.py | 15 ++++- pyogp/lib/base/interfaces.py | 11 ++-- pyogp/lib/base/tests/login.txt | 107 ++++++++++++++++++++++++--------- 4 files changed, 98 insertions(+), 37 deletions(-) diff --git a/pyogp/lib/base/agentdomain.py b/pyogp/lib/base/agentdomain.py index 51f47bc..bd4ac6b 100644 --- a/pyogp/lib/base/agentdomain.py +++ b/pyogp/lib/base/agentdomain.py @@ -11,7 +11,7 @@ import grokcore.component as grok from indra.base import llsd -from interfaces import ICredentialSerializer, IPlaceAvatar, IAgentDomain +from interfaces import IPlaceAvatar, IAgentDomain from network import IRESTClient, HTTPError from zope.component import queryUtility, adapts, getUtility diff --git a/pyogp/lib/base/credentials.py b/pyogp/lib/base/credentials.py index dba43ae..2042276 100644 --- a/pyogp/lib/base/credentials.py +++ b/pyogp/lib/base/credentials.py @@ -7,7 +7,7 @@ from indra.base import llsd import grokcore.component as grok -from interfaces import IPlainPasswordCredential, ISerialization +from interfaces import IPlainPasswordCredential, ISerialization, ICredentialDeserialization class PlainPasswordCredential(object): """a plain password credential""" @@ -60,3 +60,16 @@ class PlainPasswordLLSDSerializer(grok.Adapter): """return HTTP headers needed here""" return "application/llsd+xml" + +class PlainPasswordLLSDDeserializer(grok.GlobalUtility): + """take an LLSD string and create a credential object + + This is a utility + """ + grok.implements(ICredentialDeserialization) + grok.name('application/llsd+xml') + + def deserialize(self, s): + payload = llsd.parse(s) + # TODO: make this serialization stuff more flexible in terms of other types + return PlainPasswordCredential(payload['firstname'], payload['lastname'], payload['password']) \ No newline at end of file diff --git a/pyogp/lib/base/interfaces.py b/pyogp/lib/base/interfaces.py index 2667642..0e694ee 100644 --- a/pyogp/lib/base/interfaces.py +++ b/pyogp/lib/base/interfaces.py @@ -25,15 +25,12 @@ class IDeserialization(Interface): """deserialize the context""" -class ICredentialSerializer(Interface): +class ICredentialDeserialization(Interface): """converts a credential to a serialized format for sending it over the network""" - def serialize(): - """return a serialized string""" - - def headers(): - """return headers eventually needed for sending it out""" - + def deserialize(): + """deserialize the context""" + class IAgent(Interface): """models an agent""" diff --git a/pyogp/lib/base/tests/login.txt b/pyogp/lib/base/tests/login.txt index 625bae5..e56cfb4 100644 --- a/pyogp/lib/base/tests/login.txt +++ b/pyogp/lib/base/tests/login.txt @@ -1,48 +1,99 @@ Login ===== ->>> from pyogp.lib.base.credentials import PlainPasswordCredential ->>> from pyogp.lib.base.agentdomain import AgentDomain ->>> from pyogp.lib.base.regiondomain import Region +First some imports:: + + >>> from pyogp.lib.base.credentials import PlainPasswordCredential + >>> from pyogp.lib.base.agentdomain import AgentDomain + >>> from pyogp.lib.base.regiondomain import Region -First we create some credentials: ->>> credentials = PlainPasswordCredential('Firstname', 'Lastname', 'secret') +First we create some credentials:: + + >>> credentials = PlainPasswordCredential('Firstname', 'Lastname', 'secret') -Then we need some agent domain to connect to. This might automatically retrieve some XRDS file to get the actual login endpoint: ->>> agentdomain = AgentDomain('http://localhost:12345/') +Then we need some agent domain to connect to. This might automatically retrieve some XRDS file to get the actual login endpoint:: + + >>> agentdomain = AgentDomain('http://localhost:12345/') -Now we can use both to get an agent object (which transparently handles capabilities etc.): ->>> agent = agentdomain.login(credentials) +Now we can use both to get an agent object (which transparently handles capabilities etc.):: + + >>> agent = agentdomain.login(credentials) -The agent domain instance now should contain a seed capability: ->>> agentdomain.seed_cap - +The agent domain instance now should contain a seed capability:: -We could ask this seed capability now to retrieve another cap for us: ->>> caps = agentdomain.seed_cap.get(['place_avatar']) ->>> caps -{'place_avatar': } + >>> agentdomain.seed_cap + -Now we want to place out avatar somewhere on a region. To do so we first need a Region object: ->>> region = Region('http://localhost:12345/region') +We could ask this seed capability now to retrieve another cap for us:: -Now we adapt the agent to the place avatar functionality like this: ->>> from pyogp.lib.base.interfaces import IPlaceAvatar ->>> place = IPlaceAvatar(agentdomain) + >>> caps = agentdomain.seed_cap.get(['place_avatar']) + >>> caps + {'place_avatar': } -'place' now is an adapter which knows how to call the place_avatar capability. We can ask it to do it: ->>> avatar = place(region) +Now we want to place out avatar somewhere on a region. To do so we first need a Region object:: + + >>> region = Region('http://localhost:12345/region') -The result is dummy right now and should contain a long dictionary with region info: ->>> avatar.region.details['sim_ip'] -'127.0.0.1' +Now we adapt the agent to the place avatar functionality like this:: ->>> avatar.region.details['sim_port'] -12345 + >>> from pyogp.lib.base.interfaces import IPlaceAvatar + >>> place = IPlaceAvatar(agentdomain) + +'place' now is an adapter which knows how to call the place_avatar capability. We can ask it to do it:: + + >>> avatar = place(region) + +The result is dummy right now and should contain a long dictionary with region info:: + + >>> avatar.region.details['sim_ip'] + '127.0.0.1' + + >>> avatar.region.details['sim_port'] + 12345 This needs to be worked on to be a region and not an avatar. +Credential Serialization and Deserialization +============================================ + +In order to send a credential over the wire we need to serialize it:: + + >>> credential = PlainPasswordCredential('firstname','lastname','plainpw') + +Now we use an adapter to serializer it: + + >>> from pyogp.lib.base.interfaces import ISerialization + >>> serializer = ISerialization(credential) + + >>> serializer.serialize() + 'lastnamelastnamepasswordplainpwfirstnamefirstname' + >>> serializer.content_type + 'application/llsd+xml' + +So assume we received this string and need a credential object again, we do the following:: + + >>> data = serializer.serialize() + + >>> from pyogp.lib.base.interfaces import ICredentialDeserialization + >>> from zope.component import getUtility + >>> deserializer = getUtility(ICredentialDeserialization,name="application/llsd+xml") + >>> credential = deserializer.deserialize(data) + >>> credential.firstname + 'firstname' + >>> credential.lastname + 'lastname' + >>> credential.password + 'plainpw' + + + + + + + + +