def get( self, request, case_id=None, contact_id=None, submission_id=None, invitation_id=None, organisation_id=None, *args, **kwargs, ): if invitation_id: invitation = Invitation.objects.get_user_invite( invitation_id, requested_by=request.user ) return ResponseSuccess({"result": invitation.to_dict()}) invitations = Invitation.objects.filter(deleted_at__isnull=True, organisation__isnull=False) if contact_id: try: contact = Contact.objects.select_related("userprofile", "organisation").get( id=contact_id ) except Contact.DoesNotExist: raise NotFoundApiExceptions("Invalid contact id.") invitations = invitations.filter(contact=contact) if case_id: try: case = Case.objects.get(id=case_id) except Case.DoesNotExist: raise InvalidRequestParams("Invalid case id")
def post(request, *args, **kwargs): """ Changes a user's password. Arguments: request: a Django Request object Returns: ResponseSuccess response if the password was successfully changed. Raises: InvalidRequestParams if link is invalid or password is not complex enough. """ token_serializer = PasswordResetRequestSerializer(data=request.data) password_serializer = PasswordSerializer(data=request.data) user_pk = request.data.get("user_pk") if token_serializer.is_valid() and password_serializer.is_valid(): if PasswordResetRequest.objects.password_reset( token_serializer.initial_data["token"], token_serializer.initial_data["user_pk"], token_serializer.initial_data["password"], ): logger.info(f"Password reset completed for: {user_pk}") return ResponseSuccess({"result": { "reset": True }}, http_status=status.HTTP_200_OK) elif not password_serializer.is_valid(): raise ValidationAPIException( serializer_errors=password_serializer.errors) else: logger.warning(f"Could not reset password for user {user_pk}") raise InvalidRequestParams("Invalid or expired link")
def post( self, request, contact_id, case_id, case_role_id=None, submission_id=None, *args, **kwargs ): notify_template_key = None try: contact = Contact.objects.select_related("userprofile", "organisation").get( id=contact_id ) case_role = get_role(case_role_id) case = Case.objects.get(id=case_id) notify_template_key = case.type.meta.get("invite_notify_template_key") except Contact.DoesNotExist: raise NotFoundApiExceptions("Invalid contact id.") except CaseRole.DoesNotExist: raise NotFoundApiExceptions("Invalid case role id") except Case.DoesNotExist: raise InvalidRequestParams("Invalid case id") if not contact.organisation and contact.has_user: contact.organisation = contact.user.organisation.organisation # check if an invite exists already created = False invitation_kwargs = {} if submission_id: invitation_kwargs["submission__id"] = submission_id organisation_id = request.data.get("organisation_id") if organisation_id: organisation = Organisation.objects.get(id=organisation_id) else: organisation = contact.organisation try: invitation = Invitation.objects.get( contact=contact, case=case, organisation=organisation, deleted_at__isnull=True, **invitation_kwargs, ) except Invitation.DoesNotExist: invitation = Invitation.objects.create( created_by=request.user, contact=contact, case=case, case_role=case_role, organisation=organisation, short_code=crypto.get_random_string(8), code=str(uuid.uuid4()), email=contact.email, ) created = True values = {key: request.data.get(key) for key in request.data.keys()} invitation.send( sent_by=request.user, context=values, direct=True, template_key=notify_template_key ) return ResponseSuccess( { "result": invitation.to_dict(), "created": created, }, http_status=status.HTTP_201_CREATED, )
def post(request, code: str = None): """ A multipurpose endpoint (for the moment), if code is provided it will verify the code is correct and note the email verification in the database. If code is not provided, it will send out a verification email to the request.user Arguments: request: a Django Request object code: an email verification code Returns: ResponseSuccess response if the email was validated / a new link was sent out. Raises: InvalidRequestParams if the link was incorrect. """ if code: user = request.user try: profile = user.userprofile except UserProfile.DoesNotExist: profile = UserProfile.objects.filter( email_verify_code=code).first() user = profile.user serializer = VerifyEmailSerializer(data={"code": code}, context={"profile": profile}) if serializer.is_valid(): profile.email_verified_at = timezone.now() profile.save() user.refresh_from_db() return ResponseSuccess({"result": user.to_dict()}) else: raise InvalidRequestParams(serializer.errors) elif not request.user.is_anonymous: response = request.user.userprofile.verify_email() return ResponseSuccess({"result": response}) else: raise InvalidRequestParams("User unknown")
def post(request, *args, **kwargs): """ Changes a user's password. Arguments: request: a Django Request object Returns: ResponseSuccess response if the password was successfully changed. Raises: InvalidRequestParams if link is invalid or password is not complex enough. """ token_serializer = PasswordResetRequestSerializerV2(data=request.data) password_serializer = PasswordSerializer(data=request.data) request_id = request.data.get("request_id") if token_serializer.is_valid() and password_serializer.is_valid(): if PasswordResetRequest.objects.password_reset_v2( token_serializer.initial_data["token"], token_serializer.initial_data["request_id"], token_serializer.initial_data["password"], ): logger.info( f"Password reset completed for: request {request_id}") user_pk = PasswordResetRequest.objects.get( request_id=request_id).user.pk user = User.objects.get(pk=user_pk) audit_log(audit_type=AUDIT_TYPE_PASSWORD_RESET, user=user) return ResponseSuccess({"result": { "reset": True }}, http_status=status.HTTP_200_OK) elif not password_serializer.is_valid(): user_pk = PasswordResetRequest.objects.get( request_id=request_id).user.pk user = User.objects.get(pk=user_pk) audit_log(audit_type=AUDIT_TYPE_PASSWORD_RESET_FAILED, user=user) raise ValidationAPIException( serializer_errors=password_serializer.errors) else: logger.warning( f"Could not reset password for request {request_id}") user_pk = PasswordResetRequest.objects.get( request_id=request_id).user.pk user = User.objects.get(pk=user_pk) audit_log(audit_type=AUDIT_TYPE_PASSWORD_RESET_FAILED, user=user) raise InvalidRequestParams("Invalid or expired link")
def get(self, request, document_id, submission_id=None, *args, **kwargs): document = Document.objects.get(id=document_id) is_tra = request.user.is_tra() if (not is_tra and not submission_id and not request.user.email == settings.TRUSTED_USER_EMAIL): raise InvalidRequestParams("Invalid request params") if submission_id: submission = Submission.objects.get_submission(id=submission_id) doc_submission = SubmissionDocument.objects.get( submission=submission, document=document) if not is_tra and not doc_submission.downloadable_by(request.user): raise NotFoundApiExceptions( "Document not found or access is denied") doc_submission.downloads += 1 doc_submission.save() return stream_s3_file_download(document.s3_bucket, document.s3_key, filename=document.name)
def get( self, request, note_id=None, model_id=None, content_type=None, case_id=None, model_key=None, *args, **kwargs, ): if note_id: try: note = Note.objects.get(id=note_id) return ResponseSuccess({"result": note.to_dict()}) except Note.DoesNotExist: raise NotFoundApiExceptions("Invalid note id") else: notes = Note.objects.filter(deleted_at__isnull=True) if case_id: notes = notes.filter(case__id=case_id) if model_id and content_type: _content_type = get_content_type(content_type) if model_key: notes = notes.filter(model_id=model_id, content_type=_content_type, model_key=model_key) else: notes = notes.filter(model_id=model_id, content_type=_content_type) else: raise InvalidRequestParams( "A note id, case id or a model identifiers are required") notes = notes.order_by("created_at") return ResponseSuccess( {"results": [_note.to_dict() for _note in notes]})
def post( self, request, document_id=None, case_id=None, organisation_id=None, submission_id=None, bundle_id=None, *args, **kwargs, ): if document_id is None: document_id = request.data.get("document_id", None) _files = request.FILES.getlist("file", None) _issued = request.data.get("issued") or False _case_document = request.data.get("case_document") _parent_id = request.data.get("parent_id") or False _replace_id = request.data.get("replace_id") or False _bundle_id = bundle_id or request.data.get("bundle_id") _system = request.data.get("system") or bool(_bundle_id) _confidential = request.data.get("confidential") _submission_document_type = request.data.get( "submission_document_type") if _submission_document_type: submission_document_type = SubmissionDocumentType.objects.get( key=_submission_document_type) else: submission_document_type = SubmissionDocumentType.type_by_user( request.user) if _confidential is None: _confidential = True submission_type_id = request.data.get("submission_type_id") if (not _case_document and not _bundle_id and not submission_id and not submission_type_id and not _system and not document_id): raise InvalidRequestParams("Submission id or type id are required") if not _files and not document_id and not request.data.get( "file_name"): raise InvalidRequestParams("No file or documents provided") case = get_case(case_id) submission = None if submission_id: submission = Submission.objects.get_submission(id=submission_id, case=case) elif submission_type_id: submission_type = SubmissionType.objects.get(id=submission_type_id) submission = Submission.objects.create( name=submission_type.name, case=case, organisation=self.organisation, type=submission_type, status=submission_type.default_status, created_by=request.user, user_context=[request.user], ) if not _files and request.data.get("file_name"): _files = [{ "name": request.data.get("file_name"), "size": request.data.get("file_size"), "document_name": request.data.get("document_name"), }] if _files: result = [] for _file in _files: _parent = None if _parent_id: try: _parent = Document.objects.get(id=_parent_id) except Document.DoesNotExist: raise NotFoundApiExceptions( "Parent document is not found") try: document = Document.objects.create_document( file=_file, user=request.user, confidential=_confidential, system=bool(_system), parent=_parent, document=Document.objects.get( id=document_id) if document_id else None, case=case, ) except InvalidFile as e: raise InvalidFileUpload(str(e)) if _replace_id and submission: # We are being asked to replace the given doc in this submission try: # Find the document to replace and get its child _replace_doc = Document.objects.get(id=_replace_id) _child_doc = Document.objects.filter( parent_id=_replace_id).first() replace_submission_document = SubmissionDocument.objects.get( submission=submission, document=_replace_doc) replace_submission_document.set_user_context( request.user) if _child_doc: child_submission_document = SubmissionDocument.objects.get( submission=submission, document=_child_doc) child_submission_document.set_user_context( request.user) # Clone the child doc and add link to parent _child_doc.id = None _child_doc.parent = document _child_doc.save() # Update submission_doc to point to new child doc. child_submission_document.document = _child_doc child_submission_document.save() replace_submission_document.delete() except (Document.DoesNotExist, SubmissionDocument.DoesNotExist) as e: logger.warning( f"Document to replace with id '{_replace_id}' was not found: {e}" ) if submission: if _submission_document_type: submission_document_type = SubmissionDocumentType.objects.get( key=_submission_document_type) else: submission_document_type = SubmissionDocumentType.type_by_user( request.user) submission_document = submission.add_document( document=document, document_type=submission_document_type, issued=_issued, issued_by=request.user, ) result_item = submission_document.to_dict() elif _bundle_id: bundle = DocumentBundle.objects.get(id=_bundle_id) bundle.documents.add(document) document.generic_audit( message=f"Attached to bundle {bundle.name}", audit_type=AUDIT_TYPE_ATTACH, id=str(document.id), ) result_item = document.to_dict() else: result_item = document.to_dict() result.append(result_item) return ResponseSuccess({"result": result}, http_status=status.HTTP_201_CREATED) elif document_id: # We just want to attach a document document = Document.objects.get(id=document_id) if submission_id: submission_document = submission.add_document( document=document, document_type=submission_document_type, issued=_issued, issued_by=request.user, ) if not request.user.is_tra(): submission.received_at = timezone.now() submission.status = submission.type.received_status submission.save() return ResponseSuccess( {"result": submission_document.to_dict()}, http_status=status.HTTP_201_CREATED) document.confidential = _confidential document.save() return ResponseSuccess( {"result": { "document": document.to_dict() }})