- 1 Examples
- 2 Introduction
- 3 Current Limitations (Planned Fixes)
- 4 Installation
- 5
RBAC-PGClass - 6 Functions
- 7 Special Variables
- 8 Macros
- 9
RBACDevelopment
Simple Role-Based Access Control (RBAC) system implemented in Common Lisp. It provides an rbac-pg class and functions for managing users, roles, permissions, and resources.
Usage examples.
;;
;; WARNING: Use environment variables for real passwords, never hardcode them
;;
(require :rbac)
(defpackage :rbac-example (:use :cl :rbac))
(in-package :rbac-example)
;; Connect to the databse
(defparameter *rbac* (make-instance 'rbac-pg
:host "127.0.0.1"
:port "5432"
:user-name "rbac"
:password "rbac-password"))
;; Initialize the database. This will create the base users,
;; roles, and permissions. The password would normally come
;; from an environment variable.
(initialize-database *rbac* "admin-password-1")
;; Add a bogus permission
(add-permission *rbac* "bogus-permission")
;; Add some roles. The first role has the "read" permission only.
(add-role *rbac* "role-a" :permissions '("read"))
;; role-b has the default permissions, "create", "read", "update",
;; and "delete".
(add-role *rbac* "role-b")
;; role-c has the default permissions plus the "bogus-permission".
(add-role *rbac* "role-c"
:permissions (cons "bogus-permission" *default-permissions*))
;; role-d has only the "bogus" permission only.
(add-role *rbac* "role-d"
:permissions '("bogus-permission"))
;; Add a user with roles "role-a" and "role-b"
(add-user *rbac* "user-1" "user-1@example.com" "password-01"
:roles '("role-a" "role-b"))
;; Add a resource that is accessible to the public
(add-resource *rbac* "test:resource-1"
:roles '("public" "role-b"))
;; Should list 3 users: "admin", "guest", and the user we just
;; added, "user-1"
(list-user-names *rbac*)
;; Should list the default permissions
(list-permission-names *rbac*)
;; Lists the roles for user "user-1", including "role-a" and
;; "role-b", which we assigned, the user's exclusive role,
;; "user-1:exclusive", which the system assigned, and the
;; "logged-in" role, also assigned by the system.
(list-user-role-names *rbac* "user-1")
;; Lists the permissions that "user-1" has on resource
;; "test:resource-1", which should be all the permissions from
;; the roles that the user and the resource share, "public"
;; and "role-b". This amounts to all the default permissions.
(list-user-resource-permission-names *rbac* "user-1" "test:resource-1")
;; Returns T, because "read" is among the permissions that
;; the user has on the resource.
(user-allowed *rbac* "user-1" "read" "test:resource-1")This library provides functions and initial SQL for supporting Role-Based Access Control (RBAC).
The system provides users, roles, permissions, and resources. Users have roles. Roles have permissions. Resources also have roles. However, resources do not have users. To determine if user 'adam' has 'read' access to resource 'book', the user and the book must both have the same role and the role must have the 'read' permission.
A role can be exclusive, which means that it can be associated with only one user. Exclusive roles are managed by the system, so there's never any need to create or delete exclusive roles. However, you can manage the permission for an exclusive role. Whenever a user is created with the add-user function, the library creates the user's exclusive role. The user's exclusive role is also removed when the user is removed. Thus, the exclusive role represents that user only. In this way, it's possible to give a specific user access to the resource. All users have a corresponding exclusive role, except for the guest user. You can obtain the name of a user's exclusive role with the exclusive-role-for function.
All new users are created with default roles: 'logged-in', 'public', and the exclusive role for that user. If a resource has the 'logged-in' role, then every logged-in user (that is, every user except for 'guest') has access to the resource. If a resource has the 'public' role, then all users, including the guest user (not logged in), have access to the resource. The 'public' and 'logged-in' roles have 'read' permission by default.
Unless you specify specific permissions when creating a new role, its permission defaults to 'create', 'read', 'update', and 'delete'. These are general, default permissions, but you can add any permission you like to the system.
All new resources are created with the default role 'admin'.
RBAC operations span multiple transactions for maximum flexibility. Thus, this library will not work well with multi-threaded clients unless RBAC calls are serialized.
Status: Transaction wrappers planned for future release.
Username salting prevents casual DB lookups, but doesn't provide optimal security.
Status: Argon2/PBKDF2 with iterations planned for future release.
You'll need to install some dependencies first:
ros install postmodern
ros install fiveam
ros install cl-csv
ros install trivial-utf-8
ros install ironclad
ros install swank
ros install macnod/dc-dlist/v1.0
ros install macnod/dc-ds/v0.5
ros install macnod/dc-time/v0.5
ros install macnod/p-log/v0.9
ros install macnod/dc-eclectic/v0.51Then, you can install rbac like this:
ros install macnod/rbac/vX.X
where X.X is the release. You can find the latest release in the repo.
Clone the repo to a directory that Quicklisp or ASDF can see, such as ~/common-lisp. For example:
cd ~/common-lisp
git clone git@github.com:macnod/rbac.git
cd rbacThen, install the macnod dependencies in a similar fashion. If use Quicklisp, then Quicklisp will take care of installing the other dependencies (non-macnod) when you do (ql:quickload :rbac).
One way to use the RBAC library is to create a project that includes the RBAC init.sql file. You might want to edit the init.sql file to change the database name, for example, or to add some tables.
Your project should start PostgreSQL, initialize the database with init.sql (if that hasn't already been done), and load the RBAC library.
Your project can then use the library via the RBAC API.
RBAC-PG Class and Accessors.
-
[class] RBAC-PG RBAC
RBACdatabase class for PostgreSQL.
-
[accessor] DB-HOST RBAC-PG (:DB-HOST = "postgres")
Host name for connecting to the
RBACdatabase.
-
[accessor] DB-NAME RBAC-PG (:DB-NAME = "rbac")
Name of the
RBACdatabase.
-
[accessor] DB-PASSWORD RBAC-PG (:DB-PASSWORD = "")
Password for connecting to the
RBACdatabase.
-
[accessor] DB-PORT RBAC-PG (:DB-PORT = 5432)
Port number for connecting to the
RBACdatabase.
-
[accessor] DB-USER RBAC-PG (:DB-USER = "cl-user")
User name for connecting to the
RBACdatabase.
-
[accessor] EMAIL-LENGTH-MAX RBAC (:EMAIL-LENGTH-MAX = 128)
Maximum length of an email address.
-
[accessor] EMAIL-REGEX RBAC (:EMAIL-REGEX = "^[a-zA-Z0-9][-a-zA-Z0-9._%+]+@([a-zA-Z0-9]+)(\\.?[-a-zA-Z0-9])+\\.[a-zA-Z]{2,}$|^no-email$")
Regex for validation of email address strings.
-
[accessor] PASSWORD-LENGTH-MAX RBAC (:PASSWORD-LENGTH-MAX = 64)
Maximum length of password string.
-
[accessor] PASSWORD-LENGTH-MIN RBAC (:PASSWORD-LENGTH-MIN = 6)
Minimum length of password string.
-
[accessor] PASSWORD-REGEXES RBAC (:PASSWORD-REGEXES = (LIST "^[\\x00-\\x7f]+$" "[a-zA-Z]" "[-!@#$%^&*()+={}[]|:;<>,.?/~`]" "[0-9]"))
List of regular expressions that a valid password must match. Every regex in the list must match.
-
[accessor] PERMISSION-LENGTH-MAX RBAC (:PERMISSION-LENGTH-MAX = 64)
Maximum length of permission name string.
-
[accessor] PERMISSION-REGEX RBAC (:PERMISSION-REGEX = "^[a-z]([-a-z0-9_.+]*[a-z0-9])*(:[a-z]+)?$")
Regex for validating permission name strings.
-
[accessor] RESOURCE-LENGTH-MAX RBAC (:RESOURCE-LENGTH-MAX = 512)
Maximum length of resource name string.
-
[accessor] RESOURCE-REGEX RBAC (:RESOURCE-REGEX = "^[a-zA-Z][-a-zA-Z0-9]*:?[a-zA-Z0-9._/][-a-zA-Z0-9._ /]*$")
Defaults to an absolute directory path string that ends with /
-
[accessor] ROLE-LENGTH-MAX RBAC (:ROLE-LENGTH-MAX = 64)
Maximum length of role name string.
-
[accessor] ROLE-REGEX RBAC (:ROLE-REGEX = "^[a-z]([-a-z0-9_.+]*[a-z0-9])*(:[a-z]+)?$")
Regex for validating role name strings.
-
[accessor] USER-NAME-LENGTH-MAX RBAC (:USER-NAME-LENGTH-MAX = 64)
Maximum length of user name string.
-
[accessor] USER-NAME-REGEX RBAC (:USER-NAME-REGEX = "^[a-zA-Z][-a-zA-Z0-9_.+]*$")
Regex for validating user name strings.
Accessors and methods for manipulating RBAC objects.
-
[generic-function] ADD-PERMISSION RBAC PERMISSION &KEY DESCRIPTION
Add a new permission and returns the ID of the new entry.
DESCRIPTIONis optional and auto-generated if not provided.
-
[generic-function] ADD-RESOURCE RBAC RESOURCE &KEY DESCRIPTION ROLES
Add a new resource and returns the ID of the new entry. The resource is automatically linked to the roles in default-resource-roles plus any additional
ROLESprovided.DESCRIPTIONis optional and auto-generated if not provided.
-
[generic-function] ADD-RESOURCE-ROLE RBAC RESOURCE ROLE
Add an existing role to an existing resource. Returns the ID of the new resource_roles row.
-
[generic-function] ADD-ROLE RBAC ROLE &KEY DESCRIPTION PERMISSIONS
Add a new
ROLE. Description is optional and auto-generated if not provided. If the role name ends with ':exclusive', the role is marked as exclusive, so theEXCLUSIVEparameter is optional.PERMISSIONSis a list of permission names to add to the role, defaulting to*DEFAULT-PERMISSIONS*. AllPERMISSIONSmust already exist. Returns the new role's ID.
-
[generic-function] ADD-ROLE-PERMISSION RBAC ROLE PERMISSION
Add an existing permission to an existing role. Returns the ID of the new role_permissions row.
-
[generic-function] ADD-ROLE-USER RBAC ROLE USER
Add an existing user to an existing role. Returns the ID of the new role_users row.
-
[generic-function] ADD-USER RBAC USER-NAME EMAIL PASSWORD &KEY ROLES
Add a new user. This creates an exclusive role, which is for this user only, and adds the user to the public and logged-in roles (given by default-user-roles). Returns the new user's ID.
-
[generic-function] ADD-USER-ROLE RBAC USER ROLE
Add an existing role to an existing user. Returns the ID of the new role_users row.
-
[function] EXCLUSIVE-ROLE-FOR USER-NAME
Returns the exclusive role for
USER-NAME.
-
[generic-function] GET-ID RBAC TABLE NAME
Returns the ID associated with
NAMEinTABLE.
-
[generic-function] GET-VALUE RBAC TABLE FIELD &REST SEARCH
Retrieves the value from
FIELDinTABLEwhereSEARCHpoints to a unique row.TABLEandFIELDare strings, andSEARCHis a series of field names and values that identify the row uniquely.TABLE,FIELD, and the field names inSEARCHmust exist in the database. If no row is found, this function returnsNIL.
-
[generic-function] ID-EXISTS-P RBAC TABLE ID
Returns
TwhenIDexists inTABLE.
-
[generic-function] INITIALIZE-DATABASE RBAC ADMIN-PASSWORD
Idempotent function that checks if the database, given by
RBAC, has been initialized. If not, then this function initializes the database, which involves creating some base permissions, roles, and users. The base permissions are 'create', 'read', 'update', and 'delete'. The base roles are 'admin', 'admin:exclusive', 'logged-in', and 'public'. All of the roles have all the base permissions, except for the 'public' and 'logged-in' roles, which have the 'read' permission only. The base users are 'guest' and 'admin'. The 'guest' user is assigned the 'public' role and the 'admin' user is assigned all of the roles and created with the passwordADMIN-PASSWORD. The 'guest' user doesn't need a password, so the bogus value 'guest-password-1' is used. The database is considered initialized the users table contains records, in which case this function does nothing.
-
[generic-function] LIST-PERMISSION-NAMES RBAC &KEY PAGE PAGE-SIZE FILTERS ORDER-BY
List of permission names (all permissions by default). Pagination is supported via the
PAGEandPAGE-SIZEparameters.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "permission_name").
-
[generic-function] LIST-PERMISSIONS RBAC &KEY PAGE PAGE-SIZE FIELDS FILTERS ORDER-BY
List information about permissions (all permissions by default). Pagination is supported via the
PAGEandPAGE-SIZEparameters.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*. TheFIELDSparameter, a list of strings, can be used to limit which fields are included in the result. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "permission_name").
-
[generic-function] LIST-RESOURCE-NAMES RBAC &KEY PAGE PAGE-SIZE FILTERS ORDER-BY
List of resource names (all resources by default). Pagination is supported via the
PAGEandPAGE-SIZEparameters.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "resource_name").
-
[generic-function] LIST-RESOURCE-ROLE-NAMES RBAC RESOURCE &KEY PAGE PAGE-SIZE FILTERS ORDER-BY
List names of roles associated with
RESOURCE. Pagination is supported via thePAGEandPAGE-SIZEparameters.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "role_name").
-
[generic-function] LIST-RESOURCE-ROLES RBAC RESOURCE &KEY PAGE PAGE-SIZE FIELDS FILTERS ORDER-BY
List information about roles associated with
RESOURCE. Pagination is supported via thePAGEandPAGE-SIZEparameters.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*. TheFIELDSparameter, a list of strings, can be used to limit which fields are included in the result. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "role_name").
-
[generic-function] LIST-RESOURCE-USER-NAMES RBAC RESOURCE PERMISSION &KEY PAGE PAGE-SIZE FILTERS ORDER-BY
List user names of resources where the user has
PERMISSIONon the resource. Pagination is supported via thePAGEandPAGE-SIZEparameters.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "u.user_name").
-
[generic-function] LIST-RESOURCE-USERS RBAC RESOURCE PERMISSION &KEY PAGE PAGE-SIZE FIELDS FILTERS ORDER-BY
List information about resource users where the user has
PERMISSIONon the resource. Pagination is supported via thePAGEandPAGE-SIZEparameters.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*. TheFIELDSparameter, a list of strings, can be used to limit which fields are included in the result. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "u.user_name").
-
[generic-function] LIST-RESOURCES RBAC &KEY PAGE PAGE-SIZE FIELDS FILTERS ORDER-BY
List information about resources (all resources by default). Pagination is supported via the
PAGEandPAGE-SIZEparameters.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*. TheFIELDSparameter, a list of strings, can be used to limit which fields are included in the result. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "resource_name").
-
[generic-function] LIST-ROLE-NAMES RBAC &KEY PAGE PAGE-SIZE FILTERS ORDER-BY
List of role names (all roles by default). Pagination is supported via the
PAGEandPAGE-SIZEparameters.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "role_name").
-
[generic-function] LIST-ROLE-PERMISSION-NAMES RBAC ROLE &KEY PAGE PAGE-SIZE FILTERS ORDER-BY
List names of permissions associated with
ROLE. Pagination is supported via thePAGEandPAGE-SIZEparameters.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "permission_name").
-
[generic-function] LIST-ROLE-PERMISSIONS RBAC ROLE &KEY PAGE PAGE-SIZE FIELDS FILTERS ORDER-BY
List information about permissions associated with
ROLE. Pagination is supported via thePAGEandPAGE-SIZEparameters.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*. TheFIELDSparameter, a list of strings, can be used to limit which fields are included in the result. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "permission_name").
-
[generic-function] LIST-ROLE-RESOURCE-NAMES RBAC ROLE &KEY PAGE PAGE-SIZE FILTERS ORDER-BY
List names of resources associated with
ROLE. Pagination is supported via thePAGEandPAGE-SIZEparameters.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "resource_name").
-
[generic-function] LIST-ROLE-RESOURCES RBAC ROLE &KEY PAGE PAGE-SIZE FIELDS FILTERS ORDER-BY
List information about resources associated with
ROLE. Pagination is supported via thePAGEandPAGE-SIZEparameters.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*. TheFIELDSparameter, a list of strings, can be used to limit which fields are included in the result. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "resource_name").
-
[generic-function] LIST-ROLE-USER-NAMES RBAC ROLE &KEY PAGE PAGE-SIZE FILTERS ORDER-BY
List names of users associated with
ROLE. Pagination is supported via thePAGEandPAGE-SIZEparameters.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "user_name").
-
[generic-function] LIST-ROLE-USERS RBAC ROLE &KEY PAGE PAGE-SIZE FIELDS FILTERS ORDER-BY
List information about users associated with
ROLE. Pagination is supported via thePAGEandPAGE-SIZEparameters.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*. TheFIELDSparameter, a list of strings, can be used to limit which fields are included in the result. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "user_name").
-
[generic-function] LIST-ROLES RBAC &KEY PAGE PAGE-SIZE FIELDS FILTERS ORDER-BY
List information about roles (all roles by default). Pagination is supported via the
PAGEandPAGE-SIZEparameters.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*. TheFIELDSparameter, a list of strings, can be used to limit which fields are included in the result. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "role_name").
-
[generic-function] LIST-USER-NAMES RBAC &KEY PAGE PAGE-SIZE FILTERS ORDER-BY
List of user names (all users by default). Pagination is supported via the
PAGEandPAGE-SIZEparameters.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "user_name").
-
[generic-function] LIST-USER-RESOURCE-NAMES RBAC USER PERMISSION &KEY PAGE PAGE-SIZE FILTERS ORDER-BY
List resource names of users where the user has
PERMISSIONon the resource. Pagination is supported via thePAGEandPAGE-SIZEparameters.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "s.resource_name").
-
[generic-function] LIST-USER-RESOURCE-NAMES-OF-TYPE RBAC USER-NAME RESOURCE-TYPE &KEY PERMISSIONS PAGE PAGE-SIZE
List the names of the resources of type
RESOURCE-TYPEthatUSER-NAMEhas access to.RESOURCE-TYPEis matched against the prefix of the resource name. Supports pagination viaPAGEandPAGE-SIZE.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*.
-
[generic-function] LIST-USER-RESOURCE-PERMISSION-NAMES RBAC USER-NAME RESOURCE-NAME &KEY PAGE PAGE-SIZE
List the names of the permissions that
USER-NAMEhas onRESOURCE-NAME. Supports pagination viaPAGEandPAGE-SIZE.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*
-
[generic-function] LIST-USER-RESOURCES RBAC USER PERMISSION &KEY PAGE PAGE-SIZE FIELDS FILTERS ORDER-BY
List information about user resources where the user has
PERMISSIONon the resource. Pagination is supported via thePAGEandPAGE-SIZEparameters.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*. TheFIELDSparameter, a list of strings, can be used to limit which fields are included in the result. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "s.resource_name").
-
[generic-function] LIST-USER-ROLE-NAMES RBAC USER &KEY PAGE PAGE-SIZE FILTERS ORDER-BY
List names of roles associated with
USER. Pagination is supported via thePAGEandPAGE-SIZEparameters.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "role_name").
-
[generic-function] LIST-USER-ROLES RBAC USER &KEY PAGE PAGE-SIZE FIELDS FILTERS ORDER-BY
List information about roles associated with
USER. Pagination is supported via thePAGEandPAGE-SIZEparameters.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*. TheFIELDSparameter, a list of strings, can be used to limit which fields are included in the result. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "role_name").
-
[generic-function] LIST-USERS RBAC &KEY PAGE PAGE-SIZE FIELDS FILTERS ORDER-BY
List information about users (all users by default). Pagination is supported via the
PAGEandPAGE-SIZEparameters.PAGEdefaults to 1 andPAGE-SIZEdefaults to*DEFAULT-PAGE-SIZE*. TheFIELDSparameter, a list of strings, can be used to limit which fields are included in the result. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "user_name").
-
[generic-function] LOGIN RBAC USER-NAME PASSWORD
If
USER-NAMEexists andPASSWORDis correct, update last_login forUSER-NAMEand return the user ID. Otherwise, returnNIL.
-
[function] PASSWORD-HASH USER-NAME PASSWORD
Returns the hash of
PASSWORD, usingUSER-NAMEas the salt. This is howRBACstores the password in the database.
-
[function] PASSWORD-HASH USER-NAME PASSWORD
Returns the hash of
PASSWORD, usingUSER-NAMEas the salt. This is howRBACstores the password in the database.
-
[generic-function] PERMISSION-COUNT RBAC &KEY FILTERS
Count the number of permissions (all permissions by default). The
FILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false.
-
[function] RBAC-QUERY SQL-TEMPLATE-AND-PARAMETERS &OPTIONAL (RESULT-TYPE :PLISTS)
Converts
SQL-TEMPLATE-AND-PARAMETERSinto a query that returns a list of rows, and executes that query.SQL-TEMPLATE-AND-PARAMETERSis a list where the first element is anSQLstring (optionally with placeholders) and the rest of the elements are values that are used to replace the placeholders in theSQLstring. This function needs to be called inside of a with-rbac block. Each row in the result is a plist, where the keys represent the field names.
-
[function] RBAC-QUERY-SINGLE SQL-TEMPLATE-AND-PARAMETERS
Converts
SQL-TEMPLATE-AND-PARAMETERSinto a query that returns a single value, and executes that query.SQL-TEMPLATE-AND-PARAMETERSis a list where the first element is anSQLstring (optionally with placeholders) and the rest of the elements are the values that are used to replace the placeholders in theSQLstring. This function needs to be called inside a with-rbac block.
-
[generic-function] REMOVE-PERMISSION RBAC PERMISSION
Remove
PERMISSIONfrom the database. Returns the ID of the removed permission.
-
[generic-function] REMOVE-RESOURCE RBAC RESOURCE
Remove
RESOURCEfrom the database. Returns the ID of the removed resource.
-
[generic-function] REMOVE-RESOURCE-ROLE RBAC RESOURCE ROLE
Remove a role from a resource. Returns the ID of the removed resource role.
-
[generic-function] REMOVE-ROLE RBAC ROLE
Remove a role from the database. Returns the ID of the removed role.
-
[generic-function] REMOVE-ROLE-PERMISSION RBAC ROLE PERMISSION
Remove a permission from a role. Returns the ID of the removed role-permission.
-
[generic-function] REMOVE-ROLE-USER RBAC ROLE USER
Remove a user from a role. Returns the ID of the removed role user.
-
[generic-function] REMOVE-USER RBAC USER-NAME
Remove
USER-NAMEfrom the database.
-
[generic-function] REMOVE-USER-ROLE RBAC USER ROLE
Remove a role from a user. Returns the ID of the removed user role.
-
[generic-function] RESOURCE-COUNT RBAC &KEY FILTERS
Count the number of resources (all resources by default). The
FILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false.
-
[generic-function] RESOURCE-ROLE-COUNT RBAC RESOURCE &KEY FILTERS
Count the number of roles associated with
RESOURCE. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be one of =, <>, <, >, <=, >=, is, is not, like, ilike. Value is a string, number, :null, :true, or :false.
-
[generic-function] RESOURCE-USER-COUNT RBAC RESOURCE PERMISSION &KEY FILTERS
Count the number of resource users where the user has
PERMISSIONon the resource. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be one of =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "u.user_name").
-
[generic-function] ROLE-COUNT RBAC &KEY FILTERS
Count the number of roles (all roles by default). The
FILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false.
-
[generic-function] ROLE-PERMISSION-COUNT RBAC ROLE &KEY FILTERS
Count the number of permissions associated with
ROLE. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be one of =, <>, <, >, <=, >=, is, is not, like, ilike. Value is a string, number, :null, :true, or :false.
-
[generic-function] ROLE-RESOURCE-COUNT RBAC ROLE &KEY FILTERS
Count the number of resources associated with
ROLE. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be one of =, <>, <, >, <=, >=, is, is not, like, ilike. Value is a string, number, :null, :true, or :false.
-
[generic-function] ROLE-USER-COUNT RBAC ROLE &KEY FILTERS
Count the number of users associated with
ROLE. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be one of =, <>, <, >, <=, >=, is, is not, like, ilike. Value is a string, number, :null, :true, or :false.
-
[generic-function] USER-ALLOWED RBAC USER-NAME PERMISSION RESOURCE
Returns
TifUSER-NAMEhasPERMISSIONonRESOURCE,NILotherwise. Note that this permission may exist via more than one role.
-
[generic-function] USER-COUNT RBAC &KEY FILTERS
Count the number of users (all users by default). The
FILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false.
-
[generic-function] USER-HAS-ROLE RBAC USER-NAME &REST ROLE
Returns
TifUSER-NAMEhas any of the specifiedROLE(s).
-
[generic-function] USER-RESOURCE-COUNT RBAC USER PERMISSION &KEY FILTERS
Count the number of user resources where the user has
PERMISSIONon the resource. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be one of =, <>, <, >, <=, >=, is, is not, like, or ilike. Value is a string, number, :null, :true, or :false. TheORDER-BYparameter is a list of strings that represent field names and are used to order the results. It defaults to (list "s.resource_name").
-
[generic-function] USER-ROLE-COUNT RBAC USER &KEY FILTERS
Count the number of roles associated with
USER. TheFILTERSparameter can be used to filter the results. It consists of a list of filters, where each filter is a list of three elements: field name, operator, and value. Operator, a string, can be one of =, <>, <, >, <=, >=, is, is not, like, ilike. Value is a string, number, :null, :true, or :false.
-
[generic-function] VALID-DESCRIPTION-P RBAC DESCRIPTION
Validates new
DESCRIPTIONstring.
-
[generic-function] VALID-EMAIL-P RBAC EMAIL
Validates new
EMAILstring. The string must look like an email address, with a proper domain name, and it must have a length that doesn't exceed 128 characters.
-
[generic-function] VALID-PASSWORD-P RBAC PASSWORD
Validates new
PASSWORDstring.PASSWORDmust have- at least password-length-min characters
- at least one letter
- at least one digit
- at least one common punctuation character
- at most password-length-max characters
-
[generic-function] VALID-PERMISSION-P RBAC PERMISSION
Validates new
PERMISSIONstring. PMERISSION must:- start with a letter
- consist of letters, digits, and hyphens
- optionally have a colon that is not at the beginning or the end
- contain at most permission-length-max characters
-
[generic-function] VALID-RESOURCE-P RBAC RESOURCE
Validates new
RESOURCEstring.
-
[generic-function] VALID-ROLE-P RBAC ROLE
Validates new
ROLEstring.ROLEmust:- start with a letter
- consist of letters, digits, and hyphens
- have at most role-length-max characters
- optionally have a colon that is not at the beginning or the end
-
[generic-function] VALID-USER-NAME-P RBAC USER-NAME
Validates new USERNANME string.
USER-NAMEmust:- Have at least 1 character
- Have at most user-name-length-max characters
- Start with a letter
- Contain only ASCII characters for
- letters (any case)
- digits
- underscores
- dashes
- periods
- plus sign (+)
Exported special variables.
-
[variable] *ADMIN* "admin"
Administrator user name.
-
[variable] *GUEST* "guest"
Guest user name.
-
[variable] *DEFAULT-PAGE-SIZE* 1000
Default page size. Used in functions that accept a :page-size parameter when the parameter is not specified.
-
[variable] *DEFAULT-PERMISSIONS* ("create" "delete" "read" "update")
Default permissions for a new role when no value is provided for the :roles parameter
-
[variable] *DEFAULT-RESOURCE-ROLES* ("admin")
A list of roles to be used when a resource is created without specifying a value for the :roles parameter.
-
[variable] *DEFAULT-USER-ROLES* ("logged-in" "public")
A list of roles to be used when a user is first created. These roles are appended to whatever the caller specifies for the :roles parameter.
Exported macros.
-
[macro] WITH-RBAC (RBAC) &BODY BODY
Opens a connection (pooled) to the rbac database to execute
BODY. There's no global connection, so this macro must be used wherever a connection is needed. The connection is closed afterBODYis executed.
This section describes tools to improve the efficiency and accuracy of the development of this software.
The tests are located in rbac-tests.lisp.
make test
This will start PostreSQL as a Docker container, initialize the database, run all the tests, then stop the database container.
make test-repl
This will start PostgreSQL as a Docker container, initialize the database, load the RBAC and RBAC-TEST packages, and wait for you to connect with a client such as Slime. This enables you modify the library's code and the tests in a REPL environment. Go Common Lisp!
The tests are in the :rbac-test package. You can run a specific test like this:
(in-package :rbac-test)
(run! 'name-of-test)The database is cleared at the beginning of each test. Therefore, any changes that the tests makes to the database are available to you after you run the test. For example, if the test adds a user, then after the test ends, you'll find the user among the results of calling (list-user-names *rbac*). The :rbac-tests package uses the :rbac package, so in these types of situation, you don't have to switch to the :rbac package to call list-user-names.
Compiling a function, auto-completion, and so forth all work in the usual way. If you want, you can switch to the :rbac package first. That way, you don't have to worry about some not-yet-exported function being available in the :rbac-test package.
(in-package :rbac)
(list-user-names *rbac*)When you quit the REPL environment, the PostgreSQL container stops.
This project contains a GitHub Action to run tests. It uses make test-ci. The repo is configured to run tests whenever code is pushed to the repo.
The exported functions are listed in the usual fashion in the package file, rbac-package.lisp, in alphabetical order.
This README is generated. The code to generate the README is in rbac-docs.lisp. The MGL-PAX library fetches the documentation strings from the variables, functions, accessors, and macros in the code, and uses them to help build the README.
You can generate the README from the command line with make docs, or by starting a REPL (see "Running a swank server" above) and then calling (generate-readme).
When adding a documentation string to a variable, function, class accessor, or macro, it's important to start the documentation string with ":public:" or ":private:", to indicate if the symbol should be exported. The generate-readme function removes these strings (and the space that follows the string) from the documentation when generating the README.
There's a lot of macro business going on in rbac-docs.lisp. If you don't see some new text you edited appearing in the README after calling generate-readme, simply evaluate the whole buffer. In Emacs, you can do that with M-x slime-eval-buffer, for example.
When you remove a function from the library, it can be easy to forget to update the documentation or the exports section of the package file. This project provides functions to help ensure that nothing is out of sync. Those functions are in the exports.lisp file. The most important function in that file is check-exports.
The check-exports function returns a plist with the following keys:
-
:missing-in-exports A list of the variables, functions, class accessors, and macros in the
:rbacpackage that have a documentation string that starts with ":public:" and that don't appear in the:exportssection of therbac-package.lispfile. -
:stale-exports A list of symbols that appear in the
:exportssection of therbac-package.lispfile that are not defined in the package, or that no longer have a documentation string that starts with ":public:". -
:missing-in-docs A list of the symbols that have a documentation string that starts with ":public:" and that do not appear in the
rbac-docs.lispfile. -
:stale-docs A list of the symbols in
rbac-docs.lispthat no longer exist or that no longer have a documentation string that starts with ":public:".
Thus, you can easily determine if something is missing from the documentation or the exports.
Runs the tests. Run from command line.
Runs the tests. Run from GitHub Actions. (See .github/workflows/ci.yaml.)
Start a Swank server so that you can connect to RBAC and to the RBAC tests with a REPL. Please note the Swank port number, which this command prints when the server is ready.
Generate the README.md file.