Project

General

Profile

Granular permission system » History » Version 1

Marek Hulán, 02/20/2014 11:45 AM

1 1 Marek Hulán
{{toc}}
2
3
h1. Granular permission system
4
5
On this page you can find description of old and new permission system in Foreman. The change was made in Foreman 1.5.
6
7
h2. Old model (<= 1.4)
8
9
Two independent layers 
10
11
* roles
12
* filters
13
14
Role are used for authorization of controller actions. We load all roles for current user and check whether he has permission to execute action. Permissions are hardcoded, you can assign permissions to roles.
15
16
Filters are defined per user. It's hardcoded what they can filter. It does not say anything about context in which they are applied, e.g. user filtered to hostgroup HG1 could mean he can edit HG1 or he can build hosts in HG1.
17
18
!1existing.png!
19
20
h2. Motivation for granular system
21
22
We want to assign roles and filters also to user groups. User can be member of multiple groups. Groups are organized in graph. It's inefficient to go through graph every time we need to check permissions.
23
24
We want to have different permissions for different subsets eg:
25
26
* user can edit hosts in hostgroup HG1
27
* user can view all hosts
28
29
h2. Changes between old and new
30
31
h3. User roles improvement
32
33
We can assign roles to usergroups. Also it should be possible to define admin flag on usergroup. We'll also take similar approach to cache user membership.
34
35
!2cached.png!
36
37
h3. Filters improvement
38
39
* We extract Permissions from Role and map them to filtered resources (Host, Hostgroup, ...)
40
* We extract Filter from User to a new entity.
41
* We allow to specify filters by scoped_search syntax.
42
* We assign filters to Role
43
44
!3filters.png!
45
46
There will be two types of filters
47
48
* *generic* that select all resources (search string will be NULL)
49
* *filtering* (search string actually filters the resulting collection)
50
51
When we want to a collection of objects on which user has particular permission we do the searching in following way. We find join User x Filter x Permission, there can occure three situations:
52
53
# if there's any generic filter among result we take Resource.all
54
# if there's none generic but still some filters were found we take all of them and join their search strings by OR, and apply it on like this ```"Resource.search_for( (F1) OR (F2) OR (F3) )"``` 
55
# if there's none generic nor other user simple does not have permission for this Resource, result is []
56
57
When we want to verify permissions for a specific object, we do the same as above and then just check whether object is in resulting collection.
58
59
This should be generic enough to apply on any Resource.
60
61
h2. Potential problems with granular system
62
63
h3. Effective link verification on page
64
65
Suppose we have a list of hosts. On every row we can have links to edit, build and destroy host. With this new system we can have different permissions for each host. Since we check every permission separately we'll have to do similar query for every action on page (edit, build and destroy in this case), in other words, it should be linear to actions on page.
66
67
*Solution*: We already have a collection of hosts displayed on page so queries will be limited by pagination and therefore should not be too complicated to compute.
68
69
h3. Taxonomies
70
71
We have Organizations and Locations that are currently stay outside of permission system. Also since we support taxonomy inheritance we end up in situations where we display objects from different taxonomies on one page. Therefore filters have to be applied only on specific objects.
72
73
*Solution*: Filter can be assigned taxonomies. If you assign at least one a filter becomes filtering (even if you don't specify a scoped search condition). Also all assigned taxonomies are automatically added to a scoped search string so e.g. if you assign Orgs with id 1 and 2 a scoped search would look like
74
75
<pre>
76
#{original_condition} and (organization = 1 or organization = 2)
77
</pre>
78
79
This way filters are applied only on correct objects. Also when we search for filters we can limit them only to taxonomies used in taxonomix default scope, so we don't apply all user's filters.
80
81
h3. Creating records
82
83
Using scoped_search limits us to existing records. It's open question how to verify whether user is authorized to create a new host with some parameters (e.g. 1GB RAM). Filter could forbid that host to be displayed to user but he'd be able to create it.
84
85
*Solution*: Nothing has been decided yet, it seems that this is out of the permission scope.
86
87
Two possible ways would be
88
89
* after_create hack, that would rollback transaction if the record was not found for particular user
90
* construct validations based on filters (can be tricky)
91
92
h3. Existing data
93
94
There would have to be some complex migration that would assign users to newly created Role. Not much time invested to investigated this yet.
95
96
*Solution*: There is migration which automatically converts all roles to new DB model. Also user filters are converted. There is no way back so users are advised to make a backup. We provide rake task to easily backup and restore DB.