Code

various updates
[roundup.git] / doc / security.txt
index 71a8cc11f46fba72b16690da381f05065ca21f2f..10dedbab868494510de25ac9f981dd1d27ac26b4 100644 (file)
@@ -2,7 +2,7 @@
 Security Mechanisms
 ===================
 
-:Version: $Revision: 1.9 $
+:Version: $Revision: 1.16 $
 
 Current situation
 =================
@@ -41,6 +41,9 @@ Issues
    than the From address. Support for strong identification through digital
    signatures should be added.
 5. The command-line tool has no logical controls.
+6. The anonymous control needs revising - there should only be one way to be
+   an anonymous user, not two (currently there is user==None and
+   user=='anonymous').
 
 
 Possible approaches
@@ -48,8 +51,8 @@ Possible approaches
 
 Security controls in Roundup could be approached in three ways:
 
-1) at the hyperdb level, with read/write/modify permissions on classes, nodes
-   and node properties for all or specific transitions.
+1) at the hyperdb level, with read/write/modify permissions on classes, items
+   and item properties for all or specific transitions.
 2) at the user interface level, with access permissions on CGI interface
    methods, mailgw methods, roundup-admin methods, and so on.
 3) at a logical permission level, checked as needed.
@@ -63,7 +66,7 @@ Hyperdb-level control
 ---------------------
 
 Control is implemented at the Class.get, Class.set and Class.create level. All
-other methods must access nodes through these methods. Since all accesses go
+other methods must access items through these methods. Since all accesses go
 through the database, we can implement deny by default.
 
 Pros:
@@ -76,7 +79,7 @@ Cons:
    - harder to determine the relationship between user interaction and hyperdb
      permission.
    - a lot of work to define
