def update_cohort(): params = request.get_json() cohort_id = int(params.get('id')) name = params.get('name') filters = params.get('filters') # Validation if not name and not filters: raise BadRequestError('Invalid request') if not CohortFilter.is_cohort_owned_by(cohort_id, current_user.get_id()): raise ForbiddenRequestError(f'Invalid or unauthorized request') filter_keys = list(map(lambda f: f['key'], filters)) if is_unauthorized_search(filter_keys): raise ForbiddenRequestError( 'You are unauthorized to access student data managed by other departments' ) filter_criteria = _translate_filters_to_cohort_criteria(filters) updated = CohortFilter.update( cohort_id=cohort_id, name=name, filter_criteria=filter_criteria, include_students=False, include_alerts_for_user_id=current_user.get_id(), ) _decorate_cohort(updated) return tolerant_jsonify(updated)
def download_csv_per_filters(): benchmark = get_benchmarker('cohort download_csv_per_filters') benchmark('begin') params = request.get_json() filters = get_param(params, 'filters', []) fieldnames = get_param(params, 'csvColumnsSelected', []) domain = get_param(params, 'domain', 'default') if (domain == 'default' and not filters) or filters is None: raise BadRequestError('API requires \'filters\'') filter_keys = list(map(lambda f: f['key'], filters)) if is_unauthorized_search(filter_keys): raise ForbiddenRequestError( 'You are unauthorized to access student data managed by other departments' ) domain = get_param(params, 'domain', 'default') if is_unauthorized_domain(domain): raise ForbiddenRequestError( f'You are unauthorized to query the \'{domain}\' domain') cohort = _construct_phantom_cohort( domain=domain, filters=filters, offset=0, limit=None, include_profiles=False, include_sids=True, include_students=False, ) return _response_with_csv_download(benchmark, domain, fieldnames, cohort['sids'])
def create_cohort(): params = request.get_json() domain = get_param(params, 'domain', 'default') if is_unauthorized_domain(domain): raise ForbiddenRequestError( f'You are unauthorized to query the \'{domain}\' domain') name = get_param(params, 'name', None) filters = get_param(params, 'filters', None) order_by = params.get('orderBy') # Authorization check filter_keys = list(map(lambda f: f['key'], filters)) if is_unauthorized_search(filter_keys, order_by): raise ForbiddenRequestError( 'You are unauthorized to access student data managed by other departments' ) filter_criteria = _translate_filters_to_cohort_criteria(filters, domain) if not name or not filter_criteria: raise BadRequestError( 'Cohort creation requires \'name\' and \'filters\'') cohort = CohortFilter.create( uid=current_user.get_uid(), name=name, filter_criteria=filter_criteria, domain=domain, order_by=order_by, include_alerts_for_user_id=current_user.get_id(), ) _decorate_cohort(cohort) return tolerant_jsonify(cohort)
def update_note(): params = request.form body = params.get('body', None) is_private = to_bool_or_none(params.get('isPrivate', False)) note_id = params.get('id', None) subject = params.get('subject', None) topics = get_note_topics_from_http_post() note = Note.find_by_id(note_id=note_id) if note_id else None if not note: raise ResourceNotFoundError('Note not found') if not subject: raise BadRequestError('Note subject is required') if note.author_uid != current_user.get_uid(): raise ForbiddenRequestError( 'Sorry, you are not the author of this note.') if (is_private is not note.is_private ) and not current_user.can_access_private_notes: raise ForbiddenRequestError( 'Sorry, you are not authorized to manage note privacy') note = Note.update( body=process_input_from_rich_text_editor(body), is_private=is_private, note_id=note_id, subject=subject, topics=topics, ) note_read = NoteRead.find_or_create(current_user.get_id(), note_id) return tolerant_jsonify( _boa_note_to_compatible_json(note=note, note_read=note_read))
def create_notes(): benchmark = get_benchmarker('create_notes') params = request.form sids = _get_sids_for_note_creation() benchmark(f'SID count: {len(sids)}') body = params.get('body', None) is_private = to_bool_or_none(params.get('isPrivate', False)) subject = params.get('subject', None) topics = get_note_topics_from_http_post() if not sids or not subject: benchmark('end (BadRequest)') raise BadRequestError( 'Note creation requires \'subject\' and \'sids\'') dept_codes = dept_codes_where_advising(current_user) if current_user.is_admin or not len(dept_codes): benchmark('end (Forbidden)') raise ForbiddenRequestError( 'Sorry, only advisors can create advising notes') if is_private and not current_user.can_access_private_notes: benchmark('end (Forbidden)') raise ForbiddenRequestError( 'Sorry, you are not authorized to manage note privacy.') attachments = get_note_attachments_from_http_post(tolerate_none=True) benchmark(f'Attachment count: {len(attachments)}') body = process_input_from_rich_text_editor(body) template_attachment_ids = get_template_attachment_ids_from_http_post() if len(sids) == 1: note = Note.create( **_get_author_profile(), attachments=attachments, body=body, is_private=is_private, sid=sids[0], subject=subject, template_attachment_ids=template_attachment_ids, topics=topics, ) response = tolerant_jsonify( _boa_note_to_compatible_json(note, note_read=True)) else: response = tolerant_jsonify( Note.create_batch( **_get_author_profile(), attachments=attachments, author_id=current_user.to_api_json()['id'], body=body, is_private=is_private, sids=sids, subject=subject, template_attachment_ids=template_attachment_ids, topics=topics, ), ) benchmark('end') return response
def get_waitlist(dept_code): def _is_current_user_authorized(): return current_user.is_admin or dept_code in _dept_codes_with_scheduler_privilege() dept_code = dept_code.upper() if dept_code not in BERKELEY_DEPT_CODE_TO_NAME: raise ResourceNotFoundError(f'Unrecognized department code: {dept_code}') elif _is_current_user_authorized(): show_all_statuses = current_user.is_drop_in_advisor or current_user.is_admin statuses = appointment_event_type.enums if show_all_statuses else ['reserved', 'waiting'] unresolved = [] resolved = [] for appointment in Appointment.get_drop_in_waitlist(dept_code, statuses): a = appointment.to_api_json(current_user.get_id()) if a['status'] in ['reserved', 'waiting']: unresolved.append(a) else: resolved.append(a) _put_student_profile_per_appointment(unresolved) _put_student_profile_per_appointment(resolved) return tolerant_jsonify({ 'advisors': drop_in_advisors_for_dept_code(dept_code), 'waitlist': { 'unresolved': unresolved, 'resolved': resolved, }, }) else: raise ForbiddenRequestError(f'You are unauthorized to manage {dept_code} appointments.')
def update_appointment(appointment_id): appointment = Appointment.find_by_id(appointment_id) if not appointment: raise ResourceNotFoundError('Unknown path') has_privilege = current_user.is_admin or appointment.dept_code in _dept_codes_with_scheduler_privilege() if not has_privilege: raise ForbiddenRequestError(f'You are unauthorized to manage {appointment.dept_code} appointments.') params = request.get_json() details = params.get('details', None) scheduled_time = params.get('scheduledTime', None) if scheduled_time: scheduled_time = localized_timestamp_to_utc(scheduled_time) student_contact_info = params.get('studentContactInfo', None) student_contact_type = params.get('studentContactType', None) topics = params.get('topics', None) appointment.update( details=process_input_from_rich_text_editor(details), scheduled_time=scheduled_time, student_contact_info=student_contact_info, student_contact_type=student_contact_type, topics=topics, updated_by=current_user.get_id(), ) api_json = appointment.to_api_json(current_user.get_id()) _put_student_profile_per_appointment([api_json]) return tolerant_jsonify(api_json)
def _curated_group_with_complete_student_profiles(curated_group_id, order_by='last_name', offset=0, limit=50): benchmark = get_benchmarker( f'curated group {curated_group_id} with student profiles') benchmark('begin') curated_group = CuratedGroup.find_by_id(curated_group_id) if not curated_group: raise ResourceNotFoundError( f'Sorry, no curated group found with id {curated_group_id}.') if curated_group.owner_id != current_user.get_id(): raise ForbiddenRequestError( f'Current user, {current_user.get_uid()}, does not own curated group {curated_group.id}' ) api_json = curated_group.to_api_json(order_by=order_by, offset=offset, limit=limit) sids = [s['sid'] for s in api_json['students']] benchmark('begin profile query') api_json['students'] = get_summary_student_profiles(sids) benchmark('begin alerts query') Alert.include_alert_counts_for_students( viewer_user_id=current_user.get_id(), group=api_json) benchmark('end') return api_json
def validate_sids(): params = request.get_json() sids = [sid.strip() for sid in list(params.get('sids'))] domain = params.get('domain') or 'default' if is_unauthorized_domain(domain): raise ForbiddenRequestError( f'You are unauthorized to query the \'{domain}\' domain') if sids: if next((sid for sid in sids if not sid.isnumeric()), None): raise BadRequestError('Each SID must be numeric') else: summary = [] if domain == 'admitted_students': available_sids = [ row['sid'] for row in get_admitted_students_by_sids(offset=0, sids=sids) ] else: available_sids = query_students( sids=sids, sids_only=True, academic_career_status=('all'))['sids'] for sid in sids: summary.append({ 'sid': sid, 'status': 200 if sid in available_sids else 404, }) return tolerant_jsonify(summary) else: raise BadRequestError('Requires \'sids\' param')
def search(): params = util.remove_none_values(request.get_json()) order_by = util.get(params, 'orderBy', None) if is_unauthorized_search(list(params.keys()), order_by): raise ForbiddenRequestError( 'You are unauthorized to access student data managed by other departments' ) search_phrase = util.get(params, 'searchPhrase', '').strip() domain = { 'students': util.get(params, 'students'), 'courses': util.get(params, 'courses'), 'notes': util.get(params, 'notes'), } if not domain['students'] and not domain['courses'] and not domain['notes']: raise BadRequestError('No search domain specified') if not len(search_phrase) and not domain['notes']: raise BadRequestError('Invalid or empty search input') feed = {} if len(search_phrase) and domain['students']: feed.update(_student_search(search_phrase, params, order_by)) if len(search_phrase) and domain['courses']: feed.update(_course_search(search_phrase, params, order_by)) if domain['notes']: feed.update(_notes_search(search_phrase, params)) return tolerant_jsonify(feed)
def _filters_to_filter_criteria(filters, order_by=None): filter_keys = list(map(lambda f: f['key'], filters)) if is_unauthorized_search(filter_keys, order_by): raise ForbiddenRequestError( 'You are unauthorized to access student data managed by other departments' ) return CohortFilter.translate_filters_to_cohort_criteria(filters)
def _curated_group_with_complete_student_profiles(curated_group_id, order_by='last_name', term_id=None, offset=0, limit=50): benchmark = get_benchmarker( f'curated group {curated_group_id} with student profiles') benchmark('begin') curated_group = CuratedGroup.find_by_id(curated_group_id) if not curated_group: raise ResourceNotFoundError( f'Sorry, no curated group found with id {curated_group_id}.') if not _can_current_user_view_curated_group(curated_group): raise ForbiddenRequestError( f'Current user, {current_user.get_uid()}, cannot view curated group {curated_group.id}' ) api_json = curated_group.to_api_json(order_by=order_by, offset=offset, limit=limit) sids = [s['sid'] for s in api_json['students']] benchmark('begin profile query') api_json['students'] = get_summary_student_profiles( sids, term_id=term_id, include_historical=True) benchmark('begin alerts query') Alert.include_alert_counts_for_students( viewer_user_id=current_user.get_id(), group=api_json) benchmark('end') benchmark('begin get_referencing_cohort_ids') api_json[ 'referencingCohortIds'] = curated_group.get_referencing_cohort_ids() benchmark('end') return api_json
def get_cohort(cohort_id): benchmark = get_benchmarker(f'cohort {cohort_id} get_cohort') benchmark('begin') filter_keys = list(request.args.keys()) order_by = get_param(request.args, 'orderBy', None) if is_unauthorized_search(filter_keys, order_by): raise ForbiddenRequestError( 'You are unauthorized to access student data managed by other departments' ) include_students = to_bool(get_param(request.args, 'includeStudents')) include_students = True if include_students is None else include_students offset = get_param(request.args, 'offset', 0) limit = get_param(request.args, 'limit', 50) benchmark('begin cohort filter query') cohort = CohortFilter.find_by_id( int(cohort_id), order_by=order_by, offset=int(offset), limit=int(limit), include_alerts_for_user_id=current_user.get_id(), include_profiles=True, include_students=include_students, ) if cohort and _can_current_user_view_cohort(cohort): _decorate_cohort(cohort) benchmark('end') return tolerant_jsonify(cohort) else: raise ResourceNotFoundError( f'No cohort found with identifier: {cohort_id}')
def get_note_template(note_template_id): note_template = NoteTemplate.find_by_id(note_template_id=note_template_id) if not note_template: raise ResourceNotFoundError('Template not found') if note_template.creator_id != current_user.get_id(): raise ForbiddenRequestError('Template not available') return tolerant_jsonify(note_template.to_api_json())
def batch_create_notes(): params = request.form sids = _get_sids_for_note_creation() subject = params.get('subject', None) body = params.get('body', None) topics = get_note_topics_from_http_post() if not sids or not subject: raise BadRequestError('Note creation requires \'subject\' and \'sid\'') user_dept_codes = dept_codes_where_advising(current_user) if current_user.is_admin or not len(user_dept_codes): raise ForbiddenRequestError( 'Sorry, only advisors can create advising notes') author_profile = _get_author_profile() attachments = get_note_attachments_from_http_post(tolerate_none=True) note_ids_per_sid = Note.create_batch( author_id=current_user.to_api_json()['id'], **author_profile, subject=subject, body=process_input_from_rich_text_editor(body), topics=topics, sids=sids, attachments=attachments, template_attachment_ids=get_template_attachment_ids_from_http_post(), ) return tolerant_jsonify(note_ids_per_sid)
def search_students(): params = request.get_json() if is_unauthorized_search(params): raise ForbiddenRequestError( 'You are unauthorized to access student data managed by other departments' ) search_phrase = util.get(params, 'searchPhrase', '').strip() if not len(search_phrase): raise BadRequestError('Invalid or empty search input') results = search_for_students( include_profiles=True, search_phrase=search_phrase.replace(',', ' '), is_active_asc=_convert_asc_inactive_arg( util.get(params, 'isInactiveAsc')), order_by=util.get(params, 'orderBy', None), offset=util.get(params, 'offset', 0), limit=util.get(params, 'limit', 50), ) alert_counts = Alert.current_alert_counts_for_viewer(current_user.id) students = results['students'] add_alert_counts(alert_counts, students) return tolerant_jsonify({ 'students': students, 'totalStudentCount': results['totalStudentCount'], })
def create_note_template(): params = request.form title = params.get('title', None) subject = params.get('subject', None) body = params.get('body', None) topics = get_note_topics_from_http_post() if not title or not subject: raise BadRequestError( 'Note creation requires \'subject\' and \'title\'') user_dept_codes = dept_codes_where_advising(current_user) if current_user.is_admin or not len(user_dept_codes): raise ForbiddenRequestError( 'Sorry, only advisors can create advising note templates') attachments = get_note_attachments_from_http_post(tolerate_none=True) note_template = NoteTemplate.create( attachments=attachments, body=process_input_from_rich_text_editor(body), creator_id=current_user.get_id(), is_private=to_bool_or_none(params.get('isPrivate', False)), subject=subject, title=title, topics=topics, ) return tolerant_jsonify(note_template.to_api_json())
def update_note_template(): params = request.form note_template_id = params.get('id', None) subject = params.get('subject', None) if not subject: raise BadRequestError('Requires \'subject\'') body = params.get('body', None) topics = get_note_topics_from_http_post() delete_ids_ = params.get('deleteAttachmentIds') or [] delete_ids_ = delete_ids_ if isinstance( delete_ids_, list) else str(delete_ids_).split(',') delete_attachment_ids = [int(id_) for id_ in delete_ids_] note_template = NoteTemplate.find_by_id(note_template_id=note_template_id) if not note_template: raise ResourceNotFoundError('Template not found') if note_template.creator_id != current_user.get_id(): raise ForbiddenRequestError('Template not available.') note_template = NoteTemplate.update( attachments=get_note_attachments_from_http_post(tolerate_none=True), body=process_input_from_rich_text_editor(body), delete_attachment_ids=delete_attachment_ids, is_private=to_bool_or_none(params.get('isPrivate', False)), note_template_id=note_template_id, subject=subject, topics=topics, ) return tolerant_jsonify(note_template.to_api_json())
def get_students_with_alerts(curated_group_id): offset = get_param(request.args, 'offset', 0) limit = get_param(request.args, 'limit', 50) benchmark = get_benchmarker( f'curated group {curated_group_id} students_with_alerts') benchmark('begin') curated_group = CuratedGroup.find_by_id(curated_group_id) if not curated_group: raise ResourceNotFoundError( f'Sorry, no curated group found with id {curated_group_id}.') if not _can_current_user_view_curated_group(curated_group): raise ForbiddenRequestError( f'Current user, {current_user.get_uid()}, cannot view curated group {curated_group.id}' ) students = Alert.include_alert_counts_for_students( benchmark=benchmark, viewer_user_id=current_user.get_id(), group={'sids': CuratedGroup.get_all_sids(curated_group_id)}, count_only=True, offset=offset, limit=limit, ) alert_count_per_sid = {} for s in list(filter(lambda s: s.get('alertCount') > 0, students)): sid = s.get('sid') alert_count_per_sid[sid] = s.get('alertCount') sids = list(alert_count_per_sid.keys()) benchmark('begin profile query') students_with_alerts = get_student_profile_summaries(sids=sids) benchmark('end profile query') for student in students_with_alerts: student['alertCount'] = alert_count_per_sid[student['sid']] benchmark('end') return tolerant_jsonify(students_with_alerts)
def get_cohort(cohort_id): if is_unauthorized_search(request.args): raise ForbiddenRequestError( 'You are unauthorized to access student data managed by other departments' ) include_students = util.to_bool_or_none( util.get(request.args, 'includeStudents')) include_students = True if include_students is None else include_students order_by = util.get(request.args, 'orderBy', None) offset = util.get(request.args, 'offset', 0) limit = util.get(request.args, 'limit', 50) cohort = CohortFilter.find_by_id(int(cohort_id)) if cohort and can_view_cohort(current_user, cohort): cohort = decorate_cohort( cohort, order_by=order_by, offset=int(offset), limit=int(limit), include_alerts_for_uid=current_user.uid, include_profiles=True, include_students=include_students, ) return tolerant_jsonify(cohort) else: raise ResourceNotFoundError( f'No cohort found with identifier: {cohort_id}')
def appointment_check_in(appointment_id): appointment = Appointment.find_by_id(appointment_id) if not appointment: raise ResourceNotFoundError('Unknown path') if appointment.dept_code in _dept_codes_with_scheduler_privilege(): params = request.get_json() advisor_uid = params.get('advisorUid', None) if not advisor_uid: raise BadRequestError( 'Appointment check-in requires \'advisor_uid\'') appointment = Appointment.check_in( appointment_id=appointment_id, checked_in_by=current_user.get_id(), advisor_dept_codes=params.get('advisorDeptCodes', None), advisor_name=params.get('advisorName', None), advisor_role=params.get('advisorRole', None), advisor_uid=advisor_uid, ) api_json = appointment.to_api_json(current_user.get_id()) _put_student_profile_per_appointment([api_json]) return tolerant_jsonify(api_json) else: raise ForbiddenRequestError( f'You are unauthorized to manage {appointment.dept_code} appointments.' )
def create_cohort(): params = request.get_json() if is_unauthorized_search(params): raise ForbiddenRequestError( 'You are unauthorized to access student data managed by other departments' ) label = util.get(params, 'label', None) if not label: raise BadRequestError('Cohort creation requires \'label\'') cohort = CohortFilter.create( advisor_ldap_uids=util.get(params, 'advisorLdapUids'), coe_prep_statuses=util.get(params, 'coePrepStatuses'), ethnicities=util.get(params, 'ethnicities'), genders=util.get(params, 'genders'), gpa_ranges=util.get(params, 'gpaRanges'), group_codes=util.get(params, 'groupCodes'), in_intensive_cohort=util.to_bool_or_none( params.get('inIntensiveCohort')), is_inactive_asc=util.to_bool_or_none(params.get('isInactiveAsc')), label=label, last_name_range=util.get(params, 'lastNameRange'), levels=util.get(params, 'levels'), majors=util.get(params, 'majors'), uid=current_user.get_id(), underrepresented=util.get(params, 'underrepresented'), unit_ranges=util.get(params, 'unitRanges'), ) return tolerant_jsonify(decorate_cohort(cohort))
def create_appointment(): params = request.get_json() dept_code = params.get('deptCode', None) sid = params.get('sid', None) advisor_uid = params.get('advisorUid', None) appointment_type = params.get('appointmentType', None) topics = params.get('topics', None) if not dept_code or not sid or not appointment_type or not len(topics): raise BadRequestError( 'Appointment creation: required parameters were not provided') dept_code = dept_code.upper() if dept_code not in BERKELEY_DEPT_CODE_TO_NAME: raise ResourceNotFoundError( f'Unrecognized department code: {dept_code}') if dept_code not in _dept_codes_with_scheduler_privilege(): raise ForbiddenRequestError( f'You are unauthorized to manage {dept_code} appointments.') appointment = Appointment.create( advisor_uid=advisor_uid, appointment_type=appointment_type, created_by=current_user.get_id(), dept_code=dept_code, details=params.get('details', None), student_sid=sid, topics=topics, ) AppointmentRead.find_or_create(current_user.get_id(), appointment.id) api_json = appointment.to_api_json(current_user.get_id()) _put_student_profile_per_appointment([api_json]) return tolerant_jsonify(api_json)
def get_cohort_per_filters(): benchmark = get_benchmarker('cohort get_students_per_filters') benchmark('begin') params = request.get_json() filters = get_param(params, 'filters', []) if not filters: raise BadRequestError('API requires \'filters\'') include_students = to_bool(get_param(params, 'includeStudents')) include_students = True if include_students is None else include_students order_by = get_param(params, 'orderBy', None) offset = get_param(params, 'offset', 0) limit = get_param(params, 'limit', 50) filter_keys = list(map(lambda f: f['key'], filters)) if is_unauthorized_search(filter_keys, order_by): raise ForbiddenRequestError( 'You are unauthorized to access student data managed by other departments' ) benchmark('begin phantom cohort query') cohort = _construct_phantom_cohort( filters=filters, order_by=order_by, offset=int(offset), limit=int(limit), include_alerts_for_user_id=current_user.get_id(), include_profiles=True, include_students=include_students, ) _decorate_cohort(cohort) benchmark('end') return tolerant_jsonify(cohort)
def create_note(): params = request.form sid = params.get('sid', None) subject = params.get('subject', None) body = params.get('body', None) topics = get_note_topics_from_http_post() if not sid or not subject: raise BadRequestError('Note creation requires \'subject\' and \'sid\'') user_dept_codes = dept_codes_where_advising(current_user) if current_user.is_admin or not len(user_dept_codes): raise ForbiddenRequestError( 'Sorry, only advisors can create advising notes.') author_profile = _get_author_profile() attachments = get_note_attachments_from_http_post(tolerate_none=True) note = Note.create( **author_profile, subject=subject, body=process_input_from_rich_text_editor(body), topics=topics, sid=sid, attachments=attachments, template_attachment_ids=get_template_attachment_ids_from_http_post(), ) note_read = NoteRead.find_or_create(current_user.get_id(), note.id) return tolerant_jsonify( _boa_note_to_compatible_json(note=note, note_read=note_read))
def delete_note(note_id): if not current_user.is_admin: raise ForbiddenRequestError('Sorry, you are not authorized to delete notes.') note = Note.find_by_id(note_id=note_id) if not note: raise ResourceNotFoundError('Note not found') Note.delete(note_id=note_id) return tolerant_jsonify({'message': f'Note {note_id} deleted'}), 200
def delete_note_template(note_template_id): note_template = NoteTemplate.find_by_id(note_template_id=note_template_id) if not note_template: raise ResourceNotFoundError('Template not found') if note_template.creator_id != current_user.get_id(): raise ForbiddenRequestError('Template not available') NoteTemplate.delete(note_template_id=note_template_id) return tolerant_jsonify( {'message': f'Note template {note_template_id} deleted'}), 200
def remove_student_from_curated_group(curated_group_id, sid): curated_group = CuratedGroup.find_by_id(curated_group_id) if not curated_group: raise ResourceNotFoundError( f'No curated group found with id: {curated_group_id}') if curated_group.owner_id != current_user.get_id(): raise ForbiddenRequestError( f'Current user, {current_user.get_uid()}, does not own curated group {curated_group.id}' ) CuratedGroup.remove_student(curated_group_id, sid) return tolerant_jsonify(curated_group.to_api_json(include_students=False))
def unreserve_appointment(appointment_id): appointment = Appointment.find_by_id(appointment_id) if not appointment: raise ResourceNotFoundError('Unknown path') has_privilege = current_user.is_admin or appointment.dept_code in _dept_codes_with_scheduler_privilege() if not has_privilege: raise ForbiddenRequestError(f'You are unauthorized to manage appointment {appointment_id}.') if appointment.status != 'reserved': raise BadRequestError(appointment.to_api_json(current_user.get_id())) _set_appointment_to_waiting(appointment) return Response(status=200)
def my_cohorts(): domain = get_param(request.args, 'domain', 'default') if is_unauthorized_domain(domain): raise ForbiddenRequestError( f'You are unauthorized to query the \'{domain}\' domain') cohorts = [] for cohort in CohortFilter.get_cohorts_of_user_id(current_user.get_id(), domain=domain): cohort['isOwnedByCurrentUser'] = True cohorts.append(cohort) return tolerant_jsonify(cohorts)