def create(self, request): """Create a new course. Arguments: request -- request data name -- name of the course abbreviation -- abbreviation of the course startdate -- (optional) date when the course starts enddate -- (optional) date when the course ends lti_id -- (optional) lti_id to link the course to Returns: On failure: unauthorized -- when the user is not logged in forbidden -- when the user has no permission to create new courses On succes: success -- with the course data """ request.user.check_permission('can_add_course') name, abbr = utils.required_params(request.data, 'name', 'abbreviation') startdate, enddate, lti_id = utils.optional_params( request.data, 'startdate', 'enddate', 'lti_id') course = factory.make_course(name, abbr, startdate, enddate, request.user, lti_id) serializer = self.serializer_class(course, many=False) return response.created({'course': serializer.data})
def create(self, request): """Create course role. Arguments: request -- request data course_id -- course ID name -- role name permissions -- permissions to change (default everything is false) Returns: On failure: unauthorized -- when the user is not logged in not found -- when the course does not exist forbidden -- when the user is not in the course forbidden -- when the user is unauthorized to edit its roles On success: success -- newly created course """ course_id, name, permissions = utils.required_params( request.data, 'course_id', 'name', 'permissions') course = Course.objects.get(pk=course_id) # TODO: P Is this the right permission request.user.check_permission('can_edit_course_roles', course) try: role = factory.make_role_default_no_perms(name, course, **permissions) except Exception: return response.bad_request() serializer = RoleSerializer(role, many=False) return response.created({'role': serializer.data})
def create(self, request): """Create a new course group. Arguments: request -- the request that was send with name -- name of the course group course_id -- course ID of the course lti_id -- (optional) lti_id to link the course to Returns: On failure: unauthorized -- when the user is not logged in forbidden -- when the user has no permission to create new groups On success, with the course group. """ name, course_id = utils.required_params(request.data, "name", "course_id") lti_id, = utils.optional_params(request.data, 'lti_id') course = Course.objects.get(pk=course_id) request.user.check_permission('can_add_course_user_group', course) if lti_id and Group.objects.filter(lti_id=lti_id, course=course).exists(): return response.bad_request('Course group with the desired name already exists.') course_group = factory.make_course_group(name, course, lti_id) serializer = GroupSerializer(course_group, many=False) return response.created({'group': serializer.data})
def create(self, request): """Create a new comment. Arguments: request -- request data entry_id -- entry ID text -- comment text published -- publishment state Returns: On failure: unauthorized -- when the user is not logged in key_error -- missing keys not_found -- could not find the entry, author or assignment On success: succes -- with the assignment data """ entry_id, text, published = utils.required_params(request.data, "entry_id", "text", "published") entry = Entry.objects.get(pk=entry_id) journal = entry.node.journal assignment = journal.assignment request.user.check_permission('can_comment', assignment) request.user.check_can_view(journal) # By default a comment will be published, only users who can grade can delay publishing. published = published or not request.user.has_permission('can_grade', assignment) comment = factory.make_comment(entry, request.user, text, published) return response.created({'comment': CommentSerializer(comment).data})
def create(self, request): group_id, user_id = utils.required_typed_params(request.data, (int, 'group_id'), (int, 'user_id')) group = Group.objects.get(pk=group_id) member = Participation.objects.get(user=user_id, course=group.course) request.user.check_permission('can_edit_course_user_group', group.course) member.groups.add(group) member.save() users = UserSerializer(group.course.users, context={'course': group.course}, many=True).data return response.created({'participants': users})
def create(self, request): """Set a new grade for an entry. Arguments: request -- request data entry_id -- entry ID grade -- grade published -- published state Returns: On failure: unauthorized -- when the user is not logged in key_error -- missing keys not_found -- could not find the entry, author or assignment On success: success -- with the assignment data """ entry_id, grade, published = utils.required_typed_params( request.data, (int, 'entry_id'), (float, 'grade'), (bool, 'published')) entry = Entry.objects.get(pk=entry_id) journal = entry.node.journal assignment = journal.assignment request.user.check_permission('can_grade', assignment) if published: request.user.check_permission('can_publish_grades', assignment) if grade is not None and grade < 0: return response.bad_request( 'Grade must be greater than or equal to zero.') grade = factory.make_grade(entry, request.user.pk, grade, published) if published: Comment.objects.filter(entry=entry).update(published=True) # TODO: Is the lti flag ever used? Else move replace_result to celery return response.created({ 'entry': EntrySerializer(entry, context={ 'user': request.user }).data, 'lti': lti_grade.replace_result(journal) })
def create(self, request): """Add a user to a course. Arguments: request -- request data user_id -- user ID course_id -- course ID Returns: On failure: unauthorized -- when the user is not logged in not found -- when course or user is not found forbidden -- when the logged in user is not connected to the course bad request -- when the new user is already connected to the course not found -- when the role doesnt exist On success: success -- success message """ user_id, course_id = utils.required_typed_params( request.data, (int, 'user_id'), (int, 'course_id')) role_name = 'Student' user = User.objects.get(pk=user_id) course = Course.objects.get(pk=course_id) request.user.check_permission('can_add_course_users', course) if user.is_participant(course): return response.bad_request( 'User already participates in the course.') role = Role.objects.get(name=role_name, course=course) factory.make_participation(user, course, role) assignments = course.assignment_set.all() for assignment in assignments: if not Journal.objects.filter(assignment=assignment, user=user).exists(): factory.make_journal(assignment, user) serializer = UserSerializer(user, context={'course': course}) return response.created( {'participant': serializer.data}, description='Successfully added student to course.')
def create(self, request): """Create a new assignment. Arguments: request -- request data name -- name of the assignment description -- description of the assignment course_id -- id of the course the assignment belongs to points_possible -- the possible amount of points for the assignment unlock_date -- (optional) date the assignment becomes available on due_date -- (optional) date the assignment is due for lock_date -- (optional) date the assignment becomes unavailable on lti_id -- id labeled link to LTI instance Returns: On failure: unauthorized -- when the user is not logged in not_found -- could not find the course with the given id key_error -- missing keys forbidden -- the user is not allowed to create assignments in this course On success: succes -- with the assignment data """ name, description, course_id = utils.required_params(request.data, "name", "description", "course_id") points_possible, unlock_date, due_date, lock_date, lti_id, is_published = \ utils.optional_params(request.data, "points_possible", "unlock_date", "due_date", "lock_date", "lti_id", "is_published") course = Course.objects.get(pk=course_id) request.user.check_permission('can_add_assignment', course) assignment = factory.make_assignment(name, description, courses=[course], author=request.user, lti_id=lti_id, points_possible=points_possible, unlock_date=unlock_date, due_date=due_date, lock_date=lock_date, is_published=is_published) for user in course.users.all(): factory.make_journal(assignment, user) serializer = AssignmentSerializer(assignment, context={'user': request.user, 'course': course}) return response.created({'assignment': serializer.data})
def create(self, request): """Create a new entry. Deletes remaining temporary user files if successful. Arguments: request -- the request that was send with journal_id -- the journal id template_id -- the template id to create the entry with node_id -- optional: the node to bind the entry to (only for entrydeadlines) content -- the list of {tag, data} tuples to bind data to a template field. """ journal_id, template_id, content_list = utils.required_params( request.data, "journal_id", "template_id", "content") node_id, = utils.optional_params(request.data, "node_id") journal = Journal.objects.get(pk=journal_id, user=request.user) assignment = journal.assignment template = Template.objects.get(pk=template_id) request.user.check_permission('can_have_journal', assignment) if assignment.is_locked(): return response.forbidden( 'The assignment is locked, entries can no longer be edited/changed.' ) if journal.needs_lti_link(): return response.forbidden(journal.outdated_link_warning_msg) # Check if the template is available if not (node_id or assignment.format.template_set.filter( archived=False, preset_only=False, pk=template.pk).exists()): return response.forbidden('Entry template is not available.') entry_utils.check_fields(template, content_list) # Node specific entry if node_id: node = Node.objects.get(pk=node_id, journal=journal) entry = entry_utils.add_entry_to_node(node, template) # Template specific entry else: entry = factory.make_entry(template) node = factory.make_node(journal, entry) for content in content_list: field_id, = utils.required_typed_params(content, (int, 'id')) data, = utils.required_params(content, 'data') field = Field.objects.get(pk=field_id) created_content = factory.make_content(node.entry, data, field) if field.type in field.FILE_TYPES: # Image, file or PDF user_file = file_handling.get_temp_user_file( request.user, assignment, content['data']) if user_file is None and field.required: node.entry.delete() # If there is a newly created node, delete that as well if not node_id: node.delete() return response.bad_request( 'One of your files was not correctly uploaded, please try again.' ) elif user_file: file_handling.make_permanent_file_content( user_file, created_content, node) # Notify teacher on new entry if (node.journal.sourcedid and node.entry.vle_coupling == Entry.NEED_SUBMISSION): lti_tasks.needs_grading.delay(node.pk) # Delete old user files file_handling.remove_temp_user_files(request.user) return response.created({ 'added': entry_utils.get_node_index(journal, node, request.user), 'nodes': timeline.get_nodes(journal, request.user), 'entry': serialize.EntrySerializer(entry, context={ 'user': request.user }).data })
def create(self, request): """Create a new user. Arguments: request -- request data username -- username password -- password first_name -- (optinal) first name last_name -- (optinal) last name email -- (optinal) email jwt_params -- (optinal) jwt params to get the lti information from user_id -- id of the user user_image -- user image roles -- role of the user Returns: On failure: unauthorized -- when the user is not logged in bad request -- when email/username/lti id already exists bad request -- when email/password is invalid On succes: success -- with the newly created user data """ lti_id, user_image, full_name, email, is_teacher = get_lti_params( request, 'user_id', 'custom_user_image', 'custom_user_full_name', 'custom_user_email') if full_name: first_name, last_name = lti.split_fullname(full_name) if lti_id is None: # Check if instance allows standalone registration if user did not register through some LTI instance try: instance = Instance.objects.get(pk=1) if not instance.allow_standalone_registration: return response.bad_request(('{} does not allow you to register through the website,' + ' please use an LTI instance.').format(instance.name)) except Instance.DoesNotExist: pass first_name, last_name, email = utils.optional_params(request.data, 'first_name', 'last_name', 'email') username, password = utils.required_params(request.data, 'username', 'password') if email and User.objects.filter(email=email).exists(): return response.bad_request('User with this email already exists.') validate_email(email) if User.objects.filter(username=username).exists(): return response.bad_request('User with this username already exists.') if lti_id is not None and User.objects.filter(lti_id=lti_id).exists(): return response.bad_request('User with this lti id already exists.') validators.validate_password(password) user = factory.make_user(username, password, email=email, lti_id=lti_id, is_teacher=is_teacher, first_name=first_name, last_name=last_name, profile_picture=user_image, verified_email=True if lti_id else False) if lti_id is None: try: email_handling.send_email_verification_link(user) except SMTPAuthenticationError as err: user.delete() raise err return response.created({'user': UserSerializer(user).data})
def create(self, request): """Create a new user. Arguments: request -- request data username -- username password -- password full_name -- full name email -- (optinal) email jwt_params -- (optinal) jwt params to get the lti information from user_id -- id of the user user_image -- user image roles -- role of the user Returns: On failure: unauthorized -- when the user is not logged in bad request -- when email/username/lti id already exists bad request -- when email/password is invalid On success: success -- with the newly created user data """ lti_id, user_image, full_name, email, is_teacher = get_lti_params( request, 'user_id', 'custom_user_image', 'custom_user_full_name', 'custom_user_email') is_test_student = bool(lti_id) and not bool( email) and full_name == settings.LTI_TEST_STUDENT_FULL_NAME if lti_id is None: # Check if instance allows standalone registration if user did not register through some LTI instance try: instance = Instance.objects.get(pk=1) if not instance.allow_standalone_registration: return response.bad_request(( '{} does not allow you to register through the website,' + ' please use an LTI instance.').format( instance.name)) except Instance.DoesNotExist: pass full_name, email = utils.required_params(request.data, 'full_name', 'email') username, password = utils.required_params(request.data, 'username', 'password') if email and User.objects.filter(email=email).exists(): return response.bad_request('User with this email already exists.') if User.objects.filter(username=username).exists(): return response.bad_request( 'User with this username already exists.') if lti_id is not None and User.objects.filter(lti_id=lti_id).exists(): return response.bad_request( 'User with this lti id already exists.') user = factory.make_user(username=username, email=email, lti_id=lti_id, full_name=full_name, is_teacher=is_teacher, verified_email=bool(lti_id) and bool(email), password=password, profile_picture=user_image if user_image else '/unknown-profile.png', is_test_student=is_test_student) if lti_id is None: send_email_verification_link.delay(user.pk) return response.created({'user': UserSerializer(user).data})