Changeset 15606
- Timestamp:
- 24 Sep 2019, 17:21:28 (5 years ago)
- Location:
- main/waeup.kofa/trunk/src/waeup/kofa
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
main/waeup.kofa/trunk/src/waeup/kofa/browser/pages.py
r15422 r15606 364 364 self.request.principal.id] 365 365 rel_link = '/students/%s' % self.request.principal.id 366 if student.personal_data_expired: 367 rel_link = '/students/%s/edit_personal' % ( 368 self.request.principal.id) 369 self.flash( 370 _('Your personal data record is outdated. Please update.'), 371 type='warning') 366 if student.getParentsPassword(): 367 # Add logging message 368 student.writeLogMessage(self, 'Parents logged in') 369 # Replace role if parents have logged in 370 role_manager = IPrincipalRoleManager(student) 371 role_manager.removeRoleFromPrincipal( 372 'waeup.local.StudentRecordOwner', student.student_id) 373 notify(LocalRoleSetEvent( 374 student, 'waeup.local.StudentRecordOwner', 375 student.student_id, granted=False)) 376 role_manager.assignRoleToPrincipal( 377 'waeup.local.Parents', student.student_id) 378 notify(LocalRoleSetEvent( 379 student, 'waeup.local.Parents', 380 student.student_id, granted=True)) 381 else: 382 # Redirect to personal page if data are outdated 383 if student.personal_data_expired: 384 rel_link = '/students/%s/edit_personal' % ( 385 self.request.principal.id) 386 self.flash( 387 _('Your personal data record is outdated. Please update.'), 388 type='warning') 372 389 self.redirect(self.application_url() + rel_link) 373 390 return … … 402 419 return 403 420 # Display appropriate flash message if credentials are correct 404 # but student has been deactivated or a temporary password405 # has been set.421 # but student has been deactivated or a temporary or parents 422 # password has been set. 406 423 login = self.request.form['form.login'] 407 424 if len(login) == 8 and login in grok.getSite()['students']: … … 413 430 # The student entered valid credentials. 414 431 # First we check if a temporary password has been set. 415 delta = timedelta(minutes=10) 416 now = datetime.utcnow() 417 temp_password_dict = getattr(student, 'temp_password', None) 418 if temp_password_dict is not None and \ 419 now < temp_password_dict.get('timestamp', now) + delta: 432 if student.getTempPassword(): 420 433 self.flash( 421 434 _('Your account has been temporarily deactivated.'), 435 type='warning') 436 return 437 # Next we check if a parents password has been set. 438 if student.getParentsPassword(): 439 self.flash( 440 _('Your account has been temporarily deactivated ' 441 'because your parents have logged in.'), 422 442 type='warning') 423 443 return -
main/waeup.kofa/trunk/src/waeup/kofa/doctests/permissions.txt
r15163 r15606 42 42 43 43 >>> len(list(get_waeup_roles(also_local=True))) 44 5 244 53 45 45 46 46 -
main/waeup.kofa/trunk/src/waeup/kofa/students/authentication.py
r13394 r15606 112 112 def checkPassword(self, password): 113 113 """Check whether the given `password` matches the one stored by 114 students or the temporary password set by officers. 114 students, the temporary password was set by officers or 115 the parents_password was set by parents. 115 116 We additionally check if student account has been suspended 116 117 or if the portal is blocked. … … 128 129 if temp_password: 129 130 return passwordmanager.checkPassword(temp_password, password) 131 parents_password = self.context.getParentsPassword() 132 if parents_password: 133 return passwordmanager.checkPassword(parents_password, password) 130 134 if not getattr(self.context, 'password', None): 131 135 # unset/empty passwords do never match -
main/waeup.kofa/trunk/src/waeup/kofa/students/interfaces.py
r15423 r15606 226 226 password = Attribute('Encrypted password') 227 227 temp_password = Attribute('Dictionary with user name, timestamp and encrypted password') 228 parents_password = Attribute('Dictionary with student_id, timestamp and encrypted password') 228 229 229 230 suspended = schema.Bool( … … 314 315 is not expired. Return the temporary password if valid, 315 316 None otherwise. Unset the temporary password if expired. 317 """ 318 319 def setParentsPassword(password): 320 """Set a parents password (LDAP-compatible) SSHA encoded for 321 parents. 322 """ 323 324 def getParentsPassword(): 325 """Check if a parents password has been set and if it 326 is not expired. 327 328 Return the parents password if valid, 329 None otherwise. Unset the parents password if expired. 316 330 """ 317 331 -
main/waeup.kofa/trunk/src/waeup/kofa/students/permissions.py
r15333 r15606 122 122 'waeup.handleAccommodation', 123 123 'waeup.editStudyLevel') 124 125 class Parents(grok.Role): 126 """Parents temporarily get access to view the records of their children. 127 """ 128 grok.name('waeup.local.Parents') 129 grok.title(u'Parents') 130 grok.permissions('waeup.viewStudent') 124 131 125 132 # Site Roles -
main/waeup.kofa/trunk/src/waeup/kofa/students/student.py
r15416 r15606 31 31 from zope.securitypolicy.interfaces import IPrincipalRoleManager 32 32 from zope.schema.interfaces import ConstraintNotSatisfied 33 33 from zope.event import notify 34 35 from waeup.kofa.authentication import LocalRoleSetEvent 34 36 from waeup.kofa.image import KofaImageFile 35 37 from waeup.kofa.imagestorage import DefaultFileStoreHandler … … 67 69 self.password = None 68 70 self.temp_password = None 71 self.parents_password = None 69 72 return 70 73 … … 96 99 # Unset temporary password if expired 97 100 self.temp_password = None 101 return None 102 103 def setParentsPassword(self, password): 104 """Set a temporary password (LDAP-compatible) SSHA encoded for 105 parents. 106 """ 107 passwordmanager = getUtility(IPasswordManager, 'SSHA') 108 self.parents_password = {} 109 self.parents_password[ 110 'password'] = passwordmanager.encodePassword(password) 111 self.parents_password['timestamp'] = datetime.utcnow() # offset-naive datetime 112 113 def getParentsPassword(self): 114 """Check if a parents password has been set and if it 115 is not expired. 116 117 Return the parents password if valid, 118 None otherwise. Unset the parents password and replace roles 119 if expired. 120 """ 121 parents_password_dict = getattr(self, 'parents_password', None) 122 if parents_password_dict is not None: 123 delta = timedelta(minutes=self.temp_password_minutes) 124 now = datetime.utcnow() 125 if now < parents_password_dict.get('timestamp') + delta: 126 return parents_password_dict.get('password') 127 else: 128 # Unset parents password if expired 129 self.parents_password = None 130 # Replace roles if expired 131 role_manager = IPrincipalRoleManager(self) 132 role_manager.removeRoleFromPrincipal( 133 'waeup.local.Parents', self.student_id) 134 notify(LocalRoleSetEvent( 135 self, 'waeup.local.Parents', 136 self.student_id, granted=False)) 137 role_manager.assignRoleToPrincipal( 138 'waeup.local.StudentRecordOwner', self.student_id) 139 notify(LocalRoleSetEvent( 140 self, 'waeup.local.StudentRecordOwner', 141 self.student_id, granted=True)) 98 142 return None 99 143 -
main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_authentication.py
r9334 r15606 89 89 return None 90 90 91 def getParentsPassword(self): 92 parents_password_dict = getattr(self, 'parents_password', None) 93 if parents_password_dict is not None: 94 delta = timedelta(minutes=self.temp_password_minutes) 95 now = datetime.utcnow() 96 if now < parents_password_dict.get('timestamp') + delta: 97 return parents_password_dict.get('password') 98 else: 99 # Unset temporary password if expired 100 self.parents_password = None 101 return None 102 103 91 104 92 105 class MinimalPAU(PluggableAuthentication): -
main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py
r15545 r15606 4671 4671 self.assertTrue( 4672 4672 'Uploaded file contains illegal data' in self.browser.contents) 4673 4674 class ParentsUITests(StudentsFullSetup): 4675 # Tests for UI actions when acting as parents. 4676 4677 def test_login_as_parents(self): 4678 # Sstudent login still works after all the changes made 4679 self.browser.open(self.login_path) 4680 self.browser.getControl(name="form.login").value = self.student_id 4681 self.browser.getControl(name="form.password").value = 'spwd' 4682 self.browser.getControl("Login").click() 4683 self.assertTrue('You logged in' in self.browser.contents) 4684 self.browser.open(self.edit_personal_path) 4685 self.browser.getLink("Logout").click() 4686 self.assertTrue('You have been logged out' in self.browser.contents) 4687 # We set parents password 4688 self.app['students'][self.student_id].setParentsPassword('ppwd') 4689 self.browser.open(self.login_path) 4690 # Student can't login with original password 4691 self.browser.getControl(name="form.login").value = self.student_id 4692 self.browser.getControl(name="form.password").value = 'spwd' 4693 self.browser.getControl("Login").click() 4694 self.assertEqual(self.browser.url, self.login_path) 4695 self.assertTrue('Your account has been temporarily deactivated ' 4696 'because your parents have logged in.' in self.browser.contents) 4697 # Parents can login with their password 4698 self.browser.open(self.login_path) 4699 self.browser.getControl(name="form.login").value = self.student_id 4700 self.browser.getControl(name="form.password").value = 'ppwd' 4701 self.browser.getControl("Login").click() 4702 self.assertTrue( 4703 'You logged in.' in self.browser.contents) 4704 self.assertTrue( 4705 '<a href="http://localhost/app/students/K1000000">Base Data</a>' 4706 in self.browser.contents) 4707 # They do not see all links ... 4708 self.assertFalse( 4709 '<a href="http://localhost/app/students/K1000000/history">History</a>' 4710 in self.browser.contents) 4711 # ... and can't change anything 4712 self.assertRaises( 4713 Unauthorized, self.browser.open, self.edit_personal_path) 4714 # If the password has expired, parents are logged out and the 4715 # student can login again with the original password 4716 delta = timedelta(minutes=11) 4717 self.app['students'][self.student_id].parents_password[ 4718 'timestamp'] = datetime.utcnow() - delta 4719 self.app['students'][self.student_id]._p_changed = True 4720 self.assertRaises( 4721 Unauthorized, self.browser.open, self.student_path) 4722 # Parents login is written to log file 4723 logfile = os.path.join( 4724 self.app['datacenter'].storage, 'logs', 'students.log') 4725 logcontent = open(logfile).read() 4726 self.assertTrue( 4727 'K1000000 - browser.pages.LoginPage - K1000000 - Parents logged in' 4728 in logcontent) -
main/waeup.kofa/trunk/src/waeup/kofa/students/viewlets.py
r15422 r15606 905 905 student, 'application_slip') 906 906 targets = [] 907 if student.getParentsPassword(): 908 targets += [ 909 {'url': student_url, 'title': 'Base Data'}, 910 {'url': student_url + '/studycourse', 'title': _('Study Course')}, 911 {'url': student_url + '/payments', 'title': _('Payments')}, 912 ] 913 return targets 907 914 if app_slip: 908 915 targets = [{'url': student_url + '/application_slip',
Note: See TracChangeset for help on using the changeset viewer.