source: main/waeup.sirp/trunk/src/waeup/sirp/jambtables/authentication.py @ 5440

Last change on this file since 5440 was 5440, checked in by uli, 14 years ago

Start implementing a serious credentials plugin for applicant data.

File size: 7.7 KB
Line 
1##
2## authentication.py
3## Login : <uli@pu.smp.net>
4## Started on  Tue Jul 27 14:26:35 2010 Uli Fouquet
5## $Id$
6##
7## Copyright (C) 2010 Uli Fouquet
8## This program is free software; you can redistribute it and/or modify
9## it under the terms of the GNU General Public License as published by
10## the Free Software Foundation; either version 2 of the License, or
11## (at your option) any later version.
12##
13## This program is distributed in the hope that it will be useful,
14## but WITHOUT ANY WARRANTY; without even the implied warranty of
15## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16## GNU General Public License for more details.
17##
18## You should have received a copy of the GNU General Public License
19## along with this program; if not, write to the Free Software
20## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21##
22"""Special authentication for applicants.
23
24   XXX: This is work in progress, experimental code! Don't do that at home!
25"""
26import grok
27from zope.event import notify
28from zope.pluggableauth.factories import Principal
29from zope.pluggableauth.interfaces import (
30    ICredentialsPlugin, IAuthenticatorPlugin, IPrincipalInfo,
31    IAuthenticatedPrincipalFactory, AuthenticatedPrincipalCreated)
32from zope.pluggableauth.plugins.session import SessionCredentialsPlugin
33from zope.publisher.interfaces import IRequest
34from zope.publisher.interfaces.http import IHTTPRequest
35from zope.session.interfaces import ISession
36from waeup.sirp.authentication import Account, PrincipalInfo
37from waeup.sirp.jambtables.interfaces import (
38    IApplicantPrincipalInfo, IApplicantPrincipal, IApplicantSessionCredentials,
39    IJAMBApplicantSessionCredentials)
40
41class PortalUser(grok.Role):
42    """A role for applicants.
43    """
44    grok.name('waeup.Applicant')
45    grok.permissions('waeup.Public')
46
47class ApplicantAccount(Account):
48    """An account for applicants.
49    """
50    def __init__(self, reg_no, ac):
51        self.name = u'applicant'
52        self.title = u'Applicant'
53        self.description = u'Applicant'
54        self.reg_no = reg_no
55        self.access_code = ac
56        roles = ['waeup.Applicant']
57        self.setRoles(roles)
58
59    def checkPassword(self, reg_no, ac):
60        """Check whether the given credentials exist.
61
62        `reg_no` is a JAMB registration number. `ac` an access code
63        string like ``PUDE-23-1234567890``.
64        """
65        if self.reg_no != reg_no or self.access_code != ac:
66            return False
67        return True
68        site = grok.getSite()
69        if not reg_no in site['applications']:
70            return False
71        data = get_applicant_data(reg_no, ac)
72        if data is None:
73            return False
74        return True
75
76class ApplicantPrincipalInfo(object):
77    grok.implements(IApplicantPrincipalInfo)
78
79    # def __init__(self, id, title, description):
80    def __init__(self, reg_no, access_code):
81        self.id = '%s-%s' % (reg_no, access_code)
82        self.title = u'Applicant'
83        self.description = u'An Applicant'
84        self.credentialsPlugin = None
85        self.authenticatorPlugin = None
86        self.reg_no = reg_no
87        self.access_code = access_code
88
89class ApplicantPrincipal(Principal):
90
91    grok.implements(IApplicantPrincipal)
92
93    def __init__(self, reg_no, access_code):
94        self.id = '%s-%s' % (reg_no, access_code)
95        self.title = u'Applicant'
96        self.description = u'An applicant'
97        self.groups = []
98        self.reg_no = reg_no
99        self.access_code = access_code
100
101    def __repr__(self):
102        return 'ApplicantPrincipal(%r)' % self.id
103
104class AuthenticatedApplicantPrincipalFactory(grok.MultiAdapter):
105    """Creates 'authenticated' applicant principals.
106    """
107    grok.adapts(IApplicantPrincipalInfo, IRequest)
108    grok.implements(IAuthenticatedPrincipalFactory)
109
110    def __init__(self, info, request):
111        self.info = info
112        self.request = request
113
114    def __call__(self, authentication):
115        principal = ApplicantPrincipal(
116            authentication.prefix + self.info.reg_no,
117            self.info.access_code
118            )
119        notify(
120            AuthenticatedPrincipalCreated(
121                authentication, principal, self.info, self.request))
122        return principal
123
124
125#
126# Credentials plugins and related....
127#
128
129class ApplicantCredentials(object):
130    """Credentials class for ordinary applicants.
131    """
132    grok.implements(IApplicantSessionCredentials)
133
134    def __init__(self, access_code):
135        self.access_code = access_code
136
137    def getAccessCode(self):
138        """Get the access code.
139        """
140        return self.access_code
141
142class JAMBApplicantCredentials(ApplicantCredentials):
143    """Credentials class for JAMB-screened applicants.
144    """
145    grok.implements(IJAMBApplicantSessionCredentials)
146
147    def __init__(self, access_code, jamb_reg_no):
148        self.access_code = access_code
149        self.jamb_reg_no = jamb_reg_no
150
151    def getJAMBRegNo(self):
152        """Get the JAMB registration no.
153        """
154        return self.jamb_reg_no
155
156class WAeUPApplicantCredentialsPlugin(grok.GlobalUtility,
157                                      SessionCredentialsPlugin):
158    """A credentials plugin that scans requests for applicant credentials.
159    """
160    grok.provides(ICredentialsPlugin)
161    grok.name('applicant_credentials')
162
163    loginpagename = 'login'
164    accesscode_field = 'form.access_code'
165    jamb_reg_no_field = 'form.jamb_reg_no'
166
167    def extractCredentials(self, request):
168        """Extracts credentials from a session if they exist.
169        """
170        if not IHTTPRequest.providedBy(request):
171            return None
172        session = ISession(request)
173        sessionData = session.get(
174            'zope.pluggableauth.browserplugins')
175        access_code = request.get(self.acccesscode_field, None)
176        jamb_reg_no = request.get(self.jamb_reg_no_field, None)
177        credentials = None
178
179        if access_code and jamb_reg_no:
180            credentials = JAMBApplicantCredentials(
181                access_code, jamb_reg_no)
182        elif access_code:
183            credentials = ApplicantCredentials(access_code)
184        elif not sessionData:
185            return None
186        sessionData = session[
187            'zope.pluggableauth.browserplugins']
188        if credentials:
189            sessionData['credentials'] = credentials
190        else:
191            credentials = sessionData.get('credentials', None)
192        if not credentials:
193            return None
194        if credentials.getJAMBRegNo() is not None:
195            return {'accesscode': credentials.getAccessCode(),
196                    'jambregno': credentials.getJAMBRegNo()}
197        return {'accesscode': credentials.getAccessCode()}
198
199
200class ApplicantsAuthenticatorPlugin(grok.GlobalUtility):
201    """Authenticate applicants.
202
203    XXX: This plugin currently accepts any input and authenticates the
204    user as applicant.
205    """
206    grok.provides(IAuthenticatorPlugin)
207    grok.name('applicants')
208
209    def authenticateCredentials(self, credentials):
210        #print "AUTH: ", credentials
211        if not isinstance(credentials, dict):
212            return None
213        if not 'login' in credentials.keys():
214            return None
215        if not 'password' in credentials.keys():
216            return None
217        return ApplicantPrincipalInfo(
218            credentials['login'], credentials['password']
219            )
220
221    def principalInfo(self, id):
222        """Returns an IPrincipalInfo object for the specified principal id.
223
224        Currently we always return ``None``, indicating, that the principal
225        could not be found.
226        """
227        return None
228
229def principal_id(access_code, jamb_reg_no=None):
230    """Get a principal ID for applicants.
231
232    We need unique principal ids for appliants. As access codes must
233    be unique we simply return them.
234    """
235    return access_code
Note: See TracBrowser for help on using the repository browser.