lib.itmens/common/api.py

83 lines
2.4 KiB
Python
Raw Normal View History

import logging
from typing import Any, Callable, List, Optional, Tuple, Type
from django.conf import settings
from django.db.models import QuerySet
from ninja import NinjaAPI, Schema
from ninja.pagination import PageNumberPagination as NinjaPageNumberPagination
from ninja.security import HttpBearer
from oauth2_provider.oauth2_backends import OAuthLibCore
from oauth2_provider.oauth2_validators import OAuth2Validator
from oauthlib.oauth2 import Server
_logger = logging.getLogger(__name__)
PERMITTED_WRITE_METHODS = ["PUT", "POST", "DELETE", "PATCH"]
PERMITTED_READ_METHODS = ["GET", "HEAD", "OPTIONS"]
class OAuthAccessTokenAuth(HttpBearer):
def authenticate(self, request, token) -> bool:
if not token or not request.user.is_authenticated:
_logger.debug("API auth: no access token or user not authenticated")
return False
request_scopes = []
request_method = request.method
if request_method in PERMITTED_READ_METHODS:
request_scopes = ["read"]
elif request_method in PERMITTED_WRITE_METHODS:
request_scopes = ["write"]
else:
return False
validator = OAuth2Validator()
core = OAuthLibCore(Server(validator))
valid, oauthlib_req = core.verify_request(request, scopes=request_scopes)
if not valid:
_logger.debug(f"API auth: request scope {request_scopes} not verified")
return valid
class EmptyResult(Schema):
pass
2023-02-15 15:45:57 -05:00
2023-02-15 16:22:32 -05:00
class Result(Schema):
message: str | None
# error: Optional[str]
class RedirectedResult(Schema):
message: str | None
url: str
class PageNumberPagination(NinjaPageNumberPagination):
2023-06-03 01:22:19 -04:00
items_attribute = "data"
class Output(Schema):
2023-06-03 01:22:19 -04:00
data: List[Any]
pages: int
count: int
def paginate_queryset(
self,
queryset: QuerySet,
pagination: NinjaPageNumberPagination.Input,
**params: Any,
2023-06-03 11:10:48 -04:00
):
val = super().paginate_queryset(queryset, pagination, **params)
2023-06-03 11:10:48 -04:00
return {
"data": val["items"],
"count": val["count"],
"pages": (val["count"] + self.page_size - 1) // self.page_size,
}
2023-02-15 16:22:32 -05:00
2023-02-15 15:45:57 -05:00
api = NinjaAPI(
auth=OAuthAccessTokenAuth(),
2023-08-10 17:15:00 -04:00
title=f'{settings.SITE_INFO["site_name"]} API',
2023-02-15 15:45:57 -05:00
version="1.0.0",
2023-07-10 15:29:29 -04:00
description=f"{settings.SITE_INFO['site_name']} API <hr/><a href='{settings.SITE_INFO['site_url']}'>Learn more</a>",
2023-02-15 15:45:57 -05:00
)