Skip to content

Commit 2bd7464

Browse files
author
Richard Jones
committed
Latest thoughts.
1 parent 91344e2 commit 2bd7464

File tree

1 file changed

+89
-48
lines changed

1 file changed

+89
-48
lines changed

doc/security.txt

Lines changed: 89 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Security Mechanisms
33
===================
44

5-
:Version: $Revision: 1.1 $
5+
:Version: $Revision: 1.2 $
66

77
Current situation
88
=================
@@ -67,6 +67,9 @@ Cons:
6767
- harder to determine the relationship between user interaction and hyperdb
6868
permission.
6969
- a lot of work to define
70+
- must special-case to handle by-node permissions (editing user details,
71+
having private messages)
72+
7073

7174
User-interface control
7275
----------------------
@@ -92,9 +95,17 @@ Logical control
9295
---------------
9396

9497
At each point that requires an action to be performed, the security mechanisms
95-
are asked if the current user has permission. There is no possibility to have
98+
are asked if the current user has permission. Since code must call the
99+
check function to raise a denial, there is no possibility to have automatic
96100
default of deny in this situation.
97101

102+
In practice, this is implemented as:
103+
104+
1. there's a mapping of user -> role (in hyperdb)
105+
2. there's a mapping of role -> permission (in code)
106+
3. there's a function that's available to all roundup code that can ask
107+
whether a particular user has a particular permission.
108+
98109
Pros:
99110

100111
- quite obvious what is going on
@@ -106,7 +117,6 @@ Cons:
106117
mirroring actual user interface controls.
107118

108119

109-
110120
Applying controls to users
111121
==========================
112122

@@ -117,6 +127,82 @@ allow the multiple assignment of Roles to Users, and multiple Permissions to
117127
Roles. These definitions will be stored in the hyperdb.
118128

119129

130+
A permission module defines::
131+
132+
class InMemoryImmutableClass(hyperdb.Class):
133+
''' Don't allow changes to this class's nodes.
134+
'''
135+
def __init__(self, db, classname, **properties):
136+
''' Set up an in-memory store for the nodes of this class
137+
'''
138+
139+
def create(self, **propvalues):
140+
''' Create a new node in the in-memory store
141+
'''
142+
143+
def get(self, nodeid, propname, default=_marker, cache=1):
144+
''' Get the node from the in-memory store
145+
'''
146+
147+
def set(self, *args):
148+
raise ValueError, "%s are immutable"%self.__class__.__name__
149+
150+
class PermissionClass(InMemoryImmutableClass):
151+
''' Include the default attributes:
152+
- name (String, key)
153+
- description (String)
154+
'''
155+
156+
class RoleClass(InMemoryImmutableClass):
157+
''' Include the default attributes:
158+
- name (String, key)
159+
- description (String)
160+
- permissions (PermissionClass Multilink)
161+
'''
162+
163+
def hasPermission(db, userid, permission):
164+
''' Look through all the Roles, and hence Permissions, and see if
165+
"permission" is there
166+
'''
167+
168+
169+
The instance dbinit module then has::
170+
171+
in open():
172+
173+
perm = permission.PermissionClass(db, "permission")
174+
role = permission.RoleClass(db, "role")
175+
176+
wa = perm.create(name="Web Access",
177+
description="User may log in through the web")
178+
wr = perm.create(name="Web Registration",
179+
description="User may register through the web")
180+
ma = perm.create(name="Mail Access",
181+
description="User may log in through email")
182+
mr = perm.create(name="Mail Registration",
183+
description="User may register through email")
184+
aa = perm.create(name="Access Everything",
185+
description="User may access everthing")
186+
role.create(name="User", description="A regular user, no privs",
187+
permissions=[wa, wr, ma, mr])
188+
role.create(name="Admin", description="An admin user, full privs",
189+
permissions=[aa])
190+
ro = role.create(name="No Rego", description="A user who can't register",
191+
permissions=[wa, ma])
192+
193+
in init():
194+
195+
r = db.getclass('role').find('Admin')
196+
user.create(username="admin", password=Password(adminpw),
197+
address=instance_config.ADMIN_EMAIL, roles=[r])
198+
199+
# choose your anonymous user access permission here
200+
#r = db.getclass('role').find('No Rego')
201+
r = db.getclass('role').find('User')
202+
user.create(username="anonymous", roles=[r])
203+
204+
205+
120206
Use cases
121207
=========
122208

@@ -133,48 +219,3 @@ system
133219
privacy
134220
issues that are only visible to some users
135221

136-
137-
Discussion
138-
==========
139-
140-
Date: Thu, 2 May 2002 11:46:56 -0400
141-
142-
143-
I've really appreciated roundup so far. It has been very easy to create my own
144-
template that adds functionality for my specific purpose. One area, for my
145-
needs, that does not seem to be currently addressed in roundup is roles of
146-
users. I have various roles that the users of my instance of roundup can have.
147-
I have:
148-
149-
1) end users that can submit bugs, request new features, request support.
150-
2) developers that can fix bugs, implement new features provide support
151-
3) approvers/managers that can approve new features and signoff bug fixes
152-
4) administrators that can add users and set users roles
153-
5) processors - this is isn't totally thought out yet, but for me it would be an
154-
automated request handler that would run various production scripts.
155-
156-
Each of these roles need to have specific functionality within the web client
157-
(and possibly the email client -- but I haven't looked at that much yet). An
158-
example is that I don't want end users to be able to assign a specific developer
159-
to a problem or support issue. I think that some of my functionality can be
160-
implemented via the detectors, but I haven't fully researched it yet.
161-
162-
So far, I have added a new class to the database called role which contains the
163-
various roles outlined above. I have added a multilink in the user class to the
164-
new role class. I have modified the base code in the cgi client to use the new
165-
admin role when checking for admin instead of using the user id. I am working
166-
on implementing the role for access to the individual forms and even specific
167-
fields on the forms. Has anyone else done this or seen a need to do this?
168-
169-
I am planning on implementing this as an optional feature - basically the
170-
security will be handled in a separate module so that a site could implement the
171-
role functionality or exclude it by using the module that fits their needs. My
172-
current changes to the admin checks would be pulled out into a separate
173-
replaceable module. So if an implementation did not want to use roles, the
174-
check would just check the user id to see if it was equal to "admin". In my
175-
case, it would check the role of the user to see if it contained the admin role.
176-
177-
If anyone else is interested in this, I will send the patches in when I am
178-
completed with this. If anyone else has worked on this (and hopefully gotten
179-
farther than I), please let me know.
180-

0 commit comments

Comments
 (0)