-   - must special-case to handle by-node permissions (editing user details,
+   - must special-case to handle by-item permissions (editing user details,
      having private messages)
 
 
@@ -99,7 +102,6 @@ Cons:
    - most user interfaces have multiple uses which can't be covered by a
      single permission
 
-
 Logical control
 ---------------
 
@@ -121,162 +123,6 @@ Cons:
      that implements the logical controls.
 
 
-Applying controls to users
-==========================
-
-Individual assignment of Permission to User is unwieldy. The concept of a
-Role, which encompasses several Permissions and may be assigned to many Users,
-is quite well developed in many projects. Roundup will take this path, and
-allow the multiple assignment of Roles to Users, and multiple Permissions to
-Roles. These definitions will be stored in the hyperdb. They don't need to be
-pushed to the actual database though.
-
-There will be two levels of Permission. The Class level permissions define
-logical permissions associated with all nodes of a particular class (or all
-classes). The Node level permissions define logical permissions associated
-with specific nodes by way of their user-linked properties.
-
-A permission module defines::
-
-    class InMemoryImmutableClass(hyperdb.Class):
-        ''' Don't allow changes to this class's nodes.
-        '''
-        def __init__(self, db, classname, **properties):
-            ''' Set up an in-memory store for the nodes of this class
-            '''
-
-        def create(self, **propvalues):
-            ''' Create a new node in the in-memory store
-            '''
-
-        def get(self, nodeid, propname, default=_marker, cache=1):
-            ''' Get the node from the in-memory store
-            '''
-
-        def set(self, *args):
-            raise ValueError, "%s are immutable"%self.__class__.__name__
-
-    class PermissionClass(InMemoryImmutableClass):
-        ''' Include the default attributes:
-            - name (String)
-            - classname (String)
-            - description (String)
-
-            The classname may be unset, indicating that this permission is not
-            locked to a particular class. That means there may be multiple
-            Permissions for the same name for different classes.
-        '''
-
-    class RoleClass(InMemoryImmutableClass):
-        ''' Include the default attributes:
-            - name (String, key)
-            - description (String)
-            - permissions (PermissionClass Multilink)
-        '''
-
-    def hasClassPermission(db, classname, permission, userid):
-        ''' Look through all the Roles, and hence Permissions, and see if
-            "permission" is there for the specified classname.
-
-        '''
-
-    def hasNodePermission(db, classname, nodeid, userid, properties):
-        ''' Check the named properties of the given node to see if the userid
-            appears in them. If it does, then the user is granted this
-            permission check.
-
-            'propspec' consists of a list of property names. The property
-            names must be the name of a property of classname, or a
-            KeyError is raised.  That property must be a Link or Multilink
-            property, or a TypeError is raised.
-
-            If the property is a Link, the userid must match the property
-            value. If the property is a Multilink, the userid must appear
-            in the Multilink list.
-        '''
-
-The instance dbinit module then has in ``open()``::
-
-    perm = permission.PermissionClass(db, "permission")
-    role = permission.RoleClass(db, "role")
-
-    # create some Permissions
-    wa = perm.create(name="Web Access",
-                    description="User may use the web interface")
-    wr = perm.create(name="Web Registration",
-                    description="User may register through the web")
-
-    ma = perm.create(name="Mail Access",
-                    description="User may use the email interface")
-    mr = perm.create(name="Mail Registration",
-                    description="User may register through email")
-
-    ee = perm.create(name="Edit",
-                    description="User may edit everthing")
-    ei = perm.create(name="Edit", classname="issue",
-                    description="User is allowed to edit issues")
-
-    ae = perm.create(name="Assign",
-                    description="User may be assigned to anything")
-    ai = perm.create(name="Assign", classname="issue",
-                    description="User may be assigned to issues")
-
-    # create some Roles that use the Permissions
-    role.create(name="User", description="A regular user, no privs",
-                permissions=[wa, wr, ma, mr, ei, ai])
-    role.create(name="Admin", description="An admin user, full privs",
-                permissions=[ee, ae])
-    role.create(name="No Rego", description="A user who can't register",
-                permissions=[wa, ma])
-
-in ``init()``::
-
-    r = db.getclass('role').lookup('Admin')
-    user.create(username="admin", password=Password(adminpw),
-                address=instance_config.ADMIN_EMAIL, roles=[r])
-
-    # choose your anonymous user access permission here
-    #r = db.getclass('role').lookup('No Rego')
-    r = db.getclass('role').lookup('User')
-    user.create(username="anonymous", roles=[r])
-
-Then in the code that matters, calls to ``hasPermission`` are made to
-determine if the user has permission to perform some action::
-
-    if security.hasClassPermission('issue', 'Edit', self.user):
-        # all ok
-
-    if security.hasNodePermission('issue', nodeid, self.user, ['assignedto']):
-        # all ok
-
-The htmltemplate will implement a new tag, <permission> which has the form::
-
-  <permission require=name,name,name node=assignedto>
-   HTML to display if the user has the permission.
-  <else>
-   HTML to display if the user does not have the permission.
-  </permission>
-
-where the require attribute gives a comma-separated list of permission names
-which are required, and the node attribute gives a comma-separated list of
-node properties whose value must match the current user's id. Either of these
-tests must pass or the permission check will fail. The section of html within
-the side of the ``<else>`` that fails is remove from processing.
-
-
-Authentication of Users
------------------------
-
-Users must be authenticated correctly for the above controls to work. This is
-not done in the current mail gateway at all. Use of digital signing of
-messages could alleviate this problem.
-
-The exact mechanism of registering the digital signature should be flexible,
-with perhaps a level of trust. Users who supply their signature through their
-first message into the tracker should be at a lower level of trust to those
-who supply their signature to an admin for submission to their user details.
-
-
 Action
 ======
 
@@ -293,6 +139,7 @@ The CGI interface must be changed to:
   - implement htmltemplate tests on permissions
   - switch all code over from using config vars for permission checks to using
     permissions
+  - change all explicit admin user checks for Role checks
   - include config vars for initial Roles for anonymous web, new web and new
     email users
 
@@ -310,19 +157,3 @@ The command-line tool must be changed to:
   access by admin users, and read-only by everyone else)
 
 
-Use cases
-=========
-
-public
-  end users that can submit bugs, request new features, request support
-developer
-  developers that can fix bugs, implement new features provide support
-manager
-  approvers/managers that can approve new features and signoff bug fixes
-admin
-  administrators that can add users and set user's roles
-system
-  automated request handlers running various report/escalation scripts
-privacy
-  issues that are only visible to some users
-