##// END OF EJS Templates
simplehg update
marcink -
r178:24dbf4bc default
parent child Browse files
Show More
@@ -1,85 +1,86 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 #
4 # Copyright (c) 2010 marcink. All rights reserved.
5 #
6 """
7 Created on 2010-04-28
8
9 @author: marcink
10 SimpleHG middleware for handling mercurial protocol request (push/clone etc.)
11 It's implemented with basic auth function
12 """
13
1 from mercurial.hgweb import hgweb
14 from mercurial.hgweb import hgweb
2 from mercurial.hgweb.request import wsgiapplication
15 from mercurial.hgweb.request import wsgiapplication
3 from paste.auth.basic import AuthBasicAuthenticator
16 from paste.auth.basic import AuthBasicAuthenticator
4 from paste.httpheaders import REMOTE_USER, AUTH_TYPE
17 from paste.httpheaders import REMOTE_USER, AUTH_TYPE
5 from pylons.controllers.util import abort
18 from pylons_app.lib.utils import is_mercurial
6 from pylons_app.lib.auth import authfunc
19 from pylons_app.lib.auth import authfunc
7 from pylons_app.lib.utils import make_ui, invalidate_cache
20 from pylons_app.lib.utils import make_ui, invalidate_cache
8 from webob.exc import HTTPNotFound
21 from webob.exc import HTTPNotFound
9 import os
22 import os
10
23
11 class SimpleHg(object):
24 class SimpleHg(object):
12
25
13 def __init__(self, application, config):
26 def __init__(self, application, config):
14 self.application = application
27 self.application = application
15 self.config = config
28 self.config = config
16 #authenticate this mercurial request using
29 #authenticate this mercurial request using
17 realm = '%s %s' % (config['repos_name'], 'mercurial repository')
30 realm = '%s %s' % (config['repos_name'], 'mercurial repository')
18 self.authenticate = AuthBasicAuthenticator(realm, authfunc)
31 self.authenticate = AuthBasicAuthenticator(realm, authfunc)
19
32
20 def __call__(self, environ, start_response):
33 def __call__(self, environ, start_response):
21 if not is_mercurial(environ):
34 if not is_mercurial(environ):
22 return self.application(environ, start_response)
35 return self.application(environ, start_response)
23 else:
36 else:
24 #===================================================================
37 #===================================================================
25 # AUTHENTICATE THIS MERCURIAL REQUEST
38 # AUTHENTICATE THIS MERCURIAL REQUEST
26 #===================================================================
39 #===================================================================
27 username = REMOTE_USER(environ)
40 username = REMOTE_USER(environ)
28 if not username:
41 if not username:
29 result = self.authenticate(environ)
42 result = self.authenticate(environ)
30 if isinstance(result, str):
43 if isinstance(result, str):
31 AUTH_TYPE.update(environ, 'basic')
44 AUTH_TYPE.update(environ, 'basic')
32 REMOTE_USER.update(environ, result)
45 REMOTE_USER.update(environ, result)
33 else:
46 else:
34 return result.wsgi_application(environ, start_response)
47 return result.wsgi_application(environ, start_response)
35
48
36 try:
49 try:
37 repo_name = environ['PATH_INFO'].split('/')[1]
50 repo_name = environ['PATH_INFO'].split('/')[1]
38 except:
51 except:
39 return HTTPNotFound()(environ, start_response)
52 return HTTPNotFound()(environ, start_response)
40
53
41 #since we wrap into hgweb, just reset the path
54 #since we wrap into hgweb, just reset the path
42 environ['PATH_INFO'] = '/'
55 environ['PATH_INFO'] = '/'
43 self.baseui = make_ui()
56 self.baseui = make_ui()
44 self.basepath = self.baseui.configitems('paths')[0][1]\
57 self.basepath = self.baseui.configitems('paths')[0][1]\
45 .replace('*', '')
58 .replace('*', '')
46 self.repo_path = os.path.join(self.basepath, repo_name)
59 self.repo_path = os.path.join(self.basepath, repo_name)
47 try:
60 try:
48 app = wsgiapplication(self._make_app)
61 app = wsgiapplication(self._make_app)
49 except Exception as e:
62 except Exception as e:
50 return HTTPNotFound()(environ, start_response)
63 return HTTPNotFound()(environ, start_response)
51
64
52 """we know that some change was made to repositories and we should
65 """we know that some change was made to repositories and we should
53 invalidate the cache to see the changes right away"""
66 invalidate the cache to see the changes right away"""
54 invalidate_cache('full_changelog', repo_name)
67 invalidate_cache('full_changelog', repo_name)
55 return app(environ, start_response)
68 return app(environ, start_response)
56
69
57 def _make_app(self):
70 def _make_app(self):
58 hgserve = hgweb(self.repo_path)
71 hgserve = hgweb(self.repo_path)
59 return self.load_web_settings(hgserve)
72 return self.load_web_settings(hgserve)
60
73
61
74
62 def load_web_settings(self, hgserve):
75 def load_web_settings(self, hgserve):
63 repoui = make_ui(os.path.join(self.repo_path, '.hg', 'hgrc'), False)
76 repoui = make_ui(os.path.join(self.repo_path, '.hg', 'hgrc'), False)
64 #set the global ui for hgserve
77 #set the global ui for hgserve
65 hgserve.repo.ui = self.baseui
78 hgserve.repo.ui = self.baseui
66
79
67 if repoui:
80 if repoui:
68 #set the repository based config
81 #set the repository based config
69 hgserve.repo.ui = repoui
82 hgserve.repo.ui = repoui
70
83
71 return hgserve
84 return hgserve
72
85
73
86
74
75 def is_mercurial(environ):
76 """
77 Returns True if request's target is mercurial server - header
78 ``HTTP_ACCEPT`` of such request would start with ``application/mercurial``.
79 """
80 http_accept = environ.get('HTTP_ACCEPT')
81 if http_accept and http_accept.startswith('application/mercurial'):
82 return True
83 return False
84
85
General Comments 0
You need to be logged in to leave comments. Login now