Changeset 15609


Ignore:
Timestamp:
26 Sep 2019, 11:38:36 (5 years ago)
Author:
Henrik Bettermann
Message:

Finalize parents access.

Location:
main/waeup.kofa/trunk/src/waeup/kofa
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.kofa/trunk/src/waeup/kofa/browser/templates/loginpage.pt

    r13089 r15609  
    3333    <strong><a href="changepw"> here</a></strong>.
    3434  </p>
     35  <p i18n:translate="login_trouble4"> You are student parents and want to monitor study progress
     36    of your child? Then request a temporary parents password <strong><a href="requestppw"> here</a></strong>.
     37    Prerequisite for getting access is that you have a valid email address and that this address
     38    has been entered by the student into the parents' email address field.
     39  </p>
    3540</form>
  • main/waeup.kofa/trunk/src/waeup/kofa/browser/tests/test_browser.py

    r15287 r15609  
    438438            'adm_code,clr_code,date_of_birth,email,'
    439439            'employer,firstname,flash_notice,lastname,matric_number,middlename,'
    440             'nationality,officer_comment,perm_address,personal_updated,'
     440            'nationality,officer_comment,parents_email,'
     441            'perm_address,personal_updated,'
    441442            'phone,reg_number,sex,student_id,suspended,suspended_comment,'
    442443            'password,state,history,certcode,is_postgrad,current_level,'
  • main/waeup.kofa/trunk/src/waeup/kofa/interfaces.py

    r15416 r15609  
    320320    SEMESTER_DICT = Attribute("Dict of semesters or trimesters")
    321321    SYSTEM_MAX_LOAD = Attribute("Dict of maximum system loads.")
     322    TEMP_PASSWORD_MINUTES = Attribute(
     323        "Temporary passwords and parents password validity period")
    322324
    323325    def sendContactForm(
  • main/waeup.kofa/trunk/src/waeup/kofa/mandates/mandate.py

    r15607 r15609  
    102102        elif self._setPassword():
    103103            msg = _('Parents password has been successfully set. '
    104                     'Login with your parents password.')
     104                    'Login with your new parents password.')
    105105            grok.getSite().logger.info(
    106106                'ParentsPasswordMandate used: %s '
  • main/waeup.kofa/trunk/src/waeup/kofa/mandates/tests.py

    r15607 r15609  
    291291        self.assertEqual(msg,
    292292            'Parents password has been successfully set. '
    293             'Login with your parents password.')
     293            'Login with your new parents password.')
    294294        self.assertEqual(redirect_path, '/login')
    295295        self.assertTrue(IUserAccount(student).checkPassword('mypwd1'))
  • main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py

    r15546 r15609  
    5050    academic_sessions_vocab, IDataCenter, DOCLINK)
    5151from waeup.kofa.interfaces import MessageFactory as _
    52 from waeup.kofa.mandates.mandate import PasswordMandate
     52from waeup.kofa.mandates.mandate import PasswordMandate, ParentsPasswordMandate
    5353from waeup.kofa.university.interfaces import (
    5454    IDepartment, ICertificate, ICourse)
     
    392392    grok.template('loginasstep1')
    393393    pnav = 4
     394
     395    def update(self):
     396        super(LoginAsStudentStep1, self).update()
     397        kofa_utils = getUtility(IKofaUtils)
     398        self.temp_password_minutes = kofa_utils.TEMP_PASSWORD_MINUTES
     399        return
    394400
    395401    def label(self):
     
    25552561    grok.require('waeup.handleStudent')
    25562562    form_fields = grok.AutoFields(IStudentBase).select(
    2557         'email', 'phone')
     2563        'email', 'phone', 'parents_email')
    25582564    label = _('Edit base data')
    25592565    pnav = 4
     
    32163222        return
    32173223
     3224class ParentsUser:
     3225    pass
     3226
     3227class RequestParentsPasswordPage(StudentRequestPasswordPage):
     3228    """Captcha'd request password page for parents.
     3229    """
     3230    grok.name('requestppw')
     3231    grok.template('requestppw')
     3232    label = _('Request password for parents access')
     3233
     3234    def update(self):
     3235        super(RequestParentsPasswordPage, self).update()
     3236        kofa_utils = getUtility(IKofaUtils)
     3237        self.temp_password_minutes = kofa_utils.TEMP_PASSWORD_MINUTES
     3238        return
     3239
     3240    @action(_('Send temporary login credentials to email address'), style='primary')
     3241    def get_credentials(self, **data):
     3242        if not self.captcha_result.is_valid:
     3243            # Captcha will display error messages automatically.
     3244            # No need to flash something.
     3245            return
     3246        number = data.get('number','')
     3247        lastname = data.get('lastname','')
     3248        email = data['email']
     3249        cat = getUtility(ICatalog, name='students_catalog')
     3250        results = list(
     3251            cat.searchResults(reg_number=(number, number)))
     3252        if not results:
     3253            results = list(
     3254                cat.searchResults(matric_number=(number, number)))
     3255        if results:
     3256            student = results[0]
     3257            if getattr(student,'lastname',None) is None:
     3258                self.flash(_('An error occurred.'), type="danger")
     3259                return
     3260            elif student.lastname.lower() != lastname.lower():
     3261                # Don't tell the truth here. Anonymous must not
     3262                # know that a record was found and only the lastname
     3263                # verification failed.
     3264                self.flash(_('No student record found.'), type="warning")
     3265                return
     3266            elif email != student.parents_email:
     3267                self.flash(_('Wrong email address.'), type="warning")
     3268                return
     3269        else:
     3270            self._redirect_no_student()
     3271            return
     3272        kofa_utils = getUtility(IKofaUtils)
     3273        password = kofa_utils.genPassword()
     3274        mandate = ParentsPasswordMandate()
     3275        mandate.params['password'] = password
     3276        mandate.params['student'] = student
     3277        site = grok.getSite()
     3278        site['mandates'].addMandate(mandate)
     3279        # Send email with credentials
     3280        args = {'mandate_id':mandate.mandate_id}
     3281        mandate_url = self.url(site) + '/mandate?%s' % urlencode(args)
     3282        url_info = u'Confirmation link: %s' % mandate_url
     3283        msg = _('You have successfully requested a parents password for the')
     3284        # Create a fake user
     3285        user = ParentsUser()
     3286        user.name = student.student_id
     3287        user.title = "Parents of %s" % student.display_fullname
     3288        user.email = student.parents_email
     3289        if kofa_utils.sendCredentials(user, password, url_info, msg):
     3290            email_sent = user.email
     3291        else:
     3292            email_sent = None
     3293        self._redirect(email=email_sent, password=password,
     3294            student_id=student.student_id)
     3295        ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
     3296        self.context.logger.info(
     3297            '%s - %s (%s) - %s' % (ob_class, number, student.student_id, email_sent))
     3298        return
     3299
    32183300class StudentRequestPasswordEmailSent(KofaPage):
    32193301    """Landing page after successful password request.
  • main/waeup.kofa/trunk/src/waeup/kofa/students/browser_templates/loginasstep1.pt

    r9338 r15609  
    55    for
    66    <span i18n:name="minutes"
    7           tal:replace=view/context/temp_password_minutes></span>
     7          tal:replace=view/temp_password_minutes></span>
    88    minutes. The student can't login
    99    during this time period. After expiration the student can login
  • main/waeup.kofa/trunk/src/waeup/kofa/students/interfaces.py

    r15606 r15609  
    306306        )
    307307
     308    parents_email = schema.ASCIILine(
     309        title = _(u"Parents' Email"),
     310        required = False,
     311        constraint=validate_email,
     312        )
     313
    308314    def setTempPassword(user, password):
    309315        """Set a temporary password (LDAP-compatible) SSHA encoded for
     
    427433    number = schema.TextLine(
    428434        title = _(u'Registr. or Matric. Number'),
    429         required = True,
    430         )
    431 
    432     firstname = schema.TextLine(
    433         title = _(u'First Name'),
    434435        required = True,
    435436        )
  • main/waeup.kofa/trunk/src/waeup/kofa/students/student.py

    r15606 r15609  
    5858    grok.provides(IStudent)
    5959
    60     temp_password_minutes = 10
    61 
    6260    def __init__(self):
    6361        super(Student, self).__init__()
     
    9189        """
    9290        temp_password_dict = getattr(self, 'temp_password', None)
     91        kofa_utils = getUtility(IKofaUtils)
     92        temp_password_minutes =  kofa_utils.TEMP_PASSWORD_MINUTES
    9393        if temp_password_dict is not None:
    94             delta = timedelta(minutes=self.temp_password_minutes)
     94            delta = timedelta(minutes=temp_password_minutes)
    9595            now = datetime.utcnow()
    9696            if now < temp_password_dict.get('timestamp') + delta:
     
    120120        """
    121121        parents_password_dict = getattr(self, 'parents_password', None)
     122        kofa_utils = getUtility(IKofaUtils)
     123        temp_password_minutes =  kofa_utils.TEMP_PASSWORD_MINUTES
    122124        if parents_password_dict is not None:
    123             delta = timedelta(minutes=self.temp_password_minutes)
     125            delta = timedelta(minutes=temp_password_minutes)
    124126            now = datetime.utcnow()
    125127            if now < parents_password_dict.get('timestamp') + delta:
  • main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py

    r15606 r15609  
    37833783            'adm_code,clr_code,date_of_birth,email,employer,'
    37843784            'firstname,flash_notice,lastname,matric_number,middlename,nationality,'
    3785             'officer_comment,perm_address,personal_updated,phone,reg_number,'
     3785            'officer_comment,parents_email,perm_address,'
     3786            'personal_updated,phone,reg_number,'
    37863787            'sex,student_id,suspended,suspended_comment,'
    37873788            'password,state,history,certcode,is_postgrad,'
    37883789            'current_level,current_session\r\n'
    3789             ',,1981-02-04#,aa@aa.ng,,Anna,,Tester,234,,,,,,'
     3790            ',,1981-02-04#,aa@aa.ng,,Anna,,Tester,234,,,,,,,'
    37903791            '1234#,123,m,K1000000,0,,{SSHA}' in self.browser.contents)
    37913792        self.browser.open('http://localhost/app/datacenter/@@export')
     
    39113912            'adm_code,clr_code,date_of_birth,email,employer,'
    39123913            'firstname,flash_notice,lastname,matric_number,middlename,nationality,'
    3913             'officer_comment,perm_address,personal_updated,phone,reg_number,'
     3914            'officer_comment,parents_email,perm_address,'
     3915            'personal_updated,phone,reg_number,'
    39143916            'sex,student_id,suspended,suspended_comment,'
    39153917            'password,state,history,certcode,is_postgrad,'
    39163918            'current_level,current_session\r\n'
    3917             ',,1981-02-04#,aa@aa.ng,,Anna,,Tester,234,,,,,,'
     3919            ',,1981-02-04#,aa@aa.ng,,Anna,,Tester,234,,,,,,,'
    39183920            '1234#,123,m,K1000000,0,,{SSHA}' in self.browser.contents)
    39193921        self.assertEqual(len(self.app['datacenter'].running_exports), 1)
     
    46754677    # Tests for UI actions when acting as parents.
    46764678
     4679    def test_request_ppw(self):
     4680        self.app['students'][self.student_id].parents_email = 'par@yy.zz'
     4681        self.browser.open('http://localhost/app/requestppw')
     4682        self.browser.getControl(name="form.lastname").value = 'tESTer'
     4683        self.browser.getControl(name="form.number").value = '123'
     4684        self.browser.getControl(name="form.email").value = 'par@yy.zz'
     4685        self.browser.getControl("Send temporary login credentials").click()
     4686        self.assertTrue('Your password request was successful.'
     4687            in self.browser.contents)
     4688        logfile = os.path.join(
     4689            self.app['datacenter'].storage, 'logs', 'main.log')
     4690        logcontent = open(logfile).read()
     4691        self.assertTrue('zope.anybody - students.browser.RequestParentsPasswordPage - '
     4692                        '123 (K1000000) - par@yy.zz' in logcontent)
     4693        return
     4694
    46774695    def test_login_as_parents(self):
    4678         # Sstudent login still works after all the changes made
     4696        # Student login still works after all the changes made
    46794697        self.browser.open(self.login_path)
    46804698        self.browser.getControl(name="form.login").value = self.student_id
  • main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_export.py

    r15546 r15609  
    126126    std_csv_entry = (
    127127        'my adm code,my clr code,1981-02-04#,anna@sample.com,,'
    128         'Anna,,Tester,234,M.,NG,,"Studentroad 21\nLagos 123456\n",,'
     128        'Anna,,Tester,234,M.,NG,,,"Studentroad 21\nLagos 123456\n",,'
    129129        '+234-123-12345#,123,f,A111111,0,,,created'
    130130        )
     
    158158            'adm_code,clr_code,date_of_birth,email,'
    159159            'employer,firstname,flash_notice,lastname,matric_number,middlename,'
    160             'nationality,officer_comment,perm_address,personal_updated,'
     160            'nationality,officer_comment,parents_email,'
     161            'perm_address,personal_updated,'
    161162            'phone,reg_number,sex,student_id,suspended,suspended_comment,'
    162163            'password,state,history,'
    163164            'certcode,is_postgrad,current_level,current_session\r\n'
    164165            'my adm code,my clr code,'
    165             '1981-02-04#,anna@sample.com,,Anna,,Tester,234,M.,NG,,'
     166            '1981-02-04#,anna@sample.com,,Anna,,Tester,234,M.,NG,,,'
    166167            '"Studentroad 21\nLagos 123456\n",,+234-123-12345#,123,f,'
    167168            'A111111,0,,,created'
     
    180181            'adm_code,clr_code,date_of_birth,email,'
    181182            'employer,firstname,flash_notice,lastname,matric_number,middlename,'
    182             'nationality,officer_comment,perm_address,personal_updated,'
     183            'nationality,officer_comment,parents_email,'
     184            'perm_address,personal_updated,'
    183185            'phone,reg_number,sex,student_id,suspended,suspended_comment,'
    184186            'password,state,history,certcode,'
    185187            'is_postgrad,current_level,current_session\r\n'
    186188            'my adm code,my clr code,1981-02-04#,anna@sample.com,,'
    187             'Anna,,Tester,234,M.,NG,,"Studentroad 21\nLagos 123456\n"'
     189            'Anna,,Tester,234,M.,NG,,,"Studentroad 21\nLagos 123456\n"'
    188190            ',,+234-123-12345#,123,f,A111111,0,,,created'
    189191            in result
     
    200202            'adm_code,clr_code,date_of_birth,email,'
    201203            'employer,firstname,flash_notice,lastname,matric_number,middlename,'
    202             'nationality,officer_comment,perm_address,personal_updated,'
     204            'nationality,officer_comment,parents_email,'
     205            'perm_address,personal_updated,'
    203206            'phone,reg_number,sex,student_id,suspended,suspended_comment,'
    204207            'password,state,history,certcode,'
    205208            'is_postgrad,current_level,current_session\r\n'
    206209            'my adm code,my clr code,1981-02-04#,anna@sample.com,,'
    207             'Anna,,Tester,234,M.,NG,,"Studentroad 21\nLagos 123456\n"'
     210            'Anna,,Tester,234,M.,NG,,,"Studentroad 21\nLagos 123456\n"'
    208211            ',,+234-123-12345#,123,f,A111111,0,,,created'
    209212            in result
  • main/waeup.kofa/trunk/src/waeup/kofa/utils/utils.py

    r15553 r15609  
    232232    MAX_FILES = 100
    233233
     234    #: Temporary passwords and parents password validity period
     235    TEMP_PASSWORD_MINUTES = 10
     236
    234237    def sendContactForm(self, from_name, from_addr, rcpt_name, rcpt_addr,
    235238                        from_username, usertype, portal, body, subject):
Note: See TracChangeset for help on using the changeset viewer.