0
\$\begingroup\$

I have small web application that need a users permissions system to access some content or add/edit it.

I'm using roles given to a user to manage priviliges, and also a user custom meta to set a custom priviliges to a specific user.

I want to know if this method is good ? if not why ? Is there is any suggestion better than put priviligies in a array ? because is too long :( .

    if(!function_exists('user_cap')) {
    /**
     *
     */
    function user_cap( $user_id, $cap, $action, $accesable = null ) {

        $get_user_info = get_user_info( $user_id );
        $user_role = $get_user_info->user_role;
        /**
         * Super admin role can determine custom privileges for every user 
         */
        //$user_privileges = get_user_meta( $user_id, 'user_privileges' );

        //

        $privileges = [
            'super_admin' => [
                'users' => [
                    'create' => 'yes',
                    'read' => 'yes',
                    'update' => 'yes',
                    'delete' => 'yes'
                ],
                'projects' => [
                    'create' => 'yes',
                    'read' => 'yes',
                    'update' => 'yes',
                    'delete' => 'yes'
                ],
                'locations' => [
                    'create' => 'yes',
                    'read' => 'yes',
                    'update' => 'yes',
                    'delete' => 'yes'
                ],
                'reminders' => [
                    'create' => 'yes',
                    'read' => 'yes',
                    'update' => 'yes',
                    'delete' => 'yes'
                ],              
                'administrations' => [
                    'create' => 'yes',
                    'read' => 'yes',
                    'update' => 'yes',
                    'delete' => 'yes'
                ],              
                'locations' => [
                    'create' => 'yes',
                    'read' => 'yes',
                    'update' => 'yes',
                    'delete' => 'yes'
                ],

            ],          

            'user' => [
                'users' => [
                    'create' => 'no',
                    'read' => 'no',
                    'update' => 'no',
                    'delete' => 'no'
                ],
                'projects' => [
                    'create' => 'no',
                    'read' => 'get_user_responsible_projects',
                    'update' => 'no',
                    'delete' => 'no'
                ],
                'locations' => [
                    'create' => 'no',
                    'read' => 'no',
                    'update' => 'no',
                    'delete' => 'no'
                ],
                'reminders' => [
                    'create' => 'yes',
                    'read' => 'get_user_reminders',
                    'update' => 'get_user_reminders',
                    'delete' => 'get_user_reminders'
                ],              
                'administrations' => [
                    'create' => 'no',
                    'read' => 'no',
                    'update' => 'no',
                    'delete' => 'no'
                ],              
                'locations' => [
                    'create' => 'no',
                    'read' => 'no',
                    'update' => 'no',
                    'delete' => 'no'
                ],

            ],
        ];

        $role_privilege = $privileges[$user_role][$cap][$action];

        if($privilegs == 'yes') {

            return true;

        }elseif($privilege == 'no') {

            return false;

        }else{

            $privilege = call_user_func($privilege);
            if(in_array($accesable, $privilege) {

                return true;

            }

        }

        return false;

    }
}

if(!function_exists('user_can')) {
    /**
     * @param   int     $user_id
     * @param   string  $cap
     * @param   string  $action
     */
    function user_can( $user_id, $cap, $action ) {

        return user_cap( $user_id, $cap, $action );

    }
}

if(!function_exists('current_user_can')) {
    /**
     * @param   string  $cap
     * @parzm   string  $action
     *
     * @return mixed (string on success|boolean on failure)
     */
    function current_user_can( $cap, $action ) {

        $current_user = current_user();

        if(empty($current_user)) {
            return false;
        }

        return user_can($current_user->id, $cap, $action);
    }
}
\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

There will be many, many ways to structure these permissions. I'll offer a pathway that doesn't totally abandon your original script.

  1. Don't bother writing out all of the super_admin permissions until the day when you actually have a no setting for them. Just write a simple condition on that single variable and an early return.

  2. Only store the yes and callback values. This will save lots of eye strain and scrolling. Have your program assume No permission by default and only declare the access granting keys. By doing this, you can write an early false return if the set of keys are not listed.

  3. If the listed value in the permissions lookup array is yes, early return true.

  4. Leave the "heaviest" action 'til last. This return is the final determining line, so it can be an inline condition on return.

The adjusted script might look like this: (notice no typos and no temporary variables)

function user_cap($user_id, $cap, $action, $accesable = null) {
    $get_user_info = get_user_info($user_id);
    $user_role = $get_user_info->user_role;

    $privileges = [
        'user' => [
            'projects' => [
                'read' => 'get_user_responsible_projects',
            ],
            'reminders' => [
                'create' => 'yes',
                'read' => 'get_user_reminders',
                'update' => 'get_user_reminders',
                'delete' => 'get_user_reminders'
            ]
        ]
    ];

    if ($user_role == 'super_admin') {
        return true;
    }

    if (!isset($privileges[$user_role][$cap][$action])) {
        return false;
    }

    if ($privileges[$user_role][$cap][$action] == 'yes') {
        return true;
    }

    return in_array($accesable, call_user_func($privileges[$user_role][$cap][$action]));
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.