Code

Added the web access and email access permissions, so people can restrict
authorrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Thu, 1 Aug 2002 00:56:22 +0000 (00:56 +0000)
committerrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Thu, 1 Aug 2002 00:56:22 +0000 (00:56 +0000)
access to users who register through the email interface (for example).
Also added "security" command to the roundup-admin interface to display the
Role/Permission config for an instance.

git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@944 57a73879-2fb5-44c3-a270-3262357dd7e2

roundup/admin.py
roundup/cgi_client.py
roundup/mailgw.py
roundup/templates/classic/dbinit.py
roundup/templates/extended/dbinit.py

index 305da4e355e1e5f49fffc5715299356b207fd29e..a949e05fbd4bf3d32eae6d805631c40069b825d9 100644 (file)
@@ -16,7 +16,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: admin.py,v 1.19 2002-07-25 07:14:05 richard Exp $
+# $Id: admin.py,v 1.20 2002-08-01 00:56:22 richard Exp $
 
 import sys, os, getpass, getopt, re, UserDict, shlex, shutil
 try:
@@ -249,7 +249,6 @@ Command help:
         backends = roundup.backends.__all__
         print _('Back ends:'), ', '.join(backends)
 
-
     def do_install(self, instance_home, args):
         '''Usage: install [template [backend [admin password]]]
         Install a new Roundup instance.
@@ -981,6 +980,30 @@ Date format is "YYYY-MM-DD" eg:
         self.db.reindex()
         return 0
 
+    def do_security(self, args):
+        '''Usage: security [Role name]
+        Display the Permissions available to one or all Roles.
+        '''
+        if len(args) == 1:
+            role = args[0]
+            try:
+                roles = [(args[0], self.db.security.role[args[0]])]
+            except KeyError:
+                print _('No such Role "%(role)s"')%locals()
+                return 1
+        else:
+            roles = self.db.security.role.items()
+        roles.sort()
+        for rolename, role in roles:
+            print _('Role "%(name)s":')%role.__dict__
+            for permission in role.permissions:
+                if permission.klass:
+                    print _(' %(description)s (%(name)s for "%(klass)s" '
+                        'only)')%permission.__dict__
+                else:
+                    print _(' %(description)s (%(name)s)')%permission.__dict__
+        return 0
+
     def run_command(self, args):
         '''Run a single command
         '''
@@ -1131,6 +1154,14 @@ if __name__ == '__main__':
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.19  2002/07/25 07:14:05  richard
+# Bugger it. Here's the current shape of the new security implementation.
+# Still to do:
+#  . call the security funcs from cgi and mailgw
+#  . change shipped templates to include correct initialisation and remove
+#    the old config vars
+# ... that seems like a lot. The bulk of the work has been done though. Honest :)
+#
 # Revision 1.18  2002/07/18 11:17:30  gmcm
 # Add Number and Boolean types to hyperdb.
 # Add conversion cases to web, mail & admin interfaces.
index 632b1d4f955e3c678a371056afa1fcd77e32f6c0..94aa96212799cbfa367c54c7c321b57048dfd1ee 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: cgi_client.py,v 1.154 2002-07-31 23:57:36 richard Exp $
+# $Id: cgi_client.py,v 1.155 2002-08-01 00:56:22 richard Exp $
 
 __doc__ = """
 WWW request handler (also used in the stand-alone server).
@@ -41,6 +41,8 @@ def initialiseSecurity(security):
     '''
     security.addPermission(name="Web Registration",
         description="User may register through the web")
