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())
Esempio n. 2
0
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))
Esempio n. 3
0
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)
Esempio n. 4
0
def _update_or_create_authorized_user(memberships,
                                      profile,
                                      include_deleted=False):
    user_id = profile.get('id')
    automate_degree_progress_permission = profile.get(
        'automateDegreeProgressPermission')
    can_access_canvas_data = to_bool_or_none(
        profile.get('canAccessCanvasData'))
    can_access_advising_data = to_bool_or_none(
        profile.get('canAccessAdvisingData'))
    degree_progress_permission = profile.get('degreeProgressPermission')

    if (automate_degree_progress_permission or degree_progress_permission
        ) and 'COENG' not in dept_codes_where_advising(
            {'departments': memberships}):
        raise errors.BadRequestError(
            'Degree Progress feature is only available to the College of Engineering.'
        )

    is_admin = to_bool_or_none(profile.get('isAdmin'))
    is_blocked = to_bool_or_none(profile.get('isBlocked'))
    if user_id:
        user = AuthorizedUser.update_user(
            automate_degree_progress_permission=
            automate_degree_progress_permission,
            can_access_advising_data=can_access_advising_data,
            can_access_canvas_data=can_access_canvas_data,
            degree_progress_permission=degree_progress_permission,
            include_deleted=include_deleted,
            is_admin=is_admin,
            is_blocked=is_blocked,
            user_id=user_id,
        )
        UserSession.flush_cache_for_id(user_id=user_id)
        return user
    else:
        uid = profile.get('uid')
        if AuthorizedUser.get_id_per_uid(uid, include_deleted=True):
            raise errors.BadRequestError(
                f'User with UID {uid} is already in the BOA database.')

        calnet_user = calnet.get_calnet_user_for_uid(app,
                                                     uid,
                                                     skip_expired_users=True)
        if calnet_user and calnet_user.get('csid', None):
            return AuthorizedUser.create_or_restore(
                automate_degree_progress_permission=
                automate_degree_progress_permission,
                can_access_advising_data=can_access_advising_data,
                can_access_canvas_data=can_access_canvas_data,
                created_by=current_user.get_uid(),
                degree_progress_permission=degree_progress_permission,
                is_admin=is_admin,
                is_blocked=is_blocked,
                uid=uid,
            )
        else:
            raise errors.BadRequestError('Invalid UID')
Esempio n. 5
0
def _can_current_user_view_cohort(cohort):
    if current_user.is_admin or not cohort.get('owner'):
        return True
    cohort_dept_codes = cohort['owner'].get('deptCodes', [])
    if len(cohort_dept_codes):
        user_dept_codes = dept_codes_where_advising(current_user)
        return len([c for c in user_dept_codes if c in cohort_dept_codes])
    else:
        return False
Esempio n. 6
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
def create_degree():
    params = request.get_json()
    name = get_param(params, 'name', None)
    validate_template_upsert(name=name)
    degree = DegreeProgressTemplate.create(
        advisor_dept_codes=dept_codes_where_advising(current_user),
        created_by=current_user.get_id(),
        degree_name=name,
    )
    return tolerant_jsonify(degree.to_api_json())
Esempio n. 8
0
def is_unauthorized_search(filter_keys, order_by=None):
    filter_key_set = set(filter_keys)
    asc_keys = {'inIntensiveCohort', 'isInactiveAsc', 'groupCodes'}
    if list(filter_key_set & asc_keys) or order_by in ['group_name']:
        if not current_user.is_admin and 'UWASC' not in dept_codes_where_advising(current_user):
            return True
    coe_keys = {
        'coeAdvisorLdapUids',
        'coeEthnicities',
        'coeGenders',
        'coePrepStatuses',
        'coeProbation',
        'coeUnderrepresented',
        'isInactiveCoe',
    }
    if list(filter_key_set & coe_keys):
        if not current_user.is_admin and 'COENG' not in dept_codes_where_advising(current_user):
            return True
    return False
Esempio n. 9
0
def _can_current_user_view_cohort(cohort):
    if current_user.is_admin or not cohort['owners']:
        return True
    cohort_dept_codes = {
        dept_code
        for o in cohort['owners'] for dept_code in o['deptCodes']
    }
    if len(cohort_dept_codes):
        user_dept_codes = dept_codes_where_advising(current_user)
        return len([c for c in user_dept_codes if c in cohort_dept_codes])
    else:
        return False
