99use Illuminate \Database \Eloquent \Relations \Relation ;
1010use Illuminate \Http \Request ;
1111use Illuminate \Support \Facades \Gate ;
12+ use ReflectionMethod ;
1213
1314abstract class Repository extends RestifyRepository
1415{
16+ /**
17+ * Actions to suppress from the OpenAPI document and (by convention) from custom routes().
18+ * Subclasses may override with any of: 'store', 'update', 'destroy'.
19+ *
20+ * @var string[]
21+ */
22+ protected static array $ disabledActions = [];
23+
1524 public static function authorizedToUseRepository (Request $ request ): bool
1625 {
1726 $ user = $ request ->user ();
@@ -37,4 +46,52 @@ public static function showQuery(RestifyRequest $request, Builder|Relation $quer
3746 {
3847 return $ query ;
3948 }
49+
50+ /**
51+ * Whether the action should appear in the OpenAPI document. Combines the explicit
52+ * $disabledActions list, any LibreNMS-side authorizedTo<Action> override (which by
53+ * convention returns false unconditionally), and policy method existence.
54+ */
55+ public static function actionEnabled (string $ action ): bool
56+ {
57+ if (in_array ($ action , static ::$ disabledActions , true )) {
58+ return false ;
59+ }
60+
61+ $ authMethod = match ($ action ) {
62+ 'store ' => 'authorizedToStore ' ,
63+ 'update ' => 'authorizedToUpdate ' ,
64+ 'destroy ' => 'authorizedToDelete ' ,
65+ default => null ,
66+ };
67+
68+ $ policyMethod = match ($ action ) {
69+ 'store ' => 'create ' ,
70+ 'update ' => 'update ' ,
71+ 'destroy ' => 'delete ' ,
72+ default => null ,
73+ };
74+
75+ if ($ authMethod === null || $ policyMethod === null ) {
76+ return false ;
77+ }
78+
79+ $ declaringClass = (new ReflectionMethod (static ::class, $ authMethod ))->getDeclaringClass ()->getName ();
80+ if ($ declaringClass !== self ::class && str_starts_with ($ declaringClass , 'App \\Restify \\' )) {
81+ return false ;
82+ }
83+
84+ if (! property_exists (static ::class, 'model ' )) {
85+ return false ;
86+ }
87+ /** @var class-string<\Illuminate\Database\Eloquent\Model>|null $modelClass */
88+ $ modelClass = static ::$ model ?? null ; // @phpstan-ignore staticProperty.notFound
89+ if (! is_string ($ modelClass ) || ! class_exists ($ modelClass )) {
90+ return false ;
91+ }
92+
93+ $ policy = Gate::getPolicyFor (new $ modelClass ());
94+
95+ return is_object ($ policy ) && method_exists ($ policy , $ policyMethod );
96+ }
4097}
0 commit comments