Rename ValidationError to HttpError.
This commit is contained in:
parent
34c548acda
commit
a75d5479fa
@ -25,7 +25,7 @@ from django_etebase.token_auth.models import AuthToken
|
||||
from django_etebase.token_auth.models import get_default_expiry
|
||||
from django_etebase.utils import create_user, get_user_queryset, CallbackContext
|
||||
from django_etebase.views import msgpack_encode, msgpack_decode
|
||||
from .exceptions import AuthenticationFailed, transform_validation_error, ValidationError
|
||||
from .exceptions import AuthenticationFailed, transform_validation_error, HttpError
|
||||
from .msgpack import MsgpackRoute
|
||||
from .utils import BaseModel
|
||||
|
||||
@ -207,20 +207,20 @@ def validate_login_request(
|
||||
challenge_data = msgpack_decode(box.decrypt(validated_data.challenge))
|
||||
now = int(datetime.now().timestamp())
|
||||
if validated_data.action != expected_action:
|
||||
raise ValidationError("wrong_action", f'Expected "{challenge_sent_to_user.response}" but got something else')
|
||||
raise HttpError("wrong_action", f'Expected "{challenge_sent_to_user.response}" but got something else')
|
||||
elif now - challenge_data["timestamp"] > app_settings.CHALLENGE_VALID_SECONDS:
|
||||
raise ValidationError("challenge_expired", "Login challenge has expired")
|
||||
raise HttpError("challenge_expired", "Login challenge has expired")
|
||||
elif challenge_data["userId"] != user.id:
|
||||
raise ValidationError("wrong_user", "This challenge is for the wrong user")
|
||||
raise HttpError("wrong_user", "This challenge is for the wrong user")
|
||||
elif not settings.DEBUG and validated_data.host.split(":", 1)[0] != host_from_request:
|
||||
raise ValidationError(
|
||||
raise HttpError(
|
||||
"wrong_host", f'Found wrong host name. Got: "{validated_data.host}" expected: "{host_from_request}"'
|
||||
)
|
||||
verify_key = nacl.signing.VerifyKey(bytes(user.userinfo.loginPubkey), encoder=nacl.encoding.RawEncoder)
|
||||
try:
|
||||
verify_key.verify(challenge_sent_to_user.response, challenge_sent_to_user.signature)
|
||||
except nacl.exceptions.BadSignatureError:
|
||||
raise ValidationError("login_bad_signature", "Wrong password for user.", status.HTTP_401_UNAUTHORIZED)
|
||||
raise HttpError("login_bad_signature", "Wrong password for user.", status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
|
||||
@authentication_router.get("/is_etebase/")
|
||||
@ -269,7 +269,7 @@ def dashboard_url(user: User = Depends(get_authenticated_user)):
|
||||
# XXX-TOM
|
||||
get_dashboard_url = app_settings.DASHBOARD_URL_FUNC
|
||||
if get_dashboard_url is None:
|
||||
raise ValidationError("not_supported", "This server doesn't have a user dashboard.")
|
||||
raise HttpError("not_supported", "This server doesn't have a user dashboard.")
|
||||
|
||||
ret = {
|
||||
"url": get_dashboard_url(request, *args, **kwargs),
|
||||
@ -301,7 +301,7 @@ def signup_save(data: SignupIn, request: Request) -> User:
|
||||
raise EtebaseValidationError("generic", str(e))
|
||||
|
||||
if hasattr(instance, "userinfo"):
|
||||
raise ValidationError("user_exists", "User already exists", status_code=status.HTTP_409_CONFLICT)
|
||||
raise HttpError("user_exists", "User already exists", status_code=status.HTTP_409_CONFLICT)
|
||||
|
||||
models.UserInfo.objects.create(**data.dict(exclude={"user"}), owner=instance)
|
||||
return instance
|
||||
|
@ -11,7 +11,7 @@ from fastapi import APIRouter, Depends, status
|
||||
|
||||
from django_etebase import models
|
||||
from .authentication import get_authenticated_user
|
||||
from .exceptions import ValidationError, transform_validation_error, PermissionDenied
|
||||
from .exceptions import HttpError, transform_validation_error, PermissionDenied
|
||||
from .msgpack import MsgpackRoute
|
||||
from .stoken_handler import filter_by_stoken_and_limit, filter_by_stoken, get_stoken_obj, get_queryset_stoken
|
||||
from .utils import get_object_or_404, Context, Prefetch, PrefetchQuery, is_collection_admin, BaseModel
|
||||
@ -144,7 +144,7 @@ class ItemDepIn(BaseModel):
|
||||
item = models.CollectionItem.objects.get(uid=self.uid)
|
||||
etag = self.etag
|
||||
if item.etag != etag:
|
||||
raise ValidationError(
|
||||
raise HttpError(
|
||||
"wrong_etag",
|
||||
"Wrong etag. Expected {} got {}".format(item.etag, etag),
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
@ -274,7 +274,7 @@ def process_revisions_for_item(item: models.CollectionItem, revision_data: Colle
|
||||
chunk_obj.chunkFile.save("IGNORED", ContentFile(content))
|
||||
chunk_obj.save()
|
||||
else:
|
||||
raise ValidationError("chunk_no_content", "Tried to create a new chunk without content")
|
||||
raise HttpError("chunk_no_content", "Tried to create a new chunk without content")
|
||||
|
||||
chunks_objs.append(chunk_obj)
|
||||
|
||||
@ -290,12 +290,12 @@ def process_revisions_for_item(item: models.CollectionItem, revision_data: Colle
|
||||
def _create(data: CollectionIn, user: User):
|
||||
with transaction.atomic():
|
||||
if data.item.etag is not None:
|
||||
raise ValidationError("bad_etag", "etag is not null")
|
||||
raise HttpError("bad_etag", "etag is not null")
|
||||
instance = models.Collection(uid=data.item.uid, owner=user)
|
||||
try:
|
||||
instance.validate_unique()
|
||||
except django_exceptions.ValidationError:
|
||||
raise ValidationError(
|
||||
raise HttpError(
|
||||
"unique_uid", "Collection with this uid already exists", status_code=status.HTTP_409_CONFLICT
|
||||
)
|
||||
instance.save()
|
||||
@ -355,7 +355,7 @@ def item_create(item_model: CollectionItemIn, collection: models.Collection, val
|
||||
return instance
|
||||
|
||||
if validate_etag and cur_etag != etag:
|
||||
raise ValidationError(
|
||||
raise HttpError(
|
||||
"wrong_etag",
|
||||
"Wrong etag. Expected {} got {}".format(cur_etag, etag),
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
@ -425,7 +425,7 @@ def item_bulk_common(data: ItemBatchIn, user: User, stoken: t.Optional[str], uid
|
||||
collection_object = queryset.select_for_update().get(uid=uid)
|
||||
|
||||
if stoken is not None and stoken != collection_object.stoken:
|
||||
raise ValidationError("stale_stoken", "Stoken is too old", status_code=status.HTTP_409_CONFLICT)
|
||||
raise HttpError("stale_stoken", "Stoken is too old", status_code=status.HTTP_409_CONFLICT)
|
||||
|
||||
# XXX-TOM: make sure we return compatible errors
|
||||
data.validate_db()
|
||||
@ -482,7 +482,7 @@ def fetch_updates(
|
||||
item_limit = 200
|
||||
|
||||
if len(data) > item_limit:
|
||||
raise ValidationError("too_many_items", "Request has too many items.", status_code=status.HTTP_400_BAD_REQUEST)
|
||||
raise HttpError("too_many_items", "Request has too many items.", status_code=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
queryset, stoken_rev = filter_by_stoken(stoken, queryset, models.CollectionItem.stoken_annotation)
|
||||
|
||||
|
@ -3,19 +3,17 @@ import typing as t
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from django_etebase.exceptions import EtebaseValidationError
|
||||
|
||||
|
||||
class ValidationErrorField(BaseModel):
|
||||
class HttpErrorField(BaseModel):
|
||||
field: str
|
||||
code: str
|
||||
detail: str
|
||||
|
||||
|
||||
class ValidationErrorOut(BaseModel):
|
||||
class HttpErrorOut(BaseModel):
|
||||
code: str
|
||||
detail: str
|
||||
errors: t.Optional[t.List[ValidationErrorField]]
|
||||
errors: t.Optional[t.List[HttpErrorField]]
|
||||
|
||||
|
||||
class CustomHttpException(Exception):
|
||||
@ -59,24 +57,23 @@ class PermissionDenied(CustomHttpException):
|
||||
super().__init__(code=code, detail=detail, status_code=status_code)
|
||||
|
||||
|
||||
class ValidationError(CustomHttpException):
|
||||
class HttpError(CustomHttpException):
|
||||
def __init__(
|
||||
self,
|
||||
code: str,
|
||||
detail: str,
|
||||
status_code: int = status.HTTP_400_BAD_REQUEST,
|
||||
field: t.Optional[str] = None,
|
||||
errors: t.Optional[t.List["ValidationError"]] = None,
|
||||
errors: t.Optional[t.List["HttpError"]] = None,
|
||||
):
|
||||
self.errors = errors
|
||||
super().__init__(code=code, detail=detail, status_code=status_code)
|
||||
|
||||
@property
|
||||
def as_dict(self) -> dict:
|
||||
return ValidationErrorOut(code=self.code, errors=self.errors, detail=self.detail).dict()
|
||||
return HttpErrorOut(code=self.code, errors=self.errors, detail=self.detail).dict()
|
||||
|
||||
|
||||
def flatten_errors(field_name, errors) -> t.List[ValidationError]:
|
||||
def flatten_errors(field_name, errors) -> t.List[HttpError]:
|
||||
ret = []
|
||||
if isinstance(errors, dict):
|
||||
for error_key in errors:
|
||||
@ -98,5 +95,5 @@ def transform_validation_error(prefix, err):
|
||||
elif not hasattr(err, "message"):
|
||||
errors = flatten_errors(prefix, err.error_list)
|
||||
else:
|
||||
raise EtebaseValidationError(err.code, err.message)
|
||||
raise ValidationError(code="field_errors", detail="Field validations failed.", errors=errors)
|
||||
raise HttpError(err.code, err.message)
|
||||
raise HttpError(code="field_errors", detail="Field validations failed.", errors=errors)
|
||||
|
@ -8,7 +8,7 @@ from fastapi import APIRouter, Depends, status, Request
|
||||
from django_etebase import models
|
||||
from django_etebase.utils import get_user_queryset, CallbackContext
|
||||
from .authentication import get_authenticated_user
|
||||
from .exceptions import ValidationError, PermissionDenied
|
||||
from .exceptions import HttpError, PermissionDenied
|
||||
from .msgpack import MsgpackRoute
|
||||
from .utils import get_object_or_404, Context, is_collection_admin, BaseModel
|
||||
|
||||
@ -42,7 +42,7 @@ class CollectionInvitationCommon(BaseModel):
|
||||
class CollectionInvitationIn(CollectionInvitationCommon):
|
||||
def validate_db(self, context: Context):
|
||||
if context.user.username == self.username.lower():
|
||||
raise ValidationError("no_self_invite", "Inviting yourself is not allowed")
|
||||
raise HttpError("no_self_invite", "Inviting yourself is not allowed")
|
||||
|
||||
|
||||
class CollectionInvitationOut(CollectionInvitationCommon):
|
||||
@ -186,7 +186,7 @@ def outgoing_create(
|
||||
**data.dict(exclude={"collection", "username"}), user=to_user, fromMember=member
|
||||
)
|
||||
except IntegrityError:
|
||||
raise ValidationError("invitation_exists", "Invitation already exists")
|
||||
raise HttpError("invitation_exists", "Invitation already exists")
|
||||
|
||||
|
||||
@invitation_outgoing_router.get("/", response_model=InvitationListResponse)
|
||||
|
@ -10,7 +10,7 @@ from django.contrib.auth import get_user_model
|
||||
|
||||
from django_etebase.models import AccessLevels
|
||||
|
||||
from .exceptions import ValidationError
|
||||
from .exceptions import HttpError
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
@ -35,7 +35,7 @@ def get_object_or_404(queryset: QuerySet, **kwargs):
|
||||
try:
|
||||
return queryset.get(**kwargs)
|
||||
except ObjectDoesNotExist as e:
|
||||
raise ValidationError("does_not_exist", str(e), status_code=status.HTTP_404_NOT_FOUND)
|
||||
raise HttpError("does_not_exist", str(e), status_code=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
|
||||
def is_collection_admin(collection, user):
|
||||
|
Loading…
Reference in New Issue
Block a user