def clone(template, created_by, name=None, sid=None):
    clone = DegreeProgressTemplate.create(
        advisor_dept_codes=dept_codes_where_advising(current_user),
        created_by=created_by,
        degree_name=name or template.degree_name,
        parent_template_id=template.id if sid else None,
        student_sid=sid,
    )
    unit_requirements_by_source_id = {}
    for unit_requirement in template.unit_requirements:
        source_id = unit_requirement.id
        unit_requirements_by_source_id[
            source_id] = DegreeProgressUnitRequirement.create(
                created_by=created_by,
                min_units=unit_requirement.min_units,
                name=unit_requirement.name,
                template_id=clone.id,
            )

    def _create_category(category_, parent_id):
        unit_requirement_ids = []
        for u in category_['unitRequirements']:
            source_id_ = u['id']
            cross_reference = unit_requirements_by_source_id[source_id_]
            unit_requirement_ids.append(cross_reference.id)
        return DegreeProgressCategory.create(
            category_type=category_['categoryType'],
            name=category_['name'],
            position=category_['position'],
            template_id=clone.id,
            course_units_lower=category_['unitsLower'],
            course_units_upper=category_['unitsUpper'],
            description=category_['description'],
            parent_category_id=parent_id,
            unit_requirement_ids=unit_requirement_ids,
        )

    for category in DegreeProgressCategory.get_categories(
            template_id=template.id):
        c = _create_category(category_=category, parent_id=None)
        for course in category['courseRequirements']:
            _create_category(category_=course, parent_id=c.id)
        for subcategory in category['subcategories']:
            s = _create_category(category_=subcategory, parent_id=c.id)
            for course in subcategory['courseRequirements']:
                _create_category(category_=course, parent_id=s.id)

    # TODO: Unit requirements?
    return DegreeProgressTemplate.find_by_id(clone.id)
Esempio n. 11
0
def _can_current_user_view_curated_group(curated_group):
    if current_user.is_admin:
        return True
    owner = AuthorizedUser.find_by_id(curated_group.owner_id)
    if not owner:
        return False
    curated_group_dept_codes = [
        m.university_dept.dept_code for m in owner.department_memberships
    ]
    if len(curated_group_dept_codes):
        user_dept_codes = dept_codes_where_advising(current_user)
        return len(
            [c for c in user_dept_codes if c in curated_group_dept_codes])
    else:
        return False
Esempio n. 12
0
def get_student_query_scope(user=None):
    if user is None:
        user = current_user
    # Use department membership and admin status to determine what data we can surface about which students.
    # If this code is being called outside an HTTP request context, then assume it is an administrative task.
    # Not all current_user proxy types define all attributes, and so the ordering of these conditional checks
    # is important.
    if not user:
        return ['ADMIN']
    elif hasattr(user, 'is_authenticated') and not user.is_authenticated:
        # This function can be invoked with both (1) user session object or (2) user record from the db.
        # User session object is identified by the presence of 'is_authenticated' method.
        return []
    elif user.is_admin:
        return ['ADMIN']
    elif hasattr(user, 'departments'):
        return dept_codes_where_advising(user)
    else:
        return [m.university_dept.dept_code for m in user.department_memberships]
Esempio n. 13
0
def _get_author_profile():
    author = current_user.to_api_json()
    calnet_profile = get_calnet_user_for_uid(app, author['uid'])
    if calnet_profile and calnet_profile.get('departments'):
        dept_codes = [dept.get('code') for dept in calnet_profile.get('departments')]
    else:
        dept_codes = dept_codes_where_advising(current_user)
    if calnet_profile and calnet_profile.get('title'):
        role = calnet_profile['title']
    elif current_user.departments:
        role = current_user.departments[0]['role']
    else:
        role = None

    return {
        'author_uid': author['uid'],
        'author_name': author['name'],
        'author_role': role,
        'author_dept_codes': dept_codes,
    }
Esempio n. 14
0
File: util.py Progetto: cesarvh/boac
def is_unauthorized_domain(domain):
    if domain not in ['default', 'admitted_students']:
        raise BadRequestError(f'Invalid domain: {domain}')
    elif domain == 'admitted_students' and not app.config[
            'FEATURE_FLAG_ADMITTED_STUDENTS']:
        raise ResourceNotFoundError('Unknown path')
    return domain == 'admitted_students' and not current_user.is_admin and 'ZCEEE' not in dept_codes_where_advising(
        current_user)