Laravel Gate resource with policy not existing - laravel

I am trying to implement Policies in my project and I have a custom method askFriend that I want to add to my UserRelationPolicy.
So I implemented in my UserRelationPolicy the askFriend method but when trying to call it from the UserRelationPolicy#askFriend I asked myself how to call it from this method.
Something like $this->authorize('askFriend', $friend); but it was not working, kind of ignoring it at all. So I searched further in the documentation and found that I could bind with a Gate method the specific method in the UserRelationPolicy to a resource name like this :
Gate::resource('userrelation', 'UserRelationPolicy', [
'userrelation.askfriendrelation' => 'askFriendRelation'
]);
You can find the representation here : Documentation Writing Gate
When I try to execute this code I get the following error :
Call to undefined method Illuminate\Auth\Access\Gate::resource()
And nothing more. The Resource method doesn't seem to exist at all. After many search, trying to include every Gate in the header. Trying to call it staticly or with an instance. Nothing work and the method is nowhere near to be found...
Is it something forgotten ? How can I call a custom method from a controller in a policy class ?

Are you sure you are using 5.4? The method Gate::resource was implemented only in 5.4.
If you are using any version behind you will have to use the Gate::define.
Set the Gate abilities in the App\Providers\AuthServiceProvider like this:
Gate::define('userrelation.askfriendrelation', 'UserRelationPolicy#askFriend');

Related

Laravel Gate and Policy call order

I'm working on a Laravel 5.7 site, trying to implement some new gates and policies on a site that has a few arbitrarily defined already. I am having issues figuring our the order in which gates and policies are discovered and employed when #can($name, $class) is called. The Laravel Authorization help page https://laravel.com/docs/5.7/authorization says
The before method of a policy class will not be called if the class doesn't contain a method with a name matching the name of the ability being checked.
and
If a policy is registered for the given model, the can method will automatically call the appropriate policy and return the Boolean result. If no policy is registered for the model, the can method will attempt to call the Closure based Gate matching the given action name.
So when #can($name, $class) is used, it seems like Laravel will:
Find a matching policy class via policy-model registrations and the Class of $class.
If none are found, skip to #10
Search for a matching policy functions, specified by $name.
If none are found, skip to #10
If there's a policy before() function, run it.
Run the policy function found via steps 1 and 3.
(Is there a policy after() function?)
If there's a Gate::before() function (even if a match is not found in step 10,) run it.
Attempt to find a matching Gate::define() or Gate::resource() function and run it.
If there's a Gate::after() function (even if a match is not found in step 10,) run it.
Questions:
Is this correct? Did I miss anything?
Do the other auth functions work differently? If so, how?
Gate::allow()
Gate::denies
$user->can()
middleware('can:...')
$this->authorize()
$this->authorizeResource()
#cannot()
Is there an after() function capability in the policy classes?
How does Laravel find a matching gate in step 10?
Is Laravel able to find a gate match based on the $class Class?
Does the gate need an exact $name match?
Can it figure out 'noun-verb' Gate names, and pick one based on the Class of $class?
Just a note: It seems (though not specifically stated in the documentation, yet alluded to) that the policy functions have the ability to determine the class of the object passed to it, but the gate functions don't. This may be why gates appear to have a 'verb-noun' name format like 'update-post' and policies appear to have a 'verb' name format (like 'update')
=== Update,
I'm seeing evidence that Gate::before() is run first, before the policies, in any situation.

How to call a laravel factory dynamically?

I have the following seeder.
User::factory(100)
->has(Loan::factory()->count(5))
->has(Transaction::factory()->count(5)
->has(TransactionDetail::factory()->count(1), 'transaction_detail'))
->create();
Now I want to call another Verification class based on a verified property in the User class. So verified could have three possible values - 'pending', 'unverified', 'verified'. Now when it's verified or pending, I want to create a Verification class. But when it's unverified, I don't want to call that class. Something like this...
User::factory(100)
->($user->verified !== 'unverfied') ? has(Verification::factory()) : null
->has(Loan::factory()->count(5))
->has(Transaction::factory()->count(5)
->has(TransactionDetail::factory()->count(1), 'transaction_detail'))
->create();
Now, I know this syntax doesn't make any sense. But I am just trying to explain my problem.
How do I call this verification factory based on $user->verified?
Thanks in advance.

security with method not working

