michaelryanmcneill / shibboleth

Shibboleth plugin for WordPress
https://wordpress.org/plugins/shibboleth/
19 stars 11 forks source link

A better way to use the "member" header for role mapping. #57

Closed nikoferraz closed 5 years ago

nikoferraz commented 5 years ago

We are trying to create a departmental intranet and only give access to members of the department. The problem is that value for the "member" header is a long string containing all the different groups I belong to on campus, including my unit, separated by spaces and semicolons. It seems that the plugin looks for an exact match instead of trying to match it as a substring. For example:

urn:mace:domain:campus:departmentOne groups:[...];urn:mace:domain:campus:departmentTwo ...

That's roughly what the value of "member" looks like, which is basically a mix of groups at the campus level and at the department level. I want to be able to create a role map by having it match against only a small substring. There are supposed to be a couple of filters for this, but I am not sure how to use them.

Has anyone experienced issue and have an idea of how to work around it?

Sincerely,

Nick

jrchamp commented 5 years ago

It seems like it does that logic already via https://github.com/michaelryanmcneill/shibboleth/blob/06096f23927e30594342c6c3181143c710275ff5/shibboleth.php#L682-L683

You may need to do one entry per group that is allowed so that each group is mapped to the appropriate role.

If I'm misunderstanding your request, please provide a complete example for the full header value and the "approved" role value.

jrchamp commented 5 years ago

If you need to go the filter route, here's a filter you could target to override the final value: https://github.com/michaelryanmcneill/shibboleth/blob/06096f23927e30594342c6c3181143c710275ff5/shibboleth.php#L689

In your departmental custom plugin, you would do something like:

function my_department_shibboleth_get_user_role( $user_role ) {
    $group_roles = array(
        'sysadmins' => 'administrator',
        'communications' => 'editor',
        'departmentOne' => 'author',
        'departmentTwo' => 'author',
    );
    $member = shibboleth_getenv( 'member' );
    $groups = my_function_to_turn_member_string_into_groups( $member );
    foreach ( $group_roles as $group => $role ) {
        if ( isset( $groups[ $group ] ) ) {
            $user_role = $role;
            break;
        }
    }
    return $user_role;
}
add_filter( 'shibboleth_user_role', 'my_department_shibboleth_get_user_role' );
nikoferraz commented 5 years ago

@jrchamp thanks for pointing this out! I got it to work now!

Details:

It looks like I had misunderstood how these groups were formed. I was under the impression that you could get the value of member to match a prefix. For instance, I don't belong to just a department: "urn:mace:domain:campus:department". Instead, I belong to groups nested under a department. So even though all I was interested in as a criteria for role mapping was the prefix for the department the array values are for the fully qualified path to the group. I guess we just need to create a group that is specific to this use, and that will solve the issue.

Thanks again and sorry for the misunderstanding!

Nick