A LibLime customer requires Koha be able to limit staff user access to specific functions available on the Tools page. At present, the permissions model can only specify that a staff user can access all Tools functions, or none of them.
To meet the requirement, the existing permissions model will be extended so that each top-level permission can have subordinate permissions for specific functions. For example, the tools permission will have a set of child permissions, one for each specific tool.
Currently, a Koha staff user can have one or more “userflags” set that grant permission to a more or less broad area of Koha functionality. The 17 flags defined at present are:
bit | flag | flagdesc | defaulton |
---|---|---|---|
0 | superlibrarian | Access to all librarian functions | 0 |
1 | circulate | Circulate books | 0 |
2 | catalogue | View Catalogue (Librarian Interface) | 0 |
3 | parameters | Set Koha system paramters | 0 |
4 | borrowers | Add or modify borrowers | 0 |
5 | permissions | Set user permissions | 0 |
6 | reserveforothers | Reserve books for patrons | 0 |
7 | borrow | Borrow books | 1 |
9 | editcatalogue | Edit Catalogue (Modify bibliographic/holdings data) | 0 |
10 | updatecharges | Update borrower charges | 0 |
11 | acquisition | Acquisition and/or suggestion management | 0 |
12 | management | Set library management parameters | 0 |
13 | tools | Use tools (export, import, barcodes) | 0 |
14 | editauthorities | allow to edit authorities | 0 |
15 | serials | allow to manage serials subscriptions | 0 |
16 | reports | allow to access to the reports module | 0 |
17 | staffaccess | Modify login / permissions for staff users | 0 |
Although some of the flags (e.g., borrowers, reserveforothers, updatecharges) could be considered subordinate functions of a broader category (e.g., circulate), the existing flags can serve as the top level of a two-level function/sub-function hierarchy.
The existing user flags are referred to in the user interface as “permissions” or “privileges”. In the user interface and documentation, the second-level permissions should also be referred to as “permissions” except when it is necessary to distinguish between a top-level permission and a second-level, specific permission, in which case “subpermission” could be used.
Because of the due date for the development, granular permissions will be implemented in Koha 3.0. However, in order to not force libraries who are using Koha 3 alpha or beta to have to revise their permissions, the subpermissions will be checked only if a new Boolean system preference “GranularPermissions” is ON. “GranularPermissions” will have a default value of OFF for 3.0; I recommend that the default value change to ON for 3.2.
Two tables will be added to the schema. The interpretation of one column in an existing table will change.
The permissions table will store a list of all possible second-level permissions defined for Koha.
CREATE TABLE `permissions` ( `module_bit` int(11) NOT NULL DEFAULT 0, `code` varchar(30) DEFAULT NULL, `description` varchar(255) DEFAULT NULL, PRIMARY KEY (`module_bit`, `code`), CONSTRAINT `permissions_ibfk_1` FOREIGN KEY (`module_bit`) REFERENCES `userflags` (`bit`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
The initial content of the permissions table will be
module_bit | code | description |
---|---|---|
13 | edit_news | Write news for the OPAC and staff interfaces |
13 | label_creator | Create printable labels and barcodes from catalog and patron data |
13 | edit_calendar | Define days when the library is closed |
13 | moderate_comments | Moderate patron comments |
13 | edit_notices | Define notices |
13 | edit_notice_status_triggers | Set notice/status triggers for overdue items |
13 | view_system_logs | Browse the system logs |
13 | inventory | Perform inventory (stocktaking) of your catalogue |
13 | stage_marc_import | Stage MARC records into the reservoir |
13 | manage_staged_marc | Managed staged MARC records, including completing and reversing imports |
13 | export_catalog | Export bibliographic and holdings data |
13 | import_patrons | Import patron data |
13 | delete_anonymize_patrons | Delete old borrowers and anonymize circulation history (deletes borrower reading history) |
13 | batch_upload_patron_images | Upload patron images in batch or one at a time |
13 | schedule_tasks | Schedule tasks to run |
The code value 'all' stands for all functions corresponding to the particular module represented by module_bit.
The user permissions table will store the set of specific permissions that each staff user has:
CREATE TABLE `user_permissions` ( `borrowernumber` int(11) NOT NULL DEFAULT 0, `module_bit` int(11) NOT NULL DEFAULT 0, `code` varchar(30) DEFAULT NULL, CONSTRAINT `user_permissions_ibfk_1` FOREIGN KEY (`borrowernumber`) REFERENCES `borrowers` (`borrowernumber`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `user_permissions_ibfk_2` FOREIGN KEY (`module_bit`, `code`) REFERENCES `permissions` (`module_bit`, `code`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
When “GranularPermissions” is ON, if the flag bit for a particular module is on in borrowers.flags, the staff user will have access to *all* functions of the module.
get_user_and_template takes a hashref as its argument, one of whose keys is flaqsrequired. flaqsrequired is in turn a hashref, whose keys are one or more codes from userflags.flag. Currently, get_user_and_template only considers whether a particular userflag key is present or not, and does not check the value associated with the key. Client code currently calls get_user_and_template like this:
my ($template, $loggedinuser, $cookie) = get_template_and_user({template_name => "tools/stage-marc-import.tmpl", query => $input, type => "intranet", authnotrequired => 0, flagsrequired => {tools => 1}, debug => 1, });
The API will be changed so that when “GranularPermissions” is ON, the flag value is considered. 1 will continue to be a valid value, and will signify that the user must have permission for all functions of the module in question. If the flag value is not 1, it must be either be a string containing a valid permission code for that module, e.g.,
my ($template, $loggedinuser, $cookie) = get_template_and_user({template_name => "tools/stage-marc-import.tmpl", query => $input, type => "intranet", authnotrequired => 0, flagsrequired => {tools => 'stage_marc_import'}, debug => 1, });
or the string '*', which means that the staff user must have access to at least one subfunction. Using '*' as the required permission would be useful for a modular home page, which the user should have access to as long as they can access at least one of the functions linked to from that page.
get_user_and_template() also adds a set of variables to the HTML template object of the form 'CAN_user_XXX', where 'XXX' is a flag from userflags.flag. This will be extended so that for each specific permission in the permissions table, a variable will be set (based on the staff user's privileges) called 'CAN_user_XXX_YYY', where 'XXX' is the module from userflags.flag and 'YYY' is the code from permissions.code. If a staff user has all permissions for a given module, all of the 'CAN_user' variables will be added to the template; otherwise, only the ones corresponding to privileges that the user specifically has will be set.
The third parameter of checkauth is a hashref that currently functions the same way as the value of the flagsrequired parameter of get_user_and_template(), and will be changed in the same way.
The second parameter of check_api_auth is a hashref that currently functions the same way as the value of the flagsrequired parameter of get_user_and_template(), and will be changed in the same way.
The second parameter of check_cookie_auth is a hashref that currently functions the same way as the value of the flagsrequired parameter of get_user_and_template(), and will be changed in the same way.
When “GranularPermissions” is OFF, the current UI (members/member-flags.pl) for setting staff user permissions will be used.
When “GranularPermissions” is ON, the UI for setting staff user permissions will be changed as follows:
Granular permissions are being extended to various parts of Koha module by module. It will be important to follow a common naming convention to keep intended function clear.
In general, Granular Permission for a module should cover at least 4 (and possibly 5) parts:
These can be remembered by the convenient mnemonic VADER. Additional “grains” can be added for specific functions, like in Tools.
The controlling top-level permission for cataloging will be “editcatalogue” (the old-style “viewcatalogue” may eventually be folded in). We will add VADE for several kinds of records:
Resulting in 16 subpermissions. The flagsrequired hashref would look like:
These don't follow the view/add/delete/edit structure. The flagsrequired hashref would look like:
To do…