def post(self, user_uuid): user = User.get_by_uuid_or_404(user_uuid) # anyone who passes checking below should be an instructor or admin require( EDIT, user, title="Notifications Not Updated", message= "Sorry, your system role does not allow you to update notification settings for this user." ) if not user.email: abort( 400, title="Notifications Not Updated", message= "Sorry, you cannot update notification settings since this user does not have an email address in ComPAIR." ) params = update_notification_settings_parser.parse_args() email_notification_method = params.get("email_notification_method") check_valid_email_notification_method(email_notification_method) user.email_notification_method = EmailNotificationMethod( email_notification_method) db.session.commit() on_user_notifications_update.send( self, event_name=on_user_notifications_update.name, user=current_user) return marshal(user, dataformat.get_user(is_user_access_restricted(user)))
def marshal_user_data(user): if impersonation.is_impersonating() and current_user.id == user.id: # when retrieving the profile of the student being impersonated, # don't include full profile (i.e. no email) return marshal(user, dataformat.get_user(False)) elif allow(MANAGE, user) or current_user.id == user.id: return marshal(user, dataformat.get_full_user()) else: return marshal(user, dataformat.get_user(is_user_access_restricted(user)))
def marshal_user_data(user): if impersonation.is_impersonating() and current_user.id == user.id: # when retrieving the profile of the student being impersonated, # don't include full profile (i.e. no email) return marshal(user, dataformat.get_user(False)) elif can(MANAGE, user) or current_user.id == user.id: return marshal(user, dataformat.get_full_user()) else: return marshal(user, dataformat.get_user(is_user_access_restricted(user)))
def get(self, user_uuid): user = User.get_by_uuid_or_404(user_uuid) on_user_get.send(self, event_name=on_user_get.name, user=current_user, data={'id': user.id}) return marshal(user, dataformat.get_user(is_user_access_restricted(user)))
def get(self, user_uuid): user = User.get_by_uuid_or_404(user_uuid) on_user_get.send( self, event_name=on_user_get.name, user=current_user, data={'id': user.id} ) return marshal(user, dataformat.get_user(is_user_access_restricted(user)))
def get(self, course_uuid, assignment_uuid): course = Course.get_active_by_uuid_or_404(course_uuid) assignment = Assignment.get_active_by_uuid_or_404(assignment_uuid) require(READ, Comparison(course_id=course.id), title="Comparisons Unavailable", message="Sorry, your role in this course does not allow you to view all comparisons for this assignment.") restrict_user = is_user_access_restricted(current_user) params = assignment_users_comparison_list_parser.parse_args() # only get users who have at least made one comparison # each paginated item is a user (with a set of comparisons and self-evaluations) user_query = User.query \ .join(UserCourse, and_( User.id == UserCourse.user_id, UserCourse.course_id == course.id )) \ .join(Comparison, and_( Comparison.user_id == User.id, Comparison.assignment_id == assignment.id )) \ .filter(and_( UserCourse.course_role != CourseRole.dropped, Comparison.completed == True )) \ .group_by(User) \ .order_by(User.lastname, User.firstname) self_evaluation_total = AnswerComment.query \ .join("answer") \ .with_entities( func.count(Answer.assignment_id).label('self_evaluation_count') ) \ .filter(and_( AnswerComment.active == True, AnswerComment.comment_type == AnswerCommentType.self_evaluation, AnswerComment.draft == False, Answer.active == True, Answer.practice == False, Answer.draft == False, Answer.assignment_id == assignment.id )) comparison_total = Comparison.query \ .with_entities( func.count(Comparison.assignment_id).label('comparison_count') ) \ .filter(and_( Comparison.completed == True, Comparison.assignment_id == assignment.id )) if params['author']: user = User.get_by_uuid_or_404(params['author']) user_query = user_query.filter(User.id == user.id) self_evaluation_total = self_evaluation_total.filter(AnswerComment.user_id == user.id) comparison_total = comparison_total.filter(Comparison.user_id == user.id) elif params['group']: user_query = user_query.filter(UserCourse.group_name == params['group']) self_evaluation_total = self_evaluation_total \ .join(UserCourse, and_( AnswerComment.user_id == UserCourse.user_id, UserCourse.course_id == course.id )) \ .filter(UserCourse.group_name == params['group']) comparison_total = comparison_total \ .join(UserCourse, and_( Comparison.user_id == UserCourse.user_id, UserCourse.course_id == course.id )) \ .filter(UserCourse.group_name == params['group']) page = user_query.paginate(params['page'], params['perPage']) self_evaluation_total = self_evaluation_total.scalar() comparison_total = comparison_total.scalar() comparison_sets = [] if page.total: user_ids = [user.id for user in page.items] # get all comparisons that group of users created comparisons = Comparison.query \ .filter(and_( Comparison.completed == True, Comparison.assignment_id == assignment.id, Comparison.user_id.in_(user_ids) )) \ .all() # retrieve the answer comments user_comparison_answers = {} for comparison in comparisons: user_answers = user_comparison_answers.setdefault(comparison.user_id, set()) user_answers.add(comparison.answer1_id) user_answers.add(comparison.answer2_id) conditions = [] for user_id, answer_set in user_comparison_answers.items(): conditions.append(and_( AnswerComment.comment_type == AnswerCommentType.evaluation, AnswerComment.user_id == user_id, AnswerComment.answer_id.in_(list(answer_set)), AnswerComment.assignment_id == assignment.id )) conditions.append(and_( AnswerComment.comment_type == AnswerCommentType.self_evaluation, AnswerComment.user_id == user_id, AnswerComment.assignment_id == assignment.id )) answer_comments = AnswerComment.query \ .filter(or_(*conditions)) \ .filter_by(draft=False) \ .all() # add comparison answer evaluation comments to comparison object for comparison in comparisons: comparison.answer1_feedback = [comment for comment in answer_comments if comment.user_id == comparison.user_id and comment.answer_id == comparison.answer1_id and comment.comment_type == AnswerCommentType.evaluation ] comparison.answer2_feedback = [comment for comment in answer_comments if comment.user_id == comparison.user_id and comment.answer_id == comparison.answer2_id and comment.comment_type == AnswerCommentType.evaluation ] for user in page.items: comparison_sets.append({ 'user': user, 'comparisons': [comparison for comparison in comparisons if comparison.user_id == user.id ], 'self_evaluations': [comment for comment in answer_comments if comment.user_id == user.id and comment.comment_type == AnswerCommentType.self_evaluation ] }) on_assignment_users_comparisons_get.send( self, event_name=on_assignment_users_comparisons_get.name, user=current_user, course_id=course.id, data={'assignment_id': assignment.id} ) return {"objects": marshal(comparison_sets, dataformat.get_comparison_set(restrict_user, with_user=True)), "comparison_total": comparison_total, "self_evaluation_total": self_evaluation_total, "page": page.page, "pages": page.pages, "total": page.total, "per_page": page.per_page}
def get(self, course_uuid, assignment_uuid): course = Course.get_active_by_uuid_or_404(course_uuid) assignment = Assignment.get_active_by_uuid_or_404(assignment_uuid) require(READ, assignment, title="Comparisons Unavailable", message="Sorry, your role in this course does not allow you to view comparisons for this assignment.") restrict_user = is_user_access_restricted(current_user) # get comparisons for current user comparisons = Comparison.query \ .filter(and_( Comparison.completed == True, Comparison.assignment_id == assignment.id, Comparison.user_id == current_user.id )) \ .all() # get all self-evaluations and evaluation comments for current user answer_comments = AnswerComment.query \ .join("answer") \ .filter(and_( AnswerComment.active == True, AnswerComment.comment_type.in_([AnswerCommentType.self_evaluation, AnswerCommentType.evaluation]), AnswerComment.draft == False, Answer.active == True, Answer.draft == False, Answer.assignment_id == assignment.id, AnswerComment.user_id == current_user.id )) \ .all() # add comparison answer evaluation comments to comparison object for comparison in comparisons: comparison.answer1_feedback = [comment for comment in answer_comments if comment.user_id == comparison.user_id and comment.answer_id == comparison.answer1_id and comment.comment_type == AnswerCommentType.evaluation ] comparison.answer2_feedback = [comment for comment in answer_comments if comment.user_id == comparison.user_id and comment.answer_id == comparison.answer2_id and comment.comment_type == AnswerCommentType.evaluation ] on_assignment_user_comparisons_get.send( self, event_name=on_assignment_user_comparisons_get.name, user=current_user, course_id=course.id, data={'assignment_id': assignment.id} ) comparison_set = { 'comparisons': [comparison for comparison in comparisons if comparison.user_id == current_user.id ], 'self_evaluations': [comment for comment in answer_comments if comment.user_id == current_user.id and comment.comment_type == AnswerCommentType.self_evaluation ] } return marshal(comparison_set, dataformat.get_comparison_set(restrict_user, with_user=False))
def get(self, course_uuid, assignment_uuid): course = Course.get_active_by_uuid_or_404(course_uuid) assignment = Assignment.get_active_by_uuid_or_404(assignment_uuid) require(READ, Comparison(course_id=course.id), title="Comparisons Unavailable", message="Sorry, your role in this course does not allow you to view all comparisons for this assignment.") restrict_user = is_user_access_restricted(current_user) params = assignment_users_comparison_list_parser.parse_args() # only get users who have at least made one comparison # each paginated item is a user (with a set of comparisons and self-evaluations) user_query = User.query \ .join(UserCourse, and_( User.id == UserCourse.user_id, UserCourse.course_id == course.id )) \ .join(Comparison, and_( Comparison.user_id == User.id, Comparison.assignment_id == assignment.id )) \ .filter(and_( UserCourse.course_role != CourseRole.dropped, Comparison.completed == True )) \ .group_by(User) \ .order_by(User.lastname, User.firstname) self_evaluation_total = AnswerComment.query \ .join("answer") \ .with_entities( func.count(Answer.assignment_id).label('self_evaluation_count') ) \ .filter(and_( AnswerComment.active == True, AnswerComment.comment_type == AnswerCommentType.self_evaluation, AnswerComment.draft == False, Answer.active == True, Answer.practice == False, Answer.draft == False, Answer.assignment_id == assignment.id )) comparison_total = Comparison.query \ .with_entities( func.count(Comparison.assignment_id).label('comparison_count') ) \ .filter(and_( Comparison.completed == True, Comparison.assignment_id == assignment.id )) if params['author']: user = User.get_by_uuid_or_404(params['author']) user_query = user_query.filter(User.id == user.id) self_evaluation_total = self_evaluation_total.filter(AnswerComment.user_id == user.id) comparison_total = comparison_total.filter(Comparison.user_id == user.id) elif params['group']: group = Group.get_active_by_uuid_or_404(params['group']) user_query = user_query.filter(UserCourse.group_id == group.id) self_evaluation_total = self_evaluation_total \ .join(UserCourse, and_( AnswerComment.user_id == UserCourse.user_id, UserCourse.course_id == course.id )) \ .filter(UserCourse.group_id == group.id) comparison_total = comparison_total \ .join(UserCourse, and_( Comparison.user_id == UserCourse.user_id, UserCourse.course_id == course.id )) \ .filter(UserCourse.group_id == group.id) page = user_query.paginate(params['page'], params['perPage']) self_evaluation_total = self_evaluation_total.scalar() comparison_total = comparison_total.scalar() comparison_sets = [] if page.total: user_ids = [user.id for user in page.items] # get all comparisons that group of users created comparisons = Comparison.query \ .filter(and_( Comparison.completed == True, Comparison.assignment_id == assignment.id, Comparison.user_id.in_(user_ids) )) \ .all() # retrieve the answer comments user_comparison_answers = {} for comparison in comparisons: user_answers = user_comparison_answers.setdefault(comparison.user_id, set()) user_answers.add(comparison.answer1_id) user_answers.add(comparison.answer2_id) conditions = [] for user_id, answer_set in user_comparison_answers.items(): conditions.append(and_( AnswerComment.comment_type == AnswerCommentType.evaluation, AnswerComment.user_id == user_id, AnswerComment.answer_id.in_(list(answer_set)), AnswerComment.assignment_id == assignment.id )) conditions.append(and_( AnswerComment.comment_type == AnswerCommentType.self_evaluation, AnswerComment.user_id == user_id, AnswerComment.assignment_id == assignment.id )) answer_comments = AnswerComment.query \ .filter(or_(*conditions)) \ .filter_by(draft=False) \ .all() # add comparison answer evaluation comments to comparison object for comparison in comparisons: comparison.answer1_feedback = [comment for comment in answer_comments if comment.user_id == comparison.user_id and comment.answer_id == comparison.answer1_id and comment.comment_type == AnswerCommentType.evaluation ] comparison.answer2_feedback = [comment for comment in answer_comments if comment.user_id == comparison.user_id and comment.answer_id == comparison.answer2_id and comment.comment_type == AnswerCommentType.evaluation ] for user in page.items: comparison_sets.append({ 'user': user, 'comparisons': [comparison for comparison in comparisons if comparison.user_id == user.id ], 'self_evaluations': [comment for comment in answer_comments if comment.user_id == user.id and comment.comment_type == AnswerCommentType.self_evaluation ] }) on_assignment_users_comparisons_get.send( self, event_name=on_assignment_users_comparisons_get.name, user=current_user, course_id=course.id, data={'assignment_id': assignment.id} ) return {"objects": marshal(comparison_sets, dataformat.get_comparison_set(restrict_user, with_user=True)), "comparison_total": comparison_total, "self_evaluation_total": self_evaluation_total, "page": page.page, "pages": page.pages, "total": page.total, "per_page": page.per_page}
def post(self, user_uuid): user = User.get_by_uuid_or_404(user_uuid) if is_user_access_restricted(user): abort( 403, title="User Not Saved", message="Sorry, your role does not allow you to save this user." ) params = existing_user_parser.parse_args() # make sure the user id in the url and the id matches if params['id'] != user_uuid: abort( 400, title="User Not Saved", message= "The user's ID does not match the URL, which is required in order to save the user." ) # only update username if user uses compair login method if user.uses_compair_login: username = params.get("username") if username == None: abort( 400, title="User Not Saved", message= "A username is required. Please enter a username and try saving again." ) username_exists = User.query.filter_by(username=username).first() if username_exists and username_exists.id != user.id: abort( 409, title="User Not Saved", message= "Sorry, this username already exists and usernames must be unique in ComPAIR. Please enter another username and try saving again." ) user.username = username elif allow(MANAGE, user): #admins can optionally set username for users without a username username = params.get("username") if username: username_exists = User.query.filter_by( username=username).first() if username_exists and username_exists.id != user.id: abort( 409, title="User Not Saved", message= "Sorry, this username already exists and usernames must be unique in ComPAIR. Please enter another username and try saving again." ) user.username = username else: user.username = None if allow(MANAGE, user): system_role = params.get("system_role", user.system_role.value) check_valid_system_role(system_role) user.system_role = SystemRole(system_role) if allow(MANAGE, user) or user.id == current_user.id or current_app.config.get( 'EXPOSE_EMAIL_TO_INSTRUCTOR', False): if current_user.system_role != SystemRole.student or current_app.config.get( 'ALLOW_STUDENT_CHANGE_EMAIL'): user.email = params.get("email", user.email) email_notification_method = params.get("email_notification_method") check_valid_email_notification_method(email_notification_method) user.email_notification_method = EmailNotificationMethod( email_notification_method) elif params.get("email") or params.get("email_notification_method"): abort( 400, title="User Not Saved", message= "your role does not allow you to change email settings for this user." ) if current_user.system_role != SystemRole.student or current_app.config.get( 'ALLOW_STUDENT_CHANGE_STUDENT_NUMBER'): # only students should have student numbers if user.system_role == SystemRole.student: student_number = params.get("student_number", user.student_number) student_number_exists = User.query.filter_by( student_number=student_number).first() if student_number is not None and student_number_exists and student_number_exists.id != user.id: abort( 409, title="User Not Saved", message= "Sorry, this student number already exists and student numbers must be unique in ComPAIR. Please enter another number and try saving again." ) else: user.student_number = student_number else: user.student_number = None if current_user.system_role != SystemRole.student or current_app.config.get( 'ALLOW_STUDENT_CHANGE_NAME'): user.firstname = params.get("firstname", user.firstname) user.lastname = params.get("lastname", user.lastname) if current_user.system_role != SystemRole.student or current_app.config.get( 'ALLOW_STUDENT_CHANGE_DISPLAY_NAME'): user.displayname = params.get("displayname", user.displayname) model_changes = get_model_changes(user) try: db.session.commit() on_user_modified.send(self, event_name=on_user_modified.name, user=current_user, data={ 'id': user.id, 'changes': model_changes }) except exc.IntegrityError: db.session.rollback() abort( 409, title="User Not Saved", message= "Sorry, this ID already exists and IDs must be unique in ComPAIR. Please try addding another user." ) return marshal_user_data(user)
def post(self, user_uuid): user = User.get_by_uuid_or_404(user_uuid) if is_user_access_restricted(user): abort(403, title="User Not Saved", message="Sorry, your role does not allow you to save this user.") params = existing_user_parser.parse_args() # make sure the user id in the url and the id matches if params['id'] != user_uuid: abort(400, title="User Not Saved", message="The user's ID does not match the URL, which is required in order to save the user.") # only update username if user uses compair login method if user.uses_compair_login: username = params.get("username") if username == None: abort(400, title="User Not Saved", message="A username is required. Please enter a username and try saving again.") username_exists = User.query.filter_by(username=username).first() if username_exists and username_exists.id != user.id: abort(409, title="User Not Saved", message="Sorry, this username already exists and usernames must be unique in ComPAIR. Please enter another username and try saving again.") user.username = username elif allow(MANAGE, user): #admins can optionally set username for users without a username username = params.get("username") if username: username_exists = User.query.filter_by(username=username).first() if username_exists and username_exists.id != user.id: abort(409, title="User Not Saved", message="Sorry, this username already exists and usernames must be unique in ComPAIR. Please enter another username and try saving again.") user.username = username else: user.username = None if allow(MANAGE, user): system_role = params.get("system_role", user.system_role.value) check_valid_system_role(system_role) user.system_role = SystemRole(system_role) if allow(MANAGE, user) or user.id == current_user.id or current_app.config.get('EXPOSE_EMAIL_TO_INSTRUCTOR', False): if current_user.system_role != SystemRole.student or current_app.config.get('ALLOW_STUDENT_CHANGE_EMAIL'): user.email = params.get("email", user.email) email_notification_method = params.get("email_notification_method") check_valid_email_notification_method(email_notification_method) user.email_notification_method = EmailNotificationMethod(email_notification_method) elif params.get("email") or params.get("email_notification_method"): abort(400, title="User Not Saved", message="your role does not allow you to change email settings for this user.") if current_user.system_role != SystemRole.student or current_app.config.get('ALLOW_STUDENT_CHANGE_STUDENT_NUMBER'): # only students should have student numbers if user.system_role == SystemRole.student: student_number = params.get("student_number", user.student_number) student_number_exists = User.query.filter_by(student_number=student_number).first() if student_number is not None and student_number_exists and student_number_exists.id != user.id: abort(409, title="User Not Saved", message="Sorry, this student number already exists and student numbers must be unique in ComPAIR. Please enter another number and try saving again.") else: user.student_number = student_number else: user.student_number = None if current_user.system_role != SystemRole.student or current_app.config.get('ALLOW_STUDENT_CHANGE_NAME'): user.firstname = params.get("firstname", user.firstname) user.lastname = params.get("lastname", user.lastname) if current_user.system_role != SystemRole.student or current_app.config.get('ALLOW_STUDENT_CHANGE_DISPLAY_NAME'): user.displayname = params.get("displayname", user.displayname) model_changes = get_model_changes(user) try: db.session.commit() on_user_modified.send( self, event_name=on_user_modified.name, user=current_user, data={'id': user.id, 'changes': model_changes}) except exc.IntegrityError: db.session.rollback() abort(409, title="User Not Saved", message="Sorry, this ID already exists and IDs must be unique in ComPAIR. Please try addding another user.") return marshal_user_data(user)
def get(self, course_uuid, assignment_uuid): course = Course.get_active_by_uuid_or_404(course_uuid) assignment = Assignment.get_active_by_uuid_or_404(assignment_uuid) require(READ, assignment) can_read = allow(READ, Comparison(course_id=course.id)) restrict_user = is_user_access_restricted(current_user) params = answer_comparison_list_parser.parse_args() # each pagination entry would be one comparison set by a user for the assignment comparison_sets = Comparison.query \ .with_entities(Comparison.user_id, Comparison.answer1_id, Comparison.answer2_id) \ .filter_by(assignment_id=assignment.id, completed=True) \ .group_by(Comparison.user_id, Comparison.answer1_id, Comparison.answer2_id) if not can_read: comparison_sets = comparison_sets.filter_by(user_id=current_user.id) elif params['author']: comparison_sets = comparison_sets.filter_by(user_uuid=params['author']) elif params['group']: subquery = User.query \ .with_entities(User.id) \ .join('user_courses') \ .filter_by(group_name=params['group']) \ .subquery() comparison_sets = comparison_sets.filter(Comparison.user_id.in_(subquery)) page = comparison_sets.paginate(params['page'], params['perPage']) results = [] if page.total: # retrieve the comparisons conditions = [] for user_id, answer1_id, answer2_id in page.items: conditions.append(and_( Comparison.user_id == user_id, Comparison.answer1_id == answer1_id, Comparison.answer2_id == answer2_id )) comparisons = Comparison.query \ .options(joinedload('answer1')) \ .options(joinedload('answer2')) \ .options(joinedload('criterion')) \ .filter_by(completed=True) \ .filter(or_(*conditions)) \ .order_by(Comparison.user_id, Comparison.created) \ .all() # retrieve the answer comments user_comparioson_answers = {} for (user_id, answer1_id, answer2_id), group_set in groupby(comparisons, attrgetter('user_id', 'answer1_id', 'answer2_id')): user_answers = user_comparioson_answers.setdefault(user_id, set()) user_answers.add(answer1_id) user_answers.add(answer2_id) conditions = [] for user_id, answer_set in user_comparioson_answers.items(): conditions.append(and_( AnswerComment.user_id == user_id, AnswerComment.comment_type == AnswerCommentType.evaluation, AnswerComment.answer_id.in_(list(answer_set)) )) conditions.append(and_( AnswerComment.comment_type == AnswerCommentType.self_evaluation, AnswerComment.user_id == user_id, AnswerComment.assignment_id == assignment.id )) answer_comments = AnswerComment.query \ .filter(or_(*conditions)) \ .filter_by(draft=False) \ .all() for (user_id, answer1_id, answer2_id), group_set in groupby(comparisons, attrgetter('user_id', 'answer1_id', 'answer2_id')): group = list(group_set) default = group[0] comparison_set = { 'course_uuid': default.course_uuid, 'assignment_uuid': default.assignment_uuid, 'user_uuid': default.user_uuid, 'comparisons': [comparison for comparison in group], 'answer1_uuid': default.answer1_uuid, 'answer2_uuid': default.answer2_uuid, 'answer1': default.answer1, 'answer2': default.answer2, 'user_fullname': default.user_fullname, 'user_displayname': default.user_displayname, 'user_avatar': default.user_avatar, 'answer1_feedback': [comment for comment in answer_comments if comment.user_id == user_id and comment.answer_id == default.answer1_id and comment.comment_type == AnswerCommentType.evaluation ], 'answer2_feedback': [comment for comment in answer_comments if comment.user_id == user_id and comment.answer_id == default.answer2_id and comment.comment_type == AnswerCommentType.evaluation ], 'self_evaluation': [comment for comment in answer_comments if comment.user_id == user_id and comment.comment_type == AnswerCommentType.self_evaluation ], 'created': default.created } results.append(comparison_set) on_answer_comparisons_get.send( self, event_name=on_answer_comparisons_get.name, user=current_user, course_id=course.id, data={'assignment_id': assignment.id} ) return {'objects': marshal(results, dataformat.get_comparison_set(restrict_user)), "page": page.page, "pages": page.pages, "total": page.total, "per_page": page.per_page}
def post(self, user_uuid): user = User.get_by_uuid_or_404(user_uuid) if is_user_access_restricted(user): return {'error': "Sorry, you don't have permission for this action."}, 403 params = existing_user_parser.parse_args() # make sure the user id in the url and the id matches if params['id'] != user_uuid: return {"error": "User id does not match URL."}, 400 # only update username if user uses compair login method if user.uses_compair_login: username = params.get("username") if username == None: return {"error": "Missing required parameter: username."}, 400 username_exists = User.query.filter_by(username=username).first() if username_exists and username_exists.id != user.id: return {"error": "This username already exists. Please pick another."}, 409 user.username = username elif allow(MANAGE, user): #admins can optionally set username for users without a username username = params.get("username") if username: username_exists = User.query.filter_by(username=username).first() if username_exists and username_exists.id != user.id: return {"error": "This username already exists. Please pick another."}, 409 user.username = username else: user.username = None if allow(MANAGE, user): system_role = params.get("system_role", user.system_role.value) check_valid_system_role(system_role) user.system_role = SystemRole(system_role) # only students should have student numbers if user.system_role == SystemRole.student: student_number = params.get("student_number", user.student_number) student_number_exists = User.query.filter_by(student_number=student_number).first() if student_number is not None and student_number_exists and student_number_exists.id != user.id: return {"error": "This student number already exists. Please pick another."}, 409 else: user.student_number = student_number else: user.student_number = None user.firstname = params.get("firstname", user.firstname) user.lastname = params.get("lastname", user.lastname) user.displayname = params.get("displayname", user.displayname) user.email = params.get("email", user.email) changes = get_model_changes(user) restrict_user = not allow(EDIT, user) try: db.session.commit() on_user_modified.send( self, event_name=on_user_modified.name, user=current_user, data={'id': user.id, 'changes': changes}) except exc.IntegrityError: db.session.rollback() current_app.logger.error("Failed to edit user. Duplicate.") return {'error': 'A user with the same identifier already exists.'}, 409 return marshal(user, dataformat.get_user(restrict_user))