1- from datetime import timedelta , datetime
1+ from datetime import datetime , timedelta
22
33from django .utils import timezone
4-
5- from rest_framework .permissions import BasePermission , SAFE_METHODS
64from rest_framework .exceptions import PermissionDenied
5+ from rest_framework .permissions import SAFE_METHODS , BasePermission
76
8- from projects .models import Project
97from partner_programs .models import PartnerProgramUserProfile
8+ from projects .models import Project
109
1110
1211class IsProjectLeaderOrReadOnlyForNonDrafts (BasePermission ):
@@ -79,29 +78,37 @@ class TimingAfterEndsProgramPermission(BasePermission):
7978 for `_SECONDS_AFTER_CANT_EDIT` seconds -> days from the end of the program.
8079 If the project is not in program or the request in `SAFE_METHODS` -> allowed.
8180 """
81+
8282 _SECONDS_AFTER_CANT_EDIT : int = 60 * 60 * 24 * 30 # Now 30 days.
8383
8484 def has_object_permission (self , request , view , obj ) -> bool :
8585 if request .method in SAFE_METHODS :
8686 return True
8787
8888 program_profile = (
89- PartnerProgramUserProfile .objects
90- .filter (user = request .user , project = obj )
89+ PartnerProgramUserProfile .objects .filter (user = request .user , project = obj )
9190 .select_related ("partner_program" )
9291 .first ()
9392 )
9493 moscow_time : datetime = timezone .localtime (timezone .now ())
9594
9695 if program_profile :
97- date_from_end_program : timedelta = (moscow_time - program_profile .partner_program .datetime_finished )
96+ date_from_end_program : timedelta = (
97+ moscow_time - program_profile .partner_program .datetime_finished
98+ )
9899 days_from_end_program : int = date_from_end_program .days
99100 seconds_from_end_program : int = date_from_end_program .total_seconds ()
100101 if 0 <= seconds_from_end_program <= self ._SECONDS_AFTER_CANT_EDIT :
101- raise PermissionDenied (detail = self ._prepare_exception_detail (days_from_end_program , program_profile ))
102+ raise PermissionDenied (
103+ detail = self ._prepare_exception_detail (
104+ days_from_end_program , program_profile
105+ )
106+ )
102107 return True
103108
104- def _prepare_exception_detail (self , days_from_end_program : int , program_profile : PartnerProgramUserProfile ):
109+ def _prepare_exception_detail (
110+ self , days_from_end_program : int , program_profile : PartnerProgramUserProfile
111+ ):
105112 """
106113 Prepare response body when `PermissionDenied` exception raised:
107114 program_name: str -> Program title
@@ -112,7 +119,11 @@ def _prepare_exception_detail(self, days_from_end_program: int, program_profile:
112119 when_can_edit : datetime = timezone .localtime (
113120 datetime_finished + timedelta (seconds = self ._SECONDS_AFTER_CANT_EDIT )
114121 )
115- days_until_resolution : int = int (self ._SECONDS_AFTER_CANT_EDIT / 60 / 60 / 24 ) - days_from_end_program - 1
122+ days_until_resolution : int = (
123+ int (self ._SECONDS_AFTER_CANT_EDIT / 60 / 60 / 24 )
124+ - days_from_end_program
125+ - 1
126+ )
116127 return {
117128 "program_name" : program_profile .partner_program .name ,
118129 "when_can_edit" : when_can_edit ,
@@ -140,3 +151,41 @@ def has_object_permission(self, request, view, obj):
140151 ) or obj .project .leader == request .user :
141152 return True
142153 return False
154+
155+
156+ class IsProjectLeaderOrReadOnly (BasePermission ):
157+ """
158+ Читать могут все (в т.ч. анонимы).
159+ Создавать/изменять/удалять может только лидер проекта.
160+ """
161+
162+ message = "Только лидер проекта может создавать, изменять или удалять цели."
163+
164+ def has_permission (self , request , view ):
165+ if request .method in SAFE_METHODS :
166+ return True
167+
168+ if not request .user or not request .user .is_authenticated :
169+ return False
170+
171+ project_pk = view .kwargs .get ("project_pk" )
172+ project_id = project_pk or request .data .get ("project" )
173+ if not project_id :
174+ return False
175+
176+ try :
177+ project = Project .objects .only ("id" , "leader_id" ).get (pk = project_id )
178+ except Project .DoesNotExist :
179+ return False
180+
181+ return project .leader_id == request .user .id
182+
183+ def has_object_permission (self , request , view , obj ):
184+ if request .method in SAFE_METHODS :
185+ return True
186+
187+ return (
188+ request .user
189+ and request .user .is_authenticated
190+ and obj .project .leader_id == request .user .id
191+ )
0 commit comments