summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 93afd3b)
raw | patch | inline | side by side (parent: 93afd3b)
author | richard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Mon, 29 Jul 2002 00:56:06 +0000 (00:56 +0000) | ||
committer | richard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Mon, 29 Jul 2002 00:56:06 +0000 (00:56 +0000) |
much simpler and self-contained now.
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@924 57a73879-2fb5-44c3-a270-3262357dd7e2
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@924 57a73879-2fb5-44c3-a270-3262357dd7e2
COPYING.txt | patch | blob | history | |
TODO.txt | patch | blob | history | |
roundup/security.py | patch | blob | history | |
test/test_init.py | patch | blob | history | |
test/test_mailgw.py | patch | blob | history |
diff --git a/COPYING.txt b/COPYING.txt
index db92559a13e33ddb961d4aed5e05707edf3f8a35..f518e8a1753d1a7a7f6ce1bc41311b82e9db8df6 100644 (file)
--- a/COPYING.txt
+++ b/COPYING.txt
-
Copyright (c) 2002 eKit.com Inc (http://www.ekit.com/)
Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/TODO.txt b/TODO.txt
index 102cd2efe825b2fa6f177fc549ca4c47c85f5b84..2a0c3069438132a56a90daa000bef97268979882 100644 (file)
--- a/TODO.txt
+++ b/TODO.txt
[value, value, ...] implies "in"
pending hyperdb: make creator, creation and activity available pre-commit
pending hyperdb: migrate "id" property to be Number type
+active hyperdb: modify design document to include all the changes made
pending instance: including much simpler upgrade path and the use of
non-Python configuration files (ConfigParser)
pending instance: cleanup to support config (feature request #498658)
roundup: "|roundup-mailgw /instances/dev"
vmbugs: "|roundup-mailgw /instances/dev component=voicemail"
pending project: switch to a Roundup instance for Roundup bug/feature tracking
-active security: finish doc/security.txt
-active security: implement and use the new logical control mechanisms
+active security: add info from doc/security.txt to design doc
pending security: at least an LDAP user database implementation
pending security: authenticate over a secure connection
pending security: use digital signatures in mailgw
done hyperdb: add Boolean and Number types (GM)
done mailgw: better help message (feature request #558562) (RJ)
done security: switch to sessions for web authentication (RJ)
+done security: implement and use the new logical control mechanisms
done web: saving of named queries (GM)
diff --git a/roundup/security.py b/roundup/security.py
index 49e447795014c40af6a5b2c521dca2fa5acfd127..0d50318d524cc635e20ae5abab68f8aad54a2b48 100644 (file)
--- a/roundup/security.py
+++ b/roundup/security.py
import weakref
-from roundup import hyperdb, volatiledb
+from roundup import hyperdb
-class PermissionClass(volatiledb.VolatileClass):
- ''' Include the default attributes:
- - name (String)
- - classname (String)
- - description (String)
+class Permission:
+ ''' Defines a Permission with the attributes
+ - name
+ - description
+ - klass (optional)
- The classname may be unset, indicating that this permission is not
+ The klass 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.
'''
- def __init__(self, db, classname, **properties):
- """ set up the default properties
- """
- if not properties.has_key('name'):
- properties['name'] = hyperdb.String()
- if not properties.has_key('klass'):
- properties['klass'] = hyperdb.String()
- if not properties.has_key('description'):
- properties['description'] = hyperdb.String()
- volatiledb.VolatileClass.__init__(self, db, classname, **properties)
-
-class RoleClass(volatiledb.VolatileClass):
- ''' Include the default attributes:
- - name (String, key)
- - description (String)
- - permissions (PermissionClass Multilink)
+ def __init__(self, name='', description='', klass=None):
+ self.name = name
+ self.description = description
+ self.klass = klass
+
+ def __repr__(self):
+ return '<Permission 0x%x %r,%r>'%(id(self), self.name, self.klass)
+
+class Role:
+ ''' Defines a Role with the attributes
+ - name
+ - description
+ - permissions
'''
- def __init__(self, db, classname, **properties):
- """ set up the default properties
- """
- if not properties.has_key('name'):
- properties['name'] = hyperdb.String()
- if not properties.has_key('description'):
- properties['description'] = hyperdb.String()
- if not properties.has_key('permissions'):
- properties['permissions'] = hyperdb.Multilink('permission')
- volatiledb.VolatileClass.__init__(self, db, classname, **properties)
- self.setkey('name')
+ def __init__(self, name='', description='', permissions=None):
+ self.name = name
+ self.description = description
+ if permissions is None:
+ permissions = []
+ self.permissions = permissions
+
+ def __repr__(self):
+ return '<Role 0x%x %r,%r>'%(id(self), self.name, self.permissions)
class Security:
def __init__(self, db):
''' Initialise the permission and role classes, and add in the
base roles (for admin user).
'''
- # use a weak ref to avoid circularity
- self.db = weakref.proxy(db)
+ self.db = weakref.proxy(db) # use a weak ref to avoid circularity
- # create the permission class instance (we only need one))
- self.permission = PermissionClass(db, "permission")
+ # permssions are mapped by name to a list of Permissions by class
+ self.permission = {}
- # create the role class instance (we only need one)
- self.role = RoleClass(db, "role")
+ # roles are mapped by name to the Role
+ self.role = {}
# the default Roles
self.addRole(name="User", description="A regular user, no privs")
Raise ValueError if there is no exact match.
'''
- perm = self.db.permission
- for permissionid in perm.stringFind(name=permission):
- klass = perm.get(permissionid, 'klass')
- if classname is not None and classname == klass:
- return permissionid
- elif not classname and not klass:
- return permissionid
- if not classname:
+ if not self.permission.has_key(permission):
raise ValueError, 'No permission "%s" defined'%permission
+ for perm in self.permission[permission]:
+ if perm.klass is not None and perm.klass == classname:
+ return perm
+ elif not perm.klass and not classname:
+ return perm
raise ValueError, 'No permission "%s" defined for "%s"'%(permission,
classname)
def hasPermission(self, permission, userid, classname=None):
''' Look through all the Roles, and hence Permissions, and see if
"permission" is there for the specified classname.
-
'''
roles = self.db.user.get(userid, 'roles')
if roles is None:
for rolename in roles.split(','):
if not rolename:
continue
- roleid = self.db.role.lookup(rolename)
- for permissionid in self.db.role.get(roleid, 'permissions'):
- if self.db.permission.get(permissionid, 'name') != permission:
- continue
- klass = self.db.permission.get(permissionid, 'klass')
- if klass is None or klass == classname:
+ for perm in self.role[rolename].permissions:
+ if perm.klass is None or perm.klass == classname:
return 1
return 0
''' Create a new Permission with the properties defined in
'propspec'
'''
- return self.db.permission.create(**propspec)
+ perm = Permission(**propspec)
+ self.permission.setdefault(perm.name, []).append(perm)
+ return perm
def addRole(self, **propspec):
''' Create a new Role with the properties defined in 'propspec'
'''
- return self.db.role.create(**propspec)
+ role = Role(**propspec)
+ self.role[role.name] = role
+ return role
- def addPermissionToRole(self, rolename, permissionid):
+ def addPermissionToRole(self, rolename, permission):
''' Add the permission to the role's permission list.
- 'rolename' is the name of the role to add 'permissionid'.
+ 'rolename' is the name of the role to add the permission to.
'''
- roleid = self.db.role.lookup(rolename)
- permissions = self.db.role.get(roleid, 'permissions')
- permissions.append(permissionid)
- self.db.role.set(roleid, permissions=permissions)
+ role = self.role[rolename]
+ role.permissions.append(permission)
diff --git a/test/test_init.py b/test/test_init.py
index 11e0aeb58413588bb5b75524ce1a316c3af494a0..2d454cd213e646ef72df3a8eb7f1b3f74918f5b6 100644 (file)
--- a/test/test_init.py
+++ b/test/test_init.py
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: test_init.py,v 1.14 2002-07-26 08:27:00 richard Exp $
+# $Id: test_init.py,v 1.15 2002-07-29 00:56:06 richard Exp $
import unittest, os, shutil, errno, imp, sys
l = db.keyword.list()
ae(l, [])
l = db.user.list()
- ae(l, ['1'])
+ ae(l, ['1', '2'])
l = db.msg.list()
ae(l, [])
l = db.file.list()
#
# $Log: not supported by cvs2svn $
+# Revision 1.14 2002/07/26 08:27:00 richard
+# Very close now. The cgi and mailgw now use the new security API. The two
+# templates have been migrated to that setup. Lots of unit tests. Still some
+# issue in the web form for editing Roles assigned to users.
+#
# Revision 1.13 2002/07/14 02:05:54 richard
# . all storage-specific code (ie. backend) is now implemented by the backends
#
diff --git a/test/test_mailgw.py b/test/test_mailgw.py
index 524f85034749a41cffd2a4e5b94658eb387d72a3..6d531977479a332e96b65d867b3148df37480f8d 100644 (file)
--- a/test/test_mailgw.py
+++ b/test/test_mailgw.py
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
-# $Id: test_mailgw.py,v 1.24 2002-07-26 08:27:00 richard Exp $
+# $Id: test_mailgw.py,v 1.25 2002-07-29 00:56:06 richard Exp $
import unittest, cStringIO, tempfile, os, shutil, errno, imp, sys, difflib
def testNewUserAuthor(self):
# first without the permission
- Anonid = self.db.role.lookup('Anonymous')
- self.db.role.set(Anonid, permissions=[])
+ # heh... just ignore the API for a second ;)
+ self.db.security.role['Anonymous'].permissions=[]
anonid = self.db.user.lookup('anonymous')
self.db.user.set(anonid, roles='Anonymous')
# now with the permission
p = self.db.security.getPermission('Email Registration')
- self.db.role.set(Anonid, permissions=[p])
+ self.db.security.role['Anonymous'].permissions=[p]
handler = self.instance.MailGW(self.instance, self.db)
handler.trapExceptions = 0
message = cStringIO.StringIO(s)
#
# $Log: not supported by cvs2svn $
+# Revision 1.24 2002/07/26 08:27:00 richard
+# Very close now. The cgi and mailgw now use the new security API. The two
+# templates have been migrated to that setup. Lots of unit tests. Still some
+# issue in the web form for editing Roles assigned to users.
+#
# Revision 1.23 2002/07/14 02:02:43 richard
# Fixed the unit tests for the new multilist controls in the mailgw
#