+    security.addPermission(name="Web Access",
+        description="User may access the web interface")
 
     # doing Role stuff through the web - make sure Admin can
     p = security.addPermission(name="Web Roles",
@@ -1407,8 +1409,9 @@ function help_window(helpurl, width, height) {
     def opendb(self, user):
         ''' Open the database - but include the definition of the sessions db.
         '''
-        # open the db
-        self.db = self.instance.open(user)
+        # open the db if the user has changed
+        if not hasattr(self, 'db') or user != self.db.journaltag:
+            self.db = self.instance.open(user)
 
     def main(self):
         ''' Wrap the request and handle unauthorised requests
@@ -1489,29 +1492,39 @@ function help_window(helpurl, width, height) {
                 return
             # figure the resulting page
             action = self.form['__destination_url'].value
-            if not action:
-                action = 'index'
-            self.do_action(action)
-            return
 
         # allow anonymous people to register
-        if action == 'newuser_action':
+        elif action == 'newuser_action':
             # try to add the user
             if not self.newuser_action():
                 return
             # figure the resulting page
             action = self.form['__destination_url'].value
-            if not action:
-                action = 'index'
+
+        # ok, now we have figured out who the user is, make sure the user
+        # has permission to use this interface
+        userid = self.db.user.lookup(self.user)
+        if not self.db.security.hasPermission('Web Access', userid):
+            raise Unauthorised, \
+                _("You do not have permission to access this interface.")
 
         # re-open the database for real, using the user
         self.opendb(self.user)
 
-        # just a regular action
-        self.do_action(action)
+        # make sure we have a sane action
+        if not action:
+            action = 'index'
 
-        # commit all changes to the database
-        self.db.commit()
+        # just a regular action
+        try:
+            self.do_action(action)
+        except Unauthorised, message:
+            # if unauth is raised here, then a page header will have 
+            # been displayed
+            self.write('<p class="system-msg">%s</p>'%message)
+        else:
+            # commit all changes to the database
+            self.db.commit()
 
     def do_action(self, action, dre=re.compile(r'([^\d]+)(\d+)'),
             nre=re.compile(r'new(\w+)'), sre=re.compile(r'search(\w+)')):
@@ -1690,6 +1703,9 @@ def parsePropsFromForm(db, cl, form, nodeid=0, num_re=re.compile('^\d+$')):
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.154  2002/07/31 23:57:36  richard
+#  . web forms may now unset Link values (like assignedto)
+#
 # Revision 1.153  2002/07/31 22:40:50  gmcm
 # Fixes to the search form and saving queries.
 # Fixes to  sorting in back_metakit.py.
index a1c21ac82da78bfa4ec7dc39131ee57f315baea9..ff2346bfd5b7602271854a572e3bfdcba693a4d9 100644 (file)
@@ -73,7 +73,7 @@ are calling the create() method to create a new node). If an auditor raises
 an exception, the original message is bounced back to the sender with the
 explanatory message given in the exception. 
 
-$Id: mailgw.py,v 1.79 2002-07-26 08:26:59 richard Exp $
+$Id: mailgw.py,v 1.80 2002-08-01 00:56:22 richard Exp $
 '''
 
 
@@ -104,6 +104,8 @@ def initialiseSecurity(security):
     '''
     newid = security.addPermission(name="Email Registration",
         description="Anonymous may register through e-mail")
+    security.addPermission(name="Email Access",
+        description="User may use the email interface")
 
 class Message(mimetools.Message):
     ''' subclass mimetools.Message so we can retrieve the parts of the
@@ -527,8 +529,12 @@ Subject was: "%s"
         if not self.db.security.hasPermission('Email Registration', anonid):
             create = 0
 
+        # ok, now figure out who the author is - create a new user if the
+        # "create" flag is true
         author = uidFromAddress(self.db, message.getaddrlist('from')[0],
             create=create)
+
+        # no author? means we're not author
         if not author:
             raise Unauthorized, '''
 You are not a registered user.
@@ -536,6 +542,10 @@ You are not a registered user.
 Unknown address: %s
 '''%message.getaddrlist('from')[0][1]
 
+        # make sure the author has permission to use the email interface
+        if not self.db.security.hasPermission('Email Access', author):
+            raise Unauthorized, 'You are not permitted to access this tracker.'
+
         # the author may have been created - make sure the change is
         # committed before we reopen the database
         self.db.commit()
@@ -843,6 +853,11 @@ def parseContent(content, keep_citations, keep_body,
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.79  2002/07/26 08:26:59  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.78  2002/07/25 07:14:06  richard
 # Bugger it. Here's the current shape of the new security implementation.
 # Still to do:
index 7c2153ddf5e5c2ada0db13b21c82fe4cdee4ac09..71ff79ac44a6d799f0d1685a5d066f5734343e6a 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: dbinit.py,v 1.21 2002-07-26 08:26:59 richard Exp $
+# $Id: dbinit.py,v 1.22 2002-08-01 00:56:22 richard Exp $
 
 import os
 
@@ -98,6 +98,19 @@ def open(name=None):
         db.security.addPermission(name="View", klass=cl,
             description="User is allowed to access "+cl)
 
+    # Assign the access and edit permissions for issue, file and message
+    # to regular users now
+    for cl in 'issue', 'file', 'msg':
+        p = db.security.getPermission('View', cl)
+        db.security.addPermissionToRole('User', p)
+        p = db.security.getPermission('Edit', cl)
+        db.security.addPermissionToRole('User', p)
+    # and give the regular users access to the web and email interface
+    p = db.security.getPermission('Web Access')
+    db.security.addPermissionToRole('User', p)
+    p = db.security.getPermission('Email Access')
+    db.security.addPermissionToRole('User', p)
+
     # Assign the appropriate permissions to the anonymous user's Anonymous
     # Role. Choices here are:
     # - Allow anonymous users to register through the web
@@ -117,13 +130,9 @@ def open(name=None):
     #p = db.security.getPermission('Edit', 'issue')
     #db.security.addPermissionToRole('Anonymous', p)
 
-    # Assign the access and edit permissions for issue, file and message
-    # to regular users now
-    for cl in 'issue', 'file', 'msg':
-        p = db.security.getPermission('View', cl)
-        db.security.addPermissionToRole('User', p)
-        p = db.security.getPermission('Edit', cl)
-        db.security.addPermissionToRole('User', p)
+    # oh, g'wan, let anonymous access the web interface too
+    p = db.security.getPermission('Web Access')
+    db.security.addPermissionToRole('Anonymous', p)
 
     import detectors
     detectors.init(db)
@@ -176,6 +185,11 @@ def init(adminpw):
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.21  2002/07/26 08:26:59  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.20  2002/07/17 12:39:10  gmcm
 # Saving, running & editing queries.
 #
index 6149c4dc5d8d9bf26408b4eb568703357dd85134..d5178d9a455178594bcfd129125a8b25d12fcded 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: dbinit.py,v 1.24 2002-07-26 08:27:00 richard Exp $
+# $Id: dbinit.py,v 1.25 2002-08-01 00:56:22 richard Exp $
 
 import os
 
@@ -122,6 +122,19 @@ def open(name=None):
         db.security.addPermission(name="View", klass=cl,
             description="User is allowed to access "+cl)
 
+    # Assign the access and edit permissions for issue, file and message
+    # to regular users now
+    for cl in 'issue', 'support', 'file', 'msg':
+        p = db.security.getPermission('View', cl)
+        db.security.addPermissionToRole('User', p)
+        p = db.security.getPermission('Edit', cl)
+        db.security.addPermissionToRole('User', p)
+    # and give the regular users access to the web and email interface
+    p = db.security.getPermission('Web Access')
+    db.security.addPermissionToRole('User', p)
+    p = db.security.getPermission('Email Access')
+    db.security.addPermissionToRole('User', p)
+
     # Assign the appropriate permissions to the anonymous user's Anonymous
     # Role. Choices here are:
     # - Allow anonymous users to register through the web
@@ -141,13 +154,9 @@ def open(name=None):
     #p = db.security.getPermission('Edit', 'issue')
     #db.security.addPermissionToRole('Anonymous', p)
 
-    # Assign the access and edit permissions for issue, file and message
-    # to regular users now
-    for cl in 'issue', 'support', 'file', 'msg':
-        p = db.security.getPermission('View', cl)
-        db.security.addPermissionToRole('User', p)
-        p = db.security.getPermission('Edit', cl)
-        db.security.addPermissionToRole('User', p)
+    # oh, g'wan, let anonymous access the web interface too
+    p = db.security.getPermission('Web Access')
+    db.security.addPermissionToRole('Anonymous', p)
 
     import detectors
     detectors.init(db)
@@ -217,6 +226,11 @@ def init(adminpw):
 
 #
 # $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:05:54  richard
 # . all storage-specific code (ie. backend) is now implemented by the backends
 #