def remove_user(request): canvas_course_id = request.POST.get('canvas_course_id') sis_user_id = request.POST.get('sis_user_id') canvas_role_id = request.POST.get('canvas_role_id') user_role_id = request.POST.get('user_role_id') try: course_instance_id = request.LTI['lis_course_offering_sourcedid'] except KeyError as e: return lti_key_error_response(request, e) user_role = get_user_role_if_permitted(course_instance_id, user_role_id) if user_role is None: return JsonResponse( {'result': 'failure', 'message': 'Error: The specified user role {} is not valid.' .format(user_role_id)}, status=500) if int(user_role.canvas_role_id) != int(canvas_role_id): logger.exception( u'The specified Canvas role %s does not correspond with user role ' u'%s record\'s Canvas role (%s).', canvas_role_id, user_role_id, user_role.canvas_role_id) return JsonResponse( {'result': 'failure', 'message': 'Error: The specified canvas role {} is not valid.' .format(canvas_role_id)}, status=500) # start by getting all the enrollments for this user user_id = 'sis_user_id:%s' % sis_user_id try: user_enrollments = get_all_list_data( SDK_CONTEXT, enrollments.list_enrollments_users, user_id) except CanvasAPIError as api_error: logger.exception( u"CanvasAPIError trying to get enrollments for user %s", sis_user_id, api_error) return JsonResponse( {'result': 'failure', 'message': 'Error: There was a problem getting enrollments for ' 'the user.'}, status=500) else: # create a filtered list of just the users enrollments for the course # matching the canvas_course_id and the canvas role being removed user_enrollments_to_remove = [ enrollment['id'] for enrollment in user_enrollments if (int(enrollment['course_id']) == int(canvas_course_id) and int(enrollment['role_id']) == int(canvas_role_id))] # Remove the user from all Canvas sections in course for enrollment_id in user_enrollments_to_remove: try: enrollments.conclude_enrollment(SDK_CONTEXT, canvas_course_id, enrollment_id, task='delete') except CanvasAPIError as api_error: logger.exception( u'Canvas API Error trying to delete user %s with enrollment id ' u'%s from course instance %s: %s', sis_user_id, enrollment_id, course_instance_id, api_error ) return JsonResponse( {'result': 'failure', 'message': 'Error: There was a problem in deleting the user'}, status=500) # update canvas api caches canvas_api_helper_courses.delete_cache(canvas_course_id=canvas_course_id) canvas_api_helper_enrollments.delete_cache(canvas_course_id) canvas_api_helper_sections.delete_cache(canvas_course_id) logger.debug( u'Now removing user with user_id=%s from course_instance_id=%s in ' u'CourseManager DB.', sis_user_id, course_instance_id ) # find the enrollment in question model_class = get_course_member_class(user_role) try: enrollment = model_class.objects.get( course_instance_id=course_instance_id, user_id=sis_user_id) except model_class.DoesNotExist: logger.exception(u'Unable to remove user %s from %s membership in ' u'course %s: no such membership exists.', sis_user_id, model_class._meta.db_table, course_instance_id) return JsonResponse( {'result': 'failure', 'message': 'Error: There was a problem in deleting the user'}, status=500) # now delete it try: enrollment.delete() except Exception as e: logger.exception( u"Error in deleting user=%s from course_instance_id=%s: %s", sis_user_id, course_instance_id, e.message ) return JsonResponse( {'result': 'failure', 'message': 'Error: There was a problem in deleting the user'}, status=500) # Record the delete in the audit log audit_logger.info( u'Course Enrollee=%s was deleted by user=%s for canvas_course_id=%s', sis_user_id, request.user.username, canvas_course_id) response_data = { 'result': 'success', 'message': 'User successfully removed from course', } return JsonResponse(response_data)
def add_member_to_course(user_id, user_role_id, course_instance_id, canvas_course_id): """ Returns a (existing_enrollment, person) tuple, existing_enrollment is true if there was already an existing enrollment for the given user/role """ user_role = get_user_role_if_permitted(course_instance_id, user_role_id) if user_role is None: return False, None # get an instance of the correct Course* model class for this role model_class = get_course_member_class(user_role) enrollment = model_class() # populate and store the enrollment in coursemanager enrollment.user_id = user_id enrollment.role_id = user_role_id enrollment.course_instance_id = course_instance_id logger.debug(u'Adding %s to %s table as user_role_id %s', user_id, enrollment._meta.db_table, user_role_id) existing_enrollment = False try: enrollment.save() except IntegrityError as e: existing_enrollment = True logger.exception(u'Unable to save user %s to table %s as user_role_id ' u"%s. It's possible the user is already enrolled.", user_id, enrollment._meta.db_table, user_role_id) except RuntimeError as e: existing_enrollment = True logger.exception(u'Unexpected error while saving user %s to table %s ' u'as user_role_id %s.', user_id, enrollment._meta.db_table, user_role_id) # get and annotate a Person instance for this enrollment person = Person.objects.filter(univ_id=user_id)[0] person.badge_label = get_badge_label_name(person.role_type_cd) person.role_id = user_role.role_id person.role_name = user_role.role_name # create the canvas enrollment if needed. add enrollee to primary section # if it exists, otherwise add to the course. if not existing_enrollment: # TODO: both add_canvas_*_enrollee calls expect (and pass to the api) # a role label. the api docs show that as deprecated, and the # preferred approach is to pass the role id. we should do that. # punted for now so we don't need to do another icommons_common # release. Those helpers are used elsewhere, as well, so there are # refactoring implications. We could use the SDK or the REST API # in the future. canvas_role_name = get_canvas_role_name(user_role_id) canvas_section = get_canvas_course_section(course_instance_id) if canvas_section: canvas_enrollment = add_canvas_section_enrollee( canvas_section['id'], canvas_role_name, user_id, enrollment_role_id=user_role.canvas_role_id) else: canvas_enrollment = add_canvas_course_enrollee( canvas_course_id, canvas_role_name, user_id, enrollment_role_id=user_role.canvas_role_id) if canvas_enrollment: # flush the canvas api caches on successful enrollment canvas_api_helper_courses.delete_cache( canvas_course_id=canvas_course_id) canvas_api_helper_enrollments.delete_cache(canvas_course_id) canvas_api_helper_sections.delete_cache(canvas_course_id) else: logger.error( u'Unable to enroll %s as user_role_id %s (Canvas role id %s) ' u'for course instance id %s.', user_id, user_role_id, user_role.canvas_role_id, course_instance_id) return existing_enrollment, person
def test_student(self): mock_role = Mock(guest="0", staff="0", student="1") self.assertIs(get_course_member_class(mock_role), CourseEnrollee)
def test_none_of_the_above(self): mock_role = Mock(guest="0", staff="0", student="0") with self.assertRaises(RuntimeError): get_course_member_class(mock_role)
def add_member_to_course(user_id, user_role_id, course_instance_id, canvas_course_id): """ Returns a (existing_enrollment, person) tuple, existing_enrollment is true if there was already an existing enrollment for the given user/role """ # bail early if that's not a valid role try: user_role = UserRole.objects.get(role_id=user_role_id) except UserRole.DoesNotExist as e: logger.exception(u'user_role_id %s does not map to a valid user_role ' u'record.', user_role_id) return False, None # get an instance of the correct Course* model class for this role model_class = get_course_member_class(user_role) enrollment = model_class() # populate and store the enrollment in coursemanager enrollment.user_id = user_id enrollment.role_id = user_role_id enrollment.course_instance_id = course_instance_id logger.debug(u'Adding %s to %s table as user_role_id %s', user_id, enrollment._meta.db_table, user_role_id) existing_enrollment = False try: enrollment.save() except IntegrityError as e: existing_enrollment = True logger.exception(u'Unable to save user %s to table %s as user_role_id ' u"%s. It's possible the user is already enrolled.", user_id, enrollment._meta.db_table, user_role_id) except RuntimeError as e: existing_enrollment = True logger.exception(u'Unexpected error while saving user %s to table %s ' u'as user_role_id %s.', user_id, enrollment._meta.db_table, user_role_id) # get and annotate a Person instance for this enrollment person = Person.objects.filter(univ_id=user_id)[0] person.badge_label = get_badge_label_name(person.role_type_cd) person.role_name = user_role.role_name # create the canvas enrollment if needed. add enrollee to primary section # if it exists, otherwise add to the course. if not existing_enrollment: try: mp_role = ManagePeopleRole.objects.get(user_role_id=user_role.role_id) except ManagePeopleRole.DoesNotExist: logger.exception(u"Unable to find user role id %s in the " u'manage_people_role table to find its Canvas role ' u'name.', user_role_id) else: # TODO: both add_canvas_*_enrollee calls expect (and pass to the api) # a role label. the api docs show that as deprecated, and the # preferred approach is to pass the role id. we should do that. # punted for now so we don't need to do another icommons_common # release. canvas_section = get_canvas_course_section(course_instance_id) if canvas_section: canvas_enrollment = add_canvas_section_enrollee( canvas_section['id'], mp_role.canvas_role_label, user_id) else: canvas_enrollment = add_canvas_course_enrollee( canvas_course_id, mp_role.canvas_role_label, user_id) if canvas_enrollment: # flush the canvas api caches on successful enrollment canvas_api_helper_courses.delete_cache( canvas_course_id=canvas_course_id) canvas_api_helper_enrollments.delete_cache(canvas_course_id) canvas_api_helper_sections.delete_cache(canvas_course_id) else: logger.error(u'Unable to enroll %s as user_role_id %s for course ' u'instance id %s.', user_id, user_role_id, course_instance_id) return existing_enrollment, person