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

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

Remove unused class.

File size: 8.9 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)
40from waeup.sirp.jambtables.util import get_applicant_data, application_exists
41from waeup.sirp.accesscodes import get_access_code
42
43class PortalUser(grok.Role):
44    """A role for applicants.
45    """
46    grok.name('waeup.Applicant')
47    grok.permissions('waeup.Public')
48
49class ApplicantPrincipalInfo(object):
50    """Infos about an applicant principal.
51    """
52    grok.implements(IApplicantPrincipalInfo)
53
54    # def __init__(self, id, title, description):
55    # def __init__(self, reg_no, access_code):
56    def __init__(self, access_code, jamb_reg_no=None):
57        self.id = principal_id(access_code, jamb_reg_no)
58        self.title = u'Applicant'
59        self.description = u'An Applicant'
60        self.credentialsPlugin = None
61        self.authenticatorPlugin = None
62        self.reg_no = jamb_reg_no
63        self.access_code = access_code
64
65class ApplicantPrincipal(Principal):
66    """An applicant principal.
67
68    Applicant principals provide an extra `access_code` and `reg_no`
69    attribute extending ordinary principals.
70    """
71
72    grok.implements(IApplicantPrincipal)
73
74    def __init__(self, reg_no, access_code):
75        self.id = '%s-%s' % (reg_no, access_code)
76        self.title = u'Applicant'
77        self.description = u'An applicant'
78        self.groups = []
79        self.reg_no = reg_no
80        self.access_code = access_code
81
82    def __repr__(self):
83        return 'ApplicantPrincipal(%r)' % self.id
84
85class AuthenticatedApplicantPrincipalFactory(grok.MultiAdapter):
86    """Creates 'authenticated' applicant principals.
87
88    Adapts (principal info, request) to an ApplicantPrincipal instance.
89
90    This adapter is used by the standard PAU to transform
91    PrincipalInfos into Principal instances.
92    """
93    grok.adapts(IApplicantPrincipalInfo, IRequest)
94    grok.implements(IAuthenticatedPrincipalFactory)
95
96    def __init__(self, info, request):
97        self.info = info
98        self.request = request
99
100    def __call__(self, authentication):
101        principal = ApplicantPrincipal(
102            authentication.prefix + self.info.reg_no,
103            self.info.access_code
104            )
105        notify(
106            AuthenticatedPrincipalCreated(
107                authentication, principal, self.info, self.request))
108        return principal
109
110
111#
112# Credentials plugins and related....
113#
114
115class ApplicantCredentials(object):
116    """Credentials class for ordinary applicants.
117    """
118    grok.implements(IApplicantSessionCredentials)
119
120    def __init__(self, access_code):
121        self.access_code = access_code
122
123    def getAccessCode(self):
124        """Get the access code.
125        """
126        return self.access_code
127
128    def getLogin(self):
129        """Stay compatible with non-applicant authenticators.
130        """
131        return None
132
133    def getPassword(self):
134        """Stay compatible with non-applicant authenticators.
135        """
136        return None
137   
138class JAMBApplicantCredentials(ApplicantCredentials):
139    """Credentials class for JAMB-screened applicants.
140    """
141    grok.implements(IJAMBApplicantSessionCredentials)
142
143    def __init__(self, access_code, jamb_reg_no):
144        self.access_code = access_code
145        self.jamb_reg_no = jamb_reg_no
146
147    def getJAMBRegNo(self):
148        """Get the JAMB registration no.
149        """
150        return self.jamb_reg_no
151
152class WAeUPApplicantCredentialsPlugin(grok.GlobalUtility,
153                                      SessionCredentialsPlugin):
154    """A credentials plugin that scans requests for applicant credentials.
155    """
156    grok.provides(ICredentialsPlugin)
157    grok.name('applicant_credentials')
158
159    loginpagename = 'login'
160    accesscode_prefix_field = 'form.prefix'
161    accesscode_series_field = 'form.ac_series'
162    accesscode_number_field = 'form.ac_number'
163    jamb_reg_no_field = 'form.jamb_reg_no'
164
165    def extractCredentials(self, request):
166        """Extracts credentials from a session if they exist.
167        """
168        if not IHTTPRequest.providedBy(request):
169            return None
170        session = ISession(request)
171        sessionData = session.get(
172            'zope.pluggableauth.browserplugins')
173        access_code_prefix = request.get(self.accesscode_prefix_field, None)
174        access_code_series = request.get(self.accesscode_series_field, None)
175        access_code_no = request.get(self.accesscode_number_field, None)
176        jamb_reg_no = request.get(self.jamb_reg_no_field, None)
177        access_code = '%s-%s-%s' % (
178            access_code_prefix, access_code_series, access_code_no)
179        if None in [access_code_prefix, access_code_series, access_code_no]:
180            access_code = None
181        credentials = None
182
183        if access_code and jamb_reg_no:
184            credentials = JAMBApplicantCredentials(
185                access_code, jamb_reg_no)
186        elif access_code:
187            credentials = ApplicantCredentials(access_code)
188        elif not sessionData:
189            return None
190        sessionData = session[
191            'zope.pluggableauth.browserplugins']
192        if credentials:
193            sessionData['credentials'] = credentials
194        else:
195            credentials = sessionData.get('credentials', None)
196        if not credentials:
197            return None
198        if not IJAMBApplicantSessionCredentials.providedBy(credentials):
199            # Entered credentials are ordinary applicant credentials,
200            # not JAMB-screened applicant credentials
201            return {'accesscode': credentials.getAccessCode()}
202        return {'accesscode': credentials.getAccessCode(),
203                'jambregno': credentials.getJAMBRegNo()}
204
205
206
207class ApplicantsAuthenticatorPlugin(grok.GlobalUtility):
208    """Authenticate applicants.
209
210    XXX: This plugin currently accepts any input and authenticates the
211    user as applicant.
212    """
213    grok.provides(IAuthenticatorPlugin)
214    grok.name('applicants')
215
216    def authenticateCredentials(self, credentials):
217        if not isinstance(credentials, dict):
218            return None
219        accesscode = credentials.get('accesscode', None)
220        jambregno = credentials.get('jambregno', None)
221        if accesscode is None:
222            return None
223        applicant_data, ac = get_applicant_data(jambregno, accesscode)
224        appl_ac = getattr(applicant_data, 'access_code', None)
225        #print "AUTH", accesscode, jambregno
226        if ac is None:
227            return None
228        if jambregno is not None and applicant_data is None:
229            return None
230        if ac.invalidation_date is not None and appl_ac != ac.representation:
231            return None
232        if appl_ac is not None and appl_ac != ac.representation:
233            return None
234        return ApplicantPrincipalInfo(accesscode, jambregno)
235
236    def principalInfo(self, id):
237        """Returns an IPrincipalInfo object for the specified principal id.
238
239        This method is used by the stadard PAU to lookup for instance
240        groups. If a principal belongs to a group, the group is looked
241        up by the id.  Currently we always return ``None``,
242        indicating, that the principal could not be found. This also
243        means, that is has no effect if applicant users belong to a
244        certain group. They can not gain extra-permissions this way.
245        """
246        return None
247
248def principal_id(access_code, jamb_reg_no=None):
249    """Get a principal ID for applicants.
250
251    We need unique principal ids for appliants. As access codes must
252    be unique we simply return them.
253    """
254    return access_code
Note: See TracBrowser for help on using the repository browser.