comparison rhodecode/lib/middleware/simplegit.py @ 625:d5372213db98

some hacking on simplegit middleware
author Marcin Kuzminski <marcin@python-works.com>
date Wed, 20 Oct 2010 02:08:03 +0200
parents 19a62a5490fe
children fd63782c4426
comparison
equal deleted inserted replaced
624:60a4aabf6aa6 625:d5372213db98
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # encoding: utf-8 2 # encoding: utf-8
3 # middleware to handle mercurial api calls 3 # middleware to handle git api calls
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com> 4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5 # 5 #
6 # This program is free software; you can redistribute it and/or 6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License 7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2 8 # as published by the Free Software Foundation; version 2
15 # 15 #
16 # You should have received a copy of the GNU General Public License 16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software 17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # MA 02110-1301, USA. 19 # MA 02110-1301, USA.
20 from dulwich import server as dulserver
21
22 class SimpleGitUploadPackHandler(dulserver.UploadPackHandler):
23
24 def handle(self):
25 write = lambda x: self.proto.write_sideband(1, x)
26
27 graph_walker = dulserver.ProtocolGraphWalker(self, self.repo.object_store,
28 self.repo.get_peeled)
29 objects_iter = self.repo.fetch_objects(
30 graph_walker.determine_wants, graph_walker, self.progress,
31 get_tagged=self.get_tagged)
32
33 # Do they want any objects?
34 if len(objects_iter) == 0:
35 return
36
37 self.progress("counting objects: %d, done.\n" % len(objects_iter))
38 dulserver.write_pack_data(dulserver.ProtocolFile(None, write), objects_iter,
39 len(objects_iter))
40 messages = []
41 messages.append('thank you for using rhodecode')
42
43 for msg in messages:
44 self.progress(msg + "\n")
45 # we are done
46 self.proto.write("0000")
47
48 dulserver.DEFAULT_HANDLERS = {
49 'git-upload-pack': SimpleGitUploadPackHandler,
50 'git-receive-pack': dulserver.ReceivePackHandler,
51 }
52
20 from dulwich.repo import Repo 53 from dulwich.repo import Repo
21 from dulwich.server import DictBackend
22 from dulwich.web import HTTPGitApplication 54 from dulwich.web import HTTPGitApplication
23 from itertools import chain
24 from paste.auth.basic import AuthBasicAuthenticator 55 from paste.auth.basic import AuthBasicAuthenticator
25 from paste.httpheaders import REMOTE_USER, AUTH_TYPE 56 from paste.httpheaders import REMOTE_USER, AUTH_TYPE
26 from rhodecode.lib.auth import authfunc, HasPermissionAnyMiddleware, \ 57 from rhodecode.lib.auth import authfunc, HasPermissionAnyMiddleware, \
27 get_user_cached 58 get_user_cached
28 from rhodecode.lib.utils import action_logger, is_git, invalidate_cache, \ 59 from rhodecode.lib.utils import action_logger, is_git, invalidate_cache, \
33 import traceback 64 import traceback
34 """ 65 """
35 Created on 2010-04-28 66 Created on 2010-04-28
36 67
37 @author: marcink 68 @author: marcink
38 SimpleHG middleware for handling mercurial protocol request (push/clone etc.) 69 SimpleGit middleware for handling git protocol request (push/clone etc.)
39 It's implemented with basic auth function 70 It's implemented with basic auth function
40 """ 71 """
41
42 72
43 73
44 74
45 log = logging.getLogger(__name__) 75 log = logging.getLogger(__name__)
46 76
47 class SimpleGit(object): 77 class SimpleGit(object):
48 78
49 def __init__(self, application, config): 79 def __init__(self, application, config):
50 self.application = application 80 self.application = application
51 self.config = config 81 self.config = config
52 #authenticate this mercurial request using 82 #authenticate this git request using
53 self.authenticate = AuthBasicAuthenticator('', authfunc) 83 self.authenticate = AuthBasicAuthenticator('', authfunc)
54 84
55 def __call__(self, environ, start_response): 85 def __call__(self, environ, start_response):
56 if not is_git(environ): 86 if not is_git(environ):
57 return self.application(environ, start_response) 87 return self.application(environ, start_response)
58 88
59 #=================================================================== 89 #===================================================================
60 # AUTHENTICATE THIS MERCURIAL REQUEST 90 # AUTHENTICATE THIS GIT REQUEST
61 #=================================================================== 91 #===================================================================
62 username = REMOTE_USER(environ) 92 username = REMOTE_USER(environ)
63 if not username: 93 if not username:
64 self.authenticate.realm = self.config['rhodecode_realm'] 94 self.authenticate.realm = self.config['rhodecode_realm']
65 result = self.authenticate(environ) 95 result = self.authenticate(environ)
129 if action == 'push': 159 if action == 'push':
130 self.__invalidate_cache(self.repo_name) 160 self.__invalidate_cache(self.repo_name)
131 messages = [] 161 messages = []
132 messages.append('thank you for using rhodecode') 162 messages.append('thank you for using rhodecode')
133 return app(environ, start_response) 163 return app(environ, start_response)
134 #TODO: check other alternatives for msg wrapping
135 #return self.msg_wrapper(app, environ, start_response, messages)
136 else: 164 else:
137 return app(environ, start_response) 165 return app(environ, start_response)
138 166
139 167
140 def msg_wrapper(self, app, environ, start_response, messages=[]):
141 """
142 Wrapper for custom messages that come out of mercurial respond messages
143 is a list of messages that the user will see at the end of response
144 from merurial protocol actions that involves remote answers
145 :param app:
146 :param environ:
147 :param start_response:
148 """
149 def custom_messages(msg_list):
150 for msg in msg_list:
151 yield msg + '\n'
152 org_response = app(environ, start_response)
153 return chain(org_response, custom_messages(messages))
154
155
156 def __make_app(self): 168 def __make_app(self):
157 backend = DictBackend({'/' + self.repo_name: Repo(self.repo_path)}) 169 backend = dulserver.DictBackend({'/' + self.repo_name: Repo(self.repo_path)})
158 gitserve = HTTPGitApplication(backend) 170 gitserve = HTTPGitApplication(backend)
159 171
160 return gitserve 172 return gitserve
161 173
162 def __get_environ_user(self, environ): 174 def __get_environ_user(self, environ):
171 :param environ: 183 :param environ:
172 """ 184 """
173 service = environ['QUERY_STRING'].split('=') 185 service = environ['QUERY_STRING'].split('=')
174 if len(service) > 1: 186 if len(service) > 1:
175 service_cmd = service[1] 187 service_cmd = service[1]
176 mapping = {'git-receive-pack': 'pull', 188 mapping = {'git-receive-pack': 'push',
177 'git-upload-pack': 'push', 189 'git-upload-pack': 'pull',
178 } 190 }
179 191
180 return mapping.get(service_cmd, service_cmd) 192 return mapping.get(service_cmd, service_cmd if service_cmd else 'other')
193 else:
194 return 'other'
181 195
182 def __log_user_action(self, user, action, repo, ipaddr): 196 def __log_user_action(self, user, action, repo, ipaddr):
183 action_logger(user, action, repo, ipaddr) 197 action_logger(user, action, repo, ipaddr)
184 198
185 def __invalidate_cache(self, repo_name): 199 def __invalidate_cache(self, repo_name):