Show More
@@ -1,573 +1,572 | |||||
1 | """ |
|
1 | """ | |
2 | Routes configuration |
|
2 | Routes configuration | |
3 |
|
3 | |||
4 | The more specific and detailed routes should be defined first so they |
|
4 | The more specific and detailed routes should be defined first so they | |
5 | may take precedent over the more generic routes. For more information |
|
5 | may take precedent over the more generic routes. For more information | |
6 | refer to the routes manual at http://routes.groovie.org/docs/ |
|
6 | refer to the routes manual at http://routes.groovie.org/docs/ | |
7 | """ |
|
7 | """ | |
8 | from __future__ import with_statement |
|
8 | from __future__ import with_statement | |
9 | from routes import Mapper |
|
9 | from routes import Mapper | |
10 |
|
10 | |||
11 | # prefix for non repository related links needs to be prefixed with `/` |
|
11 | # prefix for non repository related links needs to be prefixed with `/` | |
12 | ADMIN_PREFIX = '/_admin' |
|
12 | ADMIN_PREFIX = '/_admin' | |
13 |
|
13 | |||
14 |
|
14 | |||
15 | def make_map(config): |
|
15 | def make_map(config): | |
16 | """Create, configure and return the routes Mapper""" |
|
16 | """Create, configure and return the routes Mapper""" | |
17 | rmap = Mapper(directory=config['pylons.paths']['controllers'], |
|
17 | rmap = Mapper(directory=config['pylons.paths']['controllers'], | |
18 | always_scan=config['debug']) |
|
18 | always_scan=config['debug']) | |
19 | rmap.minimization = False |
|
19 | rmap.minimization = False | |
20 | rmap.explicit = False |
|
20 | rmap.explicit = False | |
21 |
|
21 | |||
22 | from rhodecode.lib.utils import is_valid_repo |
|
22 | from rhodecode.lib.utils import is_valid_repo | |
23 | from rhodecode.lib.utils import is_valid_repos_group |
|
23 | from rhodecode.lib.utils import is_valid_repos_group | |
24 |
|
24 | |||
25 | def check_repo(environ, match_dict): |
|
25 | def check_repo(environ, match_dict): | |
26 | """ |
|
26 | """ | |
27 | check for valid repository for proper 404 handling |
|
27 | check for valid repository for proper 404 handling | |
28 |
|
28 | |||
29 | :param environ: |
|
29 | :param environ: | |
30 | :param match_dict: |
|
30 | :param match_dict: | |
31 | """ |
|
31 | """ | |
32 | from rhodecode.model.db import Repository |
|
32 | from rhodecode.model.db import Repository | |
33 | repo_name = match_dict.get('repo_name') |
|
33 | repo_name = match_dict.get('repo_name') | |
34 |
|
34 | |||
35 | try: |
|
35 | try: | |
36 | by_id = repo_name.split('_') |
|
36 | by_id = repo_name.split('_') | |
37 | if len(by_id) == 2 and by_id[1].isdigit(): |
|
37 | if len(by_id) == 2 and by_id[1].isdigit(): | |
38 | repo_name = Repository.get(by_id[1]).repo_name |
|
38 | repo_name = Repository.get(by_id[1]).repo_name | |
39 | match_dict['repo_name'] = repo_name |
|
39 | match_dict['repo_name'] = repo_name | |
40 | except: |
|
40 | except: | |
41 | pass |
|
41 | pass | |
42 |
|
42 | |||
43 | return is_valid_repo(repo_name, config['base_path']) |
|
43 | return is_valid_repo(repo_name, config['base_path']) | |
44 |
|
44 | |||
45 | def check_group(environ, match_dict): |
|
45 | def check_group(environ, match_dict): | |
46 | """ |
|
46 | """ | |
47 | check for valid repositories group for proper 404 handling |
|
47 | check for valid repositories group for proper 404 handling | |
48 |
|
48 | |||
49 | :param environ: |
|
49 | :param environ: | |
50 | :param match_dict: |
|
50 | :param match_dict: | |
51 | """ |
|
51 | """ | |
52 | repos_group_name = match_dict.get('group_name') |
|
52 | repos_group_name = match_dict.get('group_name') | |
53 |
|
53 | |||
54 | return is_valid_repos_group(repos_group_name, config['base_path']) |
|
54 | return is_valid_repos_group(repos_group_name, config['base_path']) | |
55 |
|
55 | |||
56 | def check_int(environ, match_dict): |
|
56 | def check_int(environ, match_dict): | |
57 | return match_dict.get('id').isdigit() |
|
57 | return match_dict.get('id').isdigit() | |
58 |
|
58 | |||
59 | # The ErrorController route (handles 404/500 error pages); it should |
|
59 | # The ErrorController route (handles 404/500 error pages); it should | |
60 | # likely stay at the top, ensuring it can always be resolved |
|
60 | # likely stay at the top, ensuring it can always be resolved | |
61 | rmap.connect('/error/{action}', controller='error') |
|
61 | rmap.connect('/error/{action}', controller='error') | |
62 | rmap.connect('/error/{action}/{id}', controller='error') |
|
62 | rmap.connect('/error/{action}/{id}', controller='error') | |
63 |
|
63 | |||
64 | #========================================================================== |
|
64 | #========================================================================== | |
65 | # CUSTOM ROUTES HERE |
|
65 | # CUSTOM ROUTES HERE | |
66 | #========================================================================== |
|
66 | #========================================================================== | |
67 |
|
67 | |||
68 | #MAIN PAGE |
|
68 | #MAIN PAGE | |
69 | rmap.connect('home', '/', controller='home', action='index') |
|
69 | rmap.connect('home', '/', controller='home', action='index') | |
70 | rmap.connect('repo_switcher', '/repos', controller='home', |
|
70 | rmap.connect('repo_switcher', '/repos', controller='home', | |
71 | action='repo_switcher') |
|
71 | action='repo_switcher') | |
72 | rmap.connect('branch_tag_switcher', '/branches-tags/{repo_name:.*}', |
|
72 | rmap.connect('branch_tag_switcher', '/branches-tags/{repo_name:.*}', | |
73 | controller='home', action='branch_tag_switcher') |
|
73 | controller='home', action='branch_tag_switcher') | |
74 | rmap.connect('bugtracker', |
|
74 | rmap.connect('bugtracker', | |
75 | "http://bitbucket.org/marcinkuzminski/rhodecode/issues", |
|
75 | "http://bitbucket.org/marcinkuzminski/rhodecode/issues", | |
76 | _static=True) |
|
76 | _static=True) | |
77 | rmap.connect('rst_help', |
|
77 | rmap.connect('rst_help', | |
78 | "http://docutils.sourceforge.net/docs/user/rst/quickref.html", |
|
78 | "http://docutils.sourceforge.net/docs/user/rst/quickref.html", | |
79 | _static=True) |
|
79 | _static=True) | |
80 | rmap.connect('rhodecode_official', "http://rhodecode.org", _static=True) |
|
80 | rmap.connect('rhodecode_official', "http://rhodecode.org", _static=True) | |
81 |
|
81 | |||
82 | #ADMIN REPOSITORY REST ROUTES |
|
82 | #ADMIN REPOSITORY REST ROUTES | |
83 | with rmap.submapper(path_prefix=ADMIN_PREFIX, |
|
83 | with rmap.submapper(path_prefix=ADMIN_PREFIX, | |
84 | controller='admin/repos') as m: |
|
84 | controller='admin/repos') as m: | |
85 | m.connect("repos", "/repos", |
|
85 | m.connect("repos", "/repos", | |
86 | action="create", conditions=dict(method=["POST"])) |
|
86 | action="create", conditions=dict(method=["POST"])) | |
87 | m.connect("repos", "/repos", |
|
87 | m.connect("repos", "/repos", | |
88 | action="index", conditions=dict(method=["GET"])) |
|
88 | action="index", conditions=dict(method=["GET"])) | |
89 | m.connect("formatted_repos", "/repos.{format}", |
|
89 | m.connect("formatted_repos", "/repos.{format}", | |
90 | action="index", |
|
90 | action="index", | |
91 | conditions=dict(method=["GET"])) |
|
91 | conditions=dict(method=["GET"])) | |
92 | m.connect("new_repo", "/repos/new", |
|
92 | m.connect("new_repo", "/repos/new", | |
93 | action="new", conditions=dict(method=["GET"])) |
|
93 | action="new", conditions=dict(method=["GET"])) | |
94 | m.connect("formatted_new_repo", "/repos/new.{format}", |
|
94 | m.connect("formatted_new_repo", "/repos/new.{format}", | |
95 | action="new", conditions=dict(method=["GET"])) |
|
95 | action="new", conditions=dict(method=["GET"])) | |
96 | m.connect("/repos/{repo_name:.*}", |
|
96 | m.connect("/repos/{repo_name:.*}", | |
97 | action="update", conditions=dict(method=["PUT"], |
|
97 | action="update", conditions=dict(method=["PUT"], | |
98 | function=check_repo)) |
|
98 | function=check_repo)) | |
99 | m.connect("/repos/{repo_name:.*}", |
|
99 | m.connect("/repos/{repo_name:.*}", | |
100 | action="delete", conditions=dict(method=["DELETE"], |
|
100 | action="delete", conditions=dict(method=["DELETE"], | |
101 | function=check_repo)) |
|
101 | function=check_repo)) | |
102 | m.connect("edit_repo", "/repos/{repo_name:.*}/edit", |
|
102 | m.connect("edit_repo", "/repos/{repo_name:.*}/edit", | |
103 | action="edit", conditions=dict(method=["GET"], |
|
103 | action="edit", conditions=dict(method=["GET"], | |
104 | function=check_repo)) |
|
104 | function=check_repo)) | |
105 | m.connect("formatted_edit_repo", "/repos/{repo_name:.*}.{format}/edit", |
|
105 | m.connect("formatted_edit_repo", "/repos/{repo_name:.*}.{format}/edit", | |
106 | action="edit", conditions=dict(method=["GET"], |
|
106 | action="edit", conditions=dict(method=["GET"], | |
107 | function=check_repo)) |
|
107 | function=check_repo)) | |
108 | m.connect("repo", "/repos/{repo_name:.*}", |
|
108 | m.connect("repo", "/repos/{repo_name:.*}", | |
109 | action="show", conditions=dict(method=["GET"], |
|
109 | action="show", conditions=dict(method=["GET"], | |
110 | function=check_repo)) |
|
110 | function=check_repo)) | |
111 | m.connect("formatted_repo", "/repos/{repo_name:.*}.{format}", |
|
111 | m.connect("formatted_repo", "/repos/{repo_name:.*}.{format}", | |
112 | action="show", conditions=dict(method=["GET"], |
|
112 | action="show", conditions=dict(method=["GET"], | |
113 | function=check_repo)) |
|
113 | function=check_repo)) | |
114 | #ajax delete repo perm user |
|
114 | #ajax delete repo perm user | |
115 | m.connect('delete_repo_user', "/repos_delete_user/{repo_name:.*}", |
|
115 | m.connect('delete_repo_user', "/repos_delete_user/{repo_name:.*}", | |
116 | action="delete_perm_user", |
|
116 | action="delete_perm_user", | |
117 | conditions=dict(method=["DELETE"], function=check_repo)) |
|
117 | conditions=dict(method=["DELETE"], function=check_repo)) | |
118 |
|
118 | |||
119 | #ajax delete repo perm users_group |
|
119 | #ajax delete repo perm users_group | |
120 | m.connect('delete_repo_users_group', |
|
120 | m.connect('delete_repo_users_group', | |
121 | "/repos_delete_users_group/{repo_name:.*}", |
|
121 | "/repos_delete_users_group/{repo_name:.*}", | |
122 | action="delete_perm_users_group", |
|
122 | action="delete_perm_users_group", | |
123 | conditions=dict(method=["DELETE"], function=check_repo)) |
|
123 | conditions=dict(method=["DELETE"], function=check_repo)) | |
124 |
|
124 | |||
125 | #settings actions |
|
125 | #settings actions | |
126 | m.connect('repo_stats', "/repos_stats/{repo_name:.*}", |
|
126 | m.connect('repo_stats', "/repos_stats/{repo_name:.*}", | |
127 | action="repo_stats", conditions=dict(method=["DELETE"], |
|
127 | action="repo_stats", conditions=dict(method=["DELETE"], | |
128 | function=check_repo)) |
|
128 | function=check_repo)) | |
129 | m.connect('repo_cache', "/repos_cache/{repo_name:.*}", |
|
129 | m.connect('repo_cache', "/repos_cache/{repo_name:.*}", | |
130 | action="repo_cache", conditions=dict(method=["DELETE"], |
|
130 | action="repo_cache", conditions=dict(method=["DELETE"], | |
131 | function=check_repo)) |
|
131 | function=check_repo)) | |
132 | m.connect('repo_public_journal', "/repos_public_journal/{repo_name:.*}", |
|
132 | m.connect('repo_public_journal', "/repos_public_journal/{repo_name:.*}", | |
133 | action="repo_public_journal", conditions=dict(method=["PUT"], |
|
133 | action="repo_public_journal", conditions=dict(method=["PUT"], | |
134 | function=check_repo)) |
|
134 | function=check_repo)) | |
135 | m.connect('repo_pull', "/repo_pull/{repo_name:.*}", |
|
135 | m.connect('repo_pull', "/repo_pull/{repo_name:.*}", | |
136 | action="repo_pull", conditions=dict(method=["PUT"], |
|
136 | action="repo_pull", conditions=dict(method=["PUT"], | |
137 | function=check_repo)) |
|
137 | function=check_repo)) | |
138 | m.connect('repo_as_fork', "/repo_as_fork/{repo_name:.*}", |
|
138 | m.connect('repo_as_fork', "/repo_as_fork/{repo_name:.*}", | |
139 | action="repo_as_fork", conditions=dict(method=["PUT"], |
|
139 | action="repo_as_fork", conditions=dict(method=["PUT"], | |
140 | function=check_repo)) |
|
140 | function=check_repo)) | |
141 |
|
141 | |||
142 | with rmap.submapper(path_prefix=ADMIN_PREFIX, |
|
142 | with rmap.submapper(path_prefix=ADMIN_PREFIX, | |
143 | controller='admin/repos_groups') as m: |
|
143 | controller='admin/repos_groups') as m: | |
144 | m.connect("repos_groups", "/repos_groups", |
|
144 | m.connect("repos_groups", "/repos_groups", | |
145 | action="create", conditions=dict(method=["POST"])) |
|
145 | action="create", conditions=dict(method=["POST"])) | |
146 | m.connect("repos_groups", "/repos_groups", |
|
146 | m.connect("repos_groups", "/repos_groups", | |
147 | action="index", conditions=dict(method=["GET"])) |
|
147 | action="index", conditions=dict(method=["GET"])) | |
148 | m.connect("formatted_repos_groups", "/repos_groups.{format}", |
|
148 | m.connect("formatted_repos_groups", "/repos_groups.{format}", | |
149 | action="index", conditions=dict(method=["GET"])) |
|
149 | action="index", conditions=dict(method=["GET"])) | |
150 | m.connect("new_repos_group", "/repos_groups/new", |
|
150 | m.connect("new_repos_group", "/repos_groups/new", | |
151 | action="new", conditions=dict(method=["GET"])) |
|
151 | action="new", conditions=dict(method=["GET"])) | |
152 | m.connect("formatted_new_repos_group", "/repos_groups/new.{format}", |
|
152 | m.connect("formatted_new_repos_group", "/repos_groups/new.{format}", | |
153 | action="new", conditions=dict(method=["GET"])) |
|
153 | action="new", conditions=dict(method=["GET"])) | |
154 | m.connect("update_repos_group", "/repos_groups/{id}", |
|
154 | m.connect("update_repos_group", "/repos_groups/{id}", | |
155 | action="update", conditions=dict(method=["PUT"], |
|
155 | action="update", conditions=dict(method=["PUT"], | |
156 | function=check_int)) |
|
156 | function=check_int)) | |
157 | m.connect("delete_repos_group", "/repos_groups/{id}", |
|
157 | m.connect("delete_repos_group", "/repos_groups/{id}", | |
158 | action="delete", conditions=dict(method=["DELETE"], |
|
158 | action="delete", conditions=dict(method=["DELETE"], | |
159 | function=check_int)) |
|
159 | function=check_int)) | |
160 | m.connect("edit_repos_group", "/repos_groups/{id}/edit", |
|
160 | m.connect("edit_repos_group", "/repos_groups/{id}/edit", | |
161 | action="edit", conditions=dict(method=["GET"], |
|
161 | action="edit", conditions=dict(method=["GET"],)) | |
162 | function=check_int)) |
|
|||
163 | m.connect("formatted_edit_repos_group", |
|
162 | m.connect("formatted_edit_repos_group", | |
164 | "/repos_groups/{id}.{format}/edit", |
|
163 | "/repos_groups/{id}.{format}/edit", | |
165 | action="edit", conditions=dict(method=["GET"], |
|
164 | action="edit", conditions=dict(method=["GET"], | |
166 | function=check_int)) |
|
165 | function=check_int)) | |
167 | m.connect("repos_group", "/repos_groups/{id}", |
|
166 | m.connect("repos_group", "/repos_groups/{id}", | |
168 | action="show", conditions=dict(method=["GET"], |
|
167 | action="show", conditions=dict(method=["GET"], | |
169 | function=check_int)) |
|
168 | function=check_int)) | |
170 | m.connect("formatted_repos_group", "/repos_groups/{id}.{format}", |
|
169 | m.connect("formatted_repos_group", "/repos_groups/{id}.{format}", | |
171 | action="show", conditions=dict(method=["GET"], |
|
170 | action="show", conditions=dict(method=["GET"], | |
172 | function=check_int)) |
|
171 | function=check_int)) | |
173 | # ajax delete repos group perm user |
|
172 | # ajax delete repos group perm user | |
174 | m.connect('delete_repos_group_user_perm', |
|
173 | m.connect('delete_repos_group_user_perm', | |
175 | "/delete_repos_group_user_perm/{group_name:.*}", |
|
174 | "/delete_repos_group_user_perm/{group_name:.*}", | |
176 | action="delete_repos_group_user_perm", |
|
175 | action="delete_repos_group_user_perm", | |
177 | conditions=dict(method=["DELETE"], function=check_group)) |
|
176 | conditions=dict(method=["DELETE"], function=check_group)) | |
178 |
|
177 | |||
179 | # ajax delete repos group perm users_group |
|
178 | # ajax delete repos group perm users_group | |
180 | m.connect('delete_repos_group_users_group_perm', |
|
179 | m.connect('delete_repos_group_users_group_perm', | |
181 | "/delete_repos_group_users_group_perm/{group_name:.*}", |
|
180 | "/delete_repos_group_users_group_perm/{group_name:.*}", | |
182 | action="delete_repos_group_users_group_perm", |
|
181 | action="delete_repos_group_users_group_perm", | |
183 | conditions=dict(method=["DELETE"], function=check_group)) |
|
182 | conditions=dict(method=["DELETE"], function=check_group)) | |
184 |
|
183 | |||
185 | #ADMIN USER REST ROUTES |
|
184 | #ADMIN USER REST ROUTES | |
186 | with rmap.submapper(path_prefix=ADMIN_PREFIX, |
|
185 | with rmap.submapper(path_prefix=ADMIN_PREFIX, | |
187 | controller='admin/users') as m: |
|
186 | controller='admin/users') as m: | |
188 | m.connect("users", "/users", |
|
187 | m.connect("users", "/users", | |
189 | action="create", conditions=dict(method=["POST"])) |
|
188 | action="create", conditions=dict(method=["POST"])) | |
190 | m.connect("users", "/users", |
|
189 | m.connect("users", "/users", | |
191 | action="index", conditions=dict(method=["GET"])) |
|
190 | action="index", conditions=dict(method=["GET"])) | |
192 | m.connect("formatted_users", "/users.{format}", |
|
191 | m.connect("formatted_users", "/users.{format}", | |
193 | action="index", conditions=dict(method=["GET"])) |
|
192 | action="index", conditions=dict(method=["GET"])) | |
194 | m.connect("new_user", "/users/new", |
|
193 | m.connect("new_user", "/users/new", | |
195 | action="new", conditions=dict(method=["GET"])) |
|
194 | action="new", conditions=dict(method=["GET"])) | |
196 | m.connect("formatted_new_user", "/users/new.{format}", |
|
195 | m.connect("formatted_new_user", "/users/new.{format}", | |
197 | action="new", conditions=dict(method=["GET"])) |
|
196 | action="new", conditions=dict(method=["GET"])) | |
198 | m.connect("update_user", "/users/{id}", |
|
197 | m.connect("update_user", "/users/{id}", | |
199 | action="update", conditions=dict(method=["PUT"])) |
|
198 | action="update", conditions=dict(method=["PUT"])) | |
200 | m.connect("delete_user", "/users/{id}", |
|
199 | m.connect("delete_user", "/users/{id}", | |
201 | action="delete", conditions=dict(method=["DELETE"])) |
|
200 | action="delete", conditions=dict(method=["DELETE"])) | |
202 | m.connect("edit_user", "/users/{id}/edit", |
|
201 | m.connect("edit_user", "/users/{id}/edit", | |
203 | action="edit", conditions=dict(method=["GET"])) |
|
202 | action="edit", conditions=dict(method=["GET"])) | |
204 | m.connect("formatted_edit_user", |
|
203 | m.connect("formatted_edit_user", | |
205 | "/users/{id}.{format}/edit", |
|
204 | "/users/{id}.{format}/edit", | |
206 | action="edit", conditions=dict(method=["GET"])) |
|
205 | action="edit", conditions=dict(method=["GET"])) | |
207 | m.connect("user", "/users/{id}", |
|
206 | m.connect("user", "/users/{id}", | |
208 | action="show", conditions=dict(method=["GET"])) |
|
207 | action="show", conditions=dict(method=["GET"])) | |
209 | m.connect("formatted_user", "/users/{id}.{format}", |
|
208 | m.connect("formatted_user", "/users/{id}.{format}", | |
210 | action="show", conditions=dict(method=["GET"])) |
|
209 | action="show", conditions=dict(method=["GET"])) | |
211 |
|
210 | |||
212 | #EXTRAS USER ROUTES |
|
211 | #EXTRAS USER ROUTES | |
213 | m.connect("user_perm", "/users_perm/{id}", |
|
212 | m.connect("user_perm", "/users_perm/{id}", | |
214 | action="update_perm", conditions=dict(method=["PUT"])) |
|
213 | action="update_perm", conditions=dict(method=["PUT"])) | |
215 | m.connect("user_emails", "/users_emails/{id}", |
|
214 | m.connect("user_emails", "/users_emails/{id}", | |
216 | action="add_email", conditions=dict(method=["PUT"])) |
|
215 | action="add_email", conditions=dict(method=["PUT"])) | |
217 | m.connect("user_emails_delete", "/users_emails/{id}", |
|
216 | m.connect("user_emails_delete", "/users_emails/{id}", | |
218 | action="delete_email", conditions=dict(method=["DELETE"])) |
|
217 | action="delete_email", conditions=dict(method=["DELETE"])) | |
219 |
|
218 | |||
220 | #ADMIN USERS GROUPS REST ROUTES |
|
219 | #ADMIN USERS GROUPS REST ROUTES | |
221 | with rmap.submapper(path_prefix=ADMIN_PREFIX, |
|
220 | with rmap.submapper(path_prefix=ADMIN_PREFIX, | |
222 | controller='admin/users_groups') as m: |
|
221 | controller='admin/users_groups') as m: | |
223 | m.connect("users_groups", "/users_groups", |
|
222 | m.connect("users_groups", "/users_groups", | |
224 | action="create", conditions=dict(method=["POST"])) |
|
223 | action="create", conditions=dict(method=["POST"])) | |
225 | m.connect("users_groups", "/users_groups", |
|
224 | m.connect("users_groups", "/users_groups", | |
226 | action="index", conditions=dict(method=["GET"])) |
|
225 | action="index", conditions=dict(method=["GET"])) | |
227 | m.connect("formatted_users_groups", "/users_groups.{format}", |
|
226 | m.connect("formatted_users_groups", "/users_groups.{format}", | |
228 | action="index", conditions=dict(method=["GET"])) |
|
227 | action="index", conditions=dict(method=["GET"])) | |
229 | m.connect("new_users_group", "/users_groups/new", |
|
228 | m.connect("new_users_group", "/users_groups/new", | |
230 | action="new", conditions=dict(method=["GET"])) |
|
229 | action="new", conditions=dict(method=["GET"])) | |
231 | m.connect("formatted_new_users_group", "/users_groups/new.{format}", |
|
230 | m.connect("formatted_new_users_group", "/users_groups/new.{format}", | |
232 | action="new", conditions=dict(method=["GET"])) |
|
231 | action="new", conditions=dict(method=["GET"])) | |
233 | m.connect("update_users_group", "/users_groups/{id}", |
|
232 | m.connect("update_users_group", "/users_groups/{id}", | |
234 | action="update", conditions=dict(method=["PUT"])) |
|
233 | action="update", conditions=dict(method=["PUT"])) | |
235 | m.connect("delete_users_group", "/users_groups/{id}", |
|
234 | m.connect("delete_users_group", "/users_groups/{id}", | |
236 | action="delete", conditions=dict(method=["DELETE"])) |
|
235 | action="delete", conditions=dict(method=["DELETE"])) | |
237 | m.connect("edit_users_group", "/users_groups/{id}/edit", |
|
236 | m.connect("edit_users_group", "/users_groups/{id}/edit", | |
238 | action="edit", conditions=dict(method=["GET"])) |
|
237 | action="edit", conditions=dict(method=["GET"])) | |
239 | m.connect("formatted_edit_users_group", |
|
238 | m.connect("formatted_edit_users_group", | |
240 | "/users_groups/{id}.{format}/edit", |
|
239 | "/users_groups/{id}.{format}/edit", | |
241 | action="edit", conditions=dict(method=["GET"])) |
|
240 | action="edit", conditions=dict(method=["GET"])) | |
242 | m.connect("users_group", "/users_groups/{id}", |
|
241 | m.connect("users_group", "/users_groups/{id}", | |
243 | action="show", conditions=dict(method=["GET"])) |
|
242 | action="show", conditions=dict(method=["GET"])) | |
244 | m.connect("formatted_users_group", "/users_groups/{id}.{format}", |
|
243 | m.connect("formatted_users_group", "/users_groups/{id}.{format}", | |
245 | action="show", conditions=dict(method=["GET"])) |
|
244 | action="show", conditions=dict(method=["GET"])) | |
246 |
|
245 | |||
247 | #EXTRAS USER ROUTES |
|
246 | #EXTRAS USER ROUTES | |
248 | m.connect("users_group_perm", "/users_groups_perm/{id}", |
|
247 | m.connect("users_group_perm", "/users_groups_perm/{id}", | |
249 | action="update_perm", conditions=dict(method=["PUT"])) |
|
248 | action="update_perm", conditions=dict(method=["PUT"])) | |
250 |
|
249 | |||
251 | #ADMIN GROUP REST ROUTES |
|
250 | #ADMIN GROUP REST ROUTES | |
252 | rmap.resource('group', 'groups', |
|
251 | rmap.resource('group', 'groups', | |
253 | controller='admin/groups', path_prefix=ADMIN_PREFIX) |
|
252 | controller='admin/groups', path_prefix=ADMIN_PREFIX) | |
254 |
|
253 | |||
255 | #ADMIN PERMISSIONS REST ROUTES |
|
254 | #ADMIN PERMISSIONS REST ROUTES | |
256 | rmap.resource('permission', 'permissions', |
|
255 | rmap.resource('permission', 'permissions', | |
257 | controller='admin/permissions', path_prefix=ADMIN_PREFIX) |
|
256 | controller='admin/permissions', path_prefix=ADMIN_PREFIX) | |
258 |
|
257 | |||
259 | ##ADMIN LDAP SETTINGS |
|
258 | ##ADMIN LDAP SETTINGS | |
260 | rmap.connect('ldap_settings', '%s/ldap' % ADMIN_PREFIX, |
|
259 | rmap.connect('ldap_settings', '%s/ldap' % ADMIN_PREFIX, | |
261 | controller='admin/ldap_settings', action='ldap_settings', |
|
260 | controller='admin/ldap_settings', action='ldap_settings', | |
262 | conditions=dict(method=["POST"])) |
|
261 | conditions=dict(method=["POST"])) | |
263 |
|
262 | |||
264 | rmap.connect('ldap_home', '%s/ldap' % ADMIN_PREFIX, |
|
263 | rmap.connect('ldap_home', '%s/ldap' % ADMIN_PREFIX, | |
265 | controller='admin/ldap_settings') |
|
264 | controller='admin/ldap_settings') | |
266 |
|
265 | |||
267 | #ADMIN SETTINGS REST ROUTES |
|
266 | #ADMIN SETTINGS REST ROUTES | |
268 | with rmap.submapper(path_prefix=ADMIN_PREFIX, |
|
267 | with rmap.submapper(path_prefix=ADMIN_PREFIX, | |
269 | controller='admin/settings') as m: |
|
268 | controller='admin/settings') as m: | |
270 | m.connect("admin_settings", "/settings", |
|
269 | m.connect("admin_settings", "/settings", | |
271 | action="create", conditions=dict(method=["POST"])) |
|
270 | action="create", conditions=dict(method=["POST"])) | |
272 | m.connect("admin_settings", "/settings", |
|
271 | m.connect("admin_settings", "/settings", | |
273 | action="index", conditions=dict(method=["GET"])) |
|
272 | action="index", conditions=dict(method=["GET"])) | |
274 | m.connect("formatted_admin_settings", "/settings.{format}", |
|
273 | m.connect("formatted_admin_settings", "/settings.{format}", | |
275 | action="index", conditions=dict(method=["GET"])) |
|
274 | action="index", conditions=dict(method=["GET"])) | |
276 | m.connect("admin_new_setting", "/settings/new", |
|
275 | m.connect("admin_new_setting", "/settings/new", | |
277 | action="new", conditions=dict(method=["GET"])) |
|
276 | action="new", conditions=dict(method=["GET"])) | |
278 | m.connect("formatted_admin_new_setting", "/settings/new.{format}", |
|
277 | m.connect("formatted_admin_new_setting", "/settings/new.{format}", | |
279 | action="new", conditions=dict(method=["GET"])) |
|
278 | action="new", conditions=dict(method=["GET"])) | |
280 | m.connect("/settings/{setting_id}", |
|
279 | m.connect("/settings/{setting_id}", | |
281 | action="update", conditions=dict(method=["PUT"])) |
|
280 | action="update", conditions=dict(method=["PUT"])) | |
282 | m.connect("/settings/{setting_id}", |
|
281 | m.connect("/settings/{setting_id}", | |
283 | action="delete", conditions=dict(method=["DELETE"])) |
|
282 | action="delete", conditions=dict(method=["DELETE"])) | |
284 | m.connect("admin_edit_setting", "/settings/{setting_id}/edit", |
|
283 | m.connect("admin_edit_setting", "/settings/{setting_id}/edit", | |
285 | action="edit", conditions=dict(method=["GET"])) |
|
284 | action="edit", conditions=dict(method=["GET"])) | |
286 | m.connect("formatted_admin_edit_setting", |
|
285 | m.connect("formatted_admin_edit_setting", | |
287 | "/settings/{setting_id}.{format}/edit", |
|
286 | "/settings/{setting_id}.{format}/edit", | |
288 | action="edit", conditions=dict(method=["GET"])) |
|
287 | action="edit", conditions=dict(method=["GET"])) | |
289 | m.connect("admin_setting", "/settings/{setting_id}", |
|
288 | m.connect("admin_setting", "/settings/{setting_id}", | |
290 | action="show", conditions=dict(method=["GET"])) |
|
289 | action="show", conditions=dict(method=["GET"])) | |
291 | m.connect("formatted_admin_setting", "/settings/{setting_id}.{format}", |
|
290 | m.connect("formatted_admin_setting", "/settings/{setting_id}.{format}", | |
292 | action="show", conditions=dict(method=["GET"])) |
|
291 | action="show", conditions=dict(method=["GET"])) | |
293 | m.connect("admin_settings_my_account", "/my_account", |
|
292 | m.connect("admin_settings_my_account", "/my_account", | |
294 | action="my_account", conditions=dict(method=["GET"])) |
|
293 | action="my_account", conditions=dict(method=["GET"])) | |
295 | m.connect("admin_settings_my_account_update", "/my_account_update", |
|
294 | m.connect("admin_settings_my_account_update", "/my_account_update", | |
296 | action="my_account_update", conditions=dict(method=["PUT"])) |
|
295 | action="my_account_update", conditions=dict(method=["PUT"])) | |
297 | m.connect("admin_settings_create_repository", "/create_repository", |
|
296 | m.connect("admin_settings_create_repository", "/create_repository", | |
298 | action="create_repository", conditions=dict(method=["GET"])) |
|
297 | action="create_repository", conditions=dict(method=["GET"])) | |
299 | m.connect("admin_settings_my_repos", "/my_account/repos", |
|
298 | m.connect("admin_settings_my_repos", "/my_account/repos", | |
300 | action="my_account_my_repos", conditions=dict(method=["GET"])) |
|
299 | action="my_account_my_repos", conditions=dict(method=["GET"])) | |
301 | m.connect("admin_settings_my_pullrequests", "/my_account/pull_requests", |
|
300 | m.connect("admin_settings_my_pullrequests", "/my_account/pull_requests", | |
302 | action="my_account_my_pullrequests", conditions=dict(method=["GET"])) |
|
301 | action="my_account_my_pullrequests", conditions=dict(method=["GET"])) | |
303 |
|
302 | |||
304 |
|
303 | |||
305 | #NOTIFICATION REST ROUTES |
|
304 | #NOTIFICATION REST ROUTES | |
306 | with rmap.submapper(path_prefix=ADMIN_PREFIX, |
|
305 | with rmap.submapper(path_prefix=ADMIN_PREFIX, | |
307 | controller='admin/notifications') as m: |
|
306 | controller='admin/notifications') as m: | |
308 | m.connect("notifications", "/notifications", |
|
307 | m.connect("notifications", "/notifications", | |
309 | action="create", conditions=dict(method=["POST"])) |
|
308 | action="create", conditions=dict(method=["POST"])) | |
310 | m.connect("notifications", "/notifications", |
|
309 | m.connect("notifications", "/notifications", | |
311 | action="index", conditions=dict(method=["GET"])) |
|
310 | action="index", conditions=dict(method=["GET"])) | |
312 | m.connect("notifications_mark_all_read", "/notifications/mark_all_read", |
|
311 | m.connect("notifications_mark_all_read", "/notifications/mark_all_read", | |
313 | action="mark_all_read", conditions=dict(method=["GET"])) |
|
312 | action="mark_all_read", conditions=dict(method=["GET"])) | |
314 | m.connect("formatted_notifications", "/notifications.{format}", |
|
313 | m.connect("formatted_notifications", "/notifications.{format}", | |
315 | action="index", conditions=dict(method=["GET"])) |
|
314 | action="index", conditions=dict(method=["GET"])) | |
316 | m.connect("new_notification", "/notifications/new", |
|
315 | m.connect("new_notification", "/notifications/new", | |
317 | action="new", conditions=dict(method=["GET"])) |
|
316 | action="new", conditions=dict(method=["GET"])) | |
318 | m.connect("formatted_new_notification", "/notifications/new.{format}", |
|
317 | m.connect("formatted_new_notification", "/notifications/new.{format}", | |
319 | action="new", conditions=dict(method=["GET"])) |
|
318 | action="new", conditions=dict(method=["GET"])) | |
320 | m.connect("/notification/{notification_id}", |
|
319 | m.connect("/notification/{notification_id}", | |
321 | action="update", conditions=dict(method=["PUT"])) |
|
320 | action="update", conditions=dict(method=["PUT"])) | |
322 | m.connect("/notification/{notification_id}", |
|
321 | m.connect("/notification/{notification_id}", | |
323 | action="delete", conditions=dict(method=["DELETE"])) |
|
322 | action="delete", conditions=dict(method=["DELETE"])) | |
324 | m.connect("edit_notification", "/notification/{notification_id}/edit", |
|
323 | m.connect("edit_notification", "/notification/{notification_id}/edit", | |
325 | action="edit", conditions=dict(method=["GET"])) |
|
324 | action="edit", conditions=dict(method=["GET"])) | |
326 | m.connect("formatted_edit_notification", |
|
325 | m.connect("formatted_edit_notification", | |
327 | "/notification/{notification_id}.{format}/edit", |
|
326 | "/notification/{notification_id}.{format}/edit", | |
328 | action="edit", conditions=dict(method=["GET"])) |
|
327 | action="edit", conditions=dict(method=["GET"])) | |
329 | m.connect("notification", "/notification/{notification_id}", |
|
328 | m.connect("notification", "/notification/{notification_id}", | |
330 | action="show", conditions=dict(method=["GET"])) |
|
329 | action="show", conditions=dict(method=["GET"])) | |
331 | m.connect("formatted_notification", "/notifications/{notification_id}.{format}", |
|
330 | m.connect("formatted_notification", "/notifications/{notification_id}.{format}", | |
332 | action="show", conditions=dict(method=["GET"])) |
|
331 | action="show", conditions=dict(method=["GET"])) | |
333 |
|
332 | |||
334 | #ADMIN MAIN PAGES |
|
333 | #ADMIN MAIN PAGES | |
335 | with rmap.submapper(path_prefix=ADMIN_PREFIX, |
|
334 | with rmap.submapper(path_prefix=ADMIN_PREFIX, | |
336 | controller='admin/admin') as m: |
|
335 | controller='admin/admin') as m: | |
337 | m.connect('admin_home', '', action='index') |
|
336 | m.connect('admin_home', '', action='index') | |
338 | m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}', |
|
337 | m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}', | |
339 | action='add_repo') |
|
338 | action='add_repo') | |
340 |
|
339 | |||
341 | #========================================================================== |
|
340 | #========================================================================== | |
342 | # API V2 |
|
341 | # API V2 | |
343 | #========================================================================== |
|
342 | #========================================================================== | |
344 | with rmap.submapper(path_prefix=ADMIN_PREFIX, |
|
343 | with rmap.submapper(path_prefix=ADMIN_PREFIX, | |
345 | controller='api/api') as m: |
|
344 | controller='api/api') as m: | |
346 | m.connect('api', '/api') |
|
345 | m.connect('api', '/api') | |
347 |
|
346 | |||
348 | #USER JOURNAL |
|
347 | #USER JOURNAL | |
349 | rmap.connect('journal', '%s/journal' % ADMIN_PREFIX, |
|
348 | rmap.connect('journal', '%s/journal' % ADMIN_PREFIX, | |
350 | controller='journal', action='index') |
|
349 | controller='journal', action='index') | |
351 | rmap.connect('journal_rss', '%s/journal/rss' % ADMIN_PREFIX, |
|
350 | rmap.connect('journal_rss', '%s/journal/rss' % ADMIN_PREFIX, | |
352 | controller='journal', action='journal_rss') |
|
351 | controller='journal', action='journal_rss') | |
353 | rmap.connect('journal_atom', '%s/journal/atom' % ADMIN_PREFIX, |
|
352 | rmap.connect('journal_atom', '%s/journal/atom' % ADMIN_PREFIX, | |
354 | controller='journal', action='journal_atom') |
|
353 | controller='journal', action='journal_atom') | |
355 |
|
354 | |||
356 | rmap.connect('public_journal', '%s/public_journal' % ADMIN_PREFIX, |
|
355 | rmap.connect('public_journal', '%s/public_journal' % ADMIN_PREFIX, | |
357 | controller='journal', action="public_journal") |
|
356 | controller='journal', action="public_journal") | |
358 |
|
357 | |||
359 | rmap.connect('public_journal_rss', '%s/public_journal/rss' % ADMIN_PREFIX, |
|
358 | rmap.connect('public_journal_rss', '%s/public_journal/rss' % ADMIN_PREFIX, | |
360 | controller='journal', action="public_journal_rss") |
|
359 | controller='journal', action="public_journal_rss") | |
361 |
|
360 | |||
362 | rmap.connect('public_journal_rss_old', '%s/public_journal_rss' % ADMIN_PREFIX, |
|
361 | rmap.connect('public_journal_rss_old', '%s/public_journal_rss' % ADMIN_PREFIX, | |
363 | controller='journal', action="public_journal_rss") |
|
362 | controller='journal', action="public_journal_rss") | |
364 |
|
363 | |||
365 | rmap.connect('public_journal_atom', |
|
364 | rmap.connect('public_journal_atom', | |
366 | '%s/public_journal/atom' % ADMIN_PREFIX, controller='journal', |
|
365 | '%s/public_journal/atom' % ADMIN_PREFIX, controller='journal', | |
367 | action="public_journal_atom") |
|
366 | action="public_journal_atom") | |
368 |
|
367 | |||
369 | rmap.connect('public_journal_atom_old', |
|
368 | rmap.connect('public_journal_atom_old', | |
370 | '%s/public_journal_atom' % ADMIN_PREFIX, controller='journal', |
|
369 | '%s/public_journal_atom' % ADMIN_PREFIX, controller='journal', | |
371 | action="public_journal_atom") |
|
370 | action="public_journal_atom") | |
372 |
|
371 | |||
373 | rmap.connect('toggle_following', '%s/toggle_following' % ADMIN_PREFIX, |
|
372 | rmap.connect('toggle_following', '%s/toggle_following' % ADMIN_PREFIX, | |
374 | controller='journal', action='toggle_following', |
|
373 | controller='journal', action='toggle_following', | |
375 | conditions=dict(method=["POST"])) |
|
374 | conditions=dict(method=["POST"])) | |
376 |
|
375 | |||
377 | #SEARCH |
|
376 | #SEARCH | |
378 | rmap.connect('search', '%s/search' % ADMIN_PREFIX, controller='search',) |
|
377 | rmap.connect('search', '%s/search' % ADMIN_PREFIX, controller='search',) | |
379 | rmap.connect('search_repo', '%s/search/{search_repo:.*}' % ADMIN_PREFIX, |
|
378 | rmap.connect('search_repo', '%s/search/{search_repo:.*}' % ADMIN_PREFIX, | |
380 | controller='search') |
|
379 | controller='search') | |
381 |
|
380 | |||
382 | #LOGIN/LOGOUT/REGISTER/SIGN IN |
|
381 | #LOGIN/LOGOUT/REGISTER/SIGN IN | |
383 | rmap.connect('login_home', '%s/login' % ADMIN_PREFIX, controller='login') |
|
382 | rmap.connect('login_home', '%s/login' % ADMIN_PREFIX, controller='login') | |
384 | rmap.connect('logout_home', '%s/logout' % ADMIN_PREFIX, controller='login', |
|
383 | rmap.connect('logout_home', '%s/logout' % ADMIN_PREFIX, controller='login', | |
385 | action='logout') |
|
384 | action='logout') | |
386 |
|
385 | |||
387 | rmap.connect('register', '%s/register' % ADMIN_PREFIX, controller='login', |
|
386 | rmap.connect('register', '%s/register' % ADMIN_PREFIX, controller='login', | |
388 | action='register') |
|
387 | action='register') | |
389 |
|
388 | |||
390 | rmap.connect('reset_password', '%s/password_reset' % ADMIN_PREFIX, |
|
389 | rmap.connect('reset_password', '%s/password_reset' % ADMIN_PREFIX, | |
391 | controller='login', action='password_reset') |
|
390 | controller='login', action='password_reset') | |
392 |
|
391 | |||
393 | rmap.connect('reset_password_confirmation', |
|
392 | rmap.connect('reset_password_confirmation', | |
394 | '%s/password_reset_confirmation' % ADMIN_PREFIX, |
|
393 | '%s/password_reset_confirmation' % ADMIN_PREFIX, | |
395 | controller='login', action='password_reset_confirmation') |
|
394 | controller='login', action='password_reset_confirmation') | |
396 |
|
395 | |||
397 | #FEEDS |
|
396 | #FEEDS | |
398 | rmap.connect('rss_feed_home', '/{repo_name:.*}/feed/rss', |
|
397 | rmap.connect('rss_feed_home', '/{repo_name:.*}/feed/rss', | |
399 | controller='feed', action='rss', |
|
398 | controller='feed', action='rss', | |
400 | conditions=dict(function=check_repo)) |
|
399 | conditions=dict(function=check_repo)) | |
401 |
|
400 | |||
402 | rmap.connect('atom_feed_home', '/{repo_name:.*}/feed/atom', |
|
401 | rmap.connect('atom_feed_home', '/{repo_name:.*}/feed/atom', | |
403 | controller='feed', action='atom', |
|
402 | controller='feed', action='atom', | |
404 | conditions=dict(function=check_repo)) |
|
403 | conditions=dict(function=check_repo)) | |
405 |
|
404 | |||
406 | #========================================================================== |
|
405 | #========================================================================== | |
407 | # REPOSITORY ROUTES |
|
406 | # REPOSITORY ROUTES | |
408 | #========================================================================== |
|
407 | #========================================================================== | |
409 | rmap.connect('summary_home', '/{repo_name:.*}', |
|
408 | rmap.connect('summary_home', '/{repo_name:.*}', | |
410 | controller='summary', |
|
409 | controller='summary', | |
411 | conditions=dict(function=check_repo)) |
|
410 | conditions=dict(function=check_repo)) | |
412 |
|
411 | |||
413 | rmap.connect('repos_group_home', '/{group_name:.*}', |
|
412 | rmap.connect('repos_group_home', '/{group_name:.*}', | |
414 | controller='admin/repos_groups', action="show_by_name", |
|
413 | controller='admin/repos_groups', action="show_by_name", | |
415 | conditions=dict(function=check_group)) |
|
414 | conditions=dict(function=check_group)) | |
416 |
|
415 | |||
417 | rmap.connect('changeset_home', '/{repo_name:.*}/changeset/{revision}', |
|
416 | rmap.connect('changeset_home', '/{repo_name:.*}/changeset/{revision}', | |
418 | controller='changeset', revision='tip', |
|
417 | controller='changeset', revision='tip', | |
419 | conditions=dict(function=check_repo)) |
|
418 | conditions=dict(function=check_repo)) | |
420 |
|
419 | |||
421 | rmap.connect('changeset_comment', |
|
420 | rmap.connect('changeset_comment', | |
422 | '/{repo_name:.*}/changeset/{revision}/comment', |
|
421 | '/{repo_name:.*}/changeset/{revision}/comment', | |
423 | controller='changeset', revision='tip', action='comment', |
|
422 | controller='changeset', revision='tip', action='comment', | |
424 | conditions=dict(function=check_repo)) |
|
423 | conditions=dict(function=check_repo)) | |
425 |
|
424 | |||
426 | rmap.connect('changeset_comment_delete', |
|
425 | rmap.connect('changeset_comment_delete', | |
427 | '/{repo_name:.*}/changeset/comment/{comment_id}/delete', |
|
426 | '/{repo_name:.*}/changeset/comment/{comment_id}/delete', | |
428 | controller='changeset', action='delete_comment', |
|
427 | controller='changeset', action='delete_comment', | |
429 | conditions=dict(function=check_repo, method=["DELETE"])) |
|
428 | conditions=dict(function=check_repo, method=["DELETE"])) | |
430 |
|
429 | |||
431 | rmap.connect('raw_changeset_home', |
|
430 | rmap.connect('raw_changeset_home', | |
432 | '/{repo_name:.*}/raw-changeset/{revision}', |
|
431 | '/{repo_name:.*}/raw-changeset/{revision}', | |
433 | controller='changeset', action='raw_changeset', |
|
432 | controller='changeset', action='raw_changeset', | |
434 | revision='tip', conditions=dict(function=check_repo)) |
|
433 | revision='tip', conditions=dict(function=check_repo)) | |
435 |
|
434 | |||
436 | rmap.connect('compare_url', |
|
435 | rmap.connect('compare_url', | |
437 | '/{repo_name:.*}/compare/{org_ref_type}@{org_ref}...{other_ref_type}@{other_ref}', |
|
436 | '/{repo_name:.*}/compare/{org_ref_type}@{org_ref}...{other_ref_type}@{other_ref}', | |
438 | controller='compare', action='index', |
|
437 | controller='compare', action='index', | |
439 | conditions=dict(function=check_repo), |
|
438 | conditions=dict(function=check_repo), | |
440 | requirements=dict(org_ref_type='(branch|book|tag|rev)', |
|
439 | requirements=dict(org_ref_type='(branch|book|tag|rev)', | |
441 | other_ref_type='(branch|book|tag|rev)')) |
|
440 | other_ref_type='(branch|book|tag|rev)')) | |
442 |
|
441 | |||
443 | rmap.connect('pullrequest_home', |
|
442 | rmap.connect('pullrequest_home', | |
444 | '/{repo_name:.*}/pull-request/new', controller='pullrequests', |
|
443 | '/{repo_name:.*}/pull-request/new', controller='pullrequests', | |
445 | action='index', conditions=dict(function=check_repo, |
|
444 | action='index', conditions=dict(function=check_repo, | |
446 | method=["GET"])) |
|
445 | method=["GET"])) | |
447 |
|
446 | |||
448 | rmap.connect('pullrequest', |
|
447 | rmap.connect('pullrequest', | |
449 | '/{repo_name:.*}/pull-request/new', controller='pullrequests', |
|
448 | '/{repo_name:.*}/pull-request/new', controller='pullrequests', | |
450 | action='create', conditions=dict(function=check_repo, |
|
449 | action='create', conditions=dict(function=check_repo, | |
451 | method=["POST"])) |
|
450 | method=["POST"])) | |
452 |
|
451 | |||
453 | rmap.connect('pullrequest_show', |
|
452 | rmap.connect('pullrequest_show', | |
454 | '/{repo_name:.*}/pull-request/{pull_request_id}', |
|
453 | '/{repo_name:.*}/pull-request/{pull_request_id}', | |
455 | controller='pullrequests', |
|
454 | controller='pullrequests', | |
456 | action='show', conditions=dict(function=check_repo, |
|
455 | action='show', conditions=dict(function=check_repo, | |
457 | method=["GET"])) |
|
456 | method=["GET"])) | |
458 | rmap.connect('pullrequest_update', |
|
457 | rmap.connect('pullrequest_update', | |
459 | '/{repo_name:.*}/pull-request/{pull_request_id}', |
|
458 | '/{repo_name:.*}/pull-request/{pull_request_id}', | |
460 | controller='pullrequests', |
|
459 | controller='pullrequests', | |
461 | action='update', conditions=dict(function=check_repo, |
|
460 | action='update', conditions=dict(function=check_repo, | |
462 | method=["PUT"])) |
|
461 | method=["PUT"])) | |
463 |
|
462 | |||
464 | rmap.connect('pullrequest_show_all', |
|
463 | rmap.connect('pullrequest_show_all', | |
465 | '/{repo_name:.*}/pull-request', |
|
464 | '/{repo_name:.*}/pull-request', | |
466 | controller='pullrequests', |
|
465 | controller='pullrequests', | |
467 | action='show_all', conditions=dict(function=check_repo, |
|
466 | action='show_all', conditions=dict(function=check_repo, | |
468 | method=["GET"])) |
|
467 | method=["GET"])) | |
469 |
|
468 | |||
470 | rmap.connect('pullrequest_comment', |
|
469 | rmap.connect('pullrequest_comment', | |
471 | '/{repo_name:.*}/pull-request-comment/{pull_request_id}', |
|
470 | '/{repo_name:.*}/pull-request-comment/{pull_request_id}', | |
472 | controller='pullrequests', |
|
471 | controller='pullrequests', | |
473 | action='comment', conditions=dict(function=check_repo, |
|
472 | action='comment', conditions=dict(function=check_repo, | |
474 | method=["POST"])) |
|
473 | method=["POST"])) | |
475 |
|
474 | |||
476 | rmap.connect('pullrequest_comment_delete', |
|
475 | rmap.connect('pullrequest_comment_delete', | |
477 | '/{repo_name:.*}/pull-request-comment/{comment_id}/delete', |
|
476 | '/{repo_name:.*}/pull-request-comment/{comment_id}/delete', | |
478 | controller='pullrequests', action='delete_comment', |
|
477 | controller='pullrequests', action='delete_comment', | |
479 | conditions=dict(function=check_repo, method=["DELETE"])) |
|
478 | conditions=dict(function=check_repo, method=["DELETE"])) | |
480 |
|
479 | |||
481 | rmap.connect('summary_home', '/{repo_name:.*}/summary', |
|
480 | rmap.connect('summary_home', '/{repo_name:.*}/summary', | |
482 | controller='summary', conditions=dict(function=check_repo)) |
|
481 | controller='summary', conditions=dict(function=check_repo)) | |
483 |
|
482 | |||
484 | rmap.connect('shortlog_home', '/{repo_name:.*}/shortlog', |
|
483 | rmap.connect('shortlog_home', '/{repo_name:.*}/shortlog', | |
485 | controller='shortlog', conditions=dict(function=check_repo)) |
|
484 | controller='shortlog', conditions=dict(function=check_repo)) | |
486 |
|
485 | |||
487 | rmap.connect('branches_home', '/{repo_name:.*}/branches', |
|
486 | rmap.connect('branches_home', '/{repo_name:.*}/branches', | |
488 | controller='branches', conditions=dict(function=check_repo)) |
|
487 | controller='branches', conditions=dict(function=check_repo)) | |
489 |
|
488 | |||
490 | rmap.connect('tags_home', '/{repo_name:.*}/tags', |
|
489 | rmap.connect('tags_home', '/{repo_name:.*}/tags', | |
491 | controller='tags', conditions=dict(function=check_repo)) |
|
490 | controller='tags', conditions=dict(function=check_repo)) | |
492 |
|
491 | |||
493 | rmap.connect('bookmarks_home', '/{repo_name:.*}/bookmarks', |
|
492 | rmap.connect('bookmarks_home', '/{repo_name:.*}/bookmarks', | |
494 | controller='bookmarks', conditions=dict(function=check_repo)) |
|
493 | controller='bookmarks', conditions=dict(function=check_repo)) | |
495 |
|
494 | |||
496 | rmap.connect('changelog_home', '/{repo_name:.*}/changelog', |
|
495 | rmap.connect('changelog_home', '/{repo_name:.*}/changelog', | |
497 | controller='changelog', conditions=dict(function=check_repo)) |
|
496 | controller='changelog', conditions=dict(function=check_repo)) | |
498 |
|
497 | |||
499 | rmap.connect('changelog_details', '/{repo_name:.*}/changelog_details/{cs}', |
|
498 | rmap.connect('changelog_details', '/{repo_name:.*}/changelog_details/{cs}', | |
500 | controller='changelog', action='changelog_details', |
|
499 | controller='changelog', action='changelog_details', | |
501 | conditions=dict(function=check_repo)) |
|
500 | conditions=dict(function=check_repo)) | |
502 |
|
501 | |||
503 | rmap.connect('files_home', '/{repo_name:.*}/files/{revision}/{f_path:.*}', |
|
502 | rmap.connect('files_home', '/{repo_name:.*}/files/{revision}/{f_path:.*}', | |
504 | controller='files', revision='tip', f_path='', |
|
503 | controller='files', revision='tip', f_path='', | |
505 | conditions=dict(function=check_repo)) |
|
504 | conditions=dict(function=check_repo)) | |
506 |
|
505 | |||
507 | rmap.connect('files_diff_home', '/{repo_name:.*}/diff/{f_path:.*}', |
|
506 | rmap.connect('files_diff_home', '/{repo_name:.*}/diff/{f_path:.*}', | |
508 | controller='files', action='diff', revision='tip', f_path='', |
|
507 | controller='files', action='diff', revision='tip', f_path='', | |
509 | conditions=dict(function=check_repo)) |
|
508 | conditions=dict(function=check_repo)) | |
510 |
|
509 | |||
511 | rmap.connect('files_rawfile_home', |
|
510 | rmap.connect('files_rawfile_home', | |
512 | '/{repo_name:.*}/rawfile/{revision}/{f_path:.*}', |
|
511 | '/{repo_name:.*}/rawfile/{revision}/{f_path:.*}', | |
513 | controller='files', action='rawfile', revision='tip', |
|
512 | controller='files', action='rawfile', revision='tip', | |
514 | f_path='', conditions=dict(function=check_repo)) |
|
513 | f_path='', conditions=dict(function=check_repo)) | |
515 |
|
514 | |||
516 | rmap.connect('files_raw_home', |
|
515 | rmap.connect('files_raw_home', | |
517 | '/{repo_name:.*}/raw/{revision}/{f_path:.*}', |
|
516 | '/{repo_name:.*}/raw/{revision}/{f_path:.*}', | |
518 | controller='files', action='raw', revision='tip', f_path='', |
|
517 | controller='files', action='raw', revision='tip', f_path='', | |
519 | conditions=dict(function=check_repo)) |
|
518 | conditions=dict(function=check_repo)) | |
520 |
|
519 | |||
521 | rmap.connect('files_annotate_home', |
|
520 | rmap.connect('files_annotate_home', | |
522 | '/{repo_name:.*}/annotate/{revision}/{f_path:.*}', |
|
521 | '/{repo_name:.*}/annotate/{revision}/{f_path:.*}', | |
523 | controller='files', action='index', revision='tip', |
|
522 | controller='files', action='index', revision='tip', | |
524 | f_path='', annotate=True, conditions=dict(function=check_repo)) |
|
523 | f_path='', annotate=True, conditions=dict(function=check_repo)) | |
525 |
|
524 | |||
526 | rmap.connect('files_edit_home', |
|
525 | rmap.connect('files_edit_home', | |
527 | '/{repo_name:.*}/edit/{revision}/{f_path:.*}', |
|
526 | '/{repo_name:.*}/edit/{revision}/{f_path:.*}', | |
528 | controller='files', action='edit', revision='tip', |
|
527 | controller='files', action='edit', revision='tip', | |
529 | f_path='', conditions=dict(function=check_repo)) |
|
528 | f_path='', conditions=dict(function=check_repo)) | |
530 |
|
529 | |||
531 | rmap.connect('files_add_home', |
|
530 | rmap.connect('files_add_home', | |
532 | '/{repo_name:.*}/add/{revision}/{f_path:.*}', |
|
531 | '/{repo_name:.*}/add/{revision}/{f_path:.*}', | |
533 | controller='files', action='add', revision='tip', |
|
532 | controller='files', action='add', revision='tip', | |
534 | f_path='', conditions=dict(function=check_repo)) |
|
533 | f_path='', conditions=dict(function=check_repo)) | |
535 |
|
534 | |||
536 | rmap.connect('files_archive_home', '/{repo_name:.*}/archive/{fname}', |
|
535 | rmap.connect('files_archive_home', '/{repo_name:.*}/archive/{fname}', | |
537 | controller='files', action='archivefile', |
|
536 | controller='files', action='archivefile', | |
538 | conditions=dict(function=check_repo)) |
|
537 | conditions=dict(function=check_repo)) | |
539 |
|
538 | |||
540 | rmap.connect('files_nodelist_home', |
|
539 | rmap.connect('files_nodelist_home', | |
541 | '/{repo_name:.*}/nodelist/{revision}/{f_path:.*}', |
|
540 | '/{repo_name:.*}/nodelist/{revision}/{f_path:.*}', | |
542 | controller='files', action='nodelist', |
|
541 | controller='files', action='nodelist', | |
543 | conditions=dict(function=check_repo)) |
|
542 | conditions=dict(function=check_repo)) | |
544 |
|
543 | |||
545 | rmap.connect('repo_settings_delete', '/{repo_name:.*}/settings', |
|
544 | rmap.connect('repo_settings_delete', '/{repo_name:.*}/settings', | |
546 | controller='settings', action="delete", |
|
545 | controller='settings', action="delete", | |
547 | conditions=dict(method=["DELETE"], function=check_repo)) |
|
546 | conditions=dict(method=["DELETE"], function=check_repo)) | |
548 |
|
547 | |||
549 | rmap.connect('repo_settings_update', '/{repo_name:.*}/settings', |
|
548 | rmap.connect('repo_settings_update', '/{repo_name:.*}/settings', | |
550 | controller='settings', action="update", |
|
549 | controller='settings', action="update", | |
551 | conditions=dict(method=["PUT"], function=check_repo)) |
|
550 | conditions=dict(method=["PUT"], function=check_repo)) | |
552 |
|
551 | |||
553 | rmap.connect('repo_settings_home', '/{repo_name:.*}/settings', |
|
552 | rmap.connect('repo_settings_home', '/{repo_name:.*}/settings', | |
554 | controller='settings', action='index', |
|
553 | controller='settings', action='index', | |
555 | conditions=dict(function=check_repo)) |
|
554 | conditions=dict(function=check_repo)) | |
556 |
|
555 | |||
557 | rmap.connect('repo_fork_create_home', '/{repo_name:.*}/fork', |
|
556 | rmap.connect('repo_fork_create_home', '/{repo_name:.*}/fork', | |
558 | controller='forks', action='fork_create', |
|
557 | controller='forks', action='fork_create', | |
559 | conditions=dict(function=check_repo, method=["POST"])) |
|
558 | conditions=dict(function=check_repo, method=["POST"])) | |
560 |
|
559 | |||
561 | rmap.connect('repo_fork_home', '/{repo_name:.*}/fork', |
|
560 | rmap.connect('repo_fork_home', '/{repo_name:.*}/fork', | |
562 | controller='forks', action='fork', |
|
561 | controller='forks', action='fork', | |
563 | conditions=dict(function=check_repo)) |
|
562 | conditions=dict(function=check_repo)) | |
564 |
|
563 | |||
565 | rmap.connect('repo_forks_home', '/{repo_name:.*}/forks', |
|
564 | rmap.connect('repo_forks_home', '/{repo_name:.*}/forks', | |
566 | controller='forks', action='forks', |
|
565 | controller='forks', action='forks', | |
567 | conditions=dict(function=check_repo)) |
|
566 | conditions=dict(function=check_repo)) | |
568 |
|
567 | |||
569 | rmap.connect('repo_followers_home', '/{repo_name:.*}/followers', |
|
568 | rmap.connect('repo_followers_home', '/{repo_name:.*}/followers', | |
570 | controller='followers', action='followers', |
|
569 | controller='followers', action='followers', | |
571 | conditions=dict(function=check_repo)) |
|
570 | conditions=dict(function=check_repo)) | |
572 |
|
571 | |||
573 | return rmap |
|
572 | return rmap |
@@ -1,317 +1,316 | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """ |
|
2 | """ | |
3 | rhodecode.controllers.admin.repos_groups |
|
3 | rhodecode.controllers.admin.repos_groups | |
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
5 |
|
5 | |||
6 | Repositories groups controller for RhodeCode |
|
6 | Repositories groups controller for RhodeCode | |
7 |
|
7 | |||
8 | :created_on: Mar 23, 2010 |
|
8 | :created_on: Mar 23, 2010 | |
9 | :author: marcink |
|
9 | :author: marcink | |
10 | :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com> |
|
10 | :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com> | |
11 | :license: GPLv3, see COPYING for more details. |
|
11 | :license: GPLv3, see COPYING for more details. | |
12 | """ |
|
12 | """ | |
13 | # This program is free software: you can redistribute it and/or modify |
|
13 | # This program is free software: you can redistribute it and/or modify | |
14 | # it under the terms of the GNU General Public License as published by |
|
14 | # it under the terms of the GNU General Public License as published by | |
15 | # the Free Software Foundation, either version 3 of the License, or |
|
15 | # the Free Software Foundation, either version 3 of the License, or | |
16 | # (at your option) any later version. |
|
16 | # (at your option) any later version. | |
17 | # |
|
17 | # | |
18 | # This program is distributed in the hope that it will be useful, |
|
18 | # This program is distributed in the hope that it will be useful, | |
19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21 | # GNU General Public License for more details. |
|
21 | # GNU General Public License for more details. | |
22 | # |
|
22 | # | |
23 | # You should have received a copy of the GNU General Public License |
|
23 | # You should have received a copy of the GNU General Public License | |
24 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
24 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
25 |
|
25 | |||
26 | import logging |
|
26 | import logging | |
27 | import traceback |
|
27 | import traceback | |
28 | import formencode |
|
28 | import formencode | |
29 |
|
29 | |||
30 | from formencode import htmlfill |
|
30 | from formencode import htmlfill | |
31 |
|
31 | |||
32 | from pylons import request, tmpl_context as c, url |
|
32 | from pylons import request, tmpl_context as c, url | |
33 | from pylons.controllers.util import redirect |
|
33 | from pylons.controllers.util import redirect | |
34 | from pylons.i18n.translation import _ |
|
34 | from pylons.i18n.translation import _ | |
35 |
|
35 | |||
36 | from sqlalchemy.exc import IntegrityError |
|
36 | from sqlalchemy.exc import IntegrityError | |
37 |
|
37 | |||
38 | from rhodecode.lib import helpers as h |
|
38 | from rhodecode.lib import helpers as h | |
39 | from rhodecode.lib.auth import LoginRequired, HasPermissionAnyDecorator,\ |
|
39 | from rhodecode.lib.auth import LoginRequired, HasPermissionAnyDecorator,\ | |
40 | HasReposGroupPermissionAnyDecorator |
|
40 | HasReposGroupPermissionAnyDecorator | |
41 | from rhodecode.lib.base import BaseController, render |
|
41 | from rhodecode.lib.base import BaseController, render | |
42 | from rhodecode.model.db import RepoGroup |
|
42 | from rhodecode.model.db import RepoGroup | |
43 | from rhodecode.model.repos_group import ReposGroupModel |
|
43 | from rhodecode.model.repos_group import ReposGroupModel | |
44 | from rhodecode.model.forms import ReposGroupForm |
|
44 | from rhodecode.model.forms import ReposGroupForm | |
45 | from rhodecode.model.meta import Session |
|
45 | from rhodecode.model.meta import Session | |
46 | from rhodecode.model.repo import RepoModel |
|
46 | from rhodecode.model.repo import RepoModel | |
47 | from webob.exc import HTTPInternalServerError, HTTPNotFound |
|
47 | from webob.exc import HTTPInternalServerError, HTTPNotFound | |
48 |
|
48 | |||
49 | log = logging.getLogger(__name__) |
|
49 | log = logging.getLogger(__name__) | |
50 |
|
50 | |||
51 |
|
51 | |||
52 | class ReposGroupsController(BaseController): |
|
52 | class ReposGroupsController(BaseController): | |
53 | """REST Controller styled on the Atom Publishing Protocol""" |
|
53 | """REST Controller styled on the Atom Publishing Protocol""" | |
54 | # To properly map this controller, ensure your config/routing.py |
|
54 | # To properly map this controller, ensure your config/routing.py | |
55 | # file has a resource setup: |
|
55 | # file has a resource setup: | |
56 | # map.resource('repos_group', 'repos_groups') |
|
56 | # map.resource('repos_group', 'repos_groups') | |
57 |
|
57 | |||
58 | @LoginRequired() |
|
58 | @LoginRequired() | |
59 | def __before__(self): |
|
59 | def __before__(self): | |
60 | super(ReposGroupsController, self).__before__() |
|
60 | super(ReposGroupsController, self).__before__() | |
61 |
|
61 | |||
62 | def __load_defaults(self): |
|
62 | def __load_defaults(self): | |
63 | c.repo_groups = RepoGroup.groups_choices() |
|
63 | c.repo_groups = RepoGroup.groups_choices() | |
64 | c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups) |
|
64 | c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups) | |
65 |
|
65 | |||
66 | repo_model = RepoModel() |
|
66 | repo_model = RepoModel() | |
67 | c.users_array = repo_model.get_users_js() |
|
67 | c.users_array = repo_model.get_users_js() | |
68 | c.users_groups_array = repo_model.get_users_groups_js() |
|
68 | c.users_groups_array = repo_model.get_users_groups_js() | |
69 |
|
69 | |||
70 | def __load_data(self, group_id): |
|
70 | def __load_data(self, group_id): | |
71 | """ |
|
71 | """ | |
72 | Load defaults settings for edit, and update |
|
72 | Load defaults settings for edit, and update | |
73 |
|
73 | |||
74 | :param group_id: |
|
74 | :param group_id: | |
75 | """ |
|
75 | """ | |
76 | self.__load_defaults() |
|
76 | self.__load_defaults() | |
77 |
|
77 | |||
78 | repo_group = RepoGroup.get_or_404(group_id) |
|
78 | repo_group = RepoGroup.get_or_404(group_id) | |
79 |
|
79 | |||
80 | data = repo_group.get_dict() |
|
80 | data = repo_group.get_dict() | |
81 |
|
81 | |||
82 | data['group_name'] = repo_group.name |
|
82 | data['group_name'] = repo_group.name | |
83 |
|
83 | |||
84 | # fill repository users |
|
84 | # fill repository users | |
85 | for p in repo_group.repo_group_to_perm: |
|
85 | for p in repo_group.repo_group_to_perm: | |
86 | data.update({'u_perm_%s' % p.user.username: |
|
86 | data.update({'u_perm_%s' % p.user.username: | |
87 | p.permission.permission_name}) |
|
87 | p.permission.permission_name}) | |
88 |
|
88 | |||
89 | # fill repository groups |
|
89 | # fill repository groups | |
90 | for p in repo_group.users_group_to_perm: |
|
90 | for p in repo_group.users_group_to_perm: | |
91 | data.update({'g_perm_%s' % p.users_group.users_group_name: |
|
91 | data.update({'g_perm_%s' % p.users_group.users_group_name: | |
92 | p.permission.permission_name}) |
|
92 | p.permission.permission_name}) | |
93 |
|
93 | |||
94 | return data |
|
94 | return data | |
95 |
|
95 | |||
96 | @HasPermissionAnyDecorator('hg.admin') |
|
96 | @HasPermissionAnyDecorator('hg.admin') | |
97 | def index(self, format='html'): |
|
97 | def index(self, format='html'): | |
98 | """GET /repos_groups: All items in the collection""" |
|
98 | """GET /repos_groups: All items in the collection""" | |
99 | # url('repos_groups') |
|
99 | # url('repos_groups') | |
100 | sk = lambda g: g.parents[0].group_name if g.parents else g.group_name |
|
100 | sk = lambda g: g.parents[0].group_name if g.parents else g.group_name | |
101 | c.groups = sorted(RepoGroup.query().all(), key=sk) |
|
101 | c.groups = sorted(RepoGroup.query().all(), key=sk) | |
102 | return render('admin/repos_groups/repos_groups_show.html') |
|
102 | return render('admin/repos_groups/repos_groups_show.html') | |
103 |
|
103 | |||
104 | @HasPermissionAnyDecorator('hg.admin') |
|
104 | @HasPermissionAnyDecorator('hg.admin') | |
105 | def create(self): |
|
105 | def create(self): | |
106 | """POST /repos_groups: Create a new item""" |
|
106 | """POST /repos_groups: Create a new item""" | |
107 | # url('repos_groups') |
|
107 | # url('repos_groups') | |
108 | self.__load_defaults() |
|
108 | self.__load_defaults() | |
109 | repos_group_form = ReposGroupForm(available_groups = |
|
109 | repos_group_form = ReposGroupForm(available_groups = | |
110 | c.repo_groups_choices)() |
|
110 | c.repo_groups_choices)() | |
111 | try: |
|
111 | try: | |
112 | form_result = repos_group_form.to_python(dict(request.POST)) |
|
112 | form_result = repos_group_form.to_python(dict(request.POST)) | |
113 | ReposGroupModel().create( |
|
113 | ReposGroupModel().create( | |
114 | group_name=form_result['group_name'], |
|
114 | group_name=form_result['group_name'], | |
115 | group_description=form_result['group_description'], |
|
115 | group_description=form_result['group_description'], | |
116 | parent=form_result['group_parent_id'] |
|
116 | parent=form_result['group_parent_id'] | |
117 | ) |
|
117 | ) | |
118 | Session.commit() |
|
118 | Session.commit() | |
119 | h.flash(_('created repos group %s') \ |
|
119 | h.flash(_('created repos group %s') \ | |
120 | % form_result['group_name'], category='success') |
|
120 | % form_result['group_name'], category='success') | |
121 | #TODO: in futureaction_logger(, '', '', '', self.sa) |
|
121 | #TODO: in futureaction_logger(, '', '', '', self.sa) | |
122 | except formencode.Invalid, errors: |
|
122 | except formencode.Invalid, errors: | |
123 |
|
123 | |||
124 | return htmlfill.render( |
|
124 | return htmlfill.render( | |
125 | render('admin/repos_groups/repos_groups_add.html'), |
|
125 | render('admin/repos_groups/repos_groups_add.html'), | |
126 | defaults=errors.value, |
|
126 | defaults=errors.value, | |
127 | errors=errors.error_dict or {}, |
|
127 | errors=errors.error_dict or {}, | |
128 | prefix_error=False, |
|
128 | prefix_error=False, | |
129 | encoding="UTF-8") |
|
129 | encoding="UTF-8") | |
130 | except Exception: |
|
130 | except Exception: | |
131 | log.error(traceback.format_exc()) |
|
131 | log.error(traceback.format_exc()) | |
132 | h.flash(_('error occurred during creation of repos group %s') \ |
|
132 | h.flash(_('error occurred during creation of repos group %s') \ | |
133 | % request.POST.get('group_name'), category='error') |
|
133 | % request.POST.get('group_name'), category='error') | |
134 |
|
134 | |||
135 | return redirect(url('repos_groups')) |
|
135 | return redirect(url('repos_groups')) | |
136 |
|
136 | |||
137 | @HasPermissionAnyDecorator('hg.admin') |
|
137 | @HasPermissionAnyDecorator('hg.admin') | |
138 | def new(self, format='html'): |
|
138 | def new(self, format='html'): | |
139 | """GET /repos_groups/new: Form to create a new item""" |
|
139 | """GET /repos_groups/new: Form to create a new item""" | |
140 | # url('new_repos_group') |
|
140 | # url('new_repos_group') | |
141 | self.__load_defaults() |
|
141 | self.__load_defaults() | |
142 | return render('admin/repos_groups/repos_groups_add.html') |
|
142 | return render('admin/repos_groups/repos_groups_add.html') | |
143 |
|
143 | |||
144 | @HasPermissionAnyDecorator('hg.admin') |
|
144 | @HasPermissionAnyDecorator('hg.admin') | |
145 | def update(self, id): |
|
145 | def update(self, id): | |
146 | """PUT /repos_groups/id: Update an existing item""" |
|
146 | """PUT /repos_groups/id: Update an existing item""" | |
147 | # Forms posted to this method should contain a hidden field: |
|
147 | # Forms posted to this method should contain a hidden field: | |
148 | # <input type="hidden" name="_method" value="PUT" /> |
|
148 | # <input type="hidden" name="_method" value="PUT" /> | |
149 | # Or using helpers: |
|
149 | # Or using helpers: | |
150 | # h.form(url('repos_group', id=ID), |
|
150 | # h.form(url('repos_group', id=ID), | |
151 | # method='put') |
|
151 | # method='put') | |
152 | # url('repos_group', id=ID) |
|
152 | # url('repos_group', id=ID) | |
153 |
|
153 | |||
154 | self.__load_defaults() |
|
154 | self.__load_defaults() | |
155 | c.repos_group = RepoGroup.get(id) |
|
155 | c.repos_group = RepoGroup.get(id) | |
156 |
|
156 | |||
157 | repos_group_form = ReposGroupForm( |
|
157 | repos_group_form = ReposGroupForm( | |
158 | edit=True, |
|
158 | edit=True, | |
159 | old_data=c.repos_group.get_dict(), |
|
159 | old_data=c.repos_group.get_dict(), | |
160 | available_groups=c.repo_groups_choices |
|
160 | available_groups=c.repo_groups_choices | |
161 | )() |
|
161 | )() | |
162 | try: |
|
162 | try: | |
163 | form_result = repos_group_form.to_python(dict(request.POST)) |
|
163 | form_result = repos_group_form.to_python(dict(request.POST)) | |
164 | ReposGroupModel().update(id, form_result) |
|
164 | ReposGroupModel().update(id, form_result) | |
165 | Session.commit() |
|
165 | Session.commit() | |
166 | h.flash(_('updated repos group %s') \ |
|
166 | h.flash(_('updated repos group %s') \ | |
167 | % form_result['group_name'], category='success') |
|
167 | % form_result['group_name'], category='success') | |
168 | #TODO: in futureaction_logger(, '', '', '', self.sa) |
|
168 | #TODO: in futureaction_logger(, '', '', '', self.sa) | |
169 | except formencode.Invalid, errors: |
|
169 | except formencode.Invalid, errors: | |
170 |
|
170 | |||
171 | return htmlfill.render( |
|
171 | return htmlfill.render( | |
172 | render('admin/repos_groups/repos_groups_edit.html'), |
|
172 | render('admin/repos_groups/repos_groups_edit.html'), | |
173 | defaults=errors.value, |
|
173 | defaults=errors.value, | |
174 | errors=errors.error_dict or {}, |
|
174 | errors=errors.error_dict or {}, | |
175 | prefix_error=False, |
|
175 | prefix_error=False, | |
176 | encoding="UTF-8") |
|
176 | encoding="UTF-8") | |
177 | except Exception: |
|
177 | except Exception: | |
178 | log.error(traceback.format_exc()) |
|
178 | log.error(traceback.format_exc()) | |
179 | h.flash(_('error occurred during update of repos group %s') \ |
|
179 | h.flash(_('error occurred during update of repos group %s') \ | |
180 | % request.POST.get('group_name'), category='error') |
|
180 | % request.POST.get('group_name'), category='error') | |
181 |
|
181 | |||
182 | return redirect(url('repos_groups')) |
|
182 | return redirect(url('repos_groups')) | |
183 |
|
183 | |||
184 | @HasPermissionAnyDecorator('hg.admin') |
|
184 | @HasPermissionAnyDecorator('hg.admin') | |
185 | def delete(self, id): |
|
185 | def delete(self, id): | |
186 | """DELETE /repos_groups/id: Delete an existing item""" |
|
186 | """DELETE /repos_groups/id: Delete an existing item""" | |
187 | # Forms posted to this method should contain a hidden field: |
|
187 | # Forms posted to this method should contain a hidden field: | |
188 | # <input type="hidden" name="_method" value="DELETE" /> |
|
188 | # <input type="hidden" name="_method" value="DELETE" /> | |
189 | # Or using helpers: |
|
189 | # Or using helpers: | |
190 | # h.form(url('repos_group', id=ID), |
|
190 | # h.form(url('repos_group', id=ID), | |
191 | # method='delete') |
|
191 | # method='delete') | |
192 | # url('repos_group', id=ID) |
|
192 | # url('repos_group', id=ID) | |
193 |
|
193 | |||
194 | gr = RepoGroup.get(id) |
|
194 | gr = RepoGroup.get(id) | |
195 | repos = gr.repositories.all() |
|
195 | repos = gr.repositories.all() | |
196 | if repos: |
|
196 | if repos: | |
197 | h.flash(_('This group contains %s repositores and cannot be ' |
|
197 | h.flash(_('This group contains %s repositores and cannot be ' | |
198 | 'deleted') % len(repos), |
|
198 | 'deleted') % len(repos), | |
199 | category='error') |
|
199 | category='error') | |
200 | return redirect(url('repos_groups')) |
|
200 | return redirect(url('repos_groups')) | |
201 |
|
201 | |||
202 | try: |
|
202 | try: | |
203 | ReposGroupModel().delete(id) |
|
203 | ReposGroupModel().delete(id) | |
204 | Session.commit() |
|
204 | Session.commit() | |
205 | h.flash(_('removed repos group %s') % gr.group_name, category='success') |
|
205 | h.flash(_('removed repos group %s') % gr.group_name, category='success') | |
206 | #TODO: in future action_logger(, '', '', '', self.sa) |
|
206 | #TODO: in future action_logger(, '', '', '', self.sa) | |
207 | except IntegrityError, e: |
|
207 | except IntegrityError, e: | |
208 | if e.message.find('groups_group_parent_id_fkey') != -1: |
|
208 | if e.message.find('groups_group_parent_id_fkey') != -1: | |
209 | log.error(traceback.format_exc()) |
|
209 | log.error(traceback.format_exc()) | |
210 | h.flash(_('Cannot delete this group it still contains ' |
|
210 | h.flash(_('Cannot delete this group it still contains ' | |
211 | 'subgroups'), |
|
211 | 'subgroups'), | |
212 | category='warning') |
|
212 | category='warning') | |
213 | else: |
|
213 | else: | |
214 | log.error(traceback.format_exc()) |
|
214 | log.error(traceback.format_exc()) | |
215 | h.flash(_('error occurred during deletion of repos ' |
|
215 | h.flash(_('error occurred during deletion of repos ' | |
216 | 'group %s') % gr.group_name, category='error') |
|
216 | 'group %s') % gr.group_name, category='error') | |
217 |
|
217 | |||
218 | except Exception: |
|
218 | except Exception: | |
219 | log.error(traceback.format_exc()) |
|
219 | log.error(traceback.format_exc()) | |
220 | h.flash(_('error occurred during deletion of repos ' |
|
220 | h.flash(_('error occurred during deletion of repos ' | |
221 | 'group %s') % gr.group_name, category='error') |
|
221 | 'group %s') % gr.group_name, category='error') | |
222 |
|
222 | |||
223 | return redirect(url('repos_groups')) |
|
223 | return redirect(url('repos_groups')) | |
224 |
|
224 | |||
225 | @HasReposGroupPermissionAnyDecorator('group.admin') |
|
225 | @HasReposGroupPermissionAnyDecorator('group.admin') | |
226 | def delete_repos_group_user_perm(self, group_name): |
|
226 | def delete_repos_group_user_perm(self, group_name): | |
227 | """ |
|
227 | """ | |
228 | DELETE an existing repositories group permission user |
|
228 | DELETE an existing repositories group permission user | |
229 |
|
229 | |||
230 | :param group_name: |
|
230 | :param group_name: | |
231 | """ |
|
231 | """ | |
232 |
|
232 | |||
233 | try: |
|
233 | try: | |
234 | ReposGroupModel().revoke_user_permission( |
|
234 | ReposGroupModel().revoke_user_permission( | |
235 | repos_group=group_name, user=request.POST['user_id'] |
|
235 | repos_group=group_name, user=request.POST['user_id'] | |
236 | ) |
|
236 | ) | |
237 | Session.commit() |
|
237 | Session.commit() | |
238 | except Exception: |
|
238 | except Exception: | |
239 | log.error(traceback.format_exc()) |
|
239 | log.error(traceback.format_exc()) | |
240 | h.flash(_('An error occurred during deletion of group user'), |
|
240 | h.flash(_('An error occurred during deletion of group user'), | |
241 | category='error') |
|
241 | category='error') | |
242 | raise HTTPInternalServerError() |
|
242 | raise HTTPInternalServerError() | |
243 |
|
243 | |||
244 | @HasReposGroupPermissionAnyDecorator('group.admin') |
|
244 | @HasReposGroupPermissionAnyDecorator('group.admin') | |
245 | def delete_repos_group_users_group_perm(self, group_name): |
|
245 | def delete_repos_group_users_group_perm(self, group_name): | |
246 | """ |
|
246 | """ | |
247 | DELETE an existing repositories group permission users group |
|
247 | DELETE an existing repositories group permission users group | |
248 |
|
248 | |||
249 | :param group_name: |
|
249 | :param group_name: | |
250 | """ |
|
250 | """ | |
251 |
|
251 | |||
252 | try: |
|
252 | try: | |
253 | ReposGroupModel().revoke_users_group_permission( |
|
253 | ReposGroupModel().revoke_users_group_permission( | |
254 | repos_group=group_name, |
|
254 | repos_group=group_name, | |
255 | group_name=request.POST['users_group_id'] |
|
255 | group_name=request.POST['users_group_id'] | |
256 | ) |
|
256 | ) | |
257 | Session.commit() |
|
257 | Session.commit() | |
258 | except Exception: |
|
258 | except Exception: | |
259 | log.error(traceback.format_exc()) |
|
259 | log.error(traceback.format_exc()) | |
260 | h.flash(_('An error occurred during deletion of group' |
|
260 | h.flash(_('An error occurred during deletion of group' | |
261 | ' users groups'), |
|
261 | ' users groups'), | |
262 | category='error') |
|
262 | category='error') | |
263 | raise HTTPInternalServerError() |
|
263 | raise HTTPInternalServerError() | |
264 |
|
264 | |||
265 | def show_by_name(self, group_name): |
|
265 | def show_by_name(self, group_name): | |
266 | """ |
|
266 | """ | |
267 | This is a proxy that does a lookup group_name -> id, and shows |
|
267 | This is a proxy that does a lookup group_name -> id, and shows | |
268 | the group by id view instead |
|
268 | the group by id view instead | |
269 | """ |
|
269 | """ | |
270 | group_name = group_name.rstrip('/') |
|
270 | group_name = group_name.rstrip('/') | |
271 | id_ = RepoGroup.get_by_group_name(group_name) |
|
271 | id_ = RepoGroup.get_by_group_name(group_name) | |
272 | if id_: |
|
272 | if id_: | |
273 | return self.show(id_.group_id) |
|
273 | return self.show(id_.group_id) | |
274 | raise HTTPNotFound |
|
274 | raise HTTPNotFound | |
275 |
|
275 | |||
276 | @HasReposGroupPermissionAnyDecorator('group.read', 'group.write', |
|
276 | @HasReposGroupPermissionAnyDecorator('group.read', 'group.write', | |
277 | 'group.admin') |
|
277 | 'group.admin') | |
278 | def show(self, id, format='html'): |
|
278 | def show(self, id, format='html'): | |
279 | """GET /repos_groups/id: Show a specific item""" |
|
279 | """GET /repos_groups/id: Show a specific item""" | |
280 | # url('repos_group', id=ID) |
|
280 | # url('repos_group', id=ID) | |
281 |
|
281 | |||
282 | c.group = RepoGroup.get_or_404(id) |
|
282 | c.group = RepoGroup.get_or_404(id) | |
283 |
|
283 | |||
284 | c.group_repos = c.group.repositories.all() |
|
284 | c.group_repos = c.group.repositories.all() | |
285 |
|
285 | |||
286 | #overwrite our cached list with current filter |
|
286 | #overwrite our cached list with current filter | |
287 | gr_filter = c.group_repos |
|
287 | gr_filter = c.group_repos | |
288 | c.cached_repo_list = self.scm_model.get_repos(all_repos=gr_filter) |
|
288 | c.cached_repo_list = self.scm_model.get_repos(all_repos=gr_filter) | |
289 |
|
289 | |||
290 | c.repos_list = c.cached_repo_list |
|
290 | c.repos_list = c.cached_repo_list | |
291 |
|
291 | |||
292 | c.repo_cnt = 0 |
|
292 | c.repo_cnt = 0 | |
293 |
|
293 | |||
294 | c.groups = self.sa.query(RepoGroup).order_by(RepoGroup.group_name)\ |
|
294 | c.groups = self.sa.query(RepoGroup).order_by(RepoGroup.group_name)\ | |
295 | .filter(RepoGroup.group_parent_id == id).all() |
|
295 | .filter(RepoGroup.group_parent_id == id).all() | |
296 |
|
296 | |||
297 | return render('admin/repos_groups/repos_groups.html') |
|
297 | return render('admin/repos_groups/repos_groups.html') | |
298 |
|
298 | |||
299 | @HasPermissionAnyDecorator('hg.admin') |
|
299 | @HasPermissionAnyDecorator('hg.admin') | |
300 | def edit(self, id, format='html'): |
|
300 | def edit(self, id, format='html'): | |
301 | """GET /repos_groups/id/edit: Form to edit an existing item""" |
|
301 | """GET /repos_groups/id/edit: Form to edit an existing item""" | |
302 | # url('edit_repos_group', id=ID) |
|
302 | # url('edit_repos_group', id=ID) | |
303 |
|
303 | |||
304 | id_ = int(id) |
|
304 | c.repos_group = ReposGroupModel()._get_repos_group(id) | |
305 |
|
305 | defaults = self.__load_data(c.repos_group.group_id) | ||
306 | c.repos_group = RepoGroup.get(id_) |
|
|||
307 | defaults = self.__load_data(id_) |
|
|||
308 |
|
306 | |||
309 | # we need to exclude this group from the group list for editing |
|
307 | # we need to exclude this group from the group list for editing | |
310 |
c.repo_groups = filter(lambda x: x[0] != |
|
308 | c.repo_groups = filter(lambda x: x[0] != c.repos_group.group_id, | |
|
309 | c.repo_groups) | |||
311 |
|
310 | |||
312 | return htmlfill.render( |
|
311 | return htmlfill.render( | |
313 | render('admin/repos_groups/repos_groups_edit.html'), |
|
312 | render('admin/repos_groups/repos_groups_edit.html'), | |
314 | defaults=defaults, |
|
313 | defaults=defaults, | |
315 | encoding="UTF-8", |
|
314 | encoding="UTF-8", | |
316 | force_defaults=False |
|
315 | force_defaults=False | |
317 | ) |
|
316 | ) |
@@ -1,523 +1,523 | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """ |
|
2 | """ | |
3 | rhodecode.model.repo |
|
3 | rhodecode.model.repo | |
4 | ~~~~~~~~~~~~~~~~~~~~ |
|
4 | ~~~~~~~~~~~~~~~~~~~~ | |
5 |
|
5 | |||
6 | Repository model for rhodecode |
|
6 | Repository model for rhodecode | |
7 |
|
7 | |||
8 | :created_on: Jun 5, 2010 |
|
8 | :created_on: Jun 5, 2010 | |
9 | :author: marcink |
|
9 | :author: marcink | |
10 | :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com> |
|
10 | :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com> | |
11 | :license: GPLv3, see COPYING for more details. |
|
11 | :license: GPLv3, see COPYING for more details. | |
12 | """ |
|
12 | """ | |
13 | # This program is free software: you can redistribute it and/or modify |
|
13 | # This program is free software: you can redistribute it and/or modify | |
14 | # it under the terms of the GNU General Public License as published by |
|
14 | # it under the terms of the GNU General Public License as published by | |
15 | # the Free Software Foundation, either version 3 of the License, or |
|
15 | # the Free Software Foundation, either version 3 of the License, or | |
16 | # (at your option) any later version. |
|
16 | # (at your option) any later version. | |
17 | # |
|
17 | # | |
18 | # This program is distributed in the hope that it will be useful, |
|
18 | # This program is distributed in the hope that it will be useful, | |
19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21 | # GNU General Public License for more details. |
|
21 | # GNU General Public License for more details. | |
22 | # |
|
22 | # | |
23 | # You should have received a copy of the GNU General Public License |
|
23 | # You should have received a copy of the GNU General Public License | |
24 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
24 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
25 | from __future__ import with_statement |
|
25 | from __future__ import with_statement | |
26 | import os |
|
26 | import os | |
27 | import shutil |
|
27 | import shutil | |
28 | import logging |
|
28 | import logging | |
29 | import traceback |
|
29 | import traceback | |
30 | from datetime import datetime |
|
30 | from datetime import datetime | |
31 |
|
31 | |||
32 | from rhodecode.lib.vcs.backends import get_backend |
|
32 | from rhodecode.lib.vcs.backends import get_backend | |
33 | from rhodecode.lib.compat import json |
|
33 | from rhodecode.lib.compat import json | |
34 | from rhodecode.lib.utils2 import LazyProperty, safe_str, safe_unicode |
|
34 | from rhodecode.lib.utils2 import LazyProperty, safe_str, safe_unicode | |
35 | from rhodecode.lib.caching_query import FromCache |
|
35 | from rhodecode.lib.caching_query import FromCache | |
36 | from rhodecode.lib.hooks import log_create_repository |
|
36 | from rhodecode.lib.hooks import log_create_repository | |
37 |
|
37 | |||
38 | from rhodecode.model import BaseModel |
|
38 | from rhodecode.model import BaseModel | |
39 | from rhodecode.model.db import Repository, UserRepoToPerm, User, Permission, \ |
|
39 | from rhodecode.model.db import Repository, UserRepoToPerm, User, Permission, \ | |
40 | Statistics, UsersGroup, UsersGroupRepoToPerm, RhodeCodeUi, RepoGroup |
|
40 | Statistics, UsersGroup, UsersGroupRepoToPerm, RhodeCodeUi, RepoGroup | |
41 | from rhodecode.lib import helpers as h |
|
41 | from rhodecode.lib import helpers as h | |
42 |
|
42 | |||
43 |
|
43 | |||
44 | log = logging.getLogger(__name__) |
|
44 | log = logging.getLogger(__name__) | |
45 |
|
45 | |||
46 |
|
46 | |||
47 | class RepoModel(BaseModel): |
|
47 | class RepoModel(BaseModel): | |
48 |
|
48 | |||
49 | cls = Repository |
|
49 | cls = Repository | |
50 | URL_SEPARATOR = Repository.url_sep() |
|
50 | URL_SEPARATOR = Repository.url_sep() | |
51 |
|
51 | |||
52 | def __get_users_group(self, users_group): |
|
52 | def __get_users_group(self, users_group): | |
53 | return self._get_instance(UsersGroup, users_group, |
|
53 | return self._get_instance(UsersGroup, users_group, | |
54 | callback=UsersGroup.get_by_group_name) |
|
54 | callback=UsersGroup.get_by_group_name) | |
55 |
|
55 | |||
56 |
def |
|
56 | def _get_repos_group(self, repos_group): | |
57 | return self._get_instance(RepoGroup, repos_group, |
|
57 | return self._get_instance(RepoGroup, repos_group, | |
58 | callback=RepoGroup.get_by_group_name) |
|
58 | callback=RepoGroup.get_by_group_name) | |
59 |
|
59 | |||
60 | @LazyProperty |
|
60 | @LazyProperty | |
61 | def repos_path(self): |
|
61 | def repos_path(self): | |
62 | """ |
|
62 | """ | |
63 | Get's the repositories root path from database |
|
63 | Get's the repositories root path from database | |
64 | """ |
|
64 | """ | |
65 |
|
65 | |||
66 | q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one() |
|
66 | q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one() | |
67 | return q.ui_value |
|
67 | return q.ui_value | |
68 |
|
68 | |||
69 | def get(self, repo_id, cache=False): |
|
69 | def get(self, repo_id, cache=False): | |
70 | repo = self.sa.query(Repository)\ |
|
70 | repo = self.sa.query(Repository)\ | |
71 | .filter(Repository.repo_id == repo_id) |
|
71 | .filter(Repository.repo_id == repo_id) | |
72 |
|
72 | |||
73 | if cache: |
|
73 | if cache: | |
74 | repo = repo.options(FromCache("sql_cache_short", |
|
74 | repo = repo.options(FromCache("sql_cache_short", | |
75 | "get_repo_%s" % repo_id)) |
|
75 | "get_repo_%s" % repo_id)) | |
76 | return repo.scalar() |
|
76 | return repo.scalar() | |
77 |
|
77 | |||
78 | def get_repo(self, repository): |
|
78 | def get_repo(self, repository): | |
79 | return self._get_repo(repository) |
|
79 | return self._get_repo(repository) | |
80 |
|
80 | |||
81 | def get_by_repo_name(self, repo_name, cache=False): |
|
81 | def get_by_repo_name(self, repo_name, cache=False): | |
82 | repo = self.sa.query(Repository)\ |
|
82 | repo = self.sa.query(Repository)\ | |
83 | .filter(Repository.repo_name == repo_name) |
|
83 | .filter(Repository.repo_name == repo_name) | |
84 |
|
84 | |||
85 | if cache: |
|
85 | if cache: | |
86 | repo = repo.options(FromCache("sql_cache_short", |
|
86 | repo = repo.options(FromCache("sql_cache_short", | |
87 | "get_repo_%s" % repo_name)) |
|
87 | "get_repo_%s" % repo_name)) | |
88 | return repo.scalar() |
|
88 | return repo.scalar() | |
89 |
|
89 | |||
90 | def get_users_js(self): |
|
90 | def get_users_js(self): | |
91 | users = self.sa.query(User).filter(User.active == True).all() |
|
91 | users = self.sa.query(User).filter(User.active == True).all() | |
92 | return json.dumps([ |
|
92 | return json.dumps([ | |
93 | { |
|
93 | { | |
94 | 'id': u.user_id, |
|
94 | 'id': u.user_id, | |
95 | 'fname': u.name, |
|
95 | 'fname': u.name, | |
96 | 'lname': u.lastname, |
|
96 | 'lname': u.lastname, | |
97 | 'nname': u.username, |
|
97 | 'nname': u.username, | |
98 | 'gravatar_lnk': h.gravatar_url(u.email, 14) |
|
98 | 'gravatar_lnk': h.gravatar_url(u.email, 14) | |
99 | } for u in users] |
|
99 | } for u in users] | |
100 | ) |
|
100 | ) | |
101 |
|
101 | |||
102 | def get_users_groups_js(self): |
|
102 | def get_users_groups_js(self): | |
103 | users_groups = self.sa.query(UsersGroup)\ |
|
103 | users_groups = self.sa.query(UsersGroup)\ | |
104 | .filter(UsersGroup.users_group_active == True).all() |
|
104 | .filter(UsersGroup.users_group_active == True).all() | |
105 |
|
105 | |||
106 | return json.dumps([ |
|
106 | return json.dumps([ | |
107 | { |
|
107 | { | |
108 | 'id': gr.users_group_id, |
|
108 | 'id': gr.users_group_id, | |
109 | 'grname': gr.users_group_name, |
|
109 | 'grname': gr.users_group_name, | |
110 | 'grmembers': len(gr.members), |
|
110 | 'grmembers': len(gr.members), | |
111 | } for gr in users_groups] |
|
111 | } for gr in users_groups] | |
112 | ) |
|
112 | ) | |
113 |
|
113 | |||
114 | def _get_defaults(self, repo_name): |
|
114 | def _get_defaults(self, repo_name): | |
115 | """ |
|
115 | """ | |
116 | Get's information about repository, and returns a dict for |
|
116 | Get's information about repository, and returns a dict for | |
117 | usage in forms |
|
117 | usage in forms | |
118 |
|
118 | |||
119 | :param repo_name: |
|
119 | :param repo_name: | |
120 | """ |
|
120 | """ | |
121 |
|
121 | |||
122 | repo_info = Repository.get_by_repo_name(repo_name) |
|
122 | repo_info = Repository.get_by_repo_name(repo_name) | |
123 |
|
123 | |||
124 | if repo_info is None: |
|
124 | if repo_info is None: | |
125 | return None |
|
125 | return None | |
126 |
|
126 | |||
127 | defaults = repo_info.get_dict() |
|
127 | defaults = repo_info.get_dict() | |
128 | group, repo_name = repo_info.groups_and_repo |
|
128 | group, repo_name = repo_info.groups_and_repo | |
129 | defaults['repo_name'] = repo_name |
|
129 | defaults['repo_name'] = repo_name | |
130 | defaults['repo_group'] = getattr(group[-1] if group else None, |
|
130 | defaults['repo_group'] = getattr(group[-1] if group else None, | |
131 | 'group_id', None) |
|
131 | 'group_id', None) | |
132 |
|
132 | |||
133 | # fill owner |
|
133 | # fill owner | |
134 | if repo_info.user: |
|
134 | if repo_info.user: | |
135 | defaults.update({'user': repo_info.user.username}) |
|
135 | defaults.update({'user': repo_info.user.username}) | |
136 | else: |
|
136 | else: | |
137 | replacement_user = User.query().filter(User.admin == |
|
137 | replacement_user = User.query().filter(User.admin == | |
138 | True).first().username |
|
138 | True).first().username | |
139 | defaults.update({'user': replacement_user}) |
|
139 | defaults.update({'user': replacement_user}) | |
140 |
|
140 | |||
141 | # fill repository users |
|
141 | # fill repository users | |
142 | for p in repo_info.repo_to_perm: |
|
142 | for p in repo_info.repo_to_perm: | |
143 | defaults.update({'u_perm_%s' % p.user.username: |
|
143 | defaults.update({'u_perm_%s' % p.user.username: | |
144 | p.permission.permission_name}) |
|
144 | p.permission.permission_name}) | |
145 |
|
145 | |||
146 | # fill repository groups |
|
146 | # fill repository groups | |
147 | for p in repo_info.users_group_to_perm: |
|
147 | for p in repo_info.users_group_to_perm: | |
148 | defaults.update({'g_perm_%s' % p.users_group.users_group_name: |
|
148 | defaults.update({'g_perm_%s' % p.users_group.users_group_name: | |
149 | p.permission.permission_name}) |
|
149 | p.permission.permission_name}) | |
150 |
|
150 | |||
151 | return defaults |
|
151 | return defaults | |
152 |
|
152 | |||
153 | def update(self, repo_name, form_data): |
|
153 | def update(self, repo_name, form_data): | |
154 | try: |
|
154 | try: | |
155 | cur_repo = self.get_by_repo_name(repo_name, cache=False) |
|
155 | cur_repo = self.get_by_repo_name(repo_name, cache=False) | |
156 |
|
156 | |||
157 | # update permissions |
|
157 | # update permissions | |
158 | for member, perm, member_type in form_data['perms_updates']: |
|
158 | for member, perm, member_type in form_data['perms_updates']: | |
159 | if member_type == 'user': |
|
159 | if member_type == 'user': | |
160 | # this updates existing one |
|
160 | # this updates existing one | |
161 | RepoModel().grant_user_permission( |
|
161 | RepoModel().grant_user_permission( | |
162 | repo=cur_repo, user=member, perm=perm |
|
162 | repo=cur_repo, user=member, perm=perm | |
163 | ) |
|
163 | ) | |
164 | else: |
|
164 | else: | |
165 | RepoModel().grant_users_group_permission( |
|
165 | RepoModel().grant_users_group_permission( | |
166 | repo=cur_repo, group_name=member, perm=perm |
|
166 | repo=cur_repo, group_name=member, perm=perm | |
167 | ) |
|
167 | ) | |
168 | # set new permissions |
|
168 | # set new permissions | |
169 | for member, perm, member_type in form_data['perms_new']: |
|
169 | for member, perm, member_type in form_data['perms_new']: | |
170 | if member_type == 'user': |
|
170 | if member_type == 'user': | |
171 | RepoModel().grant_user_permission( |
|
171 | RepoModel().grant_user_permission( | |
172 | repo=cur_repo, user=member, perm=perm |
|
172 | repo=cur_repo, user=member, perm=perm | |
173 | ) |
|
173 | ) | |
174 | else: |
|
174 | else: | |
175 | RepoModel().grant_users_group_permission( |
|
175 | RepoModel().grant_users_group_permission( | |
176 | repo=cur_repo, group_name=member, perm=perm |
|
176 | repo=cur_repo, group_name=member, perm=perm | |
177 | ) |
|
177 | ) | |
178 |
|
178 | |||
179 | # update current repo |
|
179 | # update current repo | |
180 | for k, v in form_data.items(): |
|
180 | for k, v in form_data.items(): | |
181 | if k == 'user': |
|
181 | if k == 'user': | |
182 | cur_repo.user = User.get_by_username(v) |
|
182 | cur_repo.user = User.get_by_username(v) | |
183 | elif k == 'repo_name': |
|
183 | elif k == 'repo_name': | |
184 | pass |
|
184 | pass | |
185 | elif k == 'repo_group': |
|
185 | elif k == 'repo_group': | |
186 | cur_repo.group = RepoGroup.get(v) |
|
186 | cur_repo.group = RepoGroup.get(v) | |
187 |
|
187 | |||
188 | else: |
|
188 | else: | |
189 | setattr(cur_repo, k, v) |
|
189 | setattr(cur_repo, k, v) | |
190 |
|
190 | |||
191 | new_name = cur_repo.get_new_name(form_data['repo_name']) |
|
191 | new_name = cur_repo.get_new_name(form_data['repo_name']) | |
192 | cur_repo.repo_name = new_name |
|
192 | cur_repo.repo_name = new_name | |
193 |
|
193 | |||
194 | self.sa.add(cur_repo) |
|
194 | self.sa.add(cur_repo) | |
195 |
|
195 | |||
196 | if repo_name != new_name: |
|
196 | if repo_name != new_name: | |
197 | # rename repository |
|
197 | # rename repository | |
198 | self.__rename_repo(old=repo_name, new=new_name) |
|
198 | self.__rename_repo(old=repo_name, new=new_name) | |
199 |
|
199 | |||
200 | return cur_repo |
|
200 | return cur_repo | |
201 | except: |
|
201 | except: | |
202 | log.error(traceback.format_exc()) |
|
202 | log.error(traceback.format_exc()) | |
203 | raise |
|
203 | raise | |
204 |
|
204 | |||
205 | def create_repo(self, repo_name, repo_type, description, owner, |
|
205 | def create_repo(self, repo_name, repo_type, description, owner, | |
206 | private=False, clone_uri=None, repos_group=None, |
|
206 | private=False, clone_uri=None, repos_group=None, | |
207 | landing_rev='tip', just_db=False, fork_of=None, |
|
207 | landing_rev='tip', just_db=False, fork_of=None, | |
208 | copy_fork_permissions=False): |
|
208 | copy_fork_permissions=False): | |
209 | from rhodecode.model.scm import ScmModel |
|
209 | from rhodecode.model.scm import ScmModel | |
210 |
|
210 | |||
211 | owner = self._get_user(owner) |
|
211 | owner = self._get_user(owner) | |
212 | fork_of = self._get_repo(fork_of) |
|
212 | fork_of = self._get_repo(fork_of) | |
213 |
repos_group = self. |
|
213 | repos_group = self._get_repos_group(repos_group) | |
214 | try: |
|
214 | try: | |
215 |
|
215 | |||
216 | # repo name is just a name of repository |
|
216 | # repo name is just a name of repository | |
217 | # while repo_name_full is a full qualified name that is combined |
|
217 | # while repo_name_full is a full qualified name that is combined | |
218 | # with name and path of group |
|
218 | # with name and path of group | |
219 | repo_name_full = repo_name |
|
219 | repo_name_full = repo_name | |
220 | repo_name = repo_name.split(self.URL_SEPARATOR)[-1] |
|
220 | repo_name = repo_name.split(self.URL_SEPARATOR)[-1] | |
221 |
|
221 | |||
222 | new_repo = Repository() |
|
222 | new_repo = Repository() | |
223 | new_repo.enable_statistics = False |
|
223 | new_repo.enable_statistics = False | |
224 | new_repo.repo_name = repo_name_full |
|
224 | new_repo.repo_name = repo_name_full | |
225 | new_repo.repo_type = repo_type |
|
225 | new_repo.repo_type = repo_type | |
226 | new_repo.user = owner |
|
226 | new_repo.user = owner | |
227 | new_repo.group = repos_group |
|
227 | new_repo.group = repos_group | |
228 | new_repo.description = description or repo_name |
|
228 | new_repo.description = description or repo_name | |
229 | new_repo.private = private |
|
229 | new_repo.private = private | |
230 | new_repo.clone_uri = clone_uri |
|
230 | new_repo.clone_uri = clone_uri | |
231 | new_repo.landing_rev = landing_rev |
|
231 | new_repo.landing_rev = landing_rev | |
232 |
|
232 | |||
233 | if fork_of: |
|
233 | if fork_of: | |
234 | parent_repo = fork_of |
|
234 | parent_repo = fork_of | |
235 | new_repo.fork = parent_repo |
|
235 | new_repo.fork = parent_repo | |
236 |
|
236 | |||
237 | self.sa.add(new_repo) |
|
237 | self.sa.add(new_repo) | |
238 |
|
238 | |||
239 | def _create_default_perms(): |
|
239 | def _create_default_perms(): | |
240 | # create default permission |
|
240 | # create default permission | |
241 | repo_to_perm = UserRepoToPerm() |
|
241 | repo_to_perm = UserRepoToPerm() | |
242 | default = 'repository.read' |
|
242 | default = 'repository.read' | |
243 | for p in User.get_by_username('default').user_perms: |
|
243 | for p in User.get_by_username('default').user_perms: | |
244 | if p.permission.permission_name.startswith('repository.'): |
|
244 | if p.permission.permission_name.startswith('repository.'): | |
245 | default = p.permission.permission_name |
|
245 | default = p.permission.permission_name | |
246 | break |
|
246 | break | |
247 |
|
247 | |||
248 | default_perm = 'repository.none' if private else default |
|
248 | default_perm = 'repository.none' if private else default | |
249 |
|
249 | |||
250 | repo_to_perm.permission_id = self.sa.query(Permission)\ |
|
250 | repo_to_perm.permission_id = self.sa.query(Permission)\ | |
251 | .filter(Permission.permission_name == default_perm)\ |
|
251 | .filter(Permission.permission_name == default_perm)\ | |
252 | .one().permission_id |
|
252 | .one().permission_id | |
253 |
|
253 | |||
254 | repo_to_perm.repository = new_repo |
|
254 | repo_to_perm.repository = new_repo | |
255 | repo_to_perm.user_id = User.get_by_username('default').user_id |
|
255 | repo_to_perm.user_id = User.get_by_username('default').user_id | |
256 |
|
256 | |||
257 | self.sa.add(repo_to_perm) |
|
257 | self.sa.add(repo_to_perm) | |
258 |
|
258 | |||
259 | if fork_of: |
|
259 | if fork_of: | |
260 | if copy_fork_permissions: |
|
260 | if copy_fork_permissions: | |
261 | repo = fork_of |
|
261 | repo = fork_of | |
262 | user_perms = UserRepoToPerm.query()\ |
|
262 | user_perms = UserRepoToPerm.query()\ | |
263 | .filter(UserRepoToPerm.repository == repo).all() |
|
263 | .filter(UserRepoToPerm.repository == repo).all() | |
264 | group_perms = UsersGroupRepoToPerm.query()\ |
|
264 | group_perms = UsersGroupRepoToPerm.query()\ | |
265 | .filter(UsersGroupRepoToPerm.repository == repo).all() |
|
265 | .filter(UsersGroupRepoToPerm.repository == repo).all() | |
266 |
|
266 | |||
267 | for perm in user_perms: |
|
267 | for perm in user_perms: | |
268 | UserRepoToPerm.create(perm.user, new_repo, |
|
268 | UserRepoToPerm.create(perm.user, new_repo, | |
269 | perm.permission) |
|
269 | perm.permission) | |
270 |
|
270 | |||
271 | for perm in group_perms: |
|
271 | for perm in group_perms: | |
272 | UsersGroupRepoToPerm.create(perm.users_group, new_repo, |
|
272 | UsersGroupRepoToPerm.create(perm.users_group, new_repo, | |
273 | perm.permission) |
|
273 | perm.permission) | |
274 | else: |
|
274 | else: | |
275 | _create_default_perms() |
|
275 | _create_default_perms() | |
276 | else: |
|
276 | else: | |
277 | _create_default_perms() |
|
277 | _create_default_perms() | |
278 |
|
278 | |||
279 | if not just_db: |
|
279 | if not just_db: | |
280 | self.__create_repo(repo_name, repo_type, |
|
280 | self.__create_repo(repo_name, repo_type, | |
281 | repos_group, |
|
281 | repos_group, | |
282 | clone_uri) |
|
282 | clone_uri) | |
283 | log_create_repository(new_repo.get_dict(), |
|
283 | log_create_repository(new_repo.get_dict(), | |
284 | created_by=owner.username) |
|
284 | created_by=owner.username) | |
285 |
|
285 | |||
286 | # now automatically start following this repository as owner |
|
286 | # now automatically start following this repository as owner | |
287 | ScmModel(self.sa).toggle_following_repo(new_repo.repo_id, |
|
287 | ScmModel(self.sa).toggle_following_repo(new_repo.repo_id, | |
288 | owner.user_id) |
|
288 | owner.user_id) | |
289 | return new_repo |
|
289 | return new_repo | |
290 | except: |
|
290 | except: | |
291 | log.error(traceback.format_exc()) |
|
291 | log.error(traceback.format_exc()) | |
292 | raise |
|
292 | raise | |
293 |
|
293 | |||
294 | def create(self, form_data, cur_user, just_db=False, fork=None): |
|
294 | def create(self, form_data, cur_user, just_db=False, fork=None): | |
295 |
|
295 | |||
296 | repo_name = form_data['repo_name_full'] |
|
296 | repo_name = form_data['repo_name_full'] | |
297 | repo_type = form_data['repo_type'] |
|
297 | repo_type = form_data['repo_type'] | |
298 | description = form_data['description'] |
|
298 | description = form_data['description'] | |
299 | owner = cur_user |
|
299 | owner = cur_user | |
300 | private = form_data['private'] |
|
300 | private = form_data['private'] | |
301 | clone_uri = form_data.get('clone_uri') |
|
301 | clone_uri = form_data.get('clone_uri') | |
302 | repos_group = form_data['repo_group'] |
|
302 | repos_group = form_data['repo_group'] | |
303 | landing_rev = form_data['landing_rev'] |
|
303 | landing_rev = form_data['landing_rev'] | |
304 | copy_fork_permissions = form_data.get('copy_permissions') |
|
304 | copy_fork_permissions = form_data.get('copy_permissions') | |
305 | fork_of = form_data.get('fork_parent_id') |
|
305 | fork_of = form_data.get('fork_parent_id') | |
306 | return self.create_repo( |
|
306 | return self.create_repo( | |
307 | repo_name, repo_type, description, owner, private, clone_uri, |
|
307 | repo_name, repo_type, description, owner, private, clone_uri, | |
308 | repos_group, landing_rev, just_db, fork_of, copy_fork_permissions |
|
308 | repos_group, landing_rev, just_db, fork_of, copy_fork_permissions | |
309 | ) |
|
309 | ) | |
310 |
|
310 | |||
311 | def create_fork(self, form_data, cur_user): |
|
311 | def create_fork(self, form_data, cur_user): | |
312 | """ |
|
312 | """ | |
313 | Simple wrapper into executing celery task for fork creation |
|
313 | Simple wrapper into executing celery task for fork creation | |
314 |
|
314 | |||
315 | :param form_data: |
|
315 | :param form_data: | |
316 | :param cur_user: |
|
316 | :param cur_user: | |
317 | """ |
|
317 | """ | |
318 | from rhodecode.lib.celerylib import tasks, run_task |
|
318 | from rhodecode.lib.celerylib import tasks, run_task | |
319 | run_task(tasks.create_repo_fork, form_data, cur_user) |
|
319 | run_task(tasks.create_repo_fork, form_data, cur_user) | |
320 |
|
320 | |||
321 | def delete(self, repo): |
|
321 | def delete(self, repo): | |
322 | repo = self._get_repo(repo) |
|
322 | repo = self._get_repo(repo) | |
323 | if repo: |
|
323 | if repo: | |
324 | try: |
|
324 | try: | |
325 | self.sa.delete(repo) |
|
325 | self.sa.delete(repo) | |
326 | self.__delete_repo(repo) |
|
326 | self.__delete_repo(repo) | |
327 | except: |
|
327 | except: | |
328 | log.error(traceback.format_exc()) |
|
328 | log.error(traceback.format_exc()) | |
329 | raise |
|
329 | raise | |
330 |
|
330 | |||
331 | def grant_user_permission(self, repo, user, perm): |
|
331 | def grant_user_permission(self, repo, user, perm): | |
332 | """ |
|
332 | """ | |
333 | Grant permission for user on given repository, or update existing one |
|
333 | Grant permission for user on given repository, or update existing one | |
334 | if found |
|
334 | if found | |
335 |
|
335 | |||
336 | :param repo: Instance of Repository, repository_id, or repository name |
|
336 | :param repo: Instance of Repository, repository_id, or repository name | |
337 | :param user: Instance of User, user_id or username |
|
337 | :param user: Instance of User, user_id or username | |
338 | :param perm: Instance of Permission, or permission_name |
|
338 | :param perm: Instance of Permission, or permission_name | |
339 | """ |
|
339 | """ | |
340 | user = self._get_user(user) |
|
340 | user = self._get_user(user) | |
341 | repo = self._get_repo(repo) |
|
341 | repo = self._get_repo(repo) | |
342 | permission = self._get_perm(perm) |
|
342 | permission = self._get_perm(perm) | |
343 |
|
343 | |||
344 | # check if we have that permission already |
|
344 | # check if we have that permission already | |
345 | obj = self.sa.query(UserRepoToPerm)\ |
|
345 | obj = self.sa.query(UserRepoToPerm)\ | |
346 | .filter(UserRepoToPerm.user == user)\ |
|
346 | .filter(UserRepoToPerm.user == user)\ | |
347 | .filter(UserRepoToPerm.repository == repo)\ |
|
347 | .filter(UserRepoToPerm.repository == repo)\ | |
348 | .scalar() |
|
348 | .scalar() | |
349 | if obj is None: |
|
349 | if obj is None: | |
350 | # create new ! |
|
350 | # create new ! | |
351 | obj = UserRepoToPerm() |
|
351 | obj = UserRepoToPerm() | |
352 | obj.repository = repo |
|
352 | obj.repository = repo | |
353 | obj.user = user |
|
353 | obj.user = user | |
354 | obj.permission = permission |
|
354 | obj.permission = permission | |
355 | self.sa.add(obj) |
|
355 | self.sa.add(obj) | |
356 |
|
356 | |||
357 | def revoke_user_permission(self, repo, user): |
|
357 | def revoke_user_permission(self, repo, user): | |
358 | """ |
|
358 | """ | |
359 | Revoke permission for user on given repository |
|
359 | Revoke permission for user on given repository | |
360 |
|
360 | |||
361 | :param repo: Instance of Repository, repository_id, or repository name |
|
361 | :param repo: Instance of Repository, repository_id, or repository name | |
362 | :param user: Instance of User, user_id or username |
|
362 | :param user: Instance of User, user_id or username | |
363 | """ |
|
363 | """ | |
364 |
|
364 | |||
365 | user = self._get_user(user) |
|
365 | user = self._get_user(user) | |
366 | repo = self._get_repo(repo) |
|
366 | repo = self._get_repo(repo) | |
367 |
|
367 | |||
368 | obj = self.sa.query(UserRepoToPerm)\ |
|
368 | obj = self.sa.query(UserRepoToPerm)\ | |
369 | .filter(UserRepoToPerm.repository == repo)\ |
|
369 | .filter(UserRepoToPerm.repository == repo)\ | |
370 | .filter(UserRepoToPerm.user == user)\ |
|
370 | .filter(UserRepoToPerm.user == user)\ | |
371 | .one() |
|
371 | .one() | |
372 | self.sa.delete(obj) |
|
372 | self.sa.delete(obj) | |
373 |
|
373 | |||
374 | def grant_users_group_permission(self, repo, group_name, perm): |
|
374 | def grant_users_group_permission(self, repo, group_name, perm): | |
375 | """ |
|
375 | """ | |
376 | Grant permission for users group on given repository, or update |
|
376 | Grant permission for users group on given repository, or update | |
377 | existing one if found |
|
377 | existing one if found | |
378 |
|
378 | |||
379 | :param repo: Instance of Repository, repository_id, or repository name |
|
379 | :param repo: Instance of Repository, repository_id, or repository name | |
380 | :param group_name: Instance of UserGroup, users_group_id, |
|
380 | :param group_name: Instance of UserGroup, users_group_id, | |
381 | or users group name |
|
381 | or users group name | |
382 | :param perm: Instance of Permission, or permission_name |
|
382 | :param perm: Instance of Permission, or permission_name | |
383 | """ |
|
383 | """ | |
384 | repo = self._get_repo(repo) |
|
384 | repo = self._get_repo(repo) | |
385 | group_name = self.__get_users_group(group_name) |
|
385 | group_name = self.__get_users_group(group_name) | |
386 | permission = self._get_perm(perm) |
|
386 | permission = self._get_perm(perm) | |
387 |
|
387 | |||
388 | # check if we have that permission already |
|
388 | # check if we have that permission already | |
389 | obj = self.sa.query(UsersGroupRepoToPerm)\ |
|
389 | obj = self.sa.query(UsersGroupRepoToPerm)\ | |
390 | .filter(UsersGroupRepoToPerm.users_group == group_name)\ |
|
390 | .filter(UsersGroupRepoToPerm.users_group == group_name)\ | |
391 | .filter(UsersGroupRepoToPerm.repository == repo)\ |
|
391 | .filter(UsersGroupRepoToPerm.repository == repo)\ | |
392 | .scalar() |
|
392 | .scalar() | |
393 |
|
393 | |||
394 | if obj is None: |
|
394 | if obj is None: | |
395 | # create new |
|
395 | # create new | |
396 | obj = UsersGroupRepoToPerm() |
|
396 | obj = UsersGroupRepoToPerm() | |
397 |
|
397 | |||
398 | obj.repository = repo |
|
398 | obj.repository = repo | |
399 | obj.users_group = group_name |
|
399 | obj.users_group = group_name | |
400 | obj.permission = permission |
|
400 | obj.permission = permission | |
401 | self.sa.add(obj) |
|
401 | self.sa.add(obj) | |
402 |
|
402 | |||
403 | def revoke_users_group_permission(self, repo, group_name): |
|
403 | def revoke_users_group_permission(self, repo, group_name): | |
404 | """ |
|
404 | """ | |
405 | Revoke permission for users group on given repository |
|
405 | Revoke permission for users group on given repository | |
406 |
|
406 | |||
407 | :param repo: Instance of Repository, repository_id, or repository name |
|
407 | :param repo: Instance of Repository, repository_id, or repository name | |
408 | :param group_name: Instance of UserGroup, users_group_id, |
|
408 | :param group_name: Instance of UserGroup, users_group_id, | |
409 | or users group name |
|
409 | or users group name | |
410 | """ |
|
410 | """ | |
411 | repo = self._get_repo(repo) |
|
411 | repo = self._get_repo(repo) | |
412 | group_name = self.__get_users_group(group_name) |
|
412 | group_name = self.__get_users_group(group_name) | |
413 |
|
413 | |||
414 | obj = self.sa.query(UsersGroupRepoToPerm)\ |
|
414 | obj = self.sa.query(UsersGroupRepoToPerm)\ | |
415 | .filter(UsersGroupRepoToPerm.repository == repo)\ |
|
415 | .filter(UsersGroupRepoToPerm.repository == repo)\ | |
416 | .filter(UsersGroupRepoToPerm.users_group == group_name)\ |
|
416 | .filter(UsersGroupRepoToPerm.users_group == group_name)\ | |
417 | .one() |
|
417 | .one() | |
418 | self.sa.delete(obj) |
|
418 | self.sa.delete(obj) | |
419 |
|
419 | |||
420 | def delete_stats(self, repo_name): |
|
420 | def delete_stats(self, repo_name): | |
421 | """ |
|
421 | """ | |
422 | removes stats for given repo |
|
422 | removes stats for given repo | |
423 |
|
423 | |||
424 | :param repo_name: |
|
424 | :param repo_name: | |
425 | """ |
|
425 | """ | |
426 | try: |
|
426 | try: | |
427 | obj = self.sa.query(Statistics)\ |
|
427 | obj = self.sa.query(Statistics)\ | |
428 | .filter(Statistics.repository == |
|
428 | .filter(Statistics.repository == | |
429 | self.get_by_repo_name(repo_name))\ |
|
429 | self.get_by_repo_name(repo_name))\ | |
430 | .one() |
|
430 | .one() | |
431 | self.sa.delete(obj) |
|
431 | self.sa.delete(obj) | |
432 | except: |
|
432 | except: | |
433 | log.error(traceback.format_exc()) |
|
433 | log.error(traceback.format_exc()) | |
434 | raise |
|
434 | raise | |
435 |
|
435 | |||
436 | def __create_repo(self, repo_name, alias, parent, clone_uri=False): |
|
436 | def __create_repo(self, repo_name, alias, parent, clone_uri=False): | |
437 | """ |
|
437 | """ | |
438 | makes repository on filesystem. It's group aware means it'll create |
|
438 | makes repository on filesystem. It's group aware means it'll create | |
439 | a repository within a group, and alter the paths accordingly of |
|
439 | a repository within a group, and alter the paths accordingly of | |
440 | group location |
|
440 | group location | |
441 |
|
441 | |||
442 | :param repo_name: |
|
442 | :param repo_name: | |
443 | :param alias: |
|
443 | :param alias: | |
444 | :param parent_id: |
|
444 | :param parent_id: | |
445 | :param clone_uri: |
|
445 | :param clone_uri: | |
446 | """ |
|
446 | """ | |
447 | from rhodecode.lib.utils import is_valid_repo, is_valid_repos_group |
|
447 | from rhodecode.lib.utils import is_valid_repo, is_valid_repos_group | |
448 | from rhodecode.model.scm import ScmModel |
|
448 | from rhodecode.model.scm import ScmModel | |
449 |
|
449 | |||
450 | if parent: |
|
450 | if parent: | |
451 | new_parent_path = os.sep.join(parent.full_path_splitted) |
|
451 | new_parent_path = os.sep.join(parent.full_path_splitted) | |
452 | else: |
|
452 | else: | |
453 | new_parent_path = '' |
|
453 | new_parent_path = '' | |
454 |
|
454 | |||
455 | # we need to make it str for mercurial |
|
455 | # we need to make it str for mercurial | |
456 | repo_path = os.path.join(*map(lambda x: safe_str(x), |
|
456 | repo_path = os.path.join(*map(lambda x: safe_str(x), | |
457 | [self.repos_path, new_parent_path, repo_name])) |
|
457 | [self.repos_path, new_parent_path, repo_name])) | |
458 |
|
458 | |||
459 | # check if this path is not a repository |
|
459 | # check if this path is not a repository | |
460 | if is_valid_repo(repo_path, self.repos_path): |
|
460 | if is_valid_repo(repo_path, self.repos_path): | |
461 | raise Exception('This path %s is a valid repository' % repo_path) |
|
461 | raise Exception('This path %s is a valid repository' % repo_path) | |
462 |
|
462 | |||
463 | # check if this path is a group |
|
463 | # check if this path is a group | |
464 | if is_valid_repos_group(repo_path, self.repos_path): |
|
464 | if is_valid_repos_group(repo_path, self.repos_path): | |
465 | raise Exception('This path %s is a valid group' % repo_path) |
|
465 | raise Exception('This path %s is a valid group' % repo_path) | |
466 |
|
466 | |||
467 | log.info('creating repo %s in %s @ %s' % ( |
|
467 | log.info('creating repo %s in %s @ %s' % ( | |
468 | repo_name, safe_unicode(repo_path), clone_uri |
|
468 | repo_name, safe_unicode(repo_path), clone_uri | |
469 | ) |
|
469 | ) | |
470 | ) |
|
470 | ) | |
471 | backend = get_backend(alias) |
|
471 | backend = get_backend(alias) | |
472 | if alias == 'hg': |
|
472 | if alias == 'hg': | |
473 | backend(repo_path, create=True, src_url=clone_uri) |
|
473 | backend(repo_path, create=True, src_url=clone_uri) | |
474 | elif alias == 'git': |
|
474 | elif alias == 'git': | |
475 | r = backend(repo_path, create=True, src_url=clone_uri, bare=True) |
|
475 | r = backend(repo_path, create=True, src_url=clone_uri, bare=True) | |
476 | # add rhodecode hook into this repo |
|
476 | # add rhodecode hook into this repo | |
477 | ScmModel().install_git_hook(repo=r) |
|
477 | ScmModel().install_git_hook(repo=r) | |
478 | else: |
|
478 | else: | |
479 | raise Exception('Undefined alias %s' % alias) |
|
479 | raise Exception('Undefined alias %s' % alias) | |
480 |
|
480 | |||
481 | def __rename_repo(self, old, new): |
|
481 | def __rename_repo(self, old, new): | |
482 | """ |
|
482 | """ | |
483 | renames repository on filesystem |
|
483 | renames repository on filesystem | |
484 |
|
484 | |||
485 | :param old: old name |
|
485 | :param old: old name | |
486 | :param new: new name |
|
486 | :param new: new name | |
487 | """ |
|
487 | """ | |
488 | log.info('renaming repo from %s to %s' % (old, new)) |
|
488 | log.info('renaming repo from %s to %s' % (old, new)) | |
489 |
|
489 | |||
490 | old_path = os.path.join(self.repos_path, old) |
|
490 | old_path = os.path.join(self.repos_path, old) | |
491 | new_path = os.path.join(self.repos_path, new) |
|
491 | new_path = os.path.join(self.repos_path, new) | |
492 | if os.path.isdir(new_path): |
|
492 | if os.path.isdir(new_path): | |
493 | raise Exception( |
|
493 | raise Exception( | |
494 | 'Was trying to rename to already existing dir %s' % new_path |
|
494 | 'Was trying to rename to already existing dir %s' % new_path | |
495 | ) |
|
495 | ) | |
496 | shutil.move(old_path, new_path) |
|
496 | shutil.move(old_path, new_path) | |
497 |
|
497 | |||
498 | def __delete_repo(self, repo): |
|
498 | def __delete_repo(self, repo): | |
499 | """ |
|
499 | """ | |
500 | removes repo from filesystem, the removal is acctually made by |
|
500 | removes repo from filesystem, the removal is acctually made by | |
501 | added rm__ prefix into dir, and rename internat .hg/.git dirs so this |
|
501 | added rm__ prefix into dir, and rename internat .hg/.git dirs so this | |
502 | repository is no longer valid for rhodecode, can be undeleted later on |
|
502 | repository is no longer valid for rhodecode, can be undeleted later on | |
503 | by reverting the renames on this repository |
|
503 | by reverting the renames on this repository | |
504 |
|
504 | |||
505 | :param repo: repo object |
|
505 | :param repo: repo object | |
506 | """ |
|
506 | """ | |
507 | rm_path = os.path.join(self.repos_path, repo.repo_name) |
|
507 | rm_path = os.path.join(self.repos_path, repo.repo_name) | |
508 | log.info("Removing %s" % (rm_path)) |
|
508 | log.info("Removing %s" % (rm_path)) | |
509 | # disable hg/git internal that it doesn't get detected as repo |
|
509 | # disable hg/git internal that it doesn't get detected as repo | |
510 | alias = repo.repo_type |
|
510 | alias = repo.repo_type | |
511 |
|
511 | |||
512 | bare = getattr(repo.scm_instance, 'bare', False) |
|
512 | bare = getattr(repo.scm_instance, 'bare', False) | |
513 |
|
513 | |||
514 | if not bare: |
|
514 | if not bare: | |
515 | # skip this for bare git repos |
|
515 | # skip this for bare git repos | |
516 | shutil.move(os.path.join(rm_path, '.%s' % alias), |
|
516 | shutil.move(os.path.join(rm_path, '.%s' % alias), | |
517 | os.path.join(rm_path, 'rm__.%s' % alias)) |
|
517 | os.path.join(rm_path, 'rm__.%s' % alias)) | |
518 | # disable repo |
|
518 | # disable repo | |
519 | _now = datetime.now() |
|
519 | _now = datetime.now() | |
520 | _ms = str(_now.microsecond).rjust(6, '0') |
|
520 | _ms = str(_now.microsecond).rjust(6, '0') | |
521 | _d = 'rm__%s__%s' % (_now.strftime('%Y%m%d_%H%M%S_' + _ms), |
|
521 | _d = 'rm__%s__%s' % (_now.strftime('%Y%m%d_%H%M%S_' + _ms), | |
522 | repo.repo_name) |
|
522 | repo.repo_name) | |
523 | shutil.move(rm_path, os.path.join(self.repos_path, _d)) |
|
523 | shutil.move(rm_path, os.path.join(self.repos_path, _d)) |
@@ -1,305 +1,305 | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """ |
|
2 | """ | |
3 | rhodecode.model.user_group |
|
3 | rhodecode.model.user_group | |
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
5 |
|
5 | |||
6 | users groups model for RhodeCode |
|
6 | users groups model for RhodeCode | |
7 |
|
7 | |||
8 | :created_on: Jan 25, 2011 |
|
8 | :created_on: Jan 25, 2011 | |
9 | :author: marcink |
|
9 | :author: marcink | |
10 | :copyright: (C) 2011-2012 Marcin Kuzminski <marcin@python-works.com> |
|
10 | :copyright: (C) 2011-2012 Marcin Kuzminski <marcin@python-works.com> | |
11 | :license: GPLv3, see COPYING for more details. |
|
11 | :license: GPLv3, see COPYING for more details. | |
12 | """ |
|
12 | """ | |
13 | # This program is free software: you can redistribute it and/or modify |
|
13 | # This program is free software: you can redistribute it and/or modify | |
14 | # it under the terms of the GNU General Public License as published by |
|
14 | # it under the terms of the GNU General Public License as published by | |
15 | # the Free Software Foundation, either version 3 of the License, or |
|
15 | # the Free Software Foundation, either version 3 of the License, or | |
16 | # (at your option) any later version. |
|
16 | # (at your option) any later version. | |
17 | # |
|
17 | # | |
18 | # This program is distributed in the hope that it will be useful, |
|
18 | # This program is distributed in the hope that it will be useful, | |
19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21 | # GNU General Public License for more details. |
|
21 | # GNU General Public License for more details. | |
22 | # |
|
22 | # | |
23 | # You should have received a copy of the GNU General Public License |
|
23 | # You should have received a copy of the GNU General Public License | |
24 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
24 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
25 |
|
25 | |||
26 | import os |
|
26 | import os | |
27 | import logging |
|
27 | import logging | |
28 | import traceback |
|
28 | import traceback | |
29 | import shutil |
|
29 | import shutil | |
30 |
|
30 | |||
31 | from rhodecode.lib.utils2 import LazyProperty |
|
31 | from rhodecode.lib.utils2 import LazyProperty | |
32 |
|
32 | |||
33 | from rhodecode.model import BaseModel |
|
33 | from rhodecode.model import BaseModel | |
34 | from rhodecode.model.db import RepoGroup, RhodeCodeUi, UserRepoGroupToPerm, \ |
|
34 | from rhodecode.model.db import RepoGroup, RhodeCodeUi, UserRepoGroupToPerm, \ | |
35 | User, Permission, UsersGroupRepoGroupToPerm, UsersGroup |
|
35 | User, Permission, UsersGroupRepoGroupToPerm, UsersGroup | |
36 |
|
36 | |||
37 | log = logging.getLogger(__name__) |
|
37 | log = logging.getLogger(__name__) | |
38 |
|
38 | |||
39 |
|
39 | |||
40 | class ReposGroupModel(BaseModel): |
|
40 | class ReposGroupModel(BaseModel): | |
41 |
|
41 | |||
42 | cls = RepoGroup |
|
42 | cls = RepoGroup | |
43 |
|
43 | |||
44 | def __get_users_group(self, users_group): |
|
44 | def __get_users_group(self, users_group): | |
45 | return self._get_instance(UsersGroup, users_group, |
|
45 | return self._get_instance(UsersGroup, users_group, | |
46 | callback=UsersGroup.get_by_group_name) |
|
46 | callback=UsersGroup.get_by_group_name) | |
47 |
|
47 | |||
48 |
def |
|
48 | def _get_repos_group(self, repos_group): | |
49 | return self._get_instance(RepoGroup, repos_group, |
|
49 | return self._get_instance(RepoGroup, repos_group, | |
50 | callback=RepoGroup.get_by_group_name) |
|
50 | callback=RepoGroup.get_by_group_name) | |
51 |
|
51 | |||
52 | @LazyProperty |
|
52 | @LazyProperty | |
53 | def repos_path(self): |
|
53 | def repos_path(self): | |
54 | """ |
|
54 | """ | |
55 | Get's the repositories root path from database |
|
55 | Get's the repositories root path from database | |
56 | """ |
|
56 | """ | |
57 |
|
57 | |||
58 | q = RhodeCodeUi.get_by_key('/').one() |
|
58 | q = RhodeCodeUi.get_by_key('/').one() | |
59 | return q.ui_value |
|
59 | return q.ui_value | |
60 |
|
60 | |||
61 | def _create_default_perms(self, new_group): |
|
61 | def _create_default_perms(self, new_group): | |
62 | # create default permission |
|
62 | # create default permission | |
63 | repo_group_to_perm = UserRepoGroupToPerm() |
|
63 | repo_group_to_perm = UserRepoGroupToPerm() | |
64 | default_perm = 'group.read' |
|
64 | default_perm = 'group.read' | |
65 | for p in User.get_by_username('default').user_perms: |
|
65 | for p in User.get_by_username('default').user_perms: | |
66 | if p.permission.permission_name.startswith('group.'): |
|
66 | if p.permission.permission_name.startswith('group.'): | |
67 | default_perm = p.permission.permission_name |
|
67 | default_perm = p.permission.permission_name | |
68 | break |
|
68 | break | |
69 |
|
69 | |||
70 | repo_group_to_perm.permission_id = self.sa.query(Permission)\ |
|
70 | repo_group_to_perm.permission_id = self.sa.query(Permission)\ | |
71 | .filter(Permission.permission_name == default_perm)\ |
|
71 | .filter(Permission.permission_name == default_perm)\ | |
72 | .one().permission_id |
|
72 | .one().permission_id | |
73 |
|
73 | |||
74 | repo_group_to_perm.group = new_group |
|
74 | repo_group_to_perm.group = new_group | |
75 | repo_group_to_perm.user_id = User.get_by_username('default').user_id |
|
75 | repo_group_to_perm.user_id = User.get_by_username('default').user_id | |
76 |
|
76 | |||
77 | self.sa.add(repo_group_to_perm) |
|
77 | self.sa.add(repo_group_to_perm) | |
78 |
|
78 | |||
79 | def __create_group(self, group_name): |
|
79 | def __create_group(self, group_name): | |
80 | """ |
|
80 | """ | |
81 | makes repositories group on filesystem |
|
81 | makes repositories group on filesystem | |
82 |
|
82 | |||
83 | :param repo_name: |
|
83 | :param repo_name: | |
84 | :param parent_id: |
|
84 | :param parent_id: | |
85 | """ |
|
85 | """ | |
86 |
|
86 | |||
87 | create_path = os.path.join(self.repos_path, group_name) |
|
87 | create_path = os.path.join(self.repos_path, group_name) | |
88 | log.debug('creating new group in %s' % create_path) |
|
88 | log.debug('creating new group in %s' % create_path) | |
89 |
|
89 | |||
90 | if os.path.isdir(create_path): |
|
90 | if os.path.isdir(create_path): | |
91 | raise Exception('That directory already exists !') |
|
91 | raise Exception('That directory already exists !') | |
92 |
|
92 | |||
93 | os.makedirs(create_path) |
|
93 | os.makedirs(create_path) | |
94 |
|
94 | |||
95 | def __rename_group(self, old, new): |
|
95 | def __rename_group(self, old, new): | |
96 | """ |
|
96 | """ | |
97 | Renames a group on filesystem |
|
97 | Renames a group on filesystem | |
98 |
|
98 | |||
99 | :param group_name: |
|
99 | :param group_name: | |
100 | """ |
|
100 | """ | |
101 |
|
101 | |||
102 | if old == new: |
|
102 | if old == new: | |
103 | log.debug('skipping group rename') |
|
103 | log.debug('skipping group rename') | |
104 | return |
|
104 | return | |
105 |
|
105 | |||
106 | log.debug('renaming repos group from %s to %s' % (old, new)) |
|
106 | log.debug('renaming repos group from %s to %s' % (old, new)) | |
107 |
|
107 | |||
108 | old_path = os.path.join(self.repos_path, old) |
|
108 | old_path = os.path.join(self.repos_path, old) | |
109 | new_path = os.path.join(self.repos_path, new) |
|
109 | new_path = os.path.join(self.repos_path, new) | |
110 |
|
110 | |||
111 | log.debug('renaming repos paths from %s to %s' % (old_path, new_path)) |
|
111 | log.debug('renaming repos paths from %s to %s' % (old_path, new_path)) | |
112 |
|
112 | |||
113 | if os.path.isdir(new_path): |
|
113 | if os.path.isdir(new_path): | |
114 | raise Exception('Was trying to rename to already ' |
|
114 | raise Exception('Was trying to rename to already ' | |
115 | 'existing dir %s' % new_path) |
|
115 | 'existing dir %s' % new_path) | |
116 | shutil.move(old_path, new_path) |
|
116 | shutil.move(old_path, new_path) | |
117 |
|
117 | |||
118 | def __delete_group(self, group): |
|
118 | def __delete_group(self, group): | |
119 | """ |
|
119 | """ | |
120 | Deletes a group from a filesystem |
|
120 | Deletes a group from a filesystem | |
121 |
|
121 | |||
122 | :param group: instance of group from database |
|
122 | :param group: instance of group from database | |
123 | """ |
|
123 | """ | |
124 | paths = group.full_path.split(RepoGroup.url_sep()) |
|
124 | paths = group.full_path.split(RepoGroup.url_sep()) | |
125 | paths = os.sep.join(paths) |
|
125 | paths = os.sep.join(paths) | |
126 |
|
126 | |||
127 | rm_path = os.path.join(self.repos_path, paths) |
|
127 | rm_path = os.path.join(self.repos_path, paths) | |
128 | if os.path.isdir(rm_path): |
|
128 | if os.path.isdir(rm_path): | |
129 | # delete only if that path really exists |
|
129 | # delete only if that path really exists | |
130 | os.rmdir(rm_path) |
|
130 | os.rmdir(rm_path) | |
131 |
|
131 | |||
132 | def create(self, group_name, group_description, parent=None, just_db=False): |
|
132 | def create(self, group_name, group_description, parent=None, just_db=False): | |
133 | try: |
|
133 | try: | |
134 | new_repos_group = RepoGroup() |
|
134 | new_repos_group = RepoGroup() | |
135 | new_repos_group.group_description = group_description |
|
135 | new_repos_group.group_description = group_description | |
136 |
new_repos_group.parent_group = self. |
|
136 | new_repos_group.parent_group = self._get_repos_group(parent) | |
137 | new_repos_group.group_name = new_repos_group.get_new_name(group_name) |
|
137 | new_repos_group.group_name = new_repos_group.get_new_name(group_name) | |
138 |
|
138 | |||
139 | self.sa.add(new_repos_group) |
|
139 | self.sa.add(new_repos_group) | |
140 | self._create_default_perms(new_repos_group) |
|
140 | self._create_default_perms(new_repos_group) | |
141 |
|
141 | |||
142 | if not just_db: |
|
142 | if not just_db: | |
143 | # we need to flush here, in order to check if database won't |
|
143 | # we need to flush here, in order to check if database won't | |
144 | # throw any exceptions, create filesystem dirs at the very end |
|
144 | # throw any exceptions, create filesystem dirs at the very end | |
145 | self.sa.flush() |
|
145 | self.sa.flush() | |
146 | self.__create_group(new_repos_group.group_name) |
|
146 | self.__create_group(new_repos_group.group_name) | |
147 |
|
147 | |||
148 | return new_repos_group |
|
148 | return new_repos_group | |
149 | except: |
|
149 | except: | |
150 | log.error(traceback.format_exc()) |
|
150 | log.error(traceback.format_exc()) | |
151 | raise |
|
151 | raise | |
152 |
|
152 | |||
153 | def update(self, repos_group_id, form_data): |
|
153 | def update(self, repos_group_id, form_data): | |
154 |
|
154 | |||
155 | try: |
|
155 | try: | |
156 | repos_group = RepoGroup.get(repos_group_id) |
|
156 | repos_group = RepoGroup.get(repos_group_id) | |
157 |
|
157 | |||
158 | # update permissions |
|
158 | # update permissions | |
159 | for member, perm, member_type in form_data['perms_updates']: |
|
159 | for member, perm, member_type in form_data['perms_updates']: | |
160 | if member_type == 'user': |
|
160 | if member_type == 'user': | |
161 | # this updates also current one if found |
|
161 | # this updates also current one if found | |
162 | ReposGroupModel().grant_user_permission( |
|
162 | ReposGroupModel().grant_user_permission( | |
163 | repos_group=repos_group, user=member, perm=perm |
|
163 | repos_group=repos_group, user=member, perm=perm | |
164 | ) |
|
164 | ) | |
165 | else: |
|
165 | else: | |
166 | ReposGroupModel().grant_users_group_permission( |
|
166 | ReposGroupModel().grant_users_group_permission( | |
167 | repos_group=repos_group, group_name=member, perm=perm |
|
167 | repos_group=repos_group, group_name=member, perm=perm | |
168 | ) |
|
168 | ) | |
169 | # set new permissions |
|
169 | # set new permissions | |
170 | for member, perm, member_type in form_data['perms_new']: |
|
170 | for member, perm, member_type in form_data['perms_new']: | |
171 | if member_type == 'user': |
|
171 | if member_type == 'user': | |
172 | ReposGroupModel().grant_user_permission( |
|
172 | ReposGroupModel().grant_user_permission( | |
173 | repos_group=repos_group, user=member, perm=perm |
|
173 | repos_group=repos_group, user=member, perm=perm | |
174 | ) |
|
174 | ) | |
175 | else: |
|
175 | else: | |
176 | ReposGroupModel().grant_users_group_permission( |
|
176 | ReposGroupModel().grant_users_group_permission( | |
177 | repos_group=repos_group, group_name=member, perm=perm |
|
177 | repos_group=repos_group, group_name=member, perm=perm | |
178 | ) |
|
178 | ) | |
179 |
|
179 | |||
180 | old_path = repos_group.full_path |
|
180 | old_path = repos_group.full_path | |
181 |
|
181 | |||
182 | # change properties |
|
182 | # change properties | |
183 | repos_group.group_description = form_data['group_description'] |
|
183 | repos_group.group_description = form_data['group_description'] | |
184 | repos_group.parent_group = RepoGroup.get(form_data['group_parent_id']) |
|
184 | repos_group.parent_group = RepoGroup.get(form_data['group_parent_id']) | |
185 | repos_group.group_parent_id = form_data['group_parent_id'] |
|
185 | repos_group.group_parent_id = form_data['group_parent_id'] | |
186 | repos_group.group_name = repos_group.get_new_name(form_data['group_name']) |
|
186 | repos_group.group_name = repos_group.get_new_name(form_data['group_name']) | |
187 | new_path = repos_group.full_path |
|
187 | new_path = repos_group.full_path | |
188 |
|
188 | |||
189 | self.sa.add(repos_group) |
|
189 | self.sa.add(repos_group) | |
190 |
|
190 | |||
191 | # we need to get all repositories from this new group and |
|
191 | # we need to get all repositories from this new group and | |
192 | # rename them accordingly to new group path |
|
192 | # rename them accordingly to new group path | |
193 | for r in repos_group.repositories: |
|
193 | for r in repos_group.repositories: | |
194 | r.repo_name = r.get_new_name(r.just_name) |
|
194 | r.repo_name = r.get_new_name(r.just_name) | |
195 | self.sa.add(r) |
|
195 | self.sa.add(r) | |
196 |
|
196 | |||
197 | self.__rename_group(old_path, new_path) |
|
197 | self.__rename_group(old_path, new_path) | |
198 |
|
198 | |||
199 | return repos_group |
|
199 | return repos_group | |
200 | except: |
|
200 | except: | |
201 | log.error(traceback.format_exc()) |
|
201 | log.error(traceback.format_exc()) | |
202 | raise |
|
202 | raise | |
203 |
|
203 | |||
204 | def delete(self, repos_group): |
|
204 | def delete(self, repos_group): | |
205 |
repos_group = self. |
|
205 | repos_group = self._get_repos_group(repos_group) | |
206 | try: |
|
206 | try: | |
207 | self.sa.delete(repos_group) |
|
207 | self.sa.delete(repos_group) | |
208 | self.__delete_group(repos_group) |
|
208 | self.__delete_group(repos_group) | |
209 | except: |
|
209 | except: | |
210 | log.exception('Error removing repos_group %s' % repos_group) |
|
210 | log.exception('Error removing repos_group %s' % repos_group) | |
211 | raise |
|
211 | raise | |
212 |
|
212 | |||
213 | def grant_user_permission(self, repos_group, user, perm): |
|
213 | def grant_user_permission(self, repos_group, user, perm): | |
214 | """ |
|
214 | """ | |
215 | Grant permission for user on given repositories group, or update |
|
215 | Grant permission for user on given repositories group, or update | |
216 | existing one if found |
|
216 | existing one if found | |
217 |
|
217 | |||
218 | :param repos_group: Instance of ReposGroup, repositories_group_id, |
|
218 | :param repos_group: Instance of ReposGroup, repositories_group_id, | |
219 | or repositories_group name |
|
219 | or repositories_group name | |
220 | :param user: Instance of User, user_id or username |
|
220 | :param user: Instance of User, user_id or username | |
221 | :param perm: Instance of Permission, or permission_name |
|
221 | :param perm: Instance of Permission, or permission_name | |
222 | """ |
|
222 | """ | |
223 |
|
223 | |||
224 |
repos_group = self. |
|
224 | repos_group = self._get_repos_group(repos_group) | |
225 | user = self._get_user(user) |
|
225 | user = self._get_user(user) | |
226 | permission = self._get_perm(perm) |
|
226 | permission = self._get_perm(perm) | |
227 |
|
227 | |||
228 | # check if we have that permission already |
|
228 | # check if we have that permission already | |
229 | obj = self.sa.query(UserRepoGroupToPerm)\ |
|
229 | obj = self.sa.query(UserRepoGroupToPerm)\ | |
230 | .filter(UserRepoGroupToPerm.user == user)\ |
|
230 | .filter(UserRepoGroupToPerm.user == user)\ | |
231 | .filter(UserRepoGroupToPerm.group == repos_group)\ |
|
231 | .filter(UserRepoGroupToPerm.group == repos_group)\ | |
232 | .scalar() |
|
232 | .scalar() | |
233 | if obj is None: |
|
233 | if obj is None: | |
234 | # create new ! |
|
234 | # create new ! | |
235 | obj = UserRepoGroupToPerm() |
|
235 | obj = UserRepoGroupToPerm() | |
236 | obj.group = repos_group |
|
236 | obj.group = repos_group | |
237 | obj.user = user |
|
237 | obj.user = user | |
238 | obj.permission = permission |
|
238 | obj.permission = permission | |
239 | self.sa.add(obj) |
|
239 | self.sa.add(obj) | |
240 |
|
240 | |||
241 | def revoke_user_permission(self, repos_group, user): |
|
241 | def revoke_user_permission(self, repos_group, user): | |
242 | """ |
|
242 | """ | |
243 | Revoke permission for user on given repositories group |
|
243 | Revoke permission for user on given repositories group | |
244 |
|
244 | |||
245 | :param repos_group: Instance of ReposGroup, repositories_group_id, |
|
245 | :param repos_group: Instance of ReposGroup, repositories_group_id, | |
246 | or repositories_group name |
|
246 | or repositories_group name | |
247 | :param user: Instance of User, user_id or username |
|
247 | :param user: Instance of User, user_id or username | |
248 | """ |
|
248 | """ | |
249 |
|
249 | |||
250 |
repos_group = self. |
|
250 | repos_group = self._get_repos_group(repos_group) | |
251 | user = self._get_user(user) |
|
251 | user = self._get_user(user) | |
252 |
|
252 | |||
253 | obj = self.sa.query(UserRepoGroupToPerm)\ |
|
253 | obj = self.sa.query(UserRepoGroupToPerm)\ | |
254 | .filter(UserRepoGroupToPerm.user == user)\ |
|
254 | .filter(UserRepoGroupToPerm.user == user)\ | |
255 | .filter(UserRepoGroupToPerm.group == repos_group)\ |
|
255 | .filter(UserRepoGroupToPerm.group == repos_group)\ | |
256 | .one() |
|
256 | .one() | |
257 | self.sa.delete(obj) |
|
257 | self.sa.delete(obj) | |
258 |
|
258 | |||
259 | def grant_users_group_permission(self, repos_group, group_name, perm): |
|
259 | def grant_users_group_permission(self, repos_group, group_name, perm): | |
260 | """ |
|
260 | """ | |
261 | Grant permission for users group on given repositories group, or update |
|
261 | Grant permission for users group on given repositories group, or update | |
262 | existing one if found |
|
262 | existing one if found | |
263 |
|
263 | |||
264 | :param repos_group: Instance of ReposGroup, repositories_group_id, |
|
264 | :param repos_group: Instance of ReposGroup, repositories_group_id, | |
265 | or repositories_group name |
|
265 | or repositories_group name | |
266 | :param group_name: Instance of UserGroup, users_group_id, |
|
266 | :param group_name: Instance of UserGroup, users_group_id, | |
267 | or users group name |
|
267 | or users group name | |
268 | :param perm: Instance of Permission, or permission_name |
|
268 | :param perm: Instance of Permission, or permission_name | |
269 | """ |
|
269 | """ | |
270 |
repos_group = self. |
|
270 | repos_group = self._get_repos_group(repos_group) | |
271 | group_name = self.__get_users_group(group_name) |
|
271 | group_name = self.__get_users_group(group_name) | |
272 | permission = self._get_perm(perm) |
|
272 | permission = self._get_perm(perm) | |
273 |
|
273 | |||
274 | # check if we have that permission already |
|
274 | # check if we have that permission already | |
275 | obj = self.sa.query(UsersGroupRepoGroupToPerm)\ |
|
275 | obj = self.sa.query(UsersGroupRepoGroupToPerm)\ | |
276 | .filter(UsersGroupRepoGroupToPerm.group == repos_group)\ |
|
276 | .filter(UsersGroupRepoGroupToPerm.group == repos_group)\ | |
277 | .filter(UsersGroupRepoGroupToPerm.users_group == group_name)\ |
|
277 | .filter(UsersGroupRepoGroupToPerm.users_group == group_name)\ | |
278 | .scalar() |
|
278 | .scalar() | |
279 |
|
279 | |||
280 | if obj is None: |
|
280 | if obj is None: | |
281 | # create new |
|
281 | # create new | |
282 | obj = UsersGroupRepoGroupToPerm() |
|
282 | obj = UsersGroupRepoGroupToPerm() | |
283 |
|
283 | |||
284 | obj.group = repos_group |
|
284 | obj.group = repos_group | |
285 | obj.users_group = group_name |
|
285 | obj.users_group = group_name | |
286 | obj.permission = permission |
|
286 | obj.permission = permission | |
287 | self.sa.add(obj) |
|
287 | self.sa.add(obj) | |
288 |
|
288 | |||
289 | def revoke_users_group_permission(self, repos_group, group_name): |
|
289 | def revoke_users_group_permission(self, repos_group, group_name): | |
290 | """ |
|
290 | """ | |
291 | Revoke permission for users group on given repositories group |
|
291 | Revoke permission for users group on given repositories group | |
292 |
|
292 | |||
293 | :param repos_group: Instance of ReposGroup, repositories_group_id, |
|
293 | :param repos_group: Instance of ReposGroup, repositories_group_id, | |
294 | or repositories_group name |
|
294 | or repositories_group name | |
295 | :param group_name: Instance of UserGroup, users_group_id, |
|
295 | :param group_name: Instance of UserGroup, users_group_id, | |
296 | or users group name |
|
296 | or users group name | |
297 | """ |
|
297 | """ | |
298 |
repos_group = self. |
|
298 | repos_group = self._get_repos_group(repos_group) | |
299 | group_name = self.__get_users_group(group_name) |
|
299 | group_name = self.__get_users_group(group_name) | |
300 |
|
300 | |||
301 | obj = self.sa.query(UsersGroupRepoGroupToPerm)\ |
|
301 | obj = self.sa.query(UsersGroupRepoGroupToPerm)\ | |
302 | .filter(UsersGroupRepoGroupToPerm.group == repos_group)\ |
|
302 | .filter(UsersGroupRepoGroupToPerm.group == repos_group)\ | |
303 | .filter(UsersGroupRepoGroupToPerm.users_group == group_name)\ |
|
303 | .filter(UsersGroupRepoGroupToPerm.users_group == group_name)\ | |
304 | .one() |
|
304 | .one() | |
305 | self.sa.delete(obj) |
|
305 | self.sa.delete(obj) |
@@ -1,251 +1,261 | |||||
1 | ## -*- coding: utf-8 -*- |
|
1 | ## -*- coding: utf-8 -*- | |
2 | <%inherit file="/base/base.html"/> |
|
2 | <%inherit file="/base/base.html"/> | |
3 |
|
3 | |||
4 | <%def name="title()"> |
|
4 | <%def name="title()"> | |
5 | ${_('Edit user')} ${c.user.username} - ${c.rhodecode_name} |
|
5 | ${_('Edit user')} ${c.user.username} - ${c.rhodecode_name} | |
6 | </%def> |
|
6 | </%def> | |
7 |
|
7 | |||
8 | <%def name="breadcrumbs_links()"> |
|
8 | <%def name="breadcrumbs_links()"> | |
9 | ${h.link_to(_('Admin'),h.url('admin_home'))} |
|
9 | ${h.link_to(_('Admin'),h.url('admin_home'))} | |
10 | » |
|
10 | » | |
11 | ${h.link_to(_('Users'),h.url('users'))} |
|
11 | ${h.link_to(_('Users'),h.url('users'))} | |
12 | » |
|
12 | » | |
13 | ${_('edit')} "${c.user.username}" |
|
13 | ${_('edit')} "${c.user.username}" | |
14 | </%def> |
|
14 | </%def> | |
15 |
|
15 | |||
16 | <%def name="page_nav()"> |
|
16 | <%def name="page_nav()"> | |
17 | ${self.menu('admin')} |
|
17 | ${self.menu('admin')} | |
18 | </%def> |
|
18 | </%def> | |
19 |
|
19 | |||
20 | <%def name="main()"> |
|
20 | <%def name="main()"> | |
21 | <div class="box box-left"> |
|
21 | <div class="box box-left"> | |
22 | <!-- box / title --> |
|
22 | <!-- box / title --> | |
23 | <div class="title"> |
|
23 | <div class="title"> | |
24 | ${self.breadcrumbs()} |
|
24 | ${self.breadcrumbs()} | |
25 | </div> |
|
25 | </div> | |
26 | <!-- end box / title --> |
|
26 | <!-- end box / title --> | |
27 | ${h.form(url('update_user', id=c.user.user_id),method='put')} |
|
27 | ${h.form(url('update_user', id=c.user.user_id),method='put')} | |
28 | <div class="form"> |
|
28 | <div class="form"> | |
29 | <div class="field"> |
|
29 | <div class="field"> | |
30 | <div class="gravatar_box"> |
|
30 | <div class="gravatar_box"> | |
31 | <div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(c.user.email)}"/></div> |
|
31 | <div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(c.user.email)}"/></div> | |
32 | <p> |
|
32 | <p> | |
33 | %if c.use_gravatar: |
|
33 | %if c.use_gravatar: | |
34 | <strong>${_('Change your avatar at')} <a href="http://gravatar.com">gravatar.com</a></strong> |
|
34 | <strong>${_('Change your avatar at')} <a href="http://gravatar.com">gravatar.com</a></strong> | |
35 | <br/>${_('Using')} ${c.user.email} |
|
35 | <br/>${_('Using')} ${c.user.email} | |
36 | %else: |
|
36 | %else: | |
37 | <br/>${c.user.email} |
|
37 | <br/>${c.user.email} | |
38 | %endif |
|
38 | %endif | |
39 | </div> |
|
39 | </div> | |
40 | </div> |
|
40 | </div> | |
41 | <div class="field"> |
|
41 | <div class="field"> | |
42 | <div class="label"> |
|
42 | <div class="label"> | |
43 | <label>${_('API key')}</label> ${c.user.api_key} |
|
43 | <label>${_('API key')}</label> ${c.user.api_key} | |
44 | </div> |
|
44 | </div> | |
45 | </div> |
|
45 | </div> | |
46 |
|
46 | |||
47 | <div class="fields"> |
|
47 | <div class="fields"> | |
48 | <div class="field"> |
|
48 | <div class="field"> | |
49 | <div class="label"> |
|
49 | <div class="label"> | |
50 | <label for="username">${_('Username')}:</label> |
|
50 | <label for="username">${_('Username')}:</label> | |
51 | </div> |
|
51 | </div> | |
52 | <div class="input"> |
|
52 | <div class="input"> | |
53 | ${h.text('username',class_='medium')} |
|
53 | ${h.text('username',class_='medium')} | |
54 | </div> |
|
54 | </div> | |
55 | </div> |
|
55 | </div> | |
56 |
|
56 | |||
57 | <div class="field"> |
|
57 | <div class="field"> | |
58 | <div class="label"> |
|
58 | <div class="label"> | |
59 | <label for="ldap_dn">${_('LDAP DN')}:</label> |
|
59 | <label for="ldap_dn">${_('LDAP DN')}:</label> | |
60 | </div> |
|
60 | </div> | |
61 | <div class="input"> |
|
61 | <div class="input"> | |
62 | ${h.text('ldap_dn',class_='medium disabled',readonly="readonly")} |
|
62 | ${h.text('ldap_dn',class_='medium disabled',readonly="readonly")} | |
63 | </div> |
|
63 | </div> | |
64 | </div> |
|
64 | </div> | |
65 |
|
65 | |||
66 | <div class="field"> |
|
66 | <div class="field"> | |
67 | <div class="label"> |
|
67 | <div class="label"> | |
68 | <label for="new_password">${_('New password')}:</label> |
|
68 | <label for="new_password">${_('New password')}:</label> | |
69 | </div> |
|
69 | </div> | |
70 | <div class="input"> |
|
70 | <div class="input"> | |
71 | ${h.password('new_password',class_='medium',autocomplete="off")} |
|
71 | ${h.password('new_password',class_='medium',autocomplete="off")} | |
72 | </div> |
|
72 | </div> | |
73 | </div> |
|
73 | </div> | |
74 |
|
74 | |||
75 | <div class="field"> |
|
75 | <div class="field"> | |
76 | <div class="label"> |
|
76 | <div class="label"> | |
77 | <label for="password_confirmation">${_('New password confirmation')}:</label> |
|
77 | <label for="password_confirmation">${_('New password confirmation')}:</label> | |
78 | </div> |
|
78 | </div> | |
79 | <div class="input"> |
|
79 | <div class="input"> | |
80 | ${h.password('password_confirmation',class_="medium",autocomplete="off")} |
|
80 | ${h.password('password_confirmation',class_="medium",autocomplete="off")} | |
81 | </div> |
|
81 | </div> | |
82 | </div> |
|
82 | </div> | |
83 |
|
83 | |||
84 | <div class="field"> |
|
84 | <div class="field"> | |
85 | <div class="label"> |
|
85 | <div class="label"> | |
86 | <label for="firstname">${_('First Name')}:</label> |
|
86 | <label for="firstname">${_('First Name')}:</label> | |
87 | </div> |
|
87 | </div> | |
88 | <div class="input"> |
|
88 | <div class="input"> | |
89 | ${h.text('firstname',class_='medium')} |
|
89 | ${h.text('firstname',class_='medium')} | |
90 | </div> |
|
90 | </div> | |
91 | </div> |
|
91 | </div> | |
92 |
|
92 | |||
93 | <div class="field"> |
|
93 | <div class="field"> | |
94 | <div class="label"> |
|
94 | <div class="label"> | |
95 | <label for="lastname">${_('Last Name')}:</label> |
|
95 | <label for="lastname">${_('Last Name')}:</label> | |
96 | </div> |
|
96 | </div> | |
97 | <div class="input"> |
|
97 | <div class="input"> | |
98 | ${h.text('lastname',class_='medium')} |
|
98 | ${h.text('lastname',class_='medium')} | |
99 | </div> |
|
99 | </div> | |
100 | </div> |
|
100 | </div> | |
101 |
|
101 | |||
102 | <div class="field"> |
|
102 | <div class="field"> | |
103 | <div class="label"> |
|
103 | <div class="label"> | |
104 | <label for="email">${_('Email')}:</label> |
|
104 | <label for="email">${_('Email')}:</label> | |
105 | </div> |
|
105 | </div> | |
106 | <div class="input"> |
|
106 | <div class="input"> | |
107 | ${h.text('email',class_='medium')} |
|
107 | ${h.text('email',class_='medium')} | |
108 | </div> |
|
108 | </div> | |
109 | </div> |
|
109 | </div> | |
110 |
|
110 | |||
111 | <div class="field"> |
|
111 | <div class="field"> | |
112 | <div class="label label-checkbox"> |
|
112 | <div class="label label-checkbox"> | |
113 | <label for="active">${_('Active')}:</label> |
|
113 | <label for="active">${_('Active')}:</label> | |
114 | </div> |
|
114 | </div> | |
115 | <div class="checkboxes"> |
|
115 | <div class="checkboxes"> | |
116 | ${h.checkbox('active',value=True)} |
|
116 | ${h.checkbox('active',value=True)} | |
117 | </div> |
|
117 | </div> | |
118 | </div> |
|
118 | </div> | |
119 |
|
119 | |||
120 | <div class="field"> |
|
120 | <div class="field"> | |
121 | <div class="label label-checkbox"> |
|
121 | <div class="label label-checkbox"> | |
122 | <label for="admin">${_('Admin')}:</label> |
|
122 | <label for="admin">${_('Admin')}:</label> | |
123 | </div> |
|
123 | </div> | |
124 | <div class="checkboxes"> |
|
124 | <div class="checkboxes"> | |
125 | ${h.checkbox('admin',value=True)} |
|
125 | ${h.checkbox('admin',value=True)} | |
126 | </div> |
|
126 | </div> | |
127 | </div> |
|
127 | </div> | |
128 | <div class="buttons"> |
|
128 | <div class="buttons"> | |
129 | ${h.submit('save',_('Save'),class_="ui-btn large")} |
|
129 | ${h.submit('save',_('Save'),class_="ui-btn large")} | |
130 | ${h.reset('reset',_('Reset'),class_="ui-btn large")} |
|
130 | ${h.reset('reset',_('Reset'),class_="ui-btn large")} | |
131 | </div> |
|
131 | </div> | |
132 | </div> |
|
132 | </div> | |
133 | </div> |
|
133 | </div> | |
134 | ${h.end_form()} |
|
134 | ${h.end_form()} | |
135 | </div> |
|
135 | </div> | |
136 | <div class="box box-right"> |
|
136 | <div class="box box-right"> | |
137 | <!-- box / title --> |
|
137 | <!-- box / title --> | |
138 | <div class="title"> |
|
138 | <div class="title"> | |
139 | <h5>${_('Permissions')}</h5> |
|
139 | <h5>${_('Permissions')}</h5> | |
140 | </div> |
|
140 | </div> | |
141 | ${h.form(url('user_perm', id=c.user.user_id),method='put')} |
|
141 | ${h.form(url('user_perm', id=c.user.user_id),method='put')} | |
142 | <div class="form"> |
|
142 | <div class="form"> | |
143 | <!-- fields --> |
|
143 | <!-- fields --> | |
144 | <div class="fields"> |
|
144 | <div class="fields"> | |
145 | <div class="field"> |
|
145 | <div class="field"> | |
146 | <div class="label label-checkbox"> |
|
146 | <div class="label label-checkbox"> | |
147 | <label for="create_repo_perm">${_('Create repositories')}:</label> |
|
147 | <label for="create_repo_perm">${_('Create repositories')}:</label> | |
148 | </div> |
|
148 | </div> | |
149 | <div class="checkboxes"> |
|
149 | <div class="checkboxes"> | |
150 | ${h.checkbox('create_repo_perm',value=True)} |
|
150 | ${h.checkbox('create_repo_perm',value=True)} | |
151 | </div> |
|
151 | </div> | |
152 | </div> |
|
152 | </div> | |
153 | <div class="buttons"> |
|
153 | <div class="buttons"> | |
154 | ${h.submit('save',_('Save'),class_="ui-btn large")} |
|
154 | ${h.submit('save',_('Save'),class_="ui-btn large")} | |
155 | ${h.reset('reset',_('Reset'),class_="ui-btn large")} |
|
155 | ${h.reset('reset',_('Reset'),class_="ui-btn large")} | |
156 | </div> |
|
156 | </div> | |
157 | </div> |
|
157 | </div> | |
158 | </div> |
|
158 | </div> | |
159 | ${h.end_form()} |
|
159 | ${h.end_form()} | |
160 |
|
160 | |||
161 | ## permissions overview |
|
161 | ## permissions overview | |
162 | <div id="perms" class="table"> |
|
162 | <div id="perms" class="table"> | |
163 | %for section in sorted(c.perm_user.permissions.keys()): |
|
163 | %for section in sorted(c.perm_user.permissions.keys()): | |
164 | <div class="perms_section_head">${section.replace("_"," ").capitalize()}</div> |
|
164 | <div class="perms_section_head">${section.replace("_"," ").capitalize()}</div> | |
165 |
|
165 | |||
166 | <div id='tbl_list_wrap_${section}' class="yui-skin-sam"> |
|
166 | <div id='tbl_list_wrap_${section}' class="yui-skin-sam"> | |
167 | <table id="tbl_list_${section}"> |
|
167 | <table id="tbl_list_${section}"> | |
168 | <thead> |
|
168 | <thead> | |
169 | <tr> |
|
169 | <tr> | |
170 | <th class="left">${_('Name')}</th> |
|
170 | <th class="left">${_('Name')}</th> | |
171 | <th class="left">${_('Permission')}</th> |
|
171 | <th class="left">${_('Permission')}</th> | |
|
172 | <th class="left">${_('Edit Permission')}</th> | |||
172 | </thead> |
|
173 | </thead> | |
173 | <tbody> |
|
174 | <tbody> | |
174 | %for k in c.perm_user.permissions[section]: |
|
175 | %for k in c.perm_user.permissions[section]: | |
175 | <% |
|
176 | <% | |
176 | if section != 'global': |
|
177 | if section != 'global': | |
177 | section_perm = c.perm_user.permissions[section].get(k) |
|
178 | section_perm = c.perm_user.permissions[section].get(k) | |
178 | _perm = section_perm.split('.')[-1] |
|
179 | _perm = section_perm.split('.')[-1] | |
179 | else: |
|
180 | else: | |
180 | _perm = section_perm = None |
|
181 | _perm = section_perm = None | |
181 | %> |
|
182 | %> | |
182 | <tr> |
|
183 | <tr> | |
183 | <td> |
|
184 | <td> | |
184 | %if section == 'repositories': |
|
185 | %if section == 'repositories': | |
185 | <a href="${h.url('summary_home',repo_name=k)}">${k}</a> |
|
186 | <a href="${h.url('summary_home',repo_name=k)}">${k}</a> | |
186 | %elif section == 'repositories_groups': |
|
187 | %elif section == 'repositories_groups': | |
187 | <a href="${h.url('repos_group_home',group_name=k)}">${k}</a> |
|
188 | <a href="${h.url('repos_group_home',group_name=k)}">${k}</a> | |
188 | %else: |
|
189 | %else: | |
189 | ${h.get_permission_name(k)} |
|
190 | ${h.get_permission_name(k)} | |
190 | %endif |
|
191 | %endif | |
191 | </td> |
|
192 | </td> | |
192 | <td> |
|
193 | <td> | |
193 | %if section == 'global': |
|
194 | %if section == 'global': | |
194 | ${h.bool2icon(k.split('.')[-1] != 'none')} |
|
195 | ${h.bool2icon(k.split('.')[-1] != 'none')} | |
195 | %else: |
|
196 | %else: | |
196 | <span class="perm_tag ${_perm}">${section_perm}</span> |
|
197 | <span class="perm_tag ${_perm}">${section_perm}</span> | |
197 | %endif |
|
198 | %endif | |
198 |
|
|
199 | </td> | |
|
200 | <td> | |||
|
201 | %if section == 'repositories': | |||
|
202 | <a href="${h.url('edit_repo',repo_name=k,anchor='permissions_manage')}">${_('edit')}</a> | |||
|
203 | %elif section == 'repositories_groups': | |||
|
204 | <a href="${h.url('edit_repos_group',id=k,anchor='permissions_manage')}">${_('edit')}</a> | |||
|
205 | %else: | |||
|
206 | -- | |||
|
207 | %endif | |||
|
208 | </td> | |||
199 | </tr> |
|
209 | </tr> | |
200 | %endfor |
|
210 | %endfor | |
201 | </tbody> |
|
211 | </tbody> | |
202 | </table> |
|
212 | </table> | |
203 | </div> |
|
213 | </div> | |
204 | %endfor |
|
214 | %endfor | |
205 | </div> |
|
215 | </div> | |
206 | </div> |
|
216 | </div> | |
207 | <div class="box box-left"> |
|
217 | <div class="box box-left"> | |
208 | <!-- box / title --> |
|
218 | <!-- box / title --> | |
209 | <div class="title"> |
|
219 | <div class="title"> | |
210 | <h5>${_('Email addresses')}</h5> |
|
220 | <h5>${_('Email addresses')}</h5> | |
211 | </div> |
|
221 | </div> | |
212 |
|
222 | |||
213 | <div class="emails_wrap"> |
|
223 | <div class="emails_wrap"> | |
214 | <table class="noborder"> |
|
224 | <table class="noborder"> | |
215 | %for em in c.user_email_map: |
|
225 | %for em in c.user_email_map: | |
216 | <tr> |
|
226 | <tr> | |
217 | <td><div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(em.user.email,16)}"/> </div></td> |
|
227 | <td><div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(em.user.email,16)}"/> </div></td> | |
218 | <td><div class="email">${em.email}</div></td> |
|
228 | <td><div class="email">${em.email}</div></td> | |
219 | <td> |
|
229 | <td> | |
220 | ${h.form(url('user_emails_delete', id=c.user.user_id),method='delete')} |
|
230 | ${h.form(url('user_emails_delete', id=c.user.user_id),method='delete')} | |
221 | ${h.hidden('del_email',em.email_id)} |
|
231 | ${h.hidden('del_email',em.email_id)} | |
222 | ${h.submit('remove_',_('delete'),id="remove_email_%s" % em.email_id, |
|
232 | ${h.submit('remove_',_('delete'),id="remove_email_%s" % em.email_id, | |
223 | class_="delete_icon action_button", onclick="return confirm('"+_('Confirm to delete this email: %s') % em.email+"');")} |
|
233 | class_="delete_icon action_button", onclick="return confirm('"+_('Confirm to delete this email: %s') % em.email+"');")} | |
224 | ${h.end_form()} |
|
234 | ${h.end_form()} | |
225 | </td> |
|
235 | </td> | |
226 | </tr> |
|
236 | </tr> | |
227 | %endfor |
|
237 | %endfor | |
228 | </table> |
|
238 | </table> | |
229 | </div> |
|
239 | </div> | |
230 |
|
240 | |||
231 | ${h.form(url('user_emails', id=c.user.user_id),method='put')} |
|
241 | ${h.form(url('user_emails', id=c.user.user_id),method='put')} | |
232 | <div class="form"> |
|
242 | <div class="form"> | |
233 | <!-- fields --> |
|
243 | <!-- fields --> | |
234 | <div class="fields"> |
|
244 | <div class="fields"> | |
235 | <div class="field"> |
|
245 | <div class="field"> | |
236 | <div class="label"> |
|
246 | <div class="label"> | |
237 | <label for="email">${_('New email address')}:</label> |
|
247 | <label for="email">${_('New email address')}:</label> | |
238 | </div> |
|
248 | </div> | |
239 | <div class="input"> |
|
249 | <div class="input"> | |
240 | ${h.text('new_email', class_='medium')} |
|
250 | ${h.text('new_email', class_='medium')} | |
241 | </div> |
|
251 | </div> | |
242 | </div> |
|
252 | </div> | |
243 | <div class="buttons"> |
|
253 | <div class="buttons"> | |
244 | ${h.submit('save',_('Add'),class_="ui-btn large")} |
|
254 | ${h.submit('save',_('Add'),class_="ui-btn large")} | |
245 | ${h.reset('reset',_('Reset'),class_="ui-btn large")} |
|
255 | ${h.reset('reset',_('Reset'),class_="ui-btn large")} | |
246 | </div> |
|
256 | </div> | |
247 | </div> |
|
257 | </div> | |
248 | </div> |
|
258 | </div> | |
249 | ${h.end_form()} |
|
259 | ${h.end_form()} | |
250 | </div> |
|
260 | </div> | |
251 | </%def> |
|
261 | </%def> |
General Comments 0
You need to be logged in to leave comments.
Login now