@@ -14,8 +14,8 @@ trait Authorizable
1414 /**
1515 * Determine if the current user has a given ability.
1616 *
17- * @param \Illuminate\Http\Request $request
18- * @param string $ability
17+ * @param string $ability
18+ * @param Model| string $model
1919 *
2020 * @throws \Illuminate\Auth\Access\AuthorizationException
2121 *
@@ -53,10 +53,10 @@ public function authorizeTo($ability, $model)
5353 }
5454
5555 /**
56- * Determine if the current user can view the given resource .
56+ * Determine if the current user can perform an ability on the given model .
5757 *
58- * @param \Illuminate\Http\Request $request
59- * @param string $ability
58+ * @param string $ability
59+ * @param Model| string $model
6060 *
6161 * @return bool
6262 */
@@ -88,4 +88,148 @@ public function authorizedTo($ability, $model)
8888
8989 return true ;
9090 }
91+
92+ /**
93+ * Determine if the current user has a given ability.
94+ *
95+ * @param string $ability
96+ * * @param Model $model
97+ * * @param string $toActionModel
98+ *
99+ * @throws \Illuminate\Auth\Access\AuthorizationException
100+ *
101+ * @return void
102+ */
103+ public function authorizeToPerformActionOnRelationship ($ ability , $ model , $ toActionModel )
104+ {
105+ $ gate = Gate::getPolicyFor ($ model );
106+ $ method = $ ability .class_basename ($ toActionModel );
107+
108+ if (!is_null ($ gate ) && method_exists ($ gate , $ method ) && $ this ->isAuthorizingEnabled ()) {
109+ $ resolver = function () use ($ method , $ gate , $ model , $ toActionModel ) {
110+ return !is_null ($ gate ) && method_exists ($ gate , $ method )
111+ ? Gate::authorize ($ method , [$ model , $ toActionModel ])
112+ : true ;
113+ };
114+
115+ if ($ this ->isAuthorizationCacheEnabled ()) {
116+ $ gatePasses = Cache::remember (
117+ $ this ->getAuthorizationCacheKey (
118+ app (RestRequest::class),
119+ sprintf (
120+ '%s.%s.%s.%s.%s ' ,
121+ $ ability ,
122+ $ model instanceof Model ? Str::snake ((new \ReflectionClass ($ model ))->getShortName ()) : $ model ,
123+ $ model instanceof Model ? $ model ->getKey () : null ,
124+ $ toActionModel instanceof Model ? Str::snake ((new \ReflectionClass ($ toActionModel ))->getShortName ()) : $ toActionModel ,
125+ $ toActionModel instanceof Model ? $ toActionModel ->getKey () : null ,
126+ )
127+ ),
128+ $ this ->cacheAuthorizationFor (),
129+ $ resolver
130+ );
131+ } else {
132+ $ gatePasses = $ resolver ();
133+ }
134+
135+ if (!$ gatePasses ) {
136+ Response::deny ()->authorize ();
137+ }
138+ }
139+ }
140+
141+ /**
142+ * Determine if the current user can perform an ability on the given model.
143+ *
144+ * @param string $ability
145+ * @param Model $model
146+ * @param string $toActionModel
147+ *
148+ * @return bool
149+ */
150+ public function authorizedToPerformActionOnRelationship ($ ability , $ model , $ toActionModel )
151+ {
152+ $ gate = Gate::getPolicyFor ($ model );
153+ $ method = $ ability .class_basename ($ toActionModel );
154+
155+ if (!is_null ($ gate ) && method_exists ($ gate , $ method ) && $ this ->isAuthorizingEnabled ()) {
156+ $ resolver = function () use ($ method , $ toActionModel , $ model ) {
157+ return Gate::check ($ method , [$ model , $ toActionModel ]);
158+ };
159+
160+ if ($ this ->isAuthorizationCacheEnabled ()) {
161+ return Cache::remember (
162+ $ this ->getAuthorizationCacheKey (
163+ app (RestRequest::class),
164+ sprintf (
165+ '%s.%s.%s.%s.%s ' ,
166+ $ ability ,
167+ $ model instanceof Model ? Str::snake ((new \ReflectionClass ($ model ))->getShortName ()) : $ model ,
168+ $ model instanceof Model ? $ model ->getKey () : null ,
169+ $ toActionModel instanceof Model ? Str::snake ((new \ReflectionClass ($ toActionModel ))->getShortName ()) : $ toActionModel ,
170+ $ toActionModel instanceof Model ? $ toActionModel ->getKey () : null ,
171+ )
172+ ),
173+ $ this ->cacheAuthorizationFor (),
174+ $ resolver
175+ );
176+ }
177+
178+ return $ resolver ();
179+ }
180+
181+ return true ;
182+ }
183+
184+ /**
185+ * Determine if the user can attach models of the given type to the base model.
186+ *
187+ * @param \Illuminate\Database\Eloquent\Model|string $model
188+ * @param \Illuminate\Database\Eloquent\Model|string $toAttachModel
189+ *
190+ * @return bool
191+ */
192+ public function authorizedToAttach ($ model , $ toAttachModel )
193+ {
194+ return $ this ->authorizedToPerformActionOnRelationship ('attach ' , $ model , $ toAttachModel );
195+ }
196+
197+ /**
198+ * Determine if the user can attach models of the given type to the base model.
199+ *
200+ * @param \Illuminate\Database\Eloquent\Model|string $model
201+ * @param \Illuminate\Database\Eloquent\Model|string $toAttachModel
202+ *
203+ * @return void
204+ */
205+ public function authorizeToAttach ($ model , $ toAttachModel )
206+ {
207+ $ this ->authorizeToPerformActionOnRelationship ('attach ' , $ model , $ toAttachModel );
208+ }
209+
210+ /**
211+ * Determine if the user can detach models of the given type to the base model.
212+ *
213+ * @param \Illuminate\Database\Eloquent\Model|string $model
214+ * @param \Illuminate\Database\Eloquent\Model|string $toAttachModel
215+ *
216+ * @return bool
217+ */
218+ public function authorizedToDetach ($ model , $ toAttachModel )
219+ {
220+ return $ this ->authorizedToPerformActionOnRelationship ('detach ' , $ model , $ toAttachModel );
221+ }
222+
223+ /**
224+ * Determine if the user can detach models of the given type to the base model.
225+ *
226+ * @param \Illuminate\Database\Eloquent\Model|string $model
227+ * @param \Illuminate\Database\Eloquent\Model|string $toAttachModel
228+ *
229+ * @return void
230+ */
231+ public function authorizeToDetach ($ model , $ toAttachModel )
232+ {
233+ $ this ->authorizeToPerformActionOnRelationship ('detach ' , $ model , $ toAttachModel );
234+ }
91235}
0 commit comments