Show More
@@ -45,7 +45,7 b' from rhodecode.lib.middleware import app' | |||||
45 | from rhodecode.lib.middleware.utils import scm_app |
|
45 | from rhodecode.lib.middleware.utils import scm_app | |
46 | from rhodecode.lib.utils import ( |
|
46 | from rhodecode.lib.utils import ( | |
47 | is_valid_repo, get_rhodecode_realm, get_rhodecode_base_path, SLUG_RE) |
|
47 | is_valid_repo, get_rhodecode_realm, get_rhodecode_base_path, SLUG_RE) | |
48 | from rhodecode.lib.utils2 import safe_str, fix_PATH, str2bool |
|
48 | from rhodecode.lib.utils2 import safe_str, fix_PATH, str2bool, safe_unicode | |
49 | from rhodecode.lib.vcs.conf import settings as vcs_settings |
|
49 | from rhodecode.lib.vcs.conf import settings as vcs_settings | |
50 | from rhodecode.lib.vcs.backends import base |
|
50 | from rhodecode.lib.vcs.backends import base | |
51 | from rhodecode.model import meta |
|
51 | from rhodecode.model import meta | |
@@ -120,42 +120,54 b' class SimpleVCS(object):' | |||||
120 | def set_repo_names(self, environ): |
|
120 | def set_repo_names(self, environ): | |
121 | """ |
|
121 | """ | |
122 | This will populate the attributes acl_repo_name, url_repo_name, |
|
122 | This will populate the attributes acl_repo_name, url_repo_name, | |
123 |
vcs_repo_name and is_shadow_repo |
|
123 | vcs_repo_name and is_shadow_repo. In case of requests to normal (non | |
124 | """ |
|
124 | shadow) repositories all names are equal. In case of requests to a | |
125 | # Get url repo name from environment. |
|
125 | shadow repository the acl-name points to the target repo of the pull | |
126 | self.url_repo_name = self._get_repository_name(environ) |
|
126 | request and the vcs-name points to the shadow repo file system path. | |
|
127 | The url-name is always the URL used by the vcs client program. | |||
127 |
|
|
128 | ||
128 | # Check if this is a request to a shadow repository. In case of a |
|
129 | Example in case of a shadow repo: | |
129 | # shadow repo set vcs_repo_name to the file system path pointing to the |
|
130 | acl_repo_name = RepoGroup/MyRepo | |
130 | # shadow repo. And set acl_repo_name to the pull request target repo |
|
131 | url_repo_name = RepoGroup/MyRepo/pull-request/3/repository | |
131 | # because we use the target repo for permission checks. Otherwise all |
|
132 | vcs_repo_name = /repo/base/path/RepoGroup/.__shadow_MyRepo_pr-3' | |
132 | # names are equal. |
|
133 | """ | |
|
134 | # First we set the repo name from URL for all attributes. This is the | |||
|
135 | # default if handling normal (non shadow) repo requests. | |||
|
136 | self.url_repo_name = self._get_repository_name(environ) | |||
|
137 | self.acl_repo_name = self.vcs_repo_name = self.url_repo_name | |||
|
138 | self.is_shadow_repo = False | |||
|
139 | ||||
|
140 | # Check if this is a request to a shadow repository. | |||
133 | match = self.shadow_repo_re.match(self.url_repo_name) |
|
141 | match = self.shadow_repo_re.match(self.url_repo_name) | |
134 | # TODO: martinb: Think about checking the target repo from PR against |
|
|||
135 | # the part in the URL. Otherwise we only rely on the PR id in the URL |
|
|||
136 | # and the variable parts can be anything. This will lead to 500 errors |
|
|||
137 | # from the VCSServer. |
|
|||
138 | if match: |
|
142 | if match: | |
139 | # Get pull request instance. |
|
|||
140 | match_dict = match.groupdict() |
|
143 | match_dict = match.groupdict() | |
141 | pr_id = match_dict['pr_id'] |
|
|||
142 | pull_request = PullRequest.get(pr_id) |
|
|||
143 |
|
144 | |||
144 | # Get file system path to shadow repository. |
|
145 | # Build acl repo name from regex match. | |
145 | workspace_id = PullRequestModel()._workspace_id(pull_request) |
|
146 | acl_repo_name = safe_unicode( | |
146 | target_vcs = pull_request.target_repo.scm_instance() |
|
147 | '{groups}/{target}'.format(**match_dict)) | |
147 | vcs_repo_name = target_vcs._get_shadow_repository_path( |
|
148 | ||
148 | workspace_id) |
|
149 | # Retrieve pull request instance by ID from regex match. | |
|
150 | pull_request = PullRequest.get(match_dict['pr_id']) | |||
149 |
|
151 | |||
150 | # Store names for later usage. |
|
152 | # Only proceed if we got a pull request and if acl repo name from | |
151 | self.vcs_repo_name = vcs_repo_name |
|
153 | # URL equals the target repo name of the pull request. | |
152 |
|
|
154 | if pull_request and acl_repo_name == pull_request.target_repo.repo_name: | |
153 | self.is_shadow_repo = True |
|
155 | # Get file system path to shadow repository. | |
154 | else: |
|
156 | workspace_id = PullRequestModel()._workspace_id(pull_request) | |
155 | # All names are equal for normal (non shadow) repositories. |
|
157 | target_vcs = pull_request.target_repo.scm_instance() | |
156 | self.acl_repo_name = self.url_repo_name |
|
158 | vcs_repo_name = target_vcs._get_shadow_repository_path( | |
157 | self.vcs_repo_name = self.url_repo_name |
|
159 | workspace_id) | |
158 | self.is_shadow_repo = False |
|
160 | ||
|
161 | # Store names for later usage. | |||
|
162 | self.vcs_repo_name = vcs_repo_name | |||
|
163 | self.acl_repo_name = acl_repo_name | |||
|
164 | self.is_shadow_repo = True | |||
|
165 | ||||
|
166 | log.debug('Repository names: %s', { | |||
|
167 | 'acl_repo_name': self.acl_repo_name, | |||
|
168 | 'url_repo_name': self.url_repo_name, | |||
|
169 | 'vcs_repo_name': self.vcs_repo_name, | |||
|
170 | }) | |||
159 |
|
171 | |||
160 | @property |
|
172 | @property | |
161 | def scm_app(self): |
|
173 | def scm_app(self): |
@@ -175,7 +175,7 b' class VCSMiddleware(object):' | |||||
175 | # in middleware |
|
175 | # in middleware | |
176 | environ['PATH_INFO'] = vcs_handler._get_by_id(environ['PATH_INFO']) |
|
176 | environ['PATH_INFO'] = vcs_handler._get_by_id(environ['PATH_INFO']) | |
177 |
|
177 | |||
178 | # Set repo names for permission checks, vcs and web interaction. |
|
178 | # Set acl, url and vcs repo names. | |
179 | vcs_handler.set_repo_names(environ) |
|
179 | vcs_handler.set_repo_names(environ) | |
180 |
|
180 | |||
181 | # check for type, presence in database and on filesystem |
|
181 | # check for type, presence in database and on filesystem |
@@ -58,12 +58,17 b' log = logging.getLogger(__name__)' | |||||
58 |
|
58 | |||
59 | REMOVED_REPO_PAT = re.compile(r'rm__\d{8}_\d{6}_\d{6}__.*') |
|
59 | REMOVED_REPO_PAT = re.compile(r'rm__\d{8}_\d{6}_\d{6}__.*') | |
60 |
|
60 | |||
61 |
# String |
|
61 | # String which contains characters that are not allowed in slug names for | |
|
62 | # repositories or repository groups. It is properly escaped to use it in | |||
|
63 | # regular expressions. | |||
62 | SLUG_BAD_CHARS = re.escape('`?=[]\;\'"<>,/~!@#$%^&*()+{}|:') |
|
64 | SLUG_BAD_CHARS = re.escape('`?=[]\;\'"<>,/~!@#$%^&*()+{}|:') | |
|
65 | ||||
63 | # Regex that matches forbidden characters in repo/group slugs. |
|
66 | # Regex that matches forbidden characters in repo/group slugs. | |
64 | SLUG_BAD_CHAR_RE = re.compile('[{}]'.format(SLUG_BAD_CHARS)) |
|
67 | SLUG_BAD_CHAR_RE = re.compile('[{}]'.format(SLUG_BAD_CHARS)) | |
|
68 | ||||
65 | # Regex that matches allowed characters in repo/group slugs. |
|
69 | # Regex that matches allowed characters in repo/group slugs. | |
66 | SLUG_GOOD_CHAR_RE = re.compile('[^{}]'.format(SLUG_BAD_CHARS)) |
|
70 | SLUG_GOOD_CHAR_RE = re.compile('[^{}]'.format(SLUG_BAD_CHARS)) | |
|
71 | ||||
67 | # Regex that matches whole repo/group slugs. |
|
72 | # Regex that matches whole repo/group slugs. | |
68 | SLUG_RE = re.compile('[^{}]+'.format(SLUG_BAD_CHARS)) |
|
73 | SLUG_RE = re.compile('[^{}]+'.format(SLUG_BAD_CHARS)) | |
69 |
|
74 |
General Comments 0
You need to be logged in to leave comments.
Login now