comparison rhodecode/lib/middleware/simplehg.py @ 654:7f5976da192c beta

#48 rewrite action loggers into hooks with all changesets that are inside a push
author Marcin Kuzminski <marcin@python-works.com>
date Fri, 05 Nov 2010 18:26:26 +0100
parents 7e536d1af60d
children aefc371a2531
comparison
equal deleted inserted replaced
653:4a3291628f09 654:7f5976da192c
47 def __init__(self, application, config): 47 def __init__(self, application, config):
48 self.application = application 48 self.application = application
49 self.config = config 49 self.config = config
50 #authenticate this mercurial request using 50 #authenticate this mercurial request using
51 self.authenticate = AuthBasicAuthenticator('', authfunc) 51 self.authenticate = AuthBasicAuthenticator('', authfunc)
52 52 self.ipaddr = '0.0.0.0'
53 self.repository = None
54 self.username = None
55 self.action = None
56
53 def __call__(self, environ, start_response): 57 def __call__(self, environ, start_response):
54 if not is_mercurial(environ): 58 if not is_mercurial(environ):
55 return self.application(environ, start_response) 59 return self.application(environ, start_response)
56 60
61 proxy_key = 'HTTP_X_REAL_IP'
62 def_key = 'REMOTE_ADDR'
63 self.ipaddr = environ.get(proxy_key, environ.get(def_key, '0.0.0.0'))
64
57 #=================================================================== 65 #===================================================================
58 # AUTHENTICATE THIS MERCURIAL REQUEST 66 # AUTHENTICATE THIS MERCURIAL REQUEST
59 #=================================================================== 67 #===================================================================
60 username = REMOTE_USER(environ) 68 username = REMOTE_USER(environ)
69
61 if not username: 70 if not username:
62 self.authenticate.realm = self.config['rhodecode_realm'] 71 self.authenticate.realm = self.config['rhodecode_realm']
63 result = self.authenticate(environ) 72 result = self.authenticate(environ)
64 if isinstance(result, str): 73 if isinstance(result, str):
65 AUTH_TYPE.update(environ, 'basic') 74 AUTH_TYPE.update(environ, 'basic')
66 REMOTE_USER.update(environ, result) 75 REMOTE_USER.update(environ, result)
67 else: 76 else:
68 return result.wsgi_application(environ, start_response) 77 return result.wsgi_application(environ, start_response)
69 78
79 #=======================================================================
80 # GET REPOSITORY
81 #=======================================================================
70 try: 82 try:
71 repo_name = '/'.join(environ['PATH_INFO'].split('/')[1:]) 83 repo_name = '/'.join(environ['PATH_INFO'].split('/')[1:])
72 if repo_name.endswith('/'): 84 if repo_name.endswith('/'):
73 repo_name = repo_name.rstrip('/') 85 repo_name = repo_name.rstrip('/')
86 self.repository = repo_name
74 except: 87 except:
75 log.error(traceback.format_exc()) 88 log.error(traceback.format_exc())
76 return HTTPInternalServerError()(environ, start_response) 89 return HTTPInternalServerError()(environ, start_response)
77 90
78 #=================================================================== 91 #===================================================================
79 # CHECK PERMISSIONS FOR THIS REQUEST 92 # CHECK PERMISSIONS FOR THIS REQUEST
80 #=================================================================== 93 #===================================================================
81 action = self.__get_action(environ) 94 self.action = self.__get_action(environ)
82 if action: 95 if self.action:
83 username = self.__get_environ_user(environ) 96 username = self.__get_environ_user(environ)
84 try: 97 try:
85 user = self.__get_user(username) 98 user = self.__get_user(username)
99 self.username = user.username
86 except: 100 except:
87 log.error(traceback.format_exc()) 101 log.error(traceback.format_exc())
88 return HTTPInternalServerError()(environ, start_response) 102 return HTTPInternalServerError()(environ, start_response)
89 103
90 #check permissions for this repository 104 #check permissions for this repository
91 if action == 'push': 105 if self.action == 'push':
92 if not HasPermissionAnyMiddleware('repository.write', 106 if not HasPermissionAnyMiddleware('repository.write',
93 'repository.admin')\ 107 'repository.admin')\
94 (user, repo_name): 108 (user, repo_name):
95 return HTTPForbidden()(environ, start_response) 109 return HTTPForbidden()(environ, start_response)
96 110
99 if not HasPermissionAnyMiddleware('repository.read', 113 if not HasPermissionAnyMiddleware('repository.read',
100 'repository.write', 114 'repository.write',
101 'repository.admin')\ 115 'repository.admin')\
102 (user, repo_name): 116 (user, repo_name):
103 return HTTPForbidden()(environ, start_response) 117 return HTTPForbidden()(environ, start_response)
104 118
105 #log action 119 self.extras = {'ip':self.ipaddr,
106 if action in ('push', 'pull', 'clone'): 120 'username':self.username,
107 proxy_key = 'HTTP_X_REAL_IP' 121 'action':self.action,
108 def_key = 'REMOTE_ADDR' 122 'repository':self.repository}
109 ipaddr = environ.get(proxy_key, environ.get(def_key, '0.0.0.0')) 123 print self.extras
110 self.__log_user_action(user, action, repo_name, ipaddr)
111
112 #=================================================================== 124 #===================================================================
113 # MERCURIAL REQUEST HANDLING 125 # MERCURIAL REQUEST HANDLING
114 #=================================================================== 126 #===================================================================
115 environ['PATH_INFO'] = '/'#since we wrap into hgweb, reset the path 127 environ['PATH_INFO'] = '/'#since we wrap into hgweb, reset the path
116 self.baseui = make_ui('db') 128 self.baseui = make_ui('db')
128 except Exception: 140 except Exception:
129 log.error(traceback.format_exc()) 141 log.error(traceback.format_exc())
130 return HTTPInternalServerError()(environ, start_response) 142 return HTTPInternalServerError()(environ, start_response)
131 143
132 #invalidate cache on push 144 #invalidate cache on push
133 if action == 'push': 145 if self.action == 'push':
134 self.__invalidate_cache(repo_name) 146 self.__invalidate_cache(repo_name)
135 messages = [] 147 messages = []
136 messages.append('thank you for using rhodecode') 148 messages.append('thank you for using rhodecode')
137 149
138 return self.msg_wrapper(app, environ, start_response, messages) 150 return self.msg_wrapper(app, environ, start_response, messages)
155 org_response = app(environ, start_response) 167 org_response = app(environ, start_response)
156 return chain(org_response, custom_messages(messages)) 168 return chain(org_response, custom_messages(messages))
157 169
158 def __make_app(self): 170 def __make_app(self):
159 hgserve = hgweb(str(self.repo_path), baseui=self.baseui) 171 hgserve = hgweb(str(self.repo_path), baseui=self.baseui)
160 return self.__load_web_settings(hgserve) 172 return self.__load_web_settings(hgserve, self.extras)
161 173
162 def __get_environ_user(self, environ): 174 def __get_environ_user(self, environ):
163 return environ.get('REMOTE_USER') 175 return environ.get('REMOTE_USER')
164 176
165 def __get_user(self, username): 177 def __get_user(self, username):
172 :param environ: 184 :param environ:
173 """ 185 """
174 mapping = {'changegroup': 'pull', 186 mapping = {'changegroup': 'pull',
175 'changegroupsubset': 'pull', 187 'changegroupsubset': 'pull',
176 'stream_out': 'pull', 188 'stream_out': 'pull',
177 #'listkeys': 'pull', 189 'listkeys': 'pull',
178 'unbundle': 'push', 190 'unbundle': 'push',
179 'pushkey': 'push', } 191 'pushkey': 'push', }
180 for qry in environ['QUERY_STRING'].split('&'): 192 for qry in environ['QUERY_STRING'].split('&'):
181 if qry.startswith('cmd'): 193 if qry.startswith('cmd'):
182 cmd = qry.split('=')[-1] 194 cmd = qry.split('=')[-1]
183 if mapping.has_key(cmd): 195 if mapping.has_key(cmd):
184 return mapping[cmd] 196 return mapping[cmd]
185 else: 197 else:
186 return cmd 198 return cmd
187 199
188 def __log_user_action(self, user, action, repo, ipaddr):
189 action_logger(user, action, repo, ipaddr)
190
191 def __invalidate_cache(self, repo_name): 200 def __invalidate_cache(self, repo_name):
192 """we know that some change was made to repositories and we should 201 """we know that some change was made to repositories and we should
193 invalidate the cache to see the changes right away but only for 202 invalidate the cache to see the changes right away but only for
194 push requests""" 203 push requests"""
195 invalidate_cache('cached_repo_list') 204 invalidate_cache('cached_repo_list')
196 invalidate_cache('full_changelog', repo_name) 205 invalidate_cache('full_changelog', repo_name)
197 206
198 207
199 def __load_web_settings(self, hgserve): 208 def __load_web_settings(self, hgserve, extras={}):
200 #set the global ui for hgserve instance passed 209 #set the global ui for hgserve instance passed
201 hgserve.repo.ui = self.baseui 210 hgserve.repo.ui = self.baseui
202 211
203 hgrc = os.path.join(self.repo_path, '.hg', 'hgrc') 212 hgrc = os.path.join(self.repo_path, '.hg', 'hgrc')
213
214 #inject some additional parameters that will be available in ui
215 #for hooks
216 for k, v in extras.items():
217 hgserve.repo.ui.setconfig('rhodecode_extras', k, v)
218
204 repoui = make_ui('file', hgrc, False) 219 repoui = make_ui('file', hgrc, False)
205
206 220
207 if repoui: 221 if repoui:
208 #overwrite our ui instance with the section from hgrc file 222 #overwrite our ui instance with the section from hgrc file
209 for section in ui_sections: 223 for section in ui_sections:
210 for k, v in repoui.configitems(section): 224 for k, v in repoui.configitems(section):
211 hgserve.repo.ui.setconfig(section, k, v) 225 hgserve.repo.ui.setconfig(section, k, v)
212 226
213 return hgserve 227 return hgserve
214 228
215 229
216 230
217 231