Link Search Menu Expand Document

Käyttäjäroolit ja oikeudet

Pike sisältää \Pike\Auth\ACL-luokan, jolla on helppo luoda systeemi, jolla tarkastaa mitä kukin applikaation käyttäjärooli saa, ja ei saa tehdä.

Sisällysluettelo

  1. Peruskäyttö
  2. Liittäminen reitteihin
    1. ACL-ohjeiden lisääminen reittimääritelmiin
    2. ACL-ohjeiden prosessointi HTTP-pyyntöjen yhteydessä

Peruskäyttö

Setuppi:

use \Pike\Auth\ACL;
$resources = (object) [
    'products' => (object) [
        'create'  => 1 << 1,
        'edit'    => 1 << 2,
        'comment' => 1 << 3,
    ],
    'reviews' => (object) [
        'post'     => 1 << 1,
        'moderate' => 1 << 2,
    ]
];
$userPermissions = (object) [
    ACL::ROLE_EDITOR => (object) [
        'products' => ACL::makePermissions(['comment', 'edit'], $resources->products),
        'reviews'  => ACL::makePermissions('*', $resources->reviews),
    ],
    ACL::ROLE_CONTRIBUTOR => (object) [
        'products' => ACL::makePermissions(['comment'], $resources->products),
        'reviews'  => ACL::makePermissions(['post'], $resources->reviews),
    ]
];
$acl = new ACL;
$acl->setRules((object)['resources' => $resources,
                        'userPermissions' => $userPermissions]);

Käyttäminen:

$acl->can(ACL::ROLE_EDITOR,      'create',   'products'); // false
$acl->can(ACL::ROLE_EDITOR,      'edit',     'products'); // true
$acl->can(ACL::ROLE_EDITOR,      'comment',  'products'); // true
$acl->can(ACL::ROLE_EDITOR,      'post',     'reviews');  // true
$acl->can(ACL::ROLE_EDITOR,      'moderate', 'reviews');  // true

$acl->can(ACL::ROLE_CONTRIBUTOR, 'create',   'products'); // false
$acl->can(ACL::ROLE_CONTRIBUTOR, 'edit',     'products'); // false
$acl->can(ACL::ROLE_CONTRIBUTOR, 'comment',  'products'); // true
$acl->can(ACL::ROLE_CONTRIBUTOR, 'post',     'reviews');  // true
$acl->can(ACL::ROLE_CONTRIBUTOR, 'moderate', 'reviews');  // false

Oletuskäyttäytyminen:

// false, jos role|action|resource ei olemassa
$acl->can(NONEXISTING_ROLE, 'post',              'reviews');             // false
$acl->can(ACL::ROLE_EDITOR, 'nonExistingAction', 'reviews');             // false
$acl->can(ACL::ROLE_EDITOR, 'post',              'nonExistingResource'); // false

// true, jos kyseessä super-admin
$acl->can(ACL::ROLE_SUPER_ADMIN, 'nonExistingAction', 'reviews');             // true
$acl->can(ACL::ROLE_SUPER_ADMIN, 'post',              'nonExistingResource'); // true
$acl->can(ACL::ROLE_SUPER_ADMIN, 'kissat koiria',     'gfffögkfhjd');         // true

Liittäminen reitteihin

ACL:n ja HTTP-reitteihin yhdistämiseen tarvitaan kaksi asiaa:

ACL-ohjeiden lisääminen reittimääritelmiin

...
final class MyModule {
    /**
     * @param \Pike\AppContext $ctx
     */
    public function init(AppContext $ctx): void {
        //                                                         Ohjeet
        //                                                           |
        $ctx->router->map('POST', '/products', //                   \/
            [ProductController::class, 'handleCreateProduct', 'create:products']
        );
        $ctx->router->map('PUT', '/products/[i:productId]',
            [ProductController::class, 'handleEditProduct', 'edit:products']
        );
        ...
    }
    ...
}

ACL-ohjeiden prosessointi HTTP-pyyntöjen yhteydessä

...

final class MyAuthModule {
    /**
     * @param \Pike\AppContext $ctx
     */
    public function init(AppContext $ctx): void {
        $ctx->acl = new \Pike\Auth\ACL;
        $ctx->acl->setRules(self::makeMyAclRules());
        //
        $ctx->router->on('*', function ($req, $res, $next) use ($ctx) {
            // Tämä tulisi normaalisti sessiosta ($ctx->auth->getIdentity()->role)
            $userRole = \Pike\Auth\ACL::ROLE_EDITOR;
            // ks. Step 3
            [$action, $resource] = explode(':', $req->routeInfo->myCtx);
            if (!$ctx->acl->can($userRole, $action, $resource))
                $res->status(403)->json(['err' => 'Not permitted']);
            else
                $next();
        });
    }
    /**
     * @return \stdClass
     */
    private static function makeMyAclRules(): \stdClass {
        // Nämä tulisi normaalisti esim. tiedostosta tai tietokannasta.
        $resources = (object) [
            'products' => ...,
            'reviews' => ...
        ];
        $userPermissions = (object) [
            ACL::ROLE_EDITOR => (object) [
                'products' => ...,
                'reviews'  => ...,
            ],
            ACL::ROLE_CONTRIBUTOR => (object) [
                'products' => ...,
                'reviews'  => ...,
            ]
        ];
        return (object) [
            'resources' => $resources,
            'userPermissions' => $userPermissions
        ];
    }
}

Muista myös lisätä prosessoiva moduuli applikaation moduulilistaan. Moduuli tulisi olla aina ensimmäisenä:

$myModules = [new MyAuthModule, ...];
$app = new \Pike\App($myModules);
...

Copyright © 2019-2021 ut4