Beispiel #1
0
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)
        user = user_id and app.login_manager.user_callback(user_id=user_id,
                                                           flush_cached=True)
        if user 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)
        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)
        return tolerant_jsonify(current_user.to_api_json())
    else:
        raise ResourceNotFoundError('Unknown path')
Beispiel #2
0
def get_service_announcement():
    if current_user.is_authenticated:
        announcement = _get_service_announcement()
        return tolerant_jsonify(announcement if current_user.is_admin
                                or announcement['isPublished'] else None)
    else:
        return tolerant_jsonify(None)
Beispiel #3
0
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
Beispiel #4
0
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_degree_template(template_id):
    template = fetch_degree_template(template_id).to_api_json(include_courses=True)
    parent_template_id = template['parentTemplateId']
    parent_template = DegreeProgressTemplate.find_by_id(parent_template_id) if parent_template_id else None
    if parent_template:
        template['parentTemplateUpdatedAt'] = _isoformat(parent_template.updated_at)
    return tolerant_jsonify(template)
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())
Beispiel #7
0
def _update_drop_in_status(uid, dept_code, active):
    dept_code = dept_code.upper()
    if uid == 'me':
        uid = current_user.get_uid()
    else:
        authorized_to_toggle = current_user.is_admin or dept_code in [
            d['code'] for d in current_user.departments if d.get('isScheduler')
        ]
        if not authorized_to_toggle:
            raise errors.ForbiddenRequestError(
                f'Unauthorized to toggle drop-in status for department {dept_code}'
            )
    drop_in_status = None
    user = AuthorizedUser.find_by_uid(uid)
    if user:
        drop_in_status = next(
            (d for d in user.drop_in_departments if d.dept_code == dept_code),
            None)
    if drop_in_status:
        drop_in_status.update_availability(active)
        UserSession.flush_cache_for_id(user.id)
        return tolerant_jsonify(drop_in_status.to_api_json())
    else:
        raise errors.ResourceNotFoundError(
            f'No drop-in advisor status found: (uid={uid}, dept_code={dept_code})'
        )
Beispiel #8
0
def app_config():
    current_term_name = app.config['CANVAS_CURRENT_ENROLLMENT_TERM']
    current_term_id = sis_term_id_for_name(current_term_name)
    return tolerant_jsonify({
        'boacEnv':
        app.config['BOAC_ENV'],
        'currentEnrollmentTerm':
        current_term_name,
        'currentEnrollmentTermId':
        int(current_term_id),
        'disableMatrixViewThreshold':
        app.config['DISABLE_MATRIX_VIEW_THRESHOLD'],
        'devAuthEnabled':
        app.config['DEVELOPER_AUTH_ENABLED'],
        'ebEnvironment':
        app.config['EB_ENVIRONMENT']
        if 'EB_ENVIRONMENT' in app.config else None,
        'featureFlagAdvisorAppointments':
        app.config['FEATURE_FLAG_ADVISOR_APPOINTMENTS'],
        'googleAnalyticsId':
        app.config['GOOGLE_ANALYTICS_ID'],
        'isDemoModeAvailable':
        app.config['DEMO_MODE_AVAILABLE'],
        'maxAttachmentsPerNote':
        app.config['NOTES_ATTACHMENTS_MAX_PER_NOTE'],
        'pingFrequency':
        app.config['PING_FREQUENCY'],
        'supportEmailAddress':
        app.config['BOAC_SUPPORT_EMAIL'],
        'timezone':
        app.config['TIMEZONE'],
    })
Beispiel #9
0
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)
Beispiel #10
0
def get_appointment(appointment_id):
    appointment = Appointment.find_by_id(appointment_id)
    if not appointment:
        raise ResourceNotFoundError('Unknown path')
    api_json = appointment.to_api_json(current_user.get_id())
    _put_student_profile_per_appointment([api_json])
    return tolerant_jsonify(api_json)
def add_appointment_scheduler_to_dept(dept_code):
    _verify_membership_and_appointments_enabled(current_user, dept_code)
    params = request.get_json() or {}
    scheduler_uid = params.get('uid', None)
    if not scheduler_uid:
        raise errors.BadRequestError('Scheduler UID missing')
    calnet_user = calnet.get_calnet_user_for_uid(app,
                                                 scheduler_uid,
                                                 skip_expired_users=True)
    if not calnet_user or not calnet_user.get('csid'):
        raise errors.BadRequestError('Invalid scheduler UID')
    user = AuthorizedUser.create_or_restore(
        scheduler_uid,
        created_by=current_user.get_uid(),
        is_admin=False,
        is_blocked=False,
        can_access_canvas_data=False,
    )
    Scheduler.create_or_update_membership(
        dept_code,
        user.id,
        drop_in=True,
        same_day=True,
    )
    _create_department_memberships(user, [{
        'code': dept_code,
        'role': 'scheduler',
        'automateMembership': False
    }])
    UserSession.flush_cache_for_id(user.id)
    return tolerant_jsonify(
        _get_appointment_scheduler_list(current_user, dept_code))
