##// END OF EJS Templates
ssh: use proper way of extracting the HOOK_PROTOCOL out of vcssettings....
marcink -
r2212:dc0a58ba default
parent child Browse files
Show More
@@ -1,150 +1,149 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 import os
22 22 import sys
23 23 import json
24 24 import logging
25 25
26 26 from rhodecode.lib.hooks_daemon import prepare_callback_daemon
27 from rhodecode.lib import hooks_utils
27 from rhodecode.lib.vcs.conf import settings as vcs_settings
28 28 from rhodecode.model.scm import ScmModel
29 29
30 30 log = logging.getLogger(__name__)
31 31
32 32
33 33 class VcsServer(object):
34 34 _path = None # set executable path for hg/git/svn binary
35 35 backend = None # set in child classes
36 36 tunnel = None # subprocess handling tunnel
37 37 write_perms = ['repository.admin', 'repository.write']
38 38 read_perms = ['repository.read', 'repository.admin', 'repository.write']
39 39
40 40 def __init__(self, user, user_permissions, config, env):
41 41 self.user = user
42 42 self.user_permissions = user_permissions
43 43 self.config = config
44 44 self.env = env
45 45 self.stdin = sys.stdin
46 46
47 47 self.repo_name = None
48 48 self.repo_mode = None
49 49 self.store = ''
50 50 self.ini_path = ''
51 51
52 52 def _invalidate_cache(self, repo_name):
53 53 """
54 54 Set's cache for this repository for invalidation on next access
55 55
56 56 :param repo_name: full repo name, also a cache key
57 57 """
58 58 ScmModel().mark_for_invalidation(repo_name)
59 59
60 60 def has_write_perm(self):
61 61 permission = self.user_permissions.get(self.repo_name)
62 62 if permission in ['repository.write', 'repository.admin']:
63 63 return True
64 64
65 65 return False
66 66
67 67 def _check_permissions(self, action):
68 68 permission = self.user_permissions.get(self.repo_name)
69 69 log.debug(
70 70 'permission for %s on %s are: %s',
71 71 self.user, self.repo_name, permission)
72 72
73 73 if action == 'pull':
74 74 if permission in self.read_perms:
75 75 log.info(
76 76 'READ Permissions for User "%s" detected to repo "%s"!',
77 77 self.user, self.repo_name)
78 78 return 0
79 79 else:
80 80 if permission in self.write_perms:
81 81 log.info(
82 82 'WRITE+ Permissions for User "%s" detected to repo "%s"!',
83 83 self.user, self.repo_name)
84 84 return 0
85 85
86 86 log.error('Cannot properly fetch or allow user %s permissions. '
87 87 'Return value is: %s, req action: %s',
88 88 self.user, permission, action)
89 89 return -2
90 90
91 91 def update_environment(self, action, extras=None):
92 92
93 93 scm_data = {
94 94 'ip': os.environ['SSH_CLIENT'].split()[0],
95 95 'username': self.user.username,
96 96 'action': action,
97 97 'repository': self.repo_name,
98 98 'scm': self.backend,
99 99 'config': self.ini_path,
100 100 'make_lock': None,
101 101 'locked_by': [None, None],
102 102 'server_url': None,
103 103 'is_shadow_repo': False,
104 104 'hooks_module': 'rhodecode.lib.hooks_daemon',
105 105 'hooks': ['push', 'pull'],
106 106 'SSH': True,
107 107 'SSH_PERMISSIONS': self.user_permissions.get(self.repo_name)
108 108 }
109 109 if extras:
110 110 scm_data.update(extras)
111 111 os.putenv("RC_SCM_DATA", json.dumps(scm_data))
112 112
113 113 def get_root_store(self):
114 114 root_store = self.store
115 115 if not root_store.endswith('/'):
116 116 # always append trailing slash
117 117 root_store = root_store + '/'
118 118 return root_store
119 119
120 120 def _handle_tunnel(self, extras):
121 121 # pre-auth
122 122 action = 'pull'
123 123 exit_code = self._check_permissions(action)
124 124 if exit_code:
125 125 return exit_code, False
126 126
127 127 req = self.env['request']
128 128 server_url = req.host_url + req.script_name
129 129 extras['server_url'] = server_url
130 130
131 131 log.debug('Using %s binaries from path %s', self.backend, self._path)
132 132 exit_code = self.tunnel.run(extras)
133 133
134 134 return exit_code, action == "push"
135 135
136 136 def run(self):
137 137 extras = {}
138 HOOKS_PROTOCOL = self.config.get('app:main', 'vcs.hooks.protocol')
139 138
140 139 callback_daemon, extras = prepare_callback_daemon(
141 extras, protocol=HOOKS_PROTOCOL,
140 extras, protocol=vcs_settings.HOOKS_PROTOCOL,
142 141 use_direct_calls=False)
143 142
144 143 with callback_daemon:
145 144 try:
146 145 return self._handle_tunnel(extras)
147 146 finally:
148 147 log.debug('Running cleanup with cache invalidation')
149 148 if self.repo_name:
150 149 self._invalidate_cache(self.repo_name)
General Comments 0
You need to be logged in to leave comments. Login now