I'm securing an action in security.yml. I want the user to have access if he has credentials (A and B) OR (A and C). Looking at the rather sparse docs I tried these combinations:
myaction:
credentials: [[A, B], [A, C]]
credentials: [[[A, B], [A, C]]]
credentials: [A, [B, C]]
None of them work; [A, B] works, but that's only half the battle. Has anyone got something like this to work?
I'm using Propel 1.4.2 and sfActionCredentialsGetterPlugin. Thanks for your input.
Edit:
I did my testing without using the sfActionCredentialsGetterPlugin, just straight php in a template:
<?php $sf_user->addCredentials('A', 'C'); ?>
<?php var_dump($sf_user->getCredentials()->getRawValue()) ?><br><br><br>
<?php $cred_a = 'A'; ?>
<?php $cred_b = 'B'; ?>
<?php $cred_c = 'C'; ?>
<?php $cred_3 = array('B', 'C'); ?>
<?php $has_cred1 = $sf_user->hasCredential(array($cred_a, $cred_3)) ? 'true' : 'false' ?>
<?php $has_cred2 = $sf_user->hasCredential($cred_a, $cred_b) ? 'true' : 'false' ?>
<?php echo 'has cred1? '.$has_cred1 ?><br><br>
<?php echo 'has cred2? '.$has_cred2 ?><br><br>
I'm not getting anywhere.
There's a bit more info here: http://www.symfony-project.org/gentle-introduction/1_4/en/06-Inside-the-Controller-Layer#chapter_06_sub_complex_credentials
According to that, my third try above [A, [B, C]] should work!
Anyone?
Edit 2:
I tried a simple OR combination copied from the docs:
// security.yml:
credentials: [[A, B]]
// template:
$sf_user->hasCredential(array('A', 'B'), false)
Again, no dice. I posted a bugreport: http://trac.symfony-project.org/ticket/10036
I will post my temporary workaround as an answer here. Thanks guys.
Did you follow the Complex Credentials tutorial here: http://www.symfony-project.org/jobeet/1_4/Propel/en/13 ?
I need to move on to other things, so I'm posting my workaround to this issue here.
lib/Tools.class.php:
// check if the user has any of the given credentials
// (need this because sf OR credential combo doesn't work)
// superadmins always pass this check
// param credentials: (string) single credential, or
// (array) flat array of string credentials
public static function hasAnyCredential($user, $credentials)
{
if ( !is_array($credentials) )
{
return $user->hasCredential($credentials);
}
else
{
$test = false;
foreach ($credentials as $credential)
{
$test = false;
if ( $user->hasCredential($credential) ) $test = true;
if ( $test ) break;
}
}
return $test;
}
apps/mymodule/actions/actions.class.php:
// check if user has permissions B or C
// security.yml only has credentials: [A]
protected function hasBcPermission(myUser $user)
{
return Tools::hasAnyCredential($user, array('B', 'C'));
}
This function is used to check action permissions and in the templates to hide inaccessible menus. Hope it helps someone with the same issue.
I'd still be glad to hear from anyone with a real answer!
[A,[B,C]] becomes (A AND (B OR C))
so if you need
((A AND B) OR (A AND C))
i.e. equal to
[A,[B,c]]
I needed (A AND (B OR C OR D))
I did [A,[B,C,D]]
This worked for me.
Remember!!
Each time you add a new level of square brackets, the logic swaps between AND and OR. So you can create very complex credential combinations, such as this:
credentials: [[root, [supplier, [owner, quasiowner]], accounts]]
# root OR (supplier AND (owner OR quasiowner)) OR accounts
Also don't forget to refresh your credentials and check that you are assigned to A and B or A and C
You can check the details here.
http://symfony.com/legacy/doc/gentle-introduction/1_4/en/06-Inside-the-Controller-Layer#chapter_06_sub_complex_credentials
Your code examples are a bit too detached I'm afraid. Can you also provide examples of how you are setting and checking the credentials? The problem might lie there and not with the definition itself. (also what is your security filter in filters.yml, and what exactly do you mean by "they don't work")
In the first snippet, option 2 and 3 will give a result as you expect. So any user trying to execute myaction will be allowed to do it only if he is Authenticated and has the credentials A and (B or C). Otherwise he will be send to the default login or secure action.
In the testing code there is an error which leads to wrong results:
<?php $has_cred2 = $sf_user->hasCredential($cred_a, $cred_b) ? 'true' : 'false' ?>
The hasCredential() accepts a credential or array of credentials as the first parameter and a boolean as the second. You pass two string credentials.
Every time you give examples of tests you have made give the information of what was the result you got and what should be the result you expect. This will help identify the problems.
In the third example you write a call to hasCredentials() but we don't know what credentials did you set on the user so we don't know what to check there.
Related
I'm using WordPress ACF plugin to store users' data.
The values I'm calling in template are as below:
echo $uid=get_current_user_id();
echo $lesson_order = get_field('lesson_order', 'user_'.$uid);
echo $last_lesson_time = get_field('last_lesson_time', "user_".$uid);
The values returned for admins are correct, but when logged in as a subscriber, the code returns empty values. I also checked user ids, which appear to be correct.
Can someone give me a solution to this. Thanks a lot.
I've tested both option on a local project and both were working but have you tried retrieving the user ID using this instead?
<?php
$current_user = wp_get_current_user();
echo "Current User ID " . $current_user->ID;
?>
If it still doesn't work, can you show a little more of your code?
You can also check that answer for more information : https://wordpress.stackexchange.com/questions/163407/get-current-user-id-returns-0
I've got a strange one going on here. Tried to implement is_wp_error in multiple situations, but it fails. Here's the thing, illustrated with my last attempt:
I want to login a user by wp_signon(), check if there are errors and if so, display them.
So I wrote the following lines of code:
$user = wp_signon();
if(is_wp_error($user)){
$result = 'Error-' .
$user->get_error_message();
} else {
$result = 'Login succeed';
}
echo $result;
The strange thing is, is_wp_error() doesn't return false (so there is an error). But $user->get_error_message(); is empty.
Tried it in different actions. When debugging, echo is_wp_error(); returns 0.
var_dump(wp_is_error()); returns empty arrays.
Furthermore, even when valid credentials are given, is_wp_error() still returns true. Also when testing in other circumstances (and on a clean WP installation)
Any thoughts?
I took a look through the wp_signon() code (located at http://core.trac.wordpress.org/browser/tags/3.5/wp-includes/user.php#L0 )
Looks like the error is blanked out if a blank username or password is passed in. (lines 56 and 57 of that file.)
How to get current users privileges in wordpress a plugin with respect to their roles;
Eg:-
if input is editor function should return delete_others_posts, if input is author result will be delete_published_posts and so on...
Thanks in advance
Get the name of the current user role :
function get_current_user_role() {
global $current_user;
return array_shift($current_user->roles);
}
Then using get_role($role_name) function you can get an array with all his capabilities.
E.G : $capabilities = get_current_user_role();
Another solution is to use the current_user_can($capability_name) function that return true or false
For entire explanations : http://tomarea.fr/wordpress-roles-capacites-utilisateurs/
To elaborate on koma182's answer, wrap get_role() with a var_dump or print_r and you'll see the capabilites of the current user role:
function get_current_user_role() {
global $current_user;
return array_shift($current_user->roles);
}
and then where you call the function:
var_dump(get_role(get_current_user_role()));
Thanks Koma!
I want to limit a block to only being on the a users account page. In the section "Show block on specific pages" I used users/[user-name] (did not work) then I tried users/[user-id] (did not work).
Are tokens allowed here? Is there a way to do this?
TIA
You can use PHP to get the result you want. I dont know if tokens are allowed here. If you have PHP filter enabled you may use the following:
<?php
global $user;
if (arg(0) == 'user' && $user->uid == arg(1)){
return True;
}else{
return False;
}
?>
Get the current user with global $user, than get the url arguments with arg():
The first argument should be "user", so arg(0) == 'user'.
The second should be the current user uid, so arg(1) == $user->uid.
Everything else returns false.
Hope it helps.
Try using the * wildcard in place of a token. So you would have:
users/*
This must be an easy one but I can't find documentation for it online.
I'm trying to use the l() function in Drupal to create a dynamic link. What's the syntax?
At the moment I have:
l('Destination',"path/$user->uid/category")
which points to:
path/%2Fcategory
first of all, if you're working within a function, you'll need to get access to the global user object.
Secondly, if the user is anonymous/not logged in, the $user->uid might not be set or be 0.
lastly to prevent errors, it is common to concatenate variables together with strings
global $user;
if ($user->uid)
{
l('Destination', 'path/'.$user->uid.'/category')
}
l() is correcting your URL to path/%2Fcategory because it's trying to make a workable link from the string path//category.
Your string is path//category because $user->uid has no value. It has no value because either you haven't pulled up a user object from global $user or user_load(), or your user is anonymous.
I would suggest putting checking the value of $user before calling l(), for example:
global $user; // or $user = user_load($foo);
if ($user) {
l('Destination', 'path/'.$user->uid.'/category');
} else {
l('Destination', 'path/you-are-not-logged-in');
}
Try concatenating the strings instead.
l('Destination',"path/".$user->uid."/category")
as for the documentation, here it is: http://api.drupal.org/api/function/l/4.7
l($text,
$path,
$attributes = array(),
$query = NULL,
$fragment = NULL,
$absolute = FALSE,
$html = FALSE)
The documentation for the l() function is located at:
http://api.drupal.org/api/function/l/6
Other stuff has been said yet by others :)