Beispiel #12
0
def update_service_announcement():
    params = request.get_json()
    text = process_input_from_rich_text_editor(params.get('text', ''))
    if not text and _is_service_announcement_published():
        raise BadRequestError('If the service announcement is published then API requires \'text\'')
    ToolSetting.upsert('SERVICE_ANNOUNCEMENT_TEXT', text)
    return tolerant_jsonify(_get_service_announcement())
Beispiel #13
0
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)
Beispiel #14
0
def app_config():
    return tolerant_jsonify({
        'academicStandingDescriptions': ACADEMIC_STANDING_DESCRIPTIONS,
        'apptDeskRefreshInterval': app.config['APPT_DESK_REFRESH_INTERVAL'],
        'boacEnv': app.config['BOAC_ENV'],
        'currentEnrollmentTerm': current_term_name(),
        'currentEnrollmentTermId': int(current_term_id()),
        'degreeCategoryTypeOptions': list(
            filter(
                lambda t: 'Placeholder' not in t and 'Campus' not in t, degree_progress_category_type.enums,
            ),
        ) + ['Campus Requirements'],
        'degreeProgressColorCodes': ACCENT_COLOR_CODES,
        'disableMatrixViewThreshold': app.config['DISABLE_MATRIX_VIEW_THRESHOLD'],
        'devAuthEnabled': app.config['DEVELOPER_AUTH_ENABLED'],
        'ebEnvironment': app.config['EB_ENVIRONMENT'] if 'EB_ENVIRONMENT' in app.config else None,
        'featureFlagAdmittedStudents': app.config['FEATURE_FLAG_ADMITTED_STUDENTS'],
        'featureFlagDegreeCheck': app.config['FEATURE_FLAG_DEGREE_CHECK'],
        'fixedWarningOnAllPages': app.config['FIXED_WARNING_ON_ALL_PAGES'],
        'googleAnalyticsId': app.config['GOOGLE_ANALYTICS_ID'],
        'isDemoModeAvailable': app.config['DEMO_MODE_AVAILABLE'],
        'maxAttachmentsPerNote': app.config['NOTES_ATTACHMENTS_MAX_PER_NOTE'],
        'pingFrequency': app.config['PING_FREQUENCY'],
        'supportEmailAddress': app.config['BOAC_SUPPORT_EMAIL'],
        'timezone': app.config['TIMEZONE'],
    })
def create_curated_cohort():
    params = request.get_json()
    name = params.get('name', None)
    if not name:
        raise BadRequestError('Cohort creation requires \'name\'')
    curated_cohort = CuratedCohort.create(current_user.id, name)
    return tolerant_jsonify(curated_cohort.to_api_json())
Beispiel #16
0
def students_with_alerts(cohort_id):
    benchmark = get_benchmarker(f'cohort {cohort_id} students_with_alerts')
    benchmark('begin')
    offset = get_param(request.args, 'offset', 0)
    limit = get_param(request.args, 'limit', 50)
    cohort = CohortFilter.find_by_id(
        cohort_id,
        include_alerts_for_user_id=current_user.get_id(),
        include_students=False,
        alert_offset=offset,
        alert_limit=limit,
    )
    benchmark('fetched cohort')
    if cohort and _can_current_user_view_cohort(cohort):
        _decorate_cohort(cohort)
        students = cohort.get('alerts', [])
        alert_sids = [s['sid'] for s in students]
        alert_profiles = get_summary_student_profiles(alert_sids)
        benchmark('fetched student profiles')
        alert_profiles_by_sid = {p['sid']: p for p in alert_profiles}
        for student in students:
            student.update(alert_profiles_by_sid[student['sid']])
            # The enrolled units count is the one piece of term data we want to preserve.
            if student.get('term'):
                student['term'] = {
                    'enrolledUnits': student['term'].get('enrolledUnits')
                }
    else:
        raise ResourceNotFoundError(
            f'No cohort found with identifier: {cohort_id}')
    benchmark('end')
    return tolerant_jsonify(students)
