def post(self, request): form = CatalogForm.create_from_request(request) if not request.user.has_perm('core.add_catalog'): raise ProblemDetailException(request, _("Insufficient permissions"), status=HTTPStatus.FORBIDDEN) if not form.is_valid(): raise ValidationException(request, form) if Catalog.objects.filter( url_name=form.cleaned_data['url_name']).exists(): raise ProblemDetailException( request, title=_('Catalog url_name already taken'), status=HTTPStatus.CONFLICT) service = CatalogService() catalog = service.populate(catalog=Catalog(creator=request.user), form=form) if not catalog.users.contains(request.user): UserCatalog.objects.create(catalog=catalog, user=request.user, mode=UserCatalog.Mode.MANAGE) return SingleResponse(request, catalog, serializer=CatalogSerializer.Detailed, status=HTTPStatus.CREATED)
def post(self, request): form = RefreshTokenForm.create_from_request(request) if not form.is_valid(): raise ValidationException(request, form) try: claims = JWTFactory.decode(form.cleaned_data['refresh']) except JoseError as e: raise ProblemDetailException(request, _('Invalid token.'), status=HTTPStatus.UNAUTHORIZED, previous=e) redis = Redis(host=settings.REDIS_HOST, port=settings.REDIS_PORT, db=settings.REDIS_DATABASE) if not redis.exists(f"refresh_token:{claims['jti']}"): raise UnauthorizedException(request) access_token = JWTFactory(claims['sub']).access() return SingleResponse(request, {'access_token': access_token}, status=HTTPStatus.OK)
def post(self, request): form = AccessTokenForm.create_from_request(request) if not form.is_valid(): raise ValidationException(request, form) backend = ModelBackend() user = backend.authenticate(request, username=form.cleaned_data['username'], password=form.cleaned_data['password']) if not user: raise UnauthorizedException(request) access_token = JWTFactory(user.pk).access() jti, refresh_token = JWTFactory(user.pk).refresh() redis = Redis(host=settings.REDIS_HOST, port=settings.REDIS_PORT, db=settings.REDIS_DATABASE) redis.set(f"refresh_token:{jti}", jti) redis.expire(f"refresh_token:{jti}", settings.SECURED_VIEW_JWT_REFRESH_TOKEN_EXPIRATION) return SingleResponse(request, { 'access_token': access_token, 'refresh_token': refresh_token }, status=HTTPStatus.OK)
def post(self, request): form = Auth2faForm.Basic.create_from_request(request) if not request.token: raise ApiException(request, _('User is unauthorized.'), status_code=HTTPStatus.FORBIDDEN) if not form.is_valid(): raise ValidationException(request, form) code = form.cleaned_data.get('code') user = request.user token = request.token if user.is_2fa: totp = pyotp.TOTP(user.additional_data.get('otp_secret')) totp.now() if totp.verify(code): token.active_2fa = True token.save() else: raise ApiException(request, _('Invalid or missing credentials'), status_code=HTTPStatus.UNAUTHORIZED) else: raise ApiException(request, _('User is unauthorized.'), status_code=HTTPStatus.FORBIDDEN) return SingleResponse(request, token, status=HTTPStatus.OK, serializer=TokenSerializer.Base)
def post(self, request): form = CreateUserForm.create_from_request(request) if not form.is_valid(): raise ValidationException(request, form) if not request.user.has_perm('core.add_user'): raise ProblemDetailException(request, _("Insufficient permissions"), status=HTTPStatus.FORBIDDEN) if User.objects.filter(email=form.cleaned_data['email']).exists(): raise ProblemDetailException( request, _("User with same email already exists"), status=HTTPStatus.CONFLICT) user = User() form.populate(user) user.set_password(form.cleaned_data['password']) user.save() return SingleResponse(request, user, serializer=UserSerializer.Base, status=HTTPStatus.CREATED)
def post(self, request): form = FeedForm.create_from_request(request) if not form.is_valid(): raise ValidationException(request, form) if not has_object_permission('check_catalog_manage', request.user, form.cleaned_data['catalog_id']): raise ProblemDetailException(request, _("Insufficient permissions"), status=HTTPStatus.FORBIDDEN) if Feed.objects.filter( catalog=form.cleaned_data['catalog_id'], url_name=form.cleaned_data['url_name']).exists(): raise ProblemDetailException( request, _("Feed with same url_name already exists in same catalog"), status=HTTPStatus.CONFLICT) feed = Feed(creator=request.user) form.populate(feed) feed.save() if 'entries' in form.cleaned_data.keys(): feed.entries.add(*form.cleaned_data['entries']) if 'parents' in form.cleaned_data.keys(): feed.parents.add(*form.cleaned_data['parents']) return SingleResponse(request, feed, serializer=FeedSerializer.Base, status=HTTPStatus.CREATED)
def put(self, request, feed_id: UUID): feed = self._get_feed(request, feed_id) form = FeedForm.create_from_request(request) form['parents'].queryset = form['parents'].queryset.exclude(pk=feed.pk) if not form.is_valid(): raise ValidationException(request, form) if Feed.objects.filter(catalog=form.cleaned_data['catalog_id'], url_name=form.cleaned_data['url_name']).exclude( pk=feed.id).exists(): raise ProblemDetailException( request, _("Feed with same url_name already exists in same catalog"), status=HTTPStatus.CONFLICT) form.populate(feed) feed.save() if feed.kind == Feed.FeedKind.ACQUISITION and 'entries' in form.cleaned_data.keys( ): feed.entries.clear() feed.entries.add(*form.cleaned_data['entries']) if feed.kind == Feed.FeedKind.NAVIGATION and 'parents' in form.cleaned_data.keys( ): feed.parents.clear() feed.parents.add(*form.cleaned_data['parents']) return SingleResponse(request, feed, serializer=FeedSerializer.Base)
def get(self, request, service_id): try: service = Service.objects.get(pk=service_id) except Service.DoesNotExist: raise ApiException(request, _('Service does not exist.'), status_code=HTTPStatus.NOT_FOUND) return SingleResponse(request, service, serializer=ServiceSerializer.Base)
def delete(self, request, user_id: UUID): user = self._get_user( request, user_id, lambda: request.user.has_perm('core.delete_user')) user.hard_delete() return SingleResponse(request)
def put(self, request, service_id): try: service = Service.objects.get(pk=service_id) except Service.DoesNotExist: raise ApiException(request, _('Service does not exist.'), status_code=HTTPStatus.NOT_FOUND) form = ServiceForms.Basic.create_from_request(request) if not form.is_valid(): raise ValidationException(request, form) if service.name != form.cleaned_data['name']: if form.cleaned_data['remote_id'].services.filter(name=form.cleaned_data['name']).exists(): raise ApiException( request=request, message=_('Assigned remote already has service with name: "{service_name}"').format( service_name=form.cleaned_data['name'] ), status_code=HTTPStatus.CONFLICT ) form.fill(service) service.save() return SingleResponse(request, data=service, status=HTTPStatus.OK, serializer=ServiceSerializer.Base)
def get(self, request, acquisition_id: UUID): acquisition = self._get_acquisition(request, acquisition_id, 'check_catalog_read') return SingleResponse(request, acquisition, serializer=AcquisitionSerializer.Detailed)
def put(self, request, remote_id): try: remote = Remote.objects.get(pk=remote_id) except Remote.DoesNotExist: raise ApiException(request, _('Remote does not exist.'), status_code=HTTPStatus.NOT_FOUND) form = RemoteForms.Basic.create_from_request(request) if not form.is_valid(): raise ValidationException(request, form) if remote.name != form.cleaned_data['name']: if form.cleaned_data['project_id'].remotes.filter(name=form.cleaned_data['name']).exists(): raise ApiException( request=request, message=_('Assigned project already has remote with name: "{remote_name}"').format( remote_name=form.cleaned_data['name'] ), status_code=HTTPStatus.CONFLICT ) form.fill(remote) remote.save() return SingleResponse(request, data=remote, status=HTTPStatus.OK, serializer=RemoteSerializer.Base)
def post(self, request): form = CreateAuthorForm.create_from_request(request) if not form.is_valid(): raise ValidationException(request, form) if not has_object_permission('check_catalog_write', request.user, form.cleaned_data['catalog_id']): raise ProblemDetailException(request, _("Insufficient permissions"), status=HTTPStatus.FORBIDDEN) if Author.objects.filter( catalog=form.cleaned_data['catalog_id'], name=form.cleaned_data['name'], surname=form.cleaned_data['surname']).exists(): raise ProblemDetailException( request, _("Author already exists in the catalog"), status=HTTPStatus.CONFLICT) author = Author() form.populate(author) author.save() return SingleResponse(request, author, serializer=AuthorSerializer.Detailed, status=HTTPStatus.CREATED)
def get(self, request, user_id): try: user = User.objects.get(pk=user_id) except User.DoesNotExist: raise ApiException(request, _('User does not exist.'), status_code=HTTPStatus.NOT_FOUND) return SingleResponse(request, user, serializer=UserSerializer.Detail)
def get(self, request, remote_id): try: remote = Remote.objects.get(pk=remote_id) except Remote.DoesNotExist: raise ApiException(request, _('Remote does not exist.'), status_code=HTTPStatus.NOT_FOUND) if not has_object_permission('check_remote', request.user, remote): raise ApiException(request, _('User is unauthorized.'), status_code=HTTPStatus.FORBIDDEN) return SingleResponse(request, remote, serializer=RemoteSerializer.Base)
def get(self, request, api_key_id): try: api_key = ApiKey.objects.get(pk=api_key_id) except ApiKey.DoesNotExist: raise ApiException(request, _('Api key does not exist.'), status_code=HTTPStatus.NOT_FOUND) return SingleResponse(request, api_key, serializer=ApiKeySerializer.Base)
def post(self, request): form = ProjectForms.Basic.create_from_request(request) if not form.is_valid(): raise ValidationException(request, form) project = Project() form.fill(project) project.save() return SingleResponse(request, project, status=HTTPStatus.CREATED, serializer=ProjectSerializer.Detail)
def put(self, request, catalog_id: uuid.UUID, entry_id: uuid.UUID): entry = self._get_entry(request, catalog_id, entry_id) form = EntryForm.create_from_request(request) form.fields['category_ids'].queryset = form.fields['category_ids'].queryset.filter(catalog_id=catalog_id) form.fields['author_id'].queryset = form.fields['author_id'].queryset.filter(catalog_id=catalog_id) if not form.is_valid(): raise ValidationException(request, form) service = EntryService( Catalog.objects.get(pk=catalog_id), request.user ) service.populate(entry, form) return SingleResponse(request, entry, serializer=EntrySerializer.Detailed)
def get(self, request, project_id): try: project = Project.objects.get(pk=project_id) except Project.DoesNotExist: raise ApiException(request, _('Project does not exist.'), status_code=HTTPStatus.NOT_FOUND) if not has_object_permission('check_project', request.user, project): raise ApiException(request, _('User is unauthorized.'), status_code=HTTPStatus.FORBIDDEN) return SingleResponse(request, project, serializer=ProjectSerializer.Detail)
def put(self, request, user_id: UUID): form = UserForm.create_from_request(request) user = self._get_user( request, user_id, lambda: request.user.has_perm('core.change_user')) if not form.is_valid(): raise ValidationException(request, form) form.populate(user) if 'password' in form.cleaned_data.keys(): user.set_password(form.cleaned_data['password']) user.save() return SingleResponse(request, user, serializer=UserSerializer.Base)
def delete(self, request, api_key_id: UUID): try: api_key = ApiKey.objects.get(pk=api_key_id) except ApiKey.DoesNotExist as e: raise ProblemDetailException(request, _("ApiKey not found"), status=HTTPStatus.NOT_FOUND, previous=e) if not request.user.is_superuser and api_key.user_id != request.user.id: raise ProblemDetailException(request, _("ApiKey not found"), status=HTTPStatus.NOT_FOUND) api_key.hard_delete() return SingleResponse(request, status=HTTPStatus.NO_CONTENT)
def get(self, request): response = { 'timestamp': timezone.now(), 'version': settings.VERSION, 'instance': settings.INSTANCE_NAME, 'stats': { 'catalogs': Catalog.objects.count(), 'entries': Entry.objects.count(), 'acquisitions': Acquisition.objects.count(), 'users': User.objects.count() }, } if settings.DEBUG: response['python'] = sys.version return SingleResponse(request, response)
def get(self, request, email): try: user = User.objects.get(email=email) except User.DoesNotExist: raise ApiException(request, _('User with specified email does not exist.'), status_code=HTTPStatus.NOT_FOUND) timestamp = int(datetime.utcnow().timestamp()) ts_b36 = int_to_base36(timestamp) login_timestamp = '' if user.last_login is None else user.last_login.replace( microsecond=0, tzinfo=None) hash_value = six.text_type(user.pk) + user.password + six.text_type( login_timestamp) + six.text_type(timestamp) recovery_hash = salted_hmac( settings.SECRET_KEY, hash_value, ).hexdigest()[::2] password_recovery = PasswordRecovery.objects.create( value="%s-%s" % (ts_b36, recovery_hash), user=user, expires_at=timezone.now() + settings.PASSWORD_RECOVERY_TIME) recovery_url = f'{settings.BASE_URL}/password/activate/{password_recovery.value}' NotificationService.create( recipients=[user.email], sender=f"{settings.EMAIL_SENDER_NAME} <{settings.EMAIL_SENDER}>", subject=_('[Praetorian API] - Email recovery'), content={ 'message': _('test'), 'recovery_url': recovery_url, 'email_text': _('Your recovery link to Praetorian API is: ') }, template='_emails/password_recovery.html').send_email() return SingleResponse(request, password_recovery, status=HTTPStatus.CREATED, serializer=PasswordRecoverySerializer.Base)
def post(self, request): form = ServiceForms.Basic.create_from_request(request) if not form.is_valid(): raise ValidationException(request, form) if form.cleaned_data['remote_id'].services.filter(name=form.cleaned_data['name']).exists(): raise ApiException( request=request, message=_('Assigned remote already has service with name: "{service_name}"').format( service_name=form.cleaned_data['name'] ), status_code=HTTPStatus.CONFLICT ) service = Service() form.fill(service) service.save() return SingleResponse(request, service, status=HTTPStatus.CREATED, serializer=ServiceSerializer.Base)
def put(self, request, project_id): try: project = Project.objects.get(pk=project_id) except Project.DoesNotExist: raise ApiException(request, _('Project does not exist.'), status_code=HTTPStatus.NOT_FOUND) form = ProjectForms.Basic.create_from_request(request) if not form.is_valid(): raise ValidationException(request, form) form.fill(project) project.save() return SingleResponse(request, data=project, status=HTTPStatus.OK, serializer=ProjectSerializer.Detail)
def post(self, request): form = ApiKeyForm.create_from_request(request) if not form.is_valid(): raise ValidationException(request, form) if 'user_id' in form.cleaned_data.keys( ) and not request.user.is_superuser: raise ProblemDetailException(request, _("Insufficient permissions"), status=HTTPStatus.FORBIDDEN) api_key = ApiKey(user=request.user) form.populate(api_key) api_key.save() return SingleResponse(request, api_key, serializer=ApiKeySerializer.Base, status=HTTPStatus.CREATED)
def put(self, request, api_key_id): try: api_key = ApiKey.objects.get(pk=api_key_id) except ApiKey.DoesNotExist: raise ApiException(request, _('Api key does not exist.'), status_code=HTTPStatus.NOT_FOUND) form = ApiKeyForms.Basic.create_from_request(request) if not form.is_valid(): raise ValidationException(request, form) form.fill(api_key) api_key.save() return SingleResponse(request, data=api_key, status=HTTPStatus.OK, serializer=ApiKeySerializer.Base)
def put(self, request, catalog_id: UUID): form = CatalogForm.create_from_request(request) if not form.is_valid(): raise ValidationException(request, form) catalog = self._get_catalog(request, catalog_id) if Catalog.objects.exclude(pk=catalog.pk).filter( url_name=form.cleaned_data['url_name']).exists(): raise ProblemDetailException( request, title=_('Catalog url_name already taken'), status=HTTPStatus.CONFLICT) service = CatalogService() catalog = service.populate(catalog=catalog, form=form) return SingleResponse(request, catalog, serializer=CatalogSerializer.Detailed)
def post(self, request): form = RemoteForms.Basic.create_from_request(request) if not form.is_valid(): raise ValidationException(request, form) if form.cleaned_data['project_id'].remotes.filter(name=form.cleaned_data['name']).exists(): raise ApiException( request=request, message=_('Assigned project already has remote with name: "{remote_name}"').format( remote_name=form.cleaned_data['name'] ), status_code=HTTPStatus.CONFLICT ) remote = Remote() form.fill(remote) remote.variables = {} remote.save() return SingleResponse(request, remote, status=HTTPStatus.CREATED, serializer=RemoteSerializer.Base)
def post(self, request, catalog_id: uuid.UUID): try: catalog = Catalog.objects.get(pk=catalog_id) except Catalog.DoesNotExist as e: raise ProblemDetailException(request, _("Catalog not found"), status=HTTPStatus.NOT_FOUND, previous=e) if not has_object_permission('check_catalog_write', request.user, catalog): raise ProblemDetailException(request, _("Insufficient permissions"), status=HTTPStatus.FORBIDDEN) form = EntryForm.create_from_request(request) form.fields['category_ids'].queryset = form.fields['category_ids'].queryset.filter(catalog=catalog) form.fields['author_id'].queryset = form.fields['author_id'].queryset.filter(catalog=catalog) if not form.is_valid(): raise ValidationException(request, form) entry = Entry(creator=request.user, catalog=catalog) service = EntryService(catalog, request.user) service.populate(entry, form) return SingleResponse(request, entry, serializer=EntrySerializer.Detailed, status=HTTPStatus.CREATED)