Source

trac-mq / t11287 / t11287_r11954_tracd_auth_regex.diff

Full commit
# HG changeset patch
# Parent a64bab1558a36f3c54efb7720315e9d7738e1c72
Trac #11287 : Option for regex to enforce server auth in TracStandalone

diff -r a64bab1558a3 trac/web/standalone.py
--- a/trac/web/standalone.py	Fri Aug 16 16:54:39 2013 +0000
+++ b/trac/web/standalone.py	Thu Sep 19 02:21:27 2013 -0500
@@ -21,6 +21,7 @@
 
 import pkg_resources
 import os
+import re
 import socket
 import select
 import sys
@@ -36,9 +37,12 @@
 
 class AuthenticationMiddleware(object):
 
-    def __init__(self, application, auths, single_env_name=None):
+    def __init__(self, application, auths, single_env_name=None,
+                 auth_location_match=None):
         self.application = application
         self.auths = auths
+        self.auth_regex = re.compile(auth_location_match) \
+                          if auth_location_match else None
         self.single_env_name = single_env_name
         if single_env_name:
             self.part = 0
@@ -48,7 +52,9 @@
     def __call__(self, environ, start_response):
         path_info = environ.get('PATH_INFO', '')
         path_parts = filter(None, path_info.split('/'))
-        if len(path_parts) > self.part and path_parts[self.part] == 'login':
+        _path = '/' + '/'.join(path_parts[self.part:])
+        if len(path_parts) > self.part and path_parts[self.part] == 'login' \
+                and (not self.auth_regex or self.auth_regex.match(_path)):
             env_name = self.single_env_name or path_parts[0]
             if env_name:
                 auth = self.auths.get(env_name, self.auths.get('*'))
@@ -153,6 +159,8 @@
         except ValueError:
             raise OptionValueError('Invalid octal umask value: %r' % value)
 
+    parser.add_option('--auth-regex', action='store', dest='auth_regex',
+                      help='apply auth only to regular-expression matching URLs')
     parser.add_option('-a', '--auth', action='callback', type='string',
                       metavar='DIGESTAUTH', callback=_auth_callback,
                       callback_args=(DigestAuthentication,),
@@ -275,11 +283,14 @@
                                      options.env_parent_dir, args,
                                      options.single_env)
     if auths:
+        auth_regex = options.auth_regex
         if options.single_env:
             project_name = os.path.basename(args[0])
-            wsgi_app = AuthenticationMiddleware(wsgi_app, auths, project_name)
+            wsgi_app = AuthenticationMiddleware(wsgi_app, auths, project_name,
+                                                auth_location_match=auth_regex)
         else:
-            wsgi_app = AuthenticationMiddleware(wsgi_app, auths)
+            wsgi_app = AuthenticationMiddleware(wsgi_app, auths,
+                                                auth_location_match=auth_regex)
     base_path = options.base_path.strip('/')
     if base_path:
         wsgi_app = BasePathMiddleware(wsgi_app, base_path)