I'm trying to set up security on my entities in API Platform and found that I can call a method instead of the property example used in the docs (found this in some example somewhere on the web):
* attributes={"access_control"="is_granted('ROLE_USER') and object.belongsTo(user)"},
This is necessary in my case as I keep the user account data seperate from the user profile data and the entity in question is linked to the profile, not the user entity.
This works like charm on an individual getter (/api/data/{id}) but fails with a server 500 error on the list (/api/data):
"hydra:description": "Unable to call method \"belongsTo\" of object
\"ApiPlatform\Core\Bridge\Doctrine\Orm\Paginator\".",
Wondering what is going wrong and how to fix it.
the "belongsTo()" method is fairly simple:
public function belongsTo(User $user) {
return $user == $this->owner->user;
}
Try this way
Create custom extension

Debugging Grocery_CRUD Callbacks

I have seen many people referring to the usage of call_user_func() to debug the problems in a Grocery_CRUD callback, but unfortunately no one has come off with a complete example to actually how to use it like where to to place a call to the test function [just_a_test()] in the controller an example of what I am trying to discover is here.
I am unable to understand where do we call this
just_a_test(),
how are we able to pass on the desired parameters using call_user_func(array($this,'insert_coupon_codes')); when there are no para's being passed to the just_a_test()?
how come the insert_coupon_codes will be able to get the desired para's?
Grocery CRUD add the parameters automatically from the library. You are not able (till now at version 1.1.8) to add more parameters at your callback.
Update: At the latest version of Grocery CRUD now you CAN pass as many parameters as you need. This is a functionality that PHP is offering from version PHP 5.4 or later. More specifically with the use keyword. More specifically if you have the callback callback_after_insert:
usually you would use it like this:
$crud->callback_after_insert(function ($post_array,$primary_key) {
// Your code here
});
From PHP 5.4 version and later you can add more parameters with the use so for example you could have:
$my_variable = 'test';
$another_variable = 'hello';
$crud->callback_after_insert(function ($post_array,$primary_key) use ($my_variable, $another_variable) {
// Now you can use the variables $my_variable and $another_variable at your callback
});

How to set up FubuMVC validation

I'm trying to learn FubuMVC and have gotten stuck on validating my input models.
What I want to accomplish is post-validate-redirect. That is, to redirect to same view and show the errors if the model is invalid. I'm using attributes on my models.
Also, how would I specify my own error messages, i.e localization?
I'm using the latest packages of Fubu from nuget.
My registry looks like this:
IncludeDiagnostics(true);
Applies.ToThisAssembly();
Actions.IncludeClassesSuffixedWithController();
Routes
.HomeIs<HomeController>(x => x.Index())
.IgnoreControllerNamesEntirely()
.IgnoreMethodsNamed("Index")
.IgnoreMethodsNamed("Query")
.IgnoreMethodsNamed("Command")
.IgnoreNamespaceText("Features")
.IgnoreMethodSuffix("Html")
.RootAtAssemblyNamespace()
.ConstrainToHttpMethod(x => x.Method.Name.EndsWith("Command"), "POST")
.ConstrainToHttpMethod(x => x.Method.Name.EndsWith("Query"), "GET");
this.UseSpark();
this.Validation();
HtmlConvention<SampleHtmlConventions>();
Views.TryToAttachWithDefaultConventions();
The FubuMVC.Validation package is really just an example of how to use FubuValidation as we haven't built it out for all of the edge cases. Having said that, let me explain a little bit about how it works so we can see if you can use it, or if you should just handroll your own validation behavior.
The ValidationBehavior uses the IValidationFailureHandler interface to "handle" validation failures. The Notification object built up from FubuValidation is shoved into the IFubuRequest when the behavior fires, and then the handler is called.
The ValidationFailureHandler class is wired up by default for all
validation failures. This delegates to the IValidationFailurePolicy to
determine the strategy to use for a given model type (see my post on
policies for an explanation of how this works).
The Validation extension method has an overload which gives a micro-
dsl for configuring these policies:
this.Validation(x => {
x.Failures....
});
From here you can 1) apply custom policies via the ApplyPolicy method
or 2) use the predicate based configuration approach via the IfModel methods.
If you go the predicate route (e.g., x.Failures.IfModelIs()), you can tell FubuMVC.Validation to use FubuContinuations to redirect or transfer to another behavior
chain. Rex recently posted about FubuContinuations if you're looking for some guidance in this area (http://rexflex.net/2011/07/fubumvc-fubucontinuation/).
Hope this helps and feel free to ask away if I didn't explain anything enough,
Josh

Resources