Lock
A flexible, driver based Acl package for PHP 5.4+
Install / Use
/learn @BeatSwitch/LockREADME
Lock - Acl for PHP 5.4+
<img width="100%" src="https://s3.eu-central-1.amazonaws.com/assets.beatswitch.com/lock_banner.png">I'm sad to say that Lock is currently not maintained. I won't be able to offer support or accept new contributions for the current time being. Other priorities are keeping me from putting the work into Lock that it deserves. Eventually I'll try to pick up work again but unfortunately I cannot say when. My thanks goes out to all the contributors and users.
-- Dries
Lock is a flexible, driver based Acl package for PHP 5.4+.
Created by Dries Vints. Made possible thanks to BeatSwitch. Inspired by Authority by Matthew Machuga. Logo by Jerry Low.
Table of Contents
- Terminology
- Features
- Introduction
- Drivers
- Roadmap
- Installation
- Usage
- Implementing the Caller contract
- Working with a static driver
- Working with a persistent driver
- Setting and checking permissions
- Clearing permissions
- Setting an action alias
- Setting a God caller
- Working with roles
- Working with conditions
- Retrieving allowed or denied resources
- Using the LockAware trait
- Api
- Building a driver
- Maintainer
- Contributing
- Changelog
- License
Terminology
Lock: An acl instance for a subject. This package currently ships with aCallerLockand aRoleLockCaller: An identity object that can have permissions to do somethingDriver: A storage system for permissions which can either be static or persistentPermission: A permission holds an action and an optional (unique) resource. Can be either aRestrictionor aPrivilegeRestriction: A restriction denies you from being able to perform an action (on an optional resource)Privilege: A privilege allows you to perform an action (on an optional resource)Action: An action is something you are either allowed or denied to doResource: A resource can be an object where you can perform one or more actions on. It can either target a certain type of resource or a specific resource by its unique identifierRole: A role can also hold multiple permissions. A caller can have multiple roles. Roles can inherit permissions from other roles
Features
- Flexible acl permissions for multiple identities (callers)
- Static or persistent drivers to store permissions
- Action aliases
- Roles
- Conditions (Asserts)
- Easily implement acl functionality on your caller or role with a trait
Introduction
Lock differs from other acl packages by trying to provide the most flexible way for working with multiple permission callers and storing permissions.
By working with Lock's Caller contract you can set permissions on multiple identities.
The Driver contract allows for an easy way to store permissions to a persistent or static storage system. A default static ArrayDriver ships with this package. Check out the list below for more drivers which have already been prepared for you. Or build your own by implementing the Driver contract.
You can set and check permissions for resources by manually passing along a resource's type and (optional) identifier or you can implement the Resource contract onto your objects so you can pass them along to lock more easily.
The Manager allows for an easy way to instantiate new Lock instances, set action aliases or register roles.
Drivers
If you need a framework-specific implementation, pick one of the already prepared drivers below.
- ArrayDriver (ships with this package)
- Laravel 5
Roadmap
- Group Permissions
- More drivers (Symfony, Zend Framework, Doctrine, ...)
- Event Listeners
Installation
Install this package through Composer.
$ composer require beatswitch/lock
Usage
Implementing the Caller contract
Every identity which should have permissions to do something must implement the BeatSwitch\Lock\Callers\Caller contract. The Caller contract identifies a caller by requiring it to return its type and its unique identifier. Let's look at an example below.
<?php
use BeatSwitch\Lock\Callers\Caller;
class User implements Caller
{
public function getCallerType()
{
return 'users';
}
public function getCallerId()
{
return $this->id;
}
public function getCallerRoles()
{
return ['editor', 'publisher'];
}
}
By adding the getCallerType function we can identify a group of callers through a unique type. If we would at some point wanted to set permissions on another group of callers we could easily implement the contract on another object.
<?php
use BeatSwitch\Lock\Callers\Caller;
class Organization implements Caller
{
public function getCallerType()
{
return 'organizations';
}
public function getCallerId()
{
return $this->id;
}
public function getCallerRoles()
{
return ['enterprise'];
}
}
And thus we can easily retrieve permissions for a specific caller type through a driver.
Working with a static driver
If you'd like to configure all of your permissions beforehand you can use the static ArrayDriver which ships with the package. This allows you to set a list of permissions for a caller before your application is run.
use \BeatSwitch\Lock\Drivers\ArrayDriver;
use \BeatSwitch\Lock\Lock;
use \BeatSwitch\Lock\Manager;
// Create a new Manager instance.
$manager = new Manager(new ArrayDriver());
// Instantiate a new Lock instance for an object which implements the Caller contract.
$lock = $manager->caller($caller);
// Set some permissions.
$lock->allow('manage_settings');
$lock->allow('create', 'events');
// Use the Lock instance to validate permissions on the given caller.
$lock->can('manage_settings'); // true: can manage settings
$lock->can('create', 'events'); // true: can create events
$lock->cannot('update', 'events'); // true: cannot update events
$lock->can('delete', 'events'); // false: cannot delete events
Working with a persistent driver
Working with a persistent driver allows you to store permissions to a persistent storage layer and adjust them during runtime. For example, if you'd implement the Laravel 5 driver, it would store the permissions to a database using Laravel's database component. By creating your own UI, you could easily attach the acl functionality from this package to create, for example, a user management system where different users have different permissions.
Let's take a look at a very basic user management controller to see how that's done. We'll assume we get a bootstrapped lock manager instance with our Laravel DB driver.
<?php
use BeatSwitch\Lock\Manager;
class UserManagementController extends BaseController
{
protected $lockManager;
public function __construct(Manager $lockManager)
{
$this->lockManager = $lockManager;
}
public function togglePermission()
{
$userId = Input::get('user');
$action = Input::get('action');
$resource = Input::get('resource');
$user = User::find($userId);
$this->lockManager->caller($user)->toggle($action, $resource);
return Redirect::route('user_management');
}
}
Every time the togglePermission method is used, the user's permission for the given action and resource type will be toggled.
Setting and checking permissions
You can either allow or deny a caller from doing something. Here are a couple of ways to set and check permissions.
Allow a caller to create everything.
$lock->allow('create');
$lock->can('create'); // true
Allow a caller to only create posts.
$lock->allow('create', 'posts');
$lock->can('create'); // false
$lock->can('create', 'posts'); // true
Allow a caller to only edit a specific post with an ID of 5.
$lock->allow('edit', 'posts', 5);
$lock->can('edit'); // false
$lock->can('edit', 'posts'); // false
$lock->can('edit', 'posts', 5); // true
Allow a caller to edit all posts but deny them from editing one with the id of 5.
$lock->allow('edit', 'posts');
$lock->deny('edit', 'posts', 5);
$lock->can('edit', 'posts'); // true
$lock->can('edit', 'posts', 5); // false
Toggle a permission's value.
$lock->allow('create');
$lock->can('create'); //
Related Skills
healthcheck
339.1kHost security hardening and risk-tolerance configuration for OpenClaw deployments
node-connect
339.1kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
prose
339.1kOpenProse VM skill pack. Activate on any `prose` command, .prose files, or OpenProse mentions; orchestrates multi-agent workflows.
frontend-design
83.8kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
