~vcs-imports/quotient/main

« back to all changes in this revision

Viewing changes to atop/credup.py

  • Committer: glyph
  • Date: 2003-10-26 23:44:25 UTC
  • Revision ID: Arch-1:unnamed@bazaar.ubuntu.com%series--4208--patch-749
whitespace

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- test-case-name: atop.test_credup -*-
 
2
 
 
3
from twisted.python.components import implements
 
4
from twisted.cred.portal import IRealm
 
5
from twisted.cred.credentials import IUsernamePassword, IUsernameHashedPassword
 
6
from twisted.cred.checkers import ICredentialsChecker, ANONYMOUS
 
7
from twisted.cred.error import UnauthorizedLogin
 
8
 
 
9
from atop.powerup import Storeup
 
10
from atop.store import SubStore, Pool, NameIndex
 
11
from atop.fwd import ItemForwardingComponent
 
12
 
 
13
def _localpartDomainToDBEmail(localpart, domain):
 
14
    dparts = domain.split('.')
 
15
    dparts.reverse()
 
16
    revdomain = '.'.join(dparts)
 
17
    return (revdomain+'@'+localpart)
 
18
 
 
19
 
 
20
class Avatar(SubStore):
 
21
 
 
22
    def setSecurePassword(self, passwd):
 
23
        """Save away a string for use with protocols that do not expose your
 
24
        password on the network.
 
25
        """
 
26
        self.securePassword = passwd
 
27
 
 
28
    def setInsecurePassword(self, passwd):
 
29
        """Save away a string for use with protocols that expose your password
 
30
        on the internet.
 
31
        """
 
32
        self.insecurePassword = passwd
 
33
 
 
34
    def getPassword(self, passwordSecure):
 
35
        """Retrieve a password.
 
36
        """
 
37
        if passwordSecure:
 
38
            return self.securePassword
 
39
        else:
 
40
            return self.insecurePassword
 
41
 
 
42
 
 
43
class AnonymousUser:
 
44
    ## Maybe this is pointless
 
45
    ## Maybe the adapter being registered on this class
 
46
    ## Should just be registered on the Store itself
 
47
    def __init__(self, store):
 
48
        self.store = store
 
49
 
 
50
 
 
51
class Domain(Pool):
 
52
    def __init__(self, store, name):
 
53
        Pool.__init__(self, store, name)
 
54
        self.addIndex(NameIndex())
 
55
 
 
56
class Preauthenticated:
 
57
    __implements__ = IUsernameHashedPassword
 
58
 
 
59
    def __init__(self, username):
 
60
        self.username = username
 
61
 
 
62
    def checkPassword(self, password):
 
63
        return True
 
64
 
 
65
def preauth(store, username):
 
66
    """Utility function to retrieve an avatar from a database by name.
 
67
    """
 
68
    return store.getItemByID(
 
69
        ICredentialsChecker(store).
 
70
        requestAvatarId(Preauthenticated(username)))
 
71
 
 
72
class FwdChecker(ItemForwardingComponent):
 
73
    __implements__ = ICredentialsChecker
 
74
    def __init__(self, fwdTo):
 
75
        ItemForwardingComponent.__init__(self, fwdTo)
 
76
        self.credentialInterfaces = fwdTo.getItem().credentialInterfaces
 
77
 
 
78
class FwdRealm(ItemForwardingComponent):
 
79
    __implements__ = IRealm
 
80
 
 
81
class StoreCredentialsChecker(Storeup):
 
82
 
 
83
    __implements__ = ICredentialsChecker
 
84
 
 
85
    credentialInterfaces = (IUsernamePassword, IUsernameHashedPassword)
 
86
 
 
87
    def setUpPools(self, store):
 
88
        self.touch()
 
89
        domains = Pool(store, 'domains')
 
90
        domains.addIndex(NameIndex())
 
91
        self.domainPoolRef = domains.referenceTo()
 
92
        store.setComponent(ICredentialsChecker, self)
 
93
 
 
94
    def getDomains(self):
 
95
        """Retrieve an iterator of all domains in this store.
 
96
        """
 
97
        return self.domainPoolRef.getItem().queryIndex()
 
98
 
 
99
    def getAvatars(self):
 
100
        """Retrieve an iterator of all avatars regardless of domain.
 
101
 
 
102
        This will yield certain avatars twice.
 
103
        """
 
104
        for domain in self.getDomains():
 
105
            for avatar in domain.queryIndex():
 
106
                yield avatar
 
107
 
 
108
    def getDomain(self, name=None):
 
109
        return self.domainPoolRef.getItem().getIndexItem('name', name)
 
110
 
 
111
    def addDomain(self, domainName):
 
112
        x = Domain(self.store, domainName)
 
113
        self.domainPoolRef.getItem().addItem(x)
 
114
        return x
 
115
 
 
116
    def addAvatar(self, avatar, domainName=None):
 
117
        def _():
 
118
            domain = self.getDomain(domainName)
 
119
            av2 = domain.getIndexItem("name", avatar.name, None)
 
120
            if av2 is not None:
 
121
                raise UnauthorizedLogin("You can't choose that username in that domain.")
 
122
            domain.addItem(avatar)
 
123
        return self.store.transact(_)
 
124
    addAvatarToDomain = addAvatar
 
125
 
 
126
    def getAvatar(self, localpart, domainName=None):
 
127
        def _():
 
128
            domain = self.getDomain(domainName)
 
129
            return domain.getIndexItem("name", localpart)
 
130
        return self.store.transact(_)
 
131
    getAvatarFromDomain = getAvatar
 
132
 
 
133
    def requestAvatarId(self, credentials):
 
134
        passwordSecure = implements(credentials, IUsernameHashedPassword)
 
135
        try:
 
136
            usplit = credentials.username.split('@', 1)
 
137
            avatar = self.getAvatarFromDomain(*usplit)
 
138
            password = avatar.getPassword(passwordSecure)
 
139
            if credentials.checkPassword(password):
 
140
                return avatar.storeID
 
141
        except KeyError:
 
142
            pass
 
143
        raise UnauthorizedLogin()
 
144
 
 
145
 
 
146
class StoreRealm(Storeup):
 
147
 
 
148
    dependencies = [StoreCredentialsChecker]
 
149
 
 
150
    __implements__ = IRealm
 
151
 
 
152
    def setUpPools(self, store):
 
153
        store.setComponent(IRealm, self)
 
154
 
 
155
    ##
 
156
    ## Actual IRealm implementation
 
157
    ##
 
158
 
 
159
    def requestAvatar(self, avatarId, mind, interface):
 
160
        """
 
161
        """
 
162
        def _():
 
163
            if avatarId is ANONYMOUS:
 
164
                avatar = AnonymousUser(self.store)
 
165
            else:
 
166
                avatar = self.store.getItemByID(avatarId)
 
167
            avatarAspect = interface(avatar, default=None)
 
168
            if avatarAspect is None:
 
169
                raise UnauthorizedLogin("You're not allowed to access that.")
 
170
            logout = getattr(avatarAspect, 'logout', noLogout)
 
171
            return (interface, avatarAspect, logout)
 
172
        return self.store.transact(_)
 
173
 
 
174
 
 
175
def noLogout():
 
176
    pass