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.
Related
I have a console task ran through:
$schedule->command('process:job')
->cron('* * * * *')
->withoutOverlapping();
The task is run, it can invoke different services, everything is fine in the world. However I have one specific tasks invoking a different class where the configuration is not loaded.
For specific reasons I wish to read my configuration in $_ENV (it allows me to do some key value iteration and process some keys specifically based on a pattern). But here $_ENV remains empty, I can read configuration through config() or env().
This never happens through HTTP calls nor through some command lines call (I haven't been able to understand the difference in the scheduler call and command line invocation).
Laravel 5.6
EDIT: this question is kept here because I didn't manage to find the existing relevant one Why is my $_ENV empty?
Found my solution here: Why is my $_ENV empty?
Basically $_ENV is not populated on a systematic basis but only if the flag E is in your variables_order ini variable. So if you stumble one the same problem, I suggest a quick check.
var_dump(ini_get('variables_order'));
The fix is obviously to fix your ini file.
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');
The following is a basic drools syntax:
$customer : Customer( )
Account( ) from $customer.accounts
As far as I know the first line create a new variable and assign it to the fact.
However I can't quite understand the second line especially what the "Account()" part means...
You have written class Customer, or must know it to understand what's going on here. Presumably it contains a Collection<Account> accounts (see note), which is (by the engine) retrieved one by one so that the rule fires for each Account object contained in Customer's object.
The rule will fire once for each Account object stored in any of the collections contained in all the Customer facts in working memory, with $customer being bound to the containing Customer.
You can bind another variable to Account.
Note: It could also contain a field Account accounts, but I hope the name was chosen carefully.
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
The Dynamics AX 2009 Best Practice add-in is throwing the following error on a display method override.
"TwC: Validate access to return value from the display/edit method."
Here is my display method.
display ABC_StyleName lookupModuleName(ABC_StyleSettings _ABC_StyleSettings)
{
;
return ABC_Styles::find(_ABC_StyleSettings.StyleID).StyleName;
}
I'm assuming it wants me to check a config or security key before returning a result. Any suggestions/examples on where to start?
Thanks
This is a reminder that you need to consider whether the user should have access to the data you are returning from the function. For table fields, the kernel normally does this for you based on the security groups the user is in and the security keys set on fields.
To check if a user has access to a field, use the hasFieldAccess function. To see how this is used, look at the table methods BankAccountStatement.openingBalance() or CustTable.openInvoiceBalanceMST(). There are other helper functions to check security keys such as hasMenuItemAccess, hasSecuritykeyAccess, and hasTableAccess.
In your case, add this code:
if(!hasFieldAccess(tablenum(ABC_Styles),fieldnum(ABC_Styles,StyleName)))
{
throw error("#SYS57330");
}
Even after you add that code, you will still get the Best Practice error. To tell the compiler you have addressed the issue, you need to add the following comment immediatly before the function declaration:
//BP Deviation Documented