Code

Fix thread safety with stdin in roundup-server
[roundup.git] / roundup / cgi / client.py
index b760e0c634cfbdf93e179b16b1c5966dea2108d7..3b1023806a5bd4b20c7c3040c0cb6bd8378a7406 100644 (file)
@@ -300,7 +300,7 @@ class Client:
 
         # see if we need to re-parse the environment for the form (eg Zope)
         if form is None:
-            self.form = cgi.FieldStorage(environ=env)
+            self.form = cgi.FieldStorage(fp=request.rfile, environ=env)
         else:
             self.form = form
 
@@ -380,6 +380,7 @@ class Client:
         self.determine_language()
         # Open the database as the correct user.
         self.determine_user()
+        self.check_anonymous_access()
 
         # Call the appropriate XML-RPC method.
         handler = xmlrpc.RoundupDispatcher(self.db,
@@ -437,6 +438,11 @@ class Client:
                 # figure out the context and desired content template
                 self.determine_context()
 
+                # if we've made it this far the context is to a bit of
+                # Roundup's real web interface (not a file being served up)
+                # so do the Anonymous Web Acess check now
+                self.check_anonymous_access()
+
                 # possibly handle a form submit action (may change self.classname
                 # and self.template, and may also append error/ok_messages)
                 html = self.handle_action()
@@ -711,15 +717,39 @@ class Client:
         # make sure the anonymous user is valid if we're using it
         if user == 'anonymous':
             self.make_user_anonymous()
-            if not self.db.security.hasPermission('Web Access', self.userid):
-                raise Unauthorised, self._("Anonymous users are not "
-                    "allowed to use the web interface")
         else:
             self.user = user
 
         # reopen the database as the correct user
         self.opendb(self.user)
 
+    def check_anonymous_access(self):
+        """Check that the Anonymous user is actually allowed to use the web
+        interface and short-circuit all further processing if they're not.
+        """
+        # allow Anonymous to use the "login" and "register" actions (noting
+        # that "register" has its own "Register" permission check)
+        if self.form.has_key(':action'):
+            action = self.form[':action'].value.lower()
+        elif self.form.has_key('@action'):
+            action = self.form['@action'].value.lower()
+        else:
+            action = None
+        if action in ('login', 'register'):
+            return
+
+        # allow Anonymous to view the "user" "register" template if they're
+        # allowed to register
+        if (self.db.security.hasPermission('Register', self.userid, 'user')
+                and self.classname == 'user' and self.template == 'register'):
+            return
+
+        # otherwise for everything else
+        if self.user == 'anonymous':
+            if not self.db.security.hasPermission('Web Access', self.userid):
+                raise Unauthorised, self._("Anonymous users are not "
+                    "allowed to use the web interface")
+
     def opendb(self, username):
         """Open the database and set the current user.
 
@@ -865,6 +895,8 @@ class Client:
             # The classname was not valid.
             raise NotFound, str(designator)
             
+        # perform the Anonymous user access check
+        self.check_anonymous_access()
 
         # make sure we have the appropriate properties
         props = klass.getprops()