2
from twisted.python import log
5
"""I am an Identity's view onto a service.
7
I am the interface through which most 'external' code should
8
interact with a service; I represent the actions a user may
9
perform upon a service, and the state associated with that
10
user for that service.
13
_service_cached = 0 # Has my service cached me from a loaded store, or do I live in memory usually?
15
def __init__(self, perspectiveName, identityName="Nobody"):
18
I require a name for myself and a reference to the service
19
I participate in. (My identity name will be 'Nobody' by
20
default, which will normally not resolve.)
22
self.perspectiveName = perspectiveName
23
self.identityName = identityName
25
def setIdentityName(self, name):
26
self.identityName = name
28
def setIdentity(self, identity):
29
"""Determine which identity I connect to.
31
self.setIdentityName(identity.name)
33
def makeIdentity(self, password):
34
"""Make an identity from this perspective with a password.
36
This is a utility method, which can be used in circumstances
37
where the distinction between Perspective and Identity is weak,
38
such as single-Service servers.
40
ident = Identity(self.perspectiveName, self.service.application)
41
self.setIdentityName(self.perspectiveName)
42
ident.setPassword(password)
43
ident.addKeyForPerspective(self)
44
self.service.application.authorizer.addIdentity(ident)
47
def getPerspectiveName(self):
48
"""Return the unique name of this perspective.
50
This will return a value such that
51
self.service.getPerspectiveNamed(value) is self.
53
(XXX: That's assuming I have been addPerspective'd to my service.)
55
return self.perspectiveName
62
def setService(self, service):
63
"""Change what service I am a part of.
65
self.service = service
67
def getIdentityRequest(self):
68
"""Request my identity.
70
return (self.service.application.authorizer.
71
getIdentityRequest(self.identityName))
75
def attached(self, reference, identity):
76
"""Called when a remote reference is 'attached' to me.
78
After being authorized, a remote actor can attach to me
79
through its identity. This call will be made when that
80
happens, and the return value of this method will be used
81
as the _actual_ perspective to which I am attached.
83
Note that the symmetric call, detached, will be made on
84
whatever this method returns, _not_ on me. Therefore,
85
by default I return 'self'.
87
log.msg('attached [%s]' % str(self.__class__))
88
self._attachedCount = self._attachedCount + 1
89
if self._attachedCount == 1:
90
self.service.cachePerspective(self)
92
log.msg(" (multiple references attached: %s)" % self._attachedCount)
95
def detached(self, reference, identity):
96
"""Called when a broker is 'detached' from me.
100
When a remote actor disconnects (or times out, for example,
101
with HTTP), this is called in order to indicate that the
102
reference associated with that peer is no longer attached to
105
log.msg('detached [%s]' % str(self.__class__))
106
self._attachedCount = self._attachedCount - 1
107
if self._attachedCount <= 0:
108
self.service.uncachePerspective(self)
109
if self._attachedCount < 0:
110
log.msg(" (Weird stuff: attached count = %s)" % self._attachedCount)
112
log.msg(" (multiple references attached: %s)" % self._attachedCount)