##// END OF EJS Templates
Changed auth basic handler only for mercurial request.
marcink -
r177:93bd77e1 default
parent child Browse files
Show More
@@ -1,72 +1,70 b''
1 """Pylons middleware initialization"""
1 """Pylons middleware initialization"""
2 from beaker.middleware import SessionMiddleware
2 from beaker.middleware import SessionMiddleware
3 from paste.cascade import Cascade
3 from paste.cascade import Cascade
4 from paste.registry import RegistryManager
4 from paste.registry import RegistryManager
5 from paste.urlparser import StaticURLParser
5 from paste.urlparser import StaticURLParser
6 from paste.deploy.converters import asbool
6 from paste.deploy.converters import asbool
7 from pylons.middleware import ErrorHandler, StatusCodeRedirect
7 from pylons.middleware import ErrorHandler, StatusCodeRedirect
8 from pylons.wsgiapp import PylonsApp
8 from pylons.wsgiapp import PylonsApp
9 from routes.middleware import RoutesMiddleware
9 from routes.middleware import RoutesMiddleware
10 from paste.auth.basic import AuthBasicHandler
10 from paste.auth.basic import AuthBasicHandler
11 from pylons_app.lib.simplehg import SimpleHg
11 from pylons_app.lib.simplehg import SimpleHg
12 from pylons_app.config.environment import load_environment
12 from pylons_app.config.environment import load_environment
13 from pylons_app.lib.auth import authfunc
14
13
15 def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
14 def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
16 """Create a Pylons WSGI application and return it
15 """Create a Pylons WSGI application and return it
17
16
18 ``global_conf``
17 ``global_conf``
19 The inherited configuration for this application. Normally from
18 The inherited configuration for this application. Normally from
20 the [DEFAULT] section of the Paste ini file.
19 the [DEFAULT] section of the Paste ini file.
21
20
22 ``full_stack``
21 ``full_stack``
23 Whether or not this application provides a full WSGI stack (by
22 Whether or not this application provides a full WSGI stack (by
24 default, meaning it handles its own exceptions and errors).
23 default, meaning it handles its own exceptions and errors).
25 Disable full_stack when this application is "managed" by
24 Disable full_stack when this application is "managed" by
26 another WSGI middleware.
25 another WSGI middleware.
27
26
28 ``app_conf``
27 ``app_conf``
29 The application's local configuration. Normally specified in
28 The application's local configuration. Normally specified in
30 the [app:<name>] section of the Paste ini file (where <name>
29 the [app:<name>] section of the Paste ini file (where <name>
31 defaults to main).
30 defaults to main).
32
31
33 """
32 """
34 # Configure the Pylons environment
33 # Configure the Pylons environment
35 config = load_environment(global_conf, app_conf)
34 config = load_environment(global_conf, app_conf)
36
35
37
36
38 # The Pylons WSGI app
37 # The Pylons WSGI app
39 app = PylonsApp(config=config)
38 app = PylonsApp(config=config)
40
39
41
40
42 # Routing/Session/Cache Middleware
41 # Routing/Session/Cache Middleware
43 app = RoutesMiddleware(app, config['routes.map'])
42 app = RoutesMiddleware(app, config['routes.map'])
44 app = SessionMiddleware(app, config)
43 app = SessionMiddleware(app, config)
45
44
46 # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
45 # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
47 app = SimpleHg(app, config)
46 app = SimpleHg(app, config)
48 app = AuthBasicHandler(app, config['repos_name'] + ' mercurial repository', authfunc)
49
47
50 if asbool(full_stack):
48 if asbool(full_stack):
51 # Handle Python exceptions
49 # Handle Python exceptions
52 app = ErrorHandler(app, global_conf, **config['pylons.errorware'])
50 app = ErrorHandler(app, global_conf, **config['pylons.errorware'])
53
51
54 # Display error documents for 401, 403, 404 status codes (and
52 # Display error documents for 401, 403, 404 status codes (and
55 # 500 when debug is disabled)
53 # 500 when debug is disabled)
56 if asbool(config['debug']):
54 if asbool(config['debug']):
57 app = StatusCodeRedirect(app)
55 app = StatusCodeRedirect(app)
58 else:
56 else:
59 app = StatusCodeRedirect(app, [400, 401, 403, 404, 500])
57 app = StatusCodeRedirect(app, [400, 401, 403, 404, 500])
60
58
61 # Establish the Registry for this application
59 # Establish the Registry for this application
62 app = RegistryManager(app)
60 app = RegistryManager(app)
63
61
64 if asbool(static_files):
62 if asbool(static_files):
65 # Serve static files
63 # Serve static files
66 static_app = StaticURLParser(config['pylons.paths']['static_files'])
64 static_app = StaticURLParser(config['pylons.paths']['static_files'])
67 app = Cascade([static_app, app])
65 app = Cascade([static_app, app])
68
66
69 app.config = config
67 app.config = config
70
68
71 return app
69 return app
72
70
@@ -1,64 +1,85 b''
1 import os
2 from mercurial.hgweb import hgweb
1 from mercurial.hgweb import hgweb
3 from mercurial.hgweb.request import wsgiapplication
2 from mercurial.hgweb.request import wsgiapplication
4 from pylons_app.lib.utils import make_ui, invalidate_cache
3 from paste.auth.basic import AuthBasicAuthenticator
4 from paste.httpheaders import REMOTE_USER, AUTH_TYPE
5 from pylons.controllers.util import abort
5 from pylons.controllers.util import abort
6 from pylons_app.lib.auth import authfunc
7 from pylons_app.lib.utils import make_ui, invalidate_cache
6 from webob.exc import HTTPNotFound
8 from webob.exc import HTTPNotFound
9 import os
10
7 class SimpleHg(object):
11 class SimpleHg(object):
8
12
9 def __init__(self, application, config):
13 def __init__(self, application, config):
10 self.application = application
14 self.application = application
11 self.config = config
15 self.config = config
16 #authenticate this mercurial request using
17 realm = '%s %s' % (config['repos_name'], 'mercurial repository')
18 self.authenticate = AuthBasicAuthenticator(realm, authfunc)
12
19
13 def __call__(self, environ, start_response):
20 def __call__(self, environ, start_response):
14 if not is_mercurial(environ):
21 if not is_mercurial(environ):
15 return self.application(environ, start_response)
22 return self.application(environ, start_response)
16 else:
23 else:
24 #===================================================================
25 # AUTHENTICATE THIS MERCURIAL REQUEST
26 #===================================================================
27 username = REMOTE_USER(environ)
28 if not username:
29 result = self.authenticate(environ)
30 if isinstance(result, str):
31 AUTH_TYPE.update(environ, 'basic')
32 REMOTE_USER.update(environ, result)
33 else:
34 return result.wsgi_application(environ, start_response)
35
17 try:
36 try:
18 repo_name = environ['PATH_INFO'].split('/')[1]
37 repo_name = environ['PATH_INFO'].split('/')[1]
19 except:
38 except:
20 return HTTPNotFound()(environ, start_response)
39 return HTTPNotFound()(environ, start_response)
21
40
22 #since we wrap into hgweb, just reset the path
41 #since we wrap into hgweb, just reset the path
23 environ['PATH_INFO'] = '/'
42 environ['PATH_INFO'] = '/'
24 self.baseui = make_ui()
43 self.baseui = make_ui()
25 self.basepath = self.baseui.configitems('paths')[0][1]\
44 self.basepath = self.baseui.configitems('paths')[0][1]\
26 .replace('*', '')
45 .replace('*', '')
27 self.repo_path = os.path.join(self.basepath, repo_name)
46 self.repo_path = os.path.join(self.basepath, repo_name)
28 try:
47 try:
29 app = wsgiapplication(self._make_app)
48 app = wsgiapplication(self._make_app)
30 except Exception as e:
49 except Exception as e:
31 return HTTPNotFound()(environ, start_response)
50 return HTTPNotFound()(environ, start_response)
32
51
33 """we know that some change was made to repositories and we should
52 """we know that some change was made to repositories and we should
34 invalidate the cache to see the changes right away"""
53 invalidate the cache to see the changes right away"""
35 invalidate_cache('full_changelog', repo_name)
54 invalidate_cache('full_changelog', repo_name)
36 return app(environ, start_response)
55 return app(environ, start_response)
37
56
38 def _make_app(self):
57 def _make_app(self):
39 hgserve = hgweb(self.repo_path)
58 hgserve = hgweb(self.repo_path)
40 return self.load_web_settings(hgserve)
59 return self.load_web_settings(hgserve)
41
60
42
61
43 def load_web_settings(self, hgserve):
62 def load_web_settings(self, hgserve):
44 repoui = make_ui(os.path.join(self.repo_path, '.hg', 'hgrc'), False)
63 repoui = make_ui(os.path.join(self.repo_path, '.hg', 'hgrc'), False)
45 #set the global ui for hgserve
64 #set the global ui for hgserve
46 hgserve.repo.ui = self.baseui
65 hgserve.repo.ui = self.baseui
47
66
48 if repoui:
67 if repoui:
49 #set the repository based config
68 #set the repository based config
50 hgserve.repo.ui = repoui
69 hgserve.repo.ui = repoui
51
70
52 return hgserve
71 return hgserve
72
73
53
74
54 def is_mercurial(environ):
75 def is_mercurial(environ):
55 """
76 """
56 Returns True if request's target is mercurial server - header
77 Returns True if request's target is mercurial server - header
57 ``HTTP_ACCEPT`` of such request would start with ``application/mercurial``.
78 ``HTTP_ACCEPT`` of such request would start with ``application/mercurial``.
58 """
79 """
59 http_accept = environ.get('HTTP_ACCEPT')
80 http_accept = environ.get('HTTP_ACCEPT')
60 if http_accept and http_accept.startswith('application/mercurial'):
81 if http_accept and http_accept.startswith('application/mercurial'):
61 return True
82 return True
62 return False
83 return False
63
84
64
85
General Comments 0
You need to be logged in to leave comments. Login now