Giter Club home page Giter Club logo

geggleto-acl's Introduction

Build Status

geggleto-acl

Provides a ACL repository and Middleware using Zend/Permissions/Acl library PSR-7 Compliant

How it works

  • Resources are end-points
  • Roles are a group of resources
  • You can either allow or deny those roles.

The roles a user has are loaded into the AclRepo on every request. I suggest loading them into a session variable rather than pulling them from storage everytime (usage case depending).

The current route is then inspected and compared to the list of accessable resources in a middleware. a 401 is returned if a user is not allowed. If the user is allowed the application is allowed to continue.

By default no message body is provided on the 401, and if you require a page to be rendered then you will need to write your own middleware.

Usage Example

//Define or Pull your ACL's into the following format
/*
$config = [
    "resources" => ["/", "/no", "/yes"],
    "roles" => ["guest", "user1", "user2"],
    "assignments" => [
        "allow" => [
            "guest" => ["/"],
            "user1" => ["/", "/no"],
            "user2" => ["/", "/yes"]
        ],
        "deny" => [
            "guest" => ["/no", "/yes"],
            "user1" => ["/yes"],
            "user2" => ["/no"]
        ]
    ]
];
*/

//In Slim v3
$app->add(\Geggleto\Acl\AclRepository(["guest"], 
//This should be in a nice php file by itself for easy inclusion... include '/path/to/acl/definition.php'
[
    "resources" => ["/", "/no", "/yes"],
    "roles" => ["guest", "user1", "user2"],
    "assignments" => [
        "allow" => [
            "guest" => ["/"],
            "user1" => ["/", "/no"],
            "user2" => ["/", "/yes"]
        ],
        "deny" => [
            "guest" => ["/no", "/yes"],
            "user1" => ["/yes"],
            "user2" => ["/no"]
        ]
    ]
]));

Dynamic Routes

In the case where your resource changes, it is possible to still correctly match by setting a resources with a Route Pattern. By default the system will inspect the $request's 'route' attribute and this Object should return the route pattern with ->getPatter(); Out of the box this will work with Slim 3 routes if you have turned on the 'determineRouteBeforeAppMiddleware' => true option.

Example Config:

return [
    "resources" => ["/", "/login", "/grid", "/404", "/logout", "/roles", "/roles/{pein}"],
    "roles" => ["guest", "grid", "roles"],
    "assignments" => [
        "allow" => [
            "guest" => ["/", "/404", "/login"],
            "grid" => [ '/grid', '/logout' ],
            "roles" => ['/roles', '/roles/{pein}']
        ],
        "deny" => []
    ]
];

If this does not fit your usage, feel free to override the default handler by setting your own via setHandler(callable)

Middleware

You can use the repo class directly which contains this code block... or modify this code block to suit your needs.

$app->add(function (Request $request, Response $res, $next) {
    /** @var $aclRepo AclRepository */ 
    $aclRepo = $this->get(AclRepository::class); //In Slim 3 the container is bound to function definitions
    $allowed = false; // We assume that the user cannot access the route

    $route = '/' . ltrim($request->getUri()->getPath(), '/'); //We construct our path

    try { //Check here... This will pass when a route is simple and there is no route parameters
        $allowed = $aclRepo->isAllowedWithRoles($aclRepo->getRole(), $route);
    } catch (InvalidArgumentException $iae) { //This is executed in cases where there is a route parameters... /user/{id:} 
        $fn = function (ServerRequestInterface $requestInterface, AclRepository $aclRepo) {
            //This will likely only work in Slim 3... This requires the determineRouteBeforeAppMiddleware => true to be set in the container
            $route = $requestInterface->getAttribute('route'); // Grab the route to get the pattern
            if (!empty($route)) {
                foreach ($aclRepo->getRole() as $role) {
                    if ($aclRepo->isAllowed($role, $route->getPattern())) { // check to see fi the user can access the pattern
                        return true; //Is allowed
                    }
                }
            }
            return false;
        };

        $allowed = $fn($request, $aclRepo); // Execute the fail-safe
    }

    if ($allowed) {
        return $next($request, $res);
    } else {
        return $res->withStatus(401); //Is not allowed. if you need to render a template then do that.
    }
});

White listing

You may add a URI path for white listing. The whitelisting is based upon strpos() so you may use a URI fragment to whitelist a whole class of URIs. With this it is possible to whitelist URIs by accident.

Example:

$acl = new Acl();
$acl->addWhitelistItem('/api');

In this example any URI with /api will be whitelisted.

  • /api/*
  • /myexample/api/*

geggleto-acl's People

Contributors

geggleto avatar matthewtrask avatar lotharthesavior avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.