def _dev_auth_login(uid, password): if app.config['DEVELOPER_AUTH_ENABLED']: logger = app.logger if password != app.config['DEVELOPER_AUTH_PASSWORD']: logger.error('Dev-auth: Wrong password') return tolerant_jsonify({'message': 'Invalid credentials'}, 401) user_id = AuthorizedUser.get_id_per_uid(uid) if user_id is None: logger.error( f'Dev-auth: User with UID {uid} is not registered in BOA.') return tolerant_jsonify( { 'message': f'Sorry, user with UID {uid} is not registered to use BOA.' }, 403) user = UserSession(user_id=user_id, flush_cached=True) if not user.is_active: logger.error( f'Dev-auth: UID {uid} is registered with BOA but not active.') return tolerant_jsonify( { 'message': f'Sorry, user with UID {uid} is not authorized to use BOA.' }, 403) logger.info(f'Dev-auth used to log in as UID {uid}') login_user(user, force=True, remember=True) UserLogin.record_user_login(uid) return tolerant_jsonify(current_user.to_api_json()) else: raise ResourceNotFoundError('Unknown path')
def cas_login(): logger = app.logger ticket = request.args['ticket'] target_url = request.args.get('url') uid, attributes, proxy_granting_ticket = _cas_client( target_url).verify_ticket(ticket) logger.info(f'Logged into CAS as user {uid}') user_id = AuthorizedUser.get_id_per_uid(uid) if user_id is None: logger.error(f'UID {uid} is not an authorized user.') param = ('error', f""" Sorry, you are not registered to use BOA. Please <a href="mailto:{app.config['BOAC_SUPPORT_EMAIL']}">email us</a> for assistance. """) redirect_url = add_param_to_url('/', param) else: user = UserSession(user_id=user_id, flush_cached=True) if not user.is_active: logger.error( f'UID {uid} is in the BOA db but is not authorized to use the tool.' ) param = ('error', f""" Sorry, you are not registered to use BOA. Please <a href="mailto:{app.config['BOAC_SUPPORT_EMAIL']}">email us</a> for assistance. """) redirect_url = add_param_to_url('/', param) else: login_user(user) flash('Logged in successfully.') UserLogin.record_user_login(uid) # Check if url is safe for redirects per https://flask-login.readthedocs.io/en/latest/ if not _is_safe_url(request.args.get('next')): return abort(400) if not target_url: target_url = '/' # Our googleAnalyticsService uses 'casLogin' marker to track CAS login events redirect_url = add_param_to_url(target_url, ('casLogin', 'true')) return redirect(redirect_url)
def authorized_users_api_feed(users, sort_by=None, sort_descending=False): if not users: return () calnet_users = calnet.get_calnet_users_for_uids(app, [u.uid for u in users]) profiles = [] for user in users: profile = calnet_users[user.uid] if not profile: continue if not profile.get('name'): profile['name'] = ((profile.get('firstName') or '') + ' ' + (profile.get('lastName') or '')).strip() degree_progress_permission = user.degree_progress_permission if app.config['FEATURE_FLAG_DEGREE_CHECK'] else None profile.update({ 'id': user.id, 'isAdmin': user.is_admin, 'isBlocked': user.is_blocked, 'canAccessAdvisingData': user.can_access_advising_data, 'canAccessCanvasData': user.can_access_canvas_data, 'canEditDegreeProgress': degree_progress_permission == 'read_write' or user.is_admin, 'canReadDegreeProgress': degree_progress_permission in ['read', 'read_write'] or user.is_admin, 'degreeProgressPermission': degree_progress_permission, 'deletedAt': _isoformat(user.deleted_at), 'departments': [], }) for m in user.department_memberships: profile['departments'].append({ 'code': m.university_dept.dept_code, 'name': m.university_dept.dept_name, 'role': m.role, 'automateMembership': m.automate_membership, }) profile['dropInAdvisorStatus'] = [d.to_api_json() for d in user.drop_in_departments] profile['sameDayAdvisorStatus'] = [d.to_api_json() for d in user.same_day_departments] user_login = UserLogin.last_login(user.uid) profile['lastLogin'] = _isoformat(user_login.created_at) if user_login else None profiles.append(profile) sort_by = sort_by or 'lastName' return sorted(profiles, key=lambda p: (p.get(sort_by) is None, p.get(sort_by)), reverse=sort_descending)