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
RevLine 
[5431]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 (
[5440]38    IApplicantPrincipalInfo, IApplicantPrincipal, IApplicantSessionCredentials,
39    IJAMBApplicantSessionCredentials)
[5452]40from waeup.sirp.jambtables.util import get_applicant_data, application_exists
[5447]41from waeup.sirp.accesscodes import get_access_code
[5431]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):
[5441]50    """Infos about an applicant principal.
51    """
[5431]52    grok.implements(IApplicantPrincipalInfo)
53
54    # def __init__(self, id, title, description):
[5441]55    # def __init__(self, reg_no, access_code):
56    def __init__(self, access_code, jamb_reg_no=None):
[5444]57        self.id = principal_id(access_code, jamb_reg_no)
[5431]58        self.title = u'Applicant'
59        self.description = u'An Applicant'
60        self.credentialsPlugin = None
61        self.authenticatorPlugin = None
[5441]62        self.reg_no = jamb_reg_no
[5431]63        self.access_code = access_code
64
65class ApplicantPrincipal(Principal):
[5441]66    """An applicant principal.
[5431]67
[5441]68    Applicant principals provide an extra `access_code` and `reg_no`
69    attribute extending ordinary principals.
70    """
71
[5431]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.
[5441]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.
[5431]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
[5440]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
[5444]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   
[5440]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
[5431]152class WAeUPApplicantCredentialsPlugin(grok.GlobalUtility,
153                                      SessionCredentialsPlugin):
[5440]154    """A credentials plugin that scans requests for applicant credentials.
155    """
[5431]156    grok.provides(ICredentialsPlugin)
157    grok.name('applicant_credentials')
158
159    loginpagename = 'login'
[5444]160    accesscode_prefix_field = 'form.prefix'
161    accesscode_series_field = 'form.ac_series'
162    accesscode_number_field = 'form.ac_number'
[5440]163    jamb_reg_no_field = 'form.jamb_reg_no'
[5431]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')
[5444]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)
[5440]176        jamb_reg_no = request.get(self.jamb_reg_no_field, None)
[5444]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
[5431]181        credentials = None
182
[5440]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)
[5431]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
[5452]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()}
[5431]204
205
[5452]206
[5431]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
[5460]219        accesscode = credentials.get('accesscode', None)
220        jambregno = credentials.get('jambregno', None)
221        if accesscode is None:
[5431]222            return None
[5460]223        applicant_data, ac = get_applicant_data(jambregno, accesscode)
224        appl_ac = getattr(applicant_data, 'access_code', None)
225        #print "AUTH", accesscode, jambregno
[5446]226        if ac is None:
227            return None
[5460]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)
[5431]235
236    def principalInfo(self, id):
237        """Returns an IPrincipalInfo object for the specified principal id.
238
[5441]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.
[5431]245        """
246        return None
[5435]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.