def user_search():
    snippet = request.get_json().get('snippet', '').strip()
    if snippet:
        search_by_uid = re.match(r'\d+', snippet)
        if search_by_uid:
            users = AuthorizedUser.users_with_uid_like(snippet,
                                                       include_deleted=True)
        else:
            users = AuthorizedUser.get_all_active_users(include_deleted=True)
        users = list(
            calnet.get_calnet_users_for_uids(app,
                                             [u.uid for u in users]).values())
        if not search_by_uid:
            any_ = r'.*'
            pattern = re.compile(any_ + any_.join(snippet.split()) + any_,
                                 re.IGNORECASE)
            users = list(
                filter(lambda u: u.get('name') and pattern.match(u['name']),
                       users))
    else:
        users = []

    def _label(user):
        name = user['name']
        return f"{name} ({user['uid']})" if name else user['uid']

    return tolerant_jsonify([{
        'label': _label(u),
        'uid': u['uid']
    } for u in users])
Beispiel #18
0
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_or_update_user_profile():
    params = request.get_json()
    profile = params.get('profile', None)
    memberships = params.get('memberships', None)
    delete_action = to_bool_or_none(util.get(params, 'deleteAction'))

    if not profile or not profile.get('uid') or memberships is None:
        raise errors.BadRequestError('Required parameters are missing')

    authorized_user = _update_or_create_authorized_user(memberships,
                                                        profile,
                                                        include_deleted=True)
    _delete_existing_memberships(authorized_user)
    _create_department_memberships(authorized_user, memberships)

    if delete_action is True and not authorized_user.deleted_at:
        AuthorizedUser.delete(authorized_user.uid)
    elif delete_action is False and authorized_user.deleted_at:
        AuthorizedUser.un_delete(authorized_user.uid)

    user_id = authorized_user.id
    UserSession.flush_cache_for_id(user_id)

    updated_user = AuthorizedUser.find_by_id(user_id, include_deleted=True)
    users_json = authorized_users_api_feed([updated_user])
    return tolerant_jsonify(users_json and users_json[0])
Beispiel #20
0
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 _update_drop_in_availability(uid, dept_code, new_availability):
    dept_code = dept_code.upper()
    if uid != current_user.get_uid():
        authorized_to_toggle = current_user.is_admin or dept_code in [
            d['code']
            for d in current_user.departments if d.get('role') == 'scheduler'
        ]
        if not authorized_to_toggle:
            raise errors.ForbiddenRequestError(
                f'Unauthorized to toggle drop-in availability for department {dept_code}'
            )
    drop_in_membership = None
    user = AuthorizedUser.find_by_uid(uid)
    if user:
        drop_in_membership = next(
            (d for d in user.drop_in_departments if d.dept_code == dept_code),
            None)
    if drop_in_membership:
        if drop_in_membership.is_available is True and new_availability is False:
            Appointment.unreserve_all_for_advisor(uid, current_user.get_id())
        drop_in_membership.update_availability(new_availability)
        UserSession.flush_cache_for_id(user.id)
        return tolerant_jsonify(drop_in_membership.to_api_json())
    else:
        raise errors.ResourceNotFoundError(
            f'No drop-in advisor membership found: (uid={uid}, dept_code={dept_code})'
        )
Beispiel #22
0
def user_status():
    return tolerant_jsonify({
        'isActive': current_user.is_active,
        'isAnonymous': current_user.is_anonymous,
        'isAuthenticated': current_user.is_authenticated,
        'uid': current_user.get_id(),
    })
Beispiel #23
0
def my_profile():
    uid = current_user.get_id()
    profile = calnet.get_calnet_user_for_uid(app, uid)
    if current_user.is_active:
        authorized_user_id = current_user.id
        curated_cohorts = CuratedCohort.get_curated_cohorts_by_owner_id(authorized_user_id)
        curated_cohorts = [c.to_api_json(sids_only=True) for c in curated_cohorts]
        departments = {}
        for m in current_user.department_memberships:
            departments.update({
                m.university_dept.dept_code: {
                    'isAdvisor': m.is_advisor,
                    'isDirector': m.is_director,
                },
            })
        my_cohorts = CohortFilter.all_owned_by(uid)
        profile.update({
            'myFilteredCohorts': [c.to_api_json(include_students=False) for c in my_cohorts],
            'myCuratedCohorts': curated_cohorts,
            'isAdmin': current_user.is_admin,
            'departments': departments,
        })
    else:
        profile.update({
            'myFilteredCohorts': None,
            'myCuratedCohorts': None,
            'isAdmin': False,
            'departments': None,
        })
    return tolerant_jsonify(profile)
Beispiel #24
0
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 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)
Beispiel #26
0
def all_user_profiles():
    # This feature is not available in production
    if app.config['DEVELOPER_AUTH_ENABLED']:
        users = AuthorizedUser.query.all()
        return tolerant_jsonify(authorized_users_api_feed(users))
    else:
        raise errors.ResourceNotFoundError('Unknown path')
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())
Beispiel #28
0
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 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())
Beispiel #30
0
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}')