diff --git a/backend/backend_app/models/other_viewsets.py b/backend/backend_app/models/other_viewsets.py index 69907cb1687059feb754e3b2de35d01ce0412669..607e5419286c88233931705c98987ca7e383b733 100644 --- a/backend/backend_app/models/other_viewsets.py +++ b/backend/backend_app/models/other_viewsets.py @@ -9,6 +9,7 @@ from shared import OBJ_MODERATION_PERMISSIONS class AppModerationStatusViewSet(APIView): """ + Viewset to know what is the app moderation status """ permission_classes = get_viewset_permissions("AppModerationStatusViewSet") diff --git a/backend/backend_app/utils/__does_user_have_moderation_rights.py b/backend/backend_app/utils/__does_user_have_moderation_rights.py index 05af7f7ef2ebb0ff8fce678d5b296eec8f873967..a7939ca3219a1b00148f2be957c11a59b9bf619c 100644 --- a/backend/backend_app/utils/__does_user_have_moderation_rights.py +++ b/backend/backend_app/utils/__does_user_have_moderation_rights.py @@ -1,8 +1,11 @@ from backend_app.utils import is_member +from django.contrib.auth.models import User -def does_user_have_moderation_rights(user): +def does_user_have_moderation_rights(user: User) -> bool: """ + Function to know if a user is staff or member of DRI or member of the moderator group. + TODO unit test """ return user.is_staff or is_member("DRI", user) or is_member("Moderators", user) diff --git a/backend/backend_app/utils/__find_api_end_point_for_viewset.py b/backend/backend_app/utils/__find_api_end_point_for_viewset.py index a0cfa88762805c64b6eaa46f2d2923b533833cd6..1cd8f8606bb6b70fbdce3aba63f006eda01174a2 100644 --- a/backend/backend_app/utils/__find_api_end_point_for_viewset.py +++ b/backend/backend_app/utils/__find_api_end_point_for_viewset.py @@ -1,11 +1,13 @@ -from shared import load_api_config +from shared import get_api_objs -def find_api_end_point_for_viewset(viewset_name): +def find_api_end_point_for_viewset(viewset_name: str) -> str: + """ + Gets the api endpoint associated with a viewset + """ - api_config = load_api_config() - for obj in api_config: - if obj["viewset"] == viewset_name: - return obj["api_end_point"] + for obj in get_api_objs(has_model=None, make_imports=False): + if obj.viewset == viewset_name: + return obj.api_end_point return None diff --git a/backend/backend_app/utils/__get_model_config.py b/backend/backend_app/utils/__get_model_config.py index 0d57dec51bfd3496e6054764b152a976210ec1c1..bb2cba8f95f1c4ab816ea93f1634aed988a21aa8 100644 --- a/backend/backend_app/utils/__get_model_config.py +++ b/backend/backend_app/utils/__get_model_config.py @@ -1,21 +1,22 @@ -from shared import load_api_config +from shared import get_api_objs -def get_model_config(model): - api_config = load_api_config() - - for obj in api_config: - if "is_api_view" in obj and obj["is_api_view"]: - continue - if obj["model"] == model: - tmp = { - "moderation_level": obj["moderation_level"], +def get_model_config(model: str) -> dict: + """ + Returns the configuraiton of the model + """ + for obj in get_api_objs(has_model=True, is_api_view=False, make_imports=False): + if obj.model == model: + out = { + "moderation_level": obj.moderation_level, "model": model, - "read_only": obj["read_only"], + "read_only": obj.read_only, } key = "enforce_moderation_user_level" if key in obj.keys(): - tmp[key] = obj[key] - return tmp + out[key] = obj[key] + return out - raise Exception("Model not found in API configuration, cannot process !") + raise Exception( + "Model {} not found in API configuration, cannot process !".format(model) + ) diff --git a/backend/backend_app/utils/__get_user_level.py b/backend/backend_app/utils/__get_user_level.py index 93894a02dde868586eadd1368f5024f52cf3e72a..8a9c52bb92cbf9e79719dbcd65000cd9d032f25b 100644 --- a/backend/backend_app/utils/__get_user_level.py +++ b/backend/backend_app/utils/__get_user_level.py @@ -1,9 +1,11 @@ from .__is_member import is_member +from django.contrib.auth.models import User from shared import OBJ_MODERATION_PERMISSIONS -def get_user_level(user) -> int: +def get_user_level(user: User) -> int: """ + Returns the user level as int. TODO unit test """ if user.is_staff: diff --git a/backend/backend_app/utils/__get_viewset_permissions.py b/backend/backend_app/utils/__get_viewset_permissions.py index 745d6b9f1320e58c6e1b357409ca17d4c4732940..b342251485cdb23b47cff72ae1bd2d5caf662a4a 100644 --- a/backend/backend_app/utils/__get_viewset_permissions.py +++ b/backend/backend_app/utils/__get_viewset_permissions.py @@ -8,14 +8,17 @@ from backend_app.permissions import ( ) from rest_framework.permissions import IsAdminUser from backend_app.permissions import DEFAULT_VIEWSET_PERMISSIONS -from shared import load_api_config +from shared import get_api_objs -def get_viewset_permissions(viewset): - api_config = load_api_config() - for obj in api_config: - if obj["viewset"] == viewset: - custom_permission = obj["viewset_permission"] +def get_viewset_permissions(viewset: str) -> object: + """ + Returns the permissions associated with the viewset as configured in the config file. + """ + + for obj in get_api_objs(has_model=None, make_imports=False, is_api_view=None): + if obj.viewset == viewset: + custom_permission = obj.viewset_permission if custom_permission == "IsOwner": permission = (IsOwner,) elif custom_permission == "IsStaffOrReadOnly": @@ -33,8 +36,10 @@ def get_viewset_permissions(viewset): else: raise Exception("Permission not supported ! Dev what did you do ?") - if obj["read_only"]: + if obj.read_only: permission += (ReadOnly,) return DEFAULT_VIEWSET_PERMISSIONS + permission - raise Exception("Viewset not found in API configuraiton, cannot process !") + raise Exception( + "Viewset {} not found in API configuraiton, cannot proceed !".format(viewset) + ) diff --git a/backend/backend_app/utils/__is_member.py b/backend/backend_app/utils/__is_member.py index 12f80345a4c10b7adf218c0ce8060d8616305e4d..0265f3fede42537392846c7b4767948ee973684c 100644 --- a/backend/backend_app/utils/__is_member.py +++ b/backend/backend_app/utils/__is_member.py @@ -1,4 +1,7 @@ -def is_member(group_name, user): +from django.contrib.auth.models import User + + +def is_member(group_name: str, user: User) -> bool: """ Function to know if a user is part of a specific group. diff --git a/shared/__init__.py b/shared/__init__.py index 0b82234083056007165e4fa91d91092e76b9bf57..556711974058978f5dc7400f09b8b00d7152a4f2 100644 --- a/shared/__init__.py +++ b/shared/__init__.py @@ -1,12 +1,7 @@ -from .get_api_config import load_api_config, get_api_objs +from .get_api_config import get_api_objs from .obj_moderation_permission import ( DEFAULT_OBJ_MODERATION_LV, OBJ_MODERATION_PERMISSIONS, ) -__all__ = [ - "load_api_config", - "DEFAULT_OBJ_MODERATION_LV", - "OBJ_MODERATION_PERMISSIONS", - "get_api_objs", -] +__all__ = ["DEFAULT_OBJ_MODERATION_LV", "OBJ_MODERATION_PERMISSIONS", "get_api_objs"] diff --git a/shared/api_config.yml b/shared/api_config.yml index dfb259859514beae42cacf24d48b61fa5717b422..f73a3ef3378774f9bc0f874edb1378baa7a605b0 100644 --- a/shared/api_config.yml +++ b/shared/api_config.yml @@ -1,7 +1,7 @@ # THIS FILE IS DYNAMICALLY USED FOR THE BACKEND AND THE FRONTEND # TAKE CARE WHEN MODYFING IT ;) -# model : the model name (may be null) Model can't be present more than once. +# model : the model name (may be absent) Model can't be present more than once. # viewset : the viewset name for the api # api_end_pont : the main part of the url for making request to the api # This string will also be used for naming variables in JS !! @@ -27,7 +27,7 @@ # # By default, every viewset will have : # - isAuthentificated : to use the API the client needs to be authentificated -# - noDeleteIsNotStaff : nothing can be deleted except if you are a staff member +# - noDeleteIfNotStaff : nothing can be deleted except if you are a staff member # # Some viewsets may have more presice permissions # - IsStaff @@ -36,12 +36,20 @@ # - IsOwner : (or ) # + +##################################################### +## Custom Viewsets that doesn't have a model behind +##################################################### - viewset: AppModerationStatusViewSet api_end_point: serverModerationStatus import_location: other_viewsets read_only: true is_api_view: true +##################### +## Standard Viewsets +##################### + - model: Country viewset: CountryViewSet import_location: country diff --git a/shared/get_api_config.py b/shared/get_api_config.py index a2b535dd0d41b7ea59f9368bf568ace842807be5..7be386ebcad3590f84b5e3923ccfd39fe20fa695 100644 --- a/shared/get_api_config.py +++ b/shared/get_api_config.py @@ -50,6 +50,7 @@ def get_api_objs( requires_testing: Union[None, bool, "smart"] = None, is_api_view: Optional[bool] = False, ignore_models: List[str] = list(), + make_imports: bool = True, ) -> List[DotMap]: """ Returns a list of DotMap objects corresponding the api config file @@ -59,6 +60,8 @@ def get_api_objs( There is one exception for the parameter `requires_testing` if it is set to `smart` then the object is returned only if doesn't require testing or if testing is activated. + + make_imports: do we perform the model and viewsets imports ? """ out = list() @@ -102,19 +105,20 @@ def get_api_objs( if not is_api_view and obj.is_api_view: continue - module = importlib.import_module( - "backend_app.models.{}".format(obj.import_location) - ) + if make_imports: + module = importlib.import_module( + "backend_app.models.{}".format(obj.import_location) + ) - if obj.model is not None: - if obj.model in ignore_models: - continue - Model = getattr(module, obj.model) - obj.Model = Model + if obj.model is not None: + if obj.model in ignore_models: + continue + Model = getattr(module, obj.model) + obj.Model = Model - if obj.viewset is not None: - Viewset = getattr(module, obj.viewset) - obj.Viewset = Viewset + if obj.viewset is not None: + Viewset = getattr(module, obj.viewset) + obj.Viewset = Viewset out.append(obj)