Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

might refactor views #1736

Draft
wants to merge 10 commits into
base: master
Choose a base branch
from
9 changes: 3 additions & 6 deletions backend/root/utils/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,13 @@ def save(self, *args: Any, **kwargs: Any) -> None:
LOG.info(f"{self} was saved.\nFieldTrackerMixin couldn't detect any changes to tracked fields.")
else: # Log changes.
LOG.info(f'{self} has changed:\n\nold: {dirty_fields_old}\n\n new:{dirty_fields_new}')
LOG.info(
f'{self} has changed:\n\n' f'old: {self.ftm_log_parse(fields=dirty_fields_old)}\n\n' f'new:{self.ftm_log_parse(fields=dirty_fields_new)}'
)
LOG.info(f'{self} has changed:\n\nold: {self.ftm_log_parse(fields=dirty_fields_old)}\n\nnew:{self.ftm_log_parse(fields=dirty_fields_new)}')
except Exception as e:
# Get all changes.
dirty_fields_old, dirty_fields_new = self.ftm_get_dirty_fields()
LOG.info(f'{self} failed attempting to save:\n\nold: {dirty_fields_old}\n\nnew: {dirty_fields_new}')
LOG.info(
f'{self} failed attempting to save:\n\n'
f'old: {self.ftm_log_parse(fields=dirty_fields_old)}\n\n'
f'new: {self.ftm_log_parse(fields=dirty_fields_new)}'
f'{self} failed attempting to save:\n\nold: {self.ftm_log_parse(fields=dirty_fields_old)}\n\nnew: {self.ftm_log_parse(fields=dirty_fields_new)}'
)
raise e

Expand Down Expand Up @@ -282,3 +278,4 @@ def get_created_by(self, obj: CustomBaseModel) -> str | None:

def get_updated_by(self, obj: CustomBaseModel) -> str | None:
return obj.updated_by.__str__() if obj.updated_by else None

65 changes: 65 additions & 0 deletions backend/root/utils/permission_mixins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from rest_framework.permissions import BasePermission, SAFE_METHODS
from samfundet.models.role import UserGangRole, UserGangSectionRole, UserOrgRole

class IsCreatorOrReadOnly(BasePermission):
"""
Object-level permission to only allow creators of an object to edit it.
Assumes the model instance has a `created_by` attribute from CustomBaseModel.
"""

def has_object_permission(self, request, view, obj):
# Read permissions are allowed to any request,
# so we'll always allow GET, HEAD or OPTIONS requests.
if request.method in SAFE_METHODS:
return True

# Instance must have an attribute named `created_by`.
return obj.created_by == request.user


class IsCreatorOnly(BasePermission):
"""
Object-level permission to only allow creators of an object to view or edit it.
Assumes the model instance has a `created_by` attribute from CustomBaseModel.
"""

def has_object_permission(self, request, view, obj):
# Check if the user is authenticated and is the creator
return request.user.is_authenticated and obj.created_by == request.user


class IsApplicationOwner(BasePermission):
"""Permission to only allow the owner of an application to view or edit it."""

def has_object_permission(self, request, view, obj):
# Compare IDs instead of the objects themselves
return request.user.is_authenticated and obj.user.id == request.user.id


class IsIntern(BasePermission):
from samfundet.models.role import UserGangRole, UserGangSectionRole, UserOrgRole
"""
Permission class that checks if the user has any role assigned.
Having any role signifies the user is an intern.
"""

message = 'You must be an intern to access this resource.'

def has_permission(self, request, view):
# If user isn't authenticated, deny access
if not request.user or not request.user.is_authenticated:
return False

# Check if the user has any role in any context
has_any_role = (
UserOrgRole.objects.filter(user=request.user).exists()
or UserGangRole.objects.filter(user=request.user).exists()
or UserGangSectionRole.objects.filter(user=request.user).exists()
)

return has_any_role

def has_object_permission(self, request, view, obj):
# For object-level permissions, we use the same check
# as has_permission by default
return self.has_permission(request, view)
9 changes: 9 additions & 0 deletions backend/root/utils/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -564,8 +564,17 @@
samfundet__recruitment_applications_for_position_detail = 'samfundet:recruitment_applications_for_position-detail'
samfundet__interview_list = 'samfundet:interview-list'
samfundet__interview_detail = 'samfundet:interview-detail'
samfundet__recruitment_application_list = 'samfundet:recruitment_application-list'
samfundet__recruitment_application_application_state = 'samfundet:recruitment_application-application-state'
samfundet__recruitment_application_for_section = 'samfundet:recruitment_application-for-section'
samfundet__recruitment_application_gang_applications = 'samfundet:recruitment_application-gang-applications'
samfundet__recruitment_application_recruiter_withdraw = 'samfundet:recruitment_application-recruiter-withdraw'
samfundet__recruitment_application_detail = 'samfundet:recruitment_application-detail'
samfundet__recruitment_application_applicant_withdraw = 'samfundet:recruitment_application-applicant-withdraw'
samfundet__recruitment_application_update_state = 'samfundet:recruitment_application-update-state'
samfundet__create_reservation_list = 'samfundet:create_reservation-list'
samfundet__create_reservation_detail = 'samfundet:create_reservation-detail'
samfundet__api_root = 'samfundet:api-root'
samfundet__schema = 'samfundet:schema'
samfundet__swagger_ui = 'samfundet:swagger_ui'
samfundet__redoc = 'samfundet:redoc'
Expand Down
1 change: 1 addition & 0 deletions backend/samfundet/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
router.register('recruitment-applications-for-gang', views.RecruitmentApplicationForGangView, 'recruitment_applications_for_gang')
router.register('recruitment-applications-for-position', views.RecruitmentApplicationForRecruitmentPositionView, 'recruitment_applications_for_position')
router.register('interview', views.InterviewView, 'interview')
router.register('recruitment-application', views.RecruitmentAppicationViewSet, 'recruitment_application')

######## Lyche #########
router.register('create-reservation', views.ReservationCreateView, 'create_reservation')
Expand Down
Loading