def refresh_department_memberships(): from boac.models.authorized_user import AuthorizedUser from boac.models.university_dept import UniversityDept from boac.models.university_dept_member import UniversityDeptMember depts = UniversityDept.query.all() for dept in depts: dept.delete_automated_members() std_commit(allow_test_environment=True) for dept in depts: for membership in dept.memberships_from_loch(): # A non-numeric "uid" indicates a row from SIS advising tables best ignored. if not re.match(r'^\d+$', membership['uid']): continue user = AuthorizedUser.create_or_restore( uid=membership['uid'], created_by='0', can_access_canvas_data=membership['can_access_canvas_data'], ) if user: UniversityDeptMember.create_or_update_membership( dept, user, is_advisor=True, is_director=False, is_scheduler=False, )
def refresh_department_memberships(): from boac.models.authorized_user import AuthorizedUser from boac.models.authorized_user_extension import DropInAdvisor, SameDayAdvisor, Scheduler from boac.models.university_dept import UniversityDept from boac.models.university_dept_member import UniversityDeptMember depts = UniversityDept.query.all() for dept in depts: dept.delete_automated_members() std_commit(allow_test_environment=True) for dept in depts: for membership in dept.memberships_from_loch(): # A non-numeric "uid" indicates a row from SIS advising tables best ignored. if not re.match(r'^\d+$', membership['uid']): continue user = AuthorizedUser.create_or_restore( uid=membership['uid'], created_by='0', can_access_advising_data=membership['can_access_advising_data'], can_access_canvas_data=membership['can_access_canvas_data'], degree_progress_permission=membership['degree_progress_permission'], ) if user: UniversityDeptMember.create_or_update_membership( university_dept_id=dept.id, authorized_user_id=user.id, role='advisor', ) DropInAdvisor.delete_orphans() SameDayAdvisor.delete_orphans() Scheduler.delete_orphans()
def test_deletes_drop_in_advisor_orphans(self): """Cleans up drop-in advisor record for a department membership that no longer exists.""" from boac.models.authorized_user_extension import DropInAdvisor dept_ucls = UniversityDept.query.filter_by( dept_code='QCADVMAJ').first() bad_user = AuthorizedUser.create_or_restore(uid='666', created_by='2040') UniversityDeptMember.create_or_update_membership( dept_ucls.id, bad_user.id, role='advisor', ) DropInAdvisor.create_or_update_membership(dept_ucls.dept_code, bad_user.id) std_commit(allow_test_environment=True) ucls_drop_in_advisors = DropInAdvisor.advisors_for_dept_code( dept_ucls.dept_code) assert len(ucls_drop_in_advisors) == 2 assert bad_user.id in [ d.authorized_user_id for d in ucls_drop_in_advisors ] from boac.api.cache_utils import refresh_department_memberships refresh_department_memberships() std_commit(allow_test_environment=True) ucls_drop_in_advisors = DropInAdvisor.advisors_for_dept_code( dept_ucls.dept_code) assert len(ucls_drop_in_advisors) == 1
def test_allows_advisor_to_change_departments(self): """Updates membership for a former CoE advisor who switches to L&S.""" user = AuthorizedUser.find_by_uid('242881') dept_coe = UniversityDept.query.filter_by(dept_code='COENG').first() UniversityDeptMember.create_or_update_membership( dept_coe.id, user.id, role='advisor', ) dept_ucls = UniversityDept.query.filter_by( dept_code='QCADVMAJ').first() UniversityDeptMember.delete_membership(dept_ucls.id, user.id) std_commit(allow_test_environment=True) ucls_users = [au.authorized_user for au in dept_ucls.authorized_users] assert len(ucls_users) == 2 from boac.api.cache_utils import refresh_department_memberships refresh_department_memberships() std_commit(allow_test_environment=True) ucls_users = [au.authorized_user for au in dept_ucls.authorized_users] assert len(ucls_users) == 3 assert next(u for u in ucls_users if u.uid == '242881') updated_user = AuthorizedUser.query.filter_by(uid='242881').first() assert updated_user.deleted_at is None assert updated_user.created_by == '0' assert updated_user.department_memberships[ 0].university_dept_id == dept_ucls.id
def test_removes_coe_advisors(self, app): """Removes COE advisors not found in the loch.""" dept_coe = UniversityDept.query.filter_by(dept_code='COENG').first() bad_user = AuthorizedUser.create_or_restore(uid='666', created_by='2040') UniversityDeptMember.create_or_update_membership( dept_coe.id, bad_user.id, role='advisor', ) std_commit(allow_test_environment=True) coe_users = [au.authorized_user for au in dept_coe.authorized_users] coe_user_count = len(coe_users) assert coe_user_count assert next(u for u in coe_users if u.uid == '666') assert AuthorizedUser.query.filter_by( uid='666').first().deleted_at is None from boac.api.cache_utils import refresh_department_memberships refresh_department_memberships() std_commit(allow_test_environment=True) coe_users = [au.authorized_user for au in dept_coe.authorized_users] assert len(coe_users) == coe_user_count - 1 assert next((u for u in coe_users if u.uid == '666'), None) is None assert AuthorizedUser.query.filter_by(uid='666').first().deleted_at
def _delete_existing_memberships(authorized_user): existing_memberships = UniversityDeptMember.get_existing_memberships( authorized_user_id=authorized_user.id) for university_dept_id in [ m.university_dept.id for m in existing_memberships ]: UniversityDeptMember.delete_membership( university_dept_id=university_dept_id, authorized_user_id=authorized_user.id, )
def test_respects_automate_memberships_flag(self, app, db): dept_coe = UniversityDept.query.filter_by(dept_code='COENG').first() manually_added_user = AuthorizedUser.create_or_restore( uid='1024', created_by='2040') manual_membership = UniversityDeptMember.create_or_update_membership( dept_coe, manually_added_user, is_advisor=True, is_director=False, is_scheduler=False, automate_membership=False, ) from boac.api.cache_utils import refresh_department_memberships refresh_department_memberships() std_commit(allow_test_environment=True) coe_users = [au.authorized_user for au in dept_coe.authorized_users] assert len(coe_users) == 6 assert next(u for u in coe_users if u.uid == '1024') assert AuthorizedUser.query.filter_by( uid='1024').first().deleted_at is None manual_membership.automate_membership = True db.session.add(manual_membership) std_commit(allow_test_environment=True) refresh_department_memberships() std_commit(allow_test_environment=True) coe_users = [au.authorized_user for au in dept_coe.authorized_users] assert len(coe_users) == 5 assert next((u for u in coe_users if u.uid == '1024'), None) is None assert AuthorizedUser.query.filter_by(uid='1024').first().deleted_at
def available_dept_codes(): if current_user.is_admin: dept_codes = UniversityDeptMember.get_distinct_departments() else: dept_codes = UniversityDeptMember.get_distinct_departments( authorized_user_id=current_user.get_id(), role='director', ) def _to_json(row): dept_code = row.upper() return { 'code': dept_code, 'name': BERKELEY_DEPT_CODE_TO_NAME.get(dept_code), } return tolerant_jsonify([_to_json(d) for d in dept_codes])
def _create_department_memberships(authorized_user, memberships): for membership in [ m for m in memberships if m['role'] in ('advisor', 'director', 'scheduler') ]: university_dept = UniversityDept.find_by_dept_code(membership['code']) role = membership['role'] UniversityDeptMember.create_or_update_membership( university_dept_id=university_dept.id, authorized_user_id=authorized_user.id, role=role, automate_membership=to_bool_or_none( membership['automateMembership']), ) if role == 'scheduler': _delete_drop_in_advisor_status(authorized_user, university_dept.dept_code) UserSession.flush_cache_for_id(authorized_user.id)
def _create_department_memberships(): for dept_code, dept_membership in _university_depts.items(): university_dept = UniversityDept.find_by_dept_code(dept_code) db.session.add(university_dept) for user in dept_membership['users']: authorized_user = AuthorizedUser.find_by_uid(user['uid']) UniversityDeptMember.create_or_update_membership( university_dept_id=university_dept.id, authorized_user_id=authorized_user.id, role=user['role'], automate_membership=user['automate_membership'], ) if user['isDropInAdvisor']: DropInAdvisor.create_or_update_membership( dept_code=dept_code, authorized_user_id=authorized_user.id, is_available=True, )
def _create_department_memberships(): for dept_code, dept_membership in _university_depts.items(): university_dept = UniversityDept.find_by_dept_code(dept_code) db.session.add(university_dept) for user in dept_membership['users']: authorized_user = AuthorizedUser.find_by_uid(user['uid']) UniversityDeptMember.create_or_update_membership( university_dept=university_dept, authorized_user=authorized_user, is_advisor=user['isAdvisor'], is_director=user['isDirector'], is_scheduler=user['isScheduler'], automate_membership=user['automate_membership'], ) if user['isDropInAdvisor']: DropInAdvisor.create_or_update_status( university_dept=university_dept, authorized_user=authorized_user, is_available=True, )
def add_university_dept_membership(): params = request.get_json() or {} dept = UniversityDept.find_by_dept_code(params.get('deptCode', None)) user = AuthorizedUser.find_by_uid(params.get('uid', None)) membership = UniversityDeptMember.create_or_update_membership( university_dept_id=dept.id, authorized_user_id=user.id, role=params.get('role', None), automate_membership=params.get('automateMembership', True), ) return tolerant_jsonify(membership.to_api_json())
def delete_university_dept_membership(university_dept_id, authorized_user_id): if not UniversityDeptMember.delete_membership(university_dept_id, authorized_user_id): raise errors.ResourceNotFoundError( f'University dept membership not found: university_dept_id={university_dept_id} authorized_user_id={authorized_user_id}', ) return tolerant_jsonify( { 'message': f'University dept membership deleted: university_dept_id={university_dept_id} authorized_user_id={authorized_user_id}' }, status=200, )
def add_university_dept_membership(): params = request.get_json() or {} dept = UniversityDept.find_by_dept_code(params.get('deptCode', None)) user = AuthorizedUser.find_by_uid(params.get('uid', None)) membership = UniversityDeptMember.create_or_update_membership( university_dept=dept, authorized_user=user, is_advisor=params.get('isAdvisor', False), is_director=params.get('isDirector', False), is_scheduler=params.get('isScheduler', False), automate_membership=params.get('automateMembership', True), ) return tolerant_jsonify(membership.to_api_json())
def remove_appointment_scheduler_from_dept(dept_code): _verify_membership_and_appointments_enabled(current_user, dept_code) params = request.get_json() or {} uid = params.get('uid') user = uid and AuthorizedUser.find_by_uid(uid) if not user: raise errors.BadRequestError(f'UID {uid} missing or invalid') scheduler_membership = next(( d for d in user.department_memberships if d.university_dept.dept_code == dept_code and d.role == 'scheduler'), None) if not scheduler_membership: raise errors.BadRequestError( f'UID {uid} is not a scheduler for department {dept_code}') UniversityDeptMember.delete_membership( university_dept_id=scheduler_membership.university_dept_id, authorized_user_id=user.id, ) Scheduler.delete(authorized_user_id=user.id, dept_code=dept_code) if not len(user.department_memberships): AuthorizedUser.delete(uid) return tolerant_jsonify( _get_appointment_scheduler_list(current_user, dept_code))
def update_university_dept_membership(): params = request.get_json() or {} dept = UniversityDept.find_by_dept_code(params.get('deptCode', None)) user = AuthorizedUser.find_by_uid(params.get('uid', None)) membership = UniversityDeptMember.update_membership( university_dept_id=dept.id, authorized_user_id=user.id, role=params.get('role', None), automate_membership=params.get('automateMembership', None), ) if not membership: raise errors.BadRequestError( f'Failed to update university dept membership: university_dept_id={dept.id} authorized_user_id={user.id}' ) return tolerant_jsonify(membership.to_api_json())
def test_respects_automate_memberships_flag(self, app, db): dept_coe = UniversityDept.query.filter_by(dept_code='COENG').first() manually_added_user = AuthorizedUser.create_or_restore( uid='1024', created_by='2040', degree_progress_permission='read_write', ) manual_membership = UniversityDeptMember.create_or_update_membership( dept_coe.id, manually_added_user.id, role='advisor', automate_membership=False, ) from boac.api.cache_utils import refresh_department_memberships refresh_department_memberships() std_commit(allow_test_environment=True) coe_users = [au.authorized_user for au in dept_coe.authorized_users] coe_user_count = len(coe_users) assert coe_user_count assert next(u for u in coe_users if u.uid == '1024') user = AuthorizedUser.find_by_uid(uid='1024') assert user assert user.degree_progress_permission == 'read_write' manual_membership.automate_membership = True db.session.add(manual_membership) std_commit(allow_test_environment=True) refresh_department_memberships() std_commit(allow_test_environment=True) coe_users = [au.authorized_user for au in dept_coe.authorized_users] assert len(coe_users) == coe_user_count - 1 assert next((u for u in coe_users if u.uid == '1024'), None) is None assert not AuthorizedUser.find_by_uid(uid='1024')