##// END OF EJS Templates
Fixed #161 form saves the create repository permission....
marcink -
r1266:a1bcfe58 beta
parent child Browse files
Show More
@@ -1,285 +1,312 b''
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 from rhodecode.lib.utils import check_repo_fast as cr
10 from rhodecode.lib.utils import check_repo_fast as cr
11
11
12
12
13 def make_map(config):
13 def make_map(config):
14 """Create, configure and return the routes Mapper"""
14 """Create, configure and return the routes Mapper"""
15 rmap = Mapper(directory=config['pylons.paths']['controllers'],
15 rmap = Mapper(directory=config['pylons.paths']['controllers'],
16 always_scan=config['debug'])
16 always_scan=config['debug'])
17 rmap.minimization = False
17 rmap.minimization = False
18 rmap.explicit = False
18 rmap.explicit = False
19
19
20 def check_repo(environ, match_dict):
20 def check_repo(environ, match_dict):
21 """
21 """
22 check for valid repository for proper 404 handling
22 check for valid repository for proper 404 handling
23 :param environ:
23 :param environ:
24 :param match_dict:
24 :param match_dict:
25 """
25 """
26 repo_name = match_dict.get('repo_name')
26 repo_name = match_dict.get('repo_name')
27 return not cr(repo_name, config['base_path'])
27 return not cr(repo_name, config['base_path'])
28
28
29 # The ErrorController route (handles 404/500 error pages); it should
29 # The ErrorController route (handles 404/500 error pages); it should
30 # likely stay at the top, ensuring it can always be resolved
30 # likely stay at the top, ensuring it can always be resolved
31 rmap.connect('/error/{action}', controller='error')
31 rmap.connect('/error/{action}', controller='error')
32 rmap.connect('/error/{action}/{id}', controller='error')
32 rmap.connect('/error/{action}/{id}', controller='error')
33
33
34 #==========================================================================
34 #==========================================================================
35 # CUSTOM ROUTES HERE
35 # CUSTOM ROUTES HERE
36 #==========================================================================
36 #==========================================================================
37
37
38 #MAIN PAGE
38 #MAIN PAGE
39 rmap.connect('home', '/', controller='home', action='index')
39 rmap.connect('home', '/', controller='home', action='index')
40 rmap.connect('repo_switcher', '/repos', controller='home',
40 rmap.connect('repo_switcher', '/repos', controller='home',
41 action='repo_switcher')
41 action='repo_switcher')
42 rmap.connect('bugtracker',
42 rmap.connect('bugtracker',
43 "http://bitbucket.org/marcinkuzminski/rhodecode/issues",
43 "http://bitbucket.org/marcinkuzminski/rhodecode/issues",
44 _static=True)
44 _static=True)
45 rmap.connect('rhodecode_official', "http://rhodecode.org", _static=True)
45 rmap.connect('rhodecode_official', "http://rhodecode.org", _static=True)
46
46
47 #ADMIN REPOSITORY REST ROUTES
47 #ADMIN REPOSITORY REST ROUTES
48 with rmap.submapper(path_prefix='/_admin', controller='admin/repos') as m:
48 with rmap.submapper(path_prefix='/_admin', controller='admin/repos') as m:
49 m.connect("repos", "/repos",
49 m.connect("repos", "/repos",
50 action="create", conditions=dict(method=["POST"]))
50 action="create", conditions=dict(method=["POST"]))
51 m.connect("repos", "/repos",
51 m.connect("repos", "/repos",
52 action="index", conditions=dict(method=["GET"]))
52 action="index", conditions=dict(method=["GET"]))
53 m.connect("formatted_repos", "/repos.{format}",
53 m.connect("formatted_repos", "/repos.{format}",
54 action="index",
54 action="index",
55 conditions=dict(method=["GET"]))
55 conditions=dict(method=["GET"]))
56 m.connect("new_repo", "/repos/new",
56 m.connect("new_repo", "/repos/new",
57 action="new", conditions=dict(method=["GET"]))
57 action="new", conditions=dict(method=["GET"]))
58 m.connect("formatted_new_repo", "/repos/new.{format}",
58 m.connect("formatted_new_repo", "/repos/new.{format}",
59 action="new", conditions=dict(method=["GET"]))
59 action="new", conditions=dict(method=["GET"]))
60 m.connect("/repos/{repo_name:.*}",
60 m.connect("/repos/{repo_name:.*}",
61 action="update", conditions=dict(method=["PUT"],
61 action="update", conditions=dict(method=["PUT"],
62 function=check_repo))
62 function=check_repo))
63 m.connect("/repos/{repo_name:.*}",
63 m.connect("/repos/{repo_name:.*}",
64 action="delete", conditions=dict(method=["DELETE"],
64 action="delete", conditions=dict(method=["DELETE"],
65 function=check_repo))
65 function=check_repo))
66 m.connect("edit_repo", "/repos/{repo_name:.*}/edit",
66 m.connect("edit_repo", "/repos/{repo_name:.*}/edit",
67 action="edit", conditions=dict(method=["GET"],
67 action="edit", conditions=dict(method=["GET"],
68 function=check_repo))
68 function=check_repo))
69 m.connect("formatted_edit_repo", "/repos/{repo_name:.*}.{format}/edit",
69 m.connect("formatted_edit_repo", "/repos/{repo_name:.*}.{format}/edit",
70 action="edit", conditions=dict(method=["GET"],
70 action="edit", conditions=dict(method=["GET"],
71 function=check_repo))
71 function=check_repo))
72 m.connect("repo", "/repos/{repo_name:.*}",
72 m.connect("repo", "/repos/{repo_name:.*}",
73 action="show", conditions=dict(method=["GET"],
73 action="show", conditions=dict(method=["GET"],
74 function=check_repo))
74 function=check_repo))
75 m.connect("formatted_repo", "/repos/{repo_name:.*}.{format}",
75 m.connect("formatted_repo", "/repos/{repo_name:.*}.{format}",
76 action="show", conditions=dict(method=["GET"],
76 action="show", conditions=dict(method=["GET"],
77 function=check_repo))
77 function=check_repo))
78 #ajax delete repo perm user
78 #ajax delete repo perm user
79 m.connect('delete_repo_user', "/repos_delete_user/{repo_name:.*}",
79 m.connect('delete_repo_user', "/repos_delete_user/{repo_name:.*}",
80 action="delete_perm_user", conditions=dict(method=["DELETE"],
80 action="delete_perm_user", conditions=dict(method=["DELETE"],
81 function=check_repo))
81 function=check_repo))
82 #ajax delete repo perm users_group
82 #ajax delete repo perm users_group
83 m.connect('delete_repo_users_group',
83 m.connect('delete_repo_users_group',
84 "/repos_delete_users_group/{repo_name:.*}",
84 "/repos_delete_users_group/{repo_name:.*}",
85 action="delete_perm_users_group",
85 action="delete_perm_users_group",
86 conditions=dict(method=["DELETE"], function=check_repo))
86 conditions=dict(method=["DELETE"], function=check_repo))
87
87
88 #settings actions
88 #settings actions
89 m.connect('repo_stats', "/repos_stats/{repo_name:.*}",
89 m.connect('repo_stats', "/repos_stats/{repo_name:.*}",
90 action="repo_stats", conditions=dict(method=["DELETE"],
90 action="repo_stats", conditions=dict(method=["DELETE"],
91 function=check_repo))
91 function=check_repo))
92 m.connect('repo_cache', "/repos_cache/{repo_name:.*}",
92 m.connect('repo_cache', "/repos_cache/{repo_name:.*}",
93 action="repo_cache", conditions=dict(method=["DELETE"],
93 action="repo_cache", conditions=dict(method=["DELETE"],
94 function=check_repo))
94 function=check_repo))
95 m.connect('repo_public_journal',
95 m.connect('repo_public_journal',
96 "/repos_public_journal/{repo_name:.*}",
96 "/repos_public_journal/{repo_name:.*}",
97 action="repo_public_journal", conditions=dict(method=["PUT"],
97 action="repo_public_journal", conditions=dict(method=["PUT"],
98 function=check_repo))
98 function=check_repo))
99 m.connect('repo_pull', "/repo_pull/{repo_name:.*}",
99 m.connect('repo_pull', "/repo_pull/{repo_name:.*}",
100 action="repo_pull", conditions=dict(method=["PUT"],
100 action="repo_pull", conditions=dict(method=["PUT"],
101 function=check_repo))
101 function=check_repo))
102
102
103 #ADMIN REPOS GROUP REST ROUTES
103 #ADMIN REPOS GROUP REST ROUTES
104 rmap.resource('repos_group', 'repos_groups',
104 rmap.resource('repos_group', 'repos_groups',
105 controller='admin/repos_groups', path_prefix='/_admin')
105 controller='admin/repos_groups', path_prefix='/_admin')
106
106
107 #ADMIN USER REST ROUTES
107 #ADMIN USER REST ROUTES
108 rmap.resource('user', 'users', controller='admin/users',
108 with rmap.submapper(path_prefix='/_admin', controller='admin/users') as m:
109 path_prefix='/_admin')
109 m.connect("users", "/users",
110 action="create", conditions=dict(method=["POST"]))
111 m.connect("users", "/users",
112 action="index", conditions=dict(method=["GET"]))
113 m.connect("formatted_users", "/users.{format}",
114 action="index", conditions=dict(method=["GET"]))
115 m.connect("new_user", "/users/new",
116 action="new", conditions=dict(method=["GET"]))
117 m.connect("formatted_new_user", "/users/new.{format}",
118 action="new", conditions=dict(method=["GET"]))
119 m.connect("update_user", "/users/{id}",
120 action="update", conditions=dict(method=["PUT"]))
121 m.connect("delete_user", "/users/{id}",
122 action="delete", conditions=dict(method=["DELETE"]))
123 m.connect("edit_user", "/users/{id}/edit",
124 action="edit", conditions=dict(method=["GET"]))
125 m.connect("formatted_edit_user",
126 "/users/{id}.{format}/edit",
127 action="edit", conditions=dict(method=["GET"]))
128 m.connect("user", "/users/{id}",
129 action="show", conditions=dict(method=["GET"]))
130 m.connect("formatted_user", "/users/{id}.{format}",
131 action="show", conditions=dict(method=["GET"]))
132
133 #EXTRAS USER ROUTES
134 m.connect("user_perm", "/users_perm/{id}",
135 action="update_perm", conditions=dict(method=["PUT"]))
110
136
111 #ADMIN USERS REST ROUTES
137 #ADMIN USERS REST ROUTES
112 rmap.resource('users_group', 'users_groups',
138 rmap.resource('users_group', 'users_groups',
113 controller='admin/users_groups', path_prefix='/_admin')
139 controller='admin/users_groups', path_prefix='/_admin')
114
140
115 #ADMIN GROUP REST ROUTES
141 #ADMIN GROUP REST ROUTES
116 rmap.resource('group', 'groups', controller='admin/groups',
142 rmap.resource('group', 'groups',
117 path_prefix='/_admin')
143 controller='admin/groups', path_prefix='/_admin')
118
144
119 #ADMIN PERMISSIONS REST ROUTES
145 #ADMIN PERMISSIONS REST ROUTES
120 rmap.resource('permission', 'permissions',
146 rmap.resource('permission', 'permissions',
121 controller='admin/permissions', path_prefix='/_admin')
147 controller='admin/permissions', path_prefix='/_admin')
122
148
123 ##ADMIN LDAP SETTINGS
149 ##ADMIN LDAP SETTINGS
124 rmap.connect('ldap_settings', '/_admin/ldap',
150 rmap.connect('ldap_settings', '/_admin/ldap',
125 controller='admin/ldap_settings', action='ldap_settings',
151 controller='admin/ldap_settings', action='ldap_settings',
126 conditions=dict(method=["POST"]))
152 conditions=dict(method=["POST"]))
153
127 rmap.connect('ldap_home', '/_admin/ldap',
154 rmap.connect('ldap_home', '/_admin/ldap',
128 controller='admin/ldap_settings')
155 controller='admin/ldap_settings')
129
156
130 #ADMIN SETTINGS REST ROUTES
157 #ADMIN SETTINGS REST ROUTES
131 with rmap.submapper(path_prefix='/_admin',
158 with rmap.submapper(path_prefix='/_admin',
132 controller='admin/settings') as m:
159 controller='admin/settings') as m:
133 m.connect("admin_settings", "/settings",
160 m.connect("admin_settings", "/settings",
134 action="create", conditions=dict(method=["POST"]))
161 action="create", conditions=dict(method=["POST"]))
135 m.connect("admin_settings", "/settings",
162 m.connect("admin_settings", "/settings",
136 action="index", conditions=dict(method=["GET"]))
163 action="index", conditions=dict(method=["GET"]))
137 m.connect("formatted_admin_settings", "/settings.{format}",
164 m.connect("formatted_admin_settings", "/settings.{format}",
138 action="index", conditions=dict(method=["GET"]))
165 action="index", conditions=dict(method=["GET"]))
139 m.connect("admin_new_setting", "/settings/new",
166 m.connect("admin_new_setting", "/settings/new",
140 action="new", conditions=dict(method=["GET"]))
167 action="new", conditions=dict(method=["GET"]))
141 m.connect("formatted_admin_new_setting", "/settings/new.{format}",
168 m.connect("formatted_admin_new_setting", "/settings/new.{format}",
142 action="new", conditions=dict(method=["GET"]))
169 action="new", conditions=dict(method=["GET"]))
143 m.connect("/settings/{setting_id}",
170 m.connect("/settings/{setting_id}",
144 action="update", conditions=dict(method=["PUT"]))
171 action="update", conditions=dict(method=["PUT"]))
145 m.connect("/settings/{setting_id}",
172 m.connect("/settings/{setting_id}",
146 action="delete", conditions=dict(method=["DELETE"]))
173 action="delete", conditions=dict(method=["DELETE"]))
147 m.connect("admin_edit_setting", "/settings/{setting_id}/edit",
174 m.connect("admin_edit_setting", "/settings/{setting_id}/edit",
148 action="edit", conditions=dict(method=["GET"]))
175 action="edit", conditions=dict(method=["GET"]))
149 m.connect("formatted_admin_edit_setting",
176 m.connect("formatted_admin_edit_setting",
150 "/settings/{setting_id}.{format}/edit",
177 "/settings/{setting_id}.{format}/edit",
151 action="edit", conditions=dict(method=["GET"]))
178 action="edit", conditions=dict(method=["GET"]))
152 m.connect("admin_setting", "/settings/{setting_id}",
179 m.connect("admin_setting", "/settings/{setting_id}",
153 action="show", conditions=dict(method=["GET"]))
180 action="show", conditions=dict(method=["GET"]))
154 m.connect("formatted_admin_setting", "/settings/{setting_id}.{format}",
181 m.connect("formatted_admin_setting", "/settings/{setting_id}.{format}",
155 action="show", conditions=dict(method=["GET"]))
182 action="show", conditions=dict(method=["GET"]))
156 m.connect("admin_settings_my_account", "/my_account",
183 m.connect("admin_settings_my_account", "/my_account",
157 action="my_account", conditions=dict(method=["GET"]))
184 action="my_account", conditions=dict(method=["GET"]))
158 m.connect("admin_settings_my_account_update", "/my_account_update",
185 m.connect("admin_settings_my_account_update", "/my_account_update",
159 action="my_account_update", conditions=dict(method=["PUT"]))
186 action="my_account_update", conditions=dict(method=["PUT"]))
160 m.connect("admin_settings_create_repository", "/create_repository",
187 m.connect("admin_settings_create_repository", "/create_repository",
161 action="create_repository", conditions=dict(method=["GET"]))
188 action="create_repository", conditions=dict(method=["GET"]))
162
189
163 #ADMIN MAIN PAGES
190 #ADMIN MAIN PAGES
164 with rmap.submapper(path_prefix='/_admin', controller='admin/admin') as m:
191 with rmap.submapper(path_prefix='/_admin', controller='admin/admin') as m:
165 m.connect('admin_home', '', action='index')
192 m.connect('admin_home', '', action='index')
166 m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
193 m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
167 action='add_repo')
194 action='add_repo')
168
195
169 #USER JOURNAL
196 #USER JOURNAL
170 rmap.connect('journal', '/_admin/journal', controller='journal')
197 rmap.connect('journal', '/_admin/journal', controller='journal')
171
198
172 rmap.connect('public_journal', '/_admin/public_journal',
199 rmap.connect('public_journal', '/_admin/public_journal',
173 controller='journal', action="public_journal")
200 controller='journal', action="public_journal")
174
201
175 rmap.connect('public_journal_rss', '/_admin/public_journal_rss',
202 rmap.connect('public_journal_rss', '/_admin/public_journal_rss',
176 controller='journal', action="public_journal_rss")
203 controller='journal', action="public_journal_rss")
177
204
178 rmap.connect('public_journal_atom', '/_admin/public_journal_atom',
205 rmap.connect('public_journal_atom', '/_admin/public_journal_atom',
179 controller='journal', action="public_journal_atom")
206 controller='journal', action="public_journal_atom")
180
207
181 rmap.connect('toggle_following', '/_admin/toggle_following',
208 rmap.connect('toggle_following', '/_admin/toggle_following',
182 controller='journal', action='toggle_following',
209 controller='journal', action='toggle_following',
183 conditions=dict(method=["POST"]))
210 conditions=dict(method=["POST"]))
184
211
185 #SEARCH
212 #SEARCH
186 rmap.connect('search', '/_admin/search', controller='search',)
213 rmap.connect('search', '/_admin/search', controller='search',)
187 rmap.connect('search_repo', '/_admin/search/{search_repo:.*}',
214 rmap.connect('search_repo', '/_admin/search/{search_repo:.*}',
188 controller='search')
215 controller='search')
189
216
190 #LOGIN/LOGOUT/REGISTER/SIGN IN
217 #LOGIN/LOGOUT/REGISTER/SIGN IN
191 rmap.connect('login_home', '/_admin/login', controller='login')
218 rmap.connect('login_home', '/_admin/login', controller='login')
192 rmap.connect('logout_home', '/_admin/logout', controller='login',
219 rmap.connect('logout_home', '/_admin/logout', controller='login',
193 action='logout')
220 action='logout')
194
221
195 rmap.connect('register', '/_admin/register', controller='login',
222 rmap.connect('register', '/_admin/register', controller='login',
196 action='register')
223 action='register')
197
224
198 rmap.connect('reset_password', '/_admin/password_reset',
225 rmap.connect('reset_password', '/_admin/password_reset',
199 controller='login', action='password_reset')
226 controller='login', action='password_reset')
200
227
201 #FEEDS
228 #FEEDS
202 rmap.connect('rss_feed_home', '/{repo_name:.*}/feed/rss',
229 rmap.connect('rss_feed_home', '/{repo_name:.*}/feed/rss',
203 controller='feed', action='rss',
230 controller='feed', action='rss',
204 conditions=dict(function=check_repo))
231 conditions=dict(function=check_repo))
205
232
206 rmap.connect('atom_feed_home', '/{repo_name:.*}/feed/atom',
233 rmap.connect('atom_feed_home', '/{repo_name:.*}/feed/atom',
207 controller='feed', action='atom',
234 controller='feed', action='atom',
208 conditions=dict(function=check_repo))
235 conditions=dict(function=check_repo))
209
236
210 #REPOSITORY ROUTES
237 #REPOSITORY ROUTES
211 rmap.connect('changeset_home', '/{repo_name:.*}/changeset/{revision}',
238 rmap.connect('changeset_home', '/{repo_name:.*}/changeset/{revision}',
212 controller='changeset', revision='tip',
239 controller='changeset', revision='tip',
213 conditions=dict(function=check_repo))
240 conditions=dict(function=check_repo))
214
241
215 rmap.connect('raw_changeset_home',
242 rmap.connect('raw_changeset_home',
216 '/{repo_name:.*}/raw-changeset/{revision}',
243 '/{repo_name:.*}/raw-changeset/{revision}',
217 controller='changeset', action='raw_changeset',
244 controller='changeset', action='raw_changeset',
218 revision='tip', conditions=dict(function=check_repo))
245 revision='tip', conditions=dict(function=check_repo))
219
246
220 rmap.connect('summary_home', '/{repo_name:.*}',
247 rmap.connect('summary_home', '/{repo_name:.*}',
221 controller='summary', conditions=dict(function=check_repo))
248 controller='summary', conditions=dict(function=check_repo))
222
249
223 rmap.connect('summary_home', '/{repo_name:.*}/summary',
250 rmap.connect('summary_home', '/{repo_name:.*}/summary',
224 controller='summary', conditions=dict(function=check_repo))
251 controller='summary', conditions=dict(function=check_repo))
225
252
226 rmap.connect('shortlog_home', '/{repo_name:.*}/shortlog',
253 rmap.connect('shortlog_home', '/{repo_name:.*}/shortlog',
227 controller='shortlog', conditions=dict(function=check_repo))
254 controller='shortlog', conditions=dict(function=check_repo))
228
255
229 rmap.connect('branches_home', '/{repo_name:.*}/branches',
256 rmap.connect('branches_home', '/{repo_name:.*}/branches',
230 controller='branches', conditions=dict(function=check_repo))
257 controller='branches', conditions=dict(function=check_repo))
231
258
232 rmap.connect('tags_home', '/{repo_name:.*}/tags',
259 rmap.connect('tags_home', '/{repo_name:.*}/tags',
233 controller='tags', conditions=dict(function=check_repo))
260 controller='tags', conditions=dict(function=check_repo))
234
261
235 rmap.connect('changelog_home', '/{repo_name:.*}/changelog',
262 rmap.connect('changelog_home', '/{repo_name:.*}/changelog',
236 controller='changelog', conditions=dict(function=check_repo))
263 controller='changelog', conditions=dict(function=check_repo))
237
264
238 rmap.connect('files_home', '/{repo_name:.*}/files/{revision}/{f_path:.*}',
265 rmap.connect('files_home', '/{repo_name:.*}/files/{revision}/{f_path:.*}',
239 controller='files', revision='tip', f_path='',
266 controller='files', revision='tip', f_path='',
240 conditions=dict(function=check_repo))
267 conditions=dict(function=check_repo))
241
268
242 rmap.connect('files_diff_home', '/{repo_name:.*}/diff/{f_path:.*}',
269 rmap.connect('files_diff_home', '/{repo_name:.*}/diff/{f_path:.*}',
243 controller='files', action='diff', revision='tip', f_path='',
270 controller='files', action='diff', revision='tip', f_path='',
244 conditions=dict(function=check_repo))
271 conditions=dict(function=check_repo))
245
272
246 rmap.connect('files_rawfile_home',
273 rmap.connect('files_rawfile_home',
247 '/{repo_name:.*}/rawfile/{revision}/{f_path:.*}',
274 '/{repo_name:.*}/rawfile/{revision}/{f_path:.*}',
248 controller='files', action='rawfile', revision='tip',
275 controller='files', action='rawfile', revision='tip',
249 f_path='', conditions=dict(function=check_repo))
276 f_path='', conditions=dict(function=check_repo))
250
277
251 rmap.connect('files_raw_home',
278 rmap.connect('files_raw_home',
252 '/{repo_name:.*}/raw/{revision}/{f_path:.*}',
279 '/{repo_name:.*}/raw/{revision}/{f_path:.*}',
253 controller='files', action='raw', revision='tip', f_path='',
280 controller='files', action='raw', revision='tip', f_path='',
254 conditions=dict(function=check_repo))
281 conditions=dict(function=check_repo))
255
282
256 rmap.connect('files_annotate_home',
283 rmap.connect('files_annotate_home',
257 '/{repo_name:.*}/annotate/{revision}/{f_path:.*}',
284 '/{repo_name:.*}/annotate/{revision}/{f_path:.*}',
258 controller='files', action='annotate', revision='tip',
285 controller='files', action='annotate', revision='tip',
259 f_path='', conditions=dict(function=check_repo))
286 f_path='', conditions=dict(function=check_repo))
260
287
261 rmap.connect('files_archive_home', '/{repo_name:.*}/archive/{fname}',
288 rmap.connect('files_archive_home', '/{repo_name:.*}/archive/{fname}',
262 controller='files', action='archivefile',
289 controller='files', action='archivefile',
263 conditions=dict(function=check_repo))
290 conditions=dict(function=check_repo))
264
291
265 rmap.connect('repo_settings_delete', '/{repo_name:.*}/settings',
292 rmap.connect('repo_settings_delete', '/{repo_name:.*}/settings',
266 controller='settings', action="delete",
293 controller='settings', action="delete",
267 conditions=dict(method=["DELETE"], function=check_repo))
294 conditions=dict(method=["DELETE"], function=check_repo))
268
295
269 rmap.connect('repo_settings_update', '/{repo_name:.*}/settings',
296 rmap.connect('repo_settings_update', '/{repo_name:.*}/settings',
270 controller='settings', action="update",
297 controller='settings', action="update",
271 conditions=dict(method=["PUT"], function=check_repo))
298 conditions=dict(method=["PUT"], function=check_repo))
272
299
273 rmap.connect('repo_settings_home', '/{repo_name:.*}/settings',
300 rmap.connect('repo_settings_home', '/{repo_name:.*}/settings',
274 controller='settings', action='index',
301 controller='settings', action='index',
275 conditions=dict(function=check_repo))
302 conditions=dict(function=check_repo))
276
303
277 rmap.connect('repo_fork_create_home', '/{repo_name:.*}/fork',
304 rmap.connect('repo_fork_create_home', '/{repo_name:.*}/fork',
278 controller='settings', action='fork_create',
305 controller='settings', action='fork_create',
279 conditions=dict(function=check_repo, method=["POST"]))
306 conditions=dict(function=check_repo, method=["POST"]))
280
307
281 rmap.connect('repo_fork_home', '/{repo_name:.*}/fork',
308 rmap.connect('repo_fork_home', '/{repo_name:.*}/fork',
282 controller='settings', action='fork',
309 controller='settings', action='fork',
283 conditions=dict(function=check_repo))
310 conditions=dict(function=check_repo))
284
311
285 return rmap
312 return rmap
@@ -1,167 +1,166 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.admin.permissions
3 rhodecode.controllers.admin.permissions
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 permissions controller for Rhodecode
6 permissions controller for Rhodecode
7
7
8 :created_on: Apr 27, 2010
8 :created_on: Apr 27, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2009-2011 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 from formencode import htmlfill
26 from formencode import htmlfill
27 from pylons import request, session, tmpl_context as c, url
27 from pylons import request, session, tmpl_context as c, url
28 from pylons.controllers.util import abort, redirect
28 from pylons.controllers.util import abort, redirect
29 from pylons.i18n.translation import _
29 from pylons.i18n.translation import _
30 from rhodecode.lib import helpers as h
30 from rhodecode.lib import helpers as h
31 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
31 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
32 from rhodecode.lib.auth_ldap import LdapImportError
32 from rhodecode.lib.auth_ldap import LdapImportError
33 from rhodecode.lib.base import BaseController, render
33 from rhodecode.lib.base import BaseController, render
34 from rhodecode.model.forms import LdapSettingsForm, DefaultPermissionsForm
34 from rhodecode.model.forms import LdapSettingsForm, DefaultPermissionsForm
35 from rhodecode.model.permission import PermissionModel
35 from rhodecode.model.permission import PermissionModel
36 from rhodecode.model.settings import SettingsModel
37 from rhodecode.model.user import UserModel
36 from rhodecode.model.user import UserModel
38 import formencode
37 import formencode
39 import logging
38 import logging
40 import traceback
39 import traceback
41
40
42 log = logging.getLogger(__name__)
41 log = logging.getLogger(__name__)
43
42
44
43
45 class PermissionsController(BaseController):
44 class PermissionsController(BaseController):
46 """REST Controller styled on the Atom Publishing Protocol"""
45 """REST Controller styled on the Atom Publishing Protocol"""
47 # To properly map this controller, ensure your config/routing.py
46 # To properly map this controller, ensure your config/routing.py
48 # file has a resource setup:
47 # file has a resource setup:
49 # map.resource('permission', 'permissions')
48 # map.resource('permission', 'permissions')
50
49
51 @LoginRequired()
50 @LoginRequired()
52 @HasPermissionAllDecorator('hg.admin')
51 @HasPermissionAllDecorator('hg.admin')
53 def __before__(self):
52 def __before__(self):
54 c.admin_user = session.get('admin_user')
53 c.admin_user = session.get('admin_user')
55 c.admin_username = session.get('admin_username')
54 c.admin_username = session.get('admin_username')
56 super(PermissionsController, self).__before__()
55 super(PermissionsController, self).__before__()
57
56
58 self.perms_choices = [('repository.none', _('None'),),
57 self.perms_choices = [('repository.none', _('None'),),
59 ('repository.read', _('Read'),),
58 ('repository.read', _('Read'),),
60 ('repository.write', _('Write'),),
59 ('repository.write', _('Write'),),
61 ('repository.admin', _('Admin'),)]
60 ('repository.admin', _('Admin'),)]
62 self.register_choices = [
61 self.register_choices = [
63 ('hg.register.none',
62 ('hg.register.none',
64 _('disabled')),
63 _('disabled')),
65 ('hg.register.manual_activate',
64 ('hg.register.manual_activate',
66 _('allowed with manual account activation')),
65 _('allowed with manual account activation')),
67 ('hg.register.auto_activate',
66 ('hg.register.auto_activate',
68 _('allowed with automatic account activation')), ]
67 _('allowed with automatic account activation')), ]
69
68
70 self.create_choices = [('hg.create.none', _('Disabled')),
69 self.create_choices = [('hg.create.none', _('Disabled')),
71 ('hg.create.repository', _('Enabled'))]
70 ('hg.create.repository', _('Enabled'))]
72
71
73 def index(self, format='html'):
72 def index(self, format='html'):
74 """GET /permissions: All items in the collection"""
73 """GET /permissions: All items in the collection"""
75 # url('permissions')
74 # url('permissions')
76
75
77 def create(self):
76 def create(self):
78 """POST /permissions: Create a new item"""
77 """POST /permissions: Create a new item"""
79 # url('permissions')
78 # url('permissions')
80
79
81 def new(self, format='html'):
80 def new(self, format='html'):
82 """GET /permissions/new: Form to create a new item"""
81 """GET /permissions/new: Form to create a new item"""
83 # url('new_permission')
82 # url('new_permission')
84
83
85 def update(self, id):
84 def update(self, id):
86 """PUT /permissions/id: Update an existing item"""
85 """PUT /permissions/id: Update an existing item"""
87 # Forms posted to this method should contain a hidden field:
86 # Forms posted to this method should contain a hidden field:
88 # <input type="hidden" name="_method" value="PUT" />
87 # <input type="hidden" name="_method" value="PUT" />
89 # Or using helpers:
88 # Or using helpers:
90 # h.form(url('permission', id=ID),
89 # h.form(url('permission', id=ID),
91 # method='put')
90 # method='put')
92 # url('permission', id=ID)
91 # url('permission', id=ID)
93
92
94 permission_model = PermissionModel()
93 permission_model = PermissionModel()
95
94
96 _form = DefaultPermissionsForm([x[0] for x in self.perms_choices],
95 _form = DefaultPermissionsForm([x[0] for x in self.perms_choices],
97 [x[0] for x in self.register_choices],
96 [x[0] for x in self.register_choices],
98 [x[0] for x in self.create_choices])()
97 [x[0] for x in self.create_choices])()
99
98
100 try:
99 try:
101 form_result = _form.to_python(dict(request.POST))
100 form_result = _form.to_python(dict(request.POST))
102 form_result.update({'perm_user_name': id})
101 form_result.update({'perm_user_name': id})
103 permission_model.update(form_result)
102 permission_model.update(form_result)
104 h.flash(_('Default permissions updated successfully'),
103 h.flash(_('Default permissions updated successfully'),
105 category='success')
104 category='success')
106
105
107 except formencode.Invalid, errors:
106 except formencode.Invalid, errors:
108 c.perms_choices = self.perms_choices
107 c.perms_choices = self.perms_choices
109 c.register_choices = self.register_choices
108 c.register_choices = self.register_choices
110 c.create_choices = self.create_choices
109 c.create_choices = self.create_choices
111 defaults = errors.value
110 defaults = errors.value
112
111
113 return htmlfill.render(
112 return htmlfill.render(
114 render('admin/permissions/permissions.html'),
113 render('admin/permissions/permissions.html'),
115 defaults=defaults,
114 defaults=defaults,
116 errors=errors.error_dict or {},
115 errors=errors.error_dict or {},
117 prefix_error=False,
116 prefix_error=False,
118 encoding="UTF-8")
117 encoding="UTF-8")
119 except Exception:
118 except Exception:
120 log.error(traceback.format_exc())
119 log.error(traceback.format_exc())
121 h.flash(_('error occurred during update of permissions'),
120 h.flash(_('error occurred during update of permissions'),
122 category='error')
121 category='error')
123
122
124 return redirect(url('edit_permission', id=id))
123 return redirect(url('edit_permission', id=id))
125
124
126 def delete(self, id):
125 def delete(self, id):
127 """DELETE /permissions/id: Delete an existing item"""
126 """DELETE /permissions/id: Delete an existing item"""
128 # Forms posted to this method should contain a hidden field:
127 # Forms posted to this method should contain a hidden field:
129 # <input type="hidden" name="_method" value="DELETE" />
128 # <input type="hidden" name="_method" value="DELETE" />
130 # Or using helpers:
129 # Or using helpers:
131 # h.form(url('permission', id=ID),
130 # h.form(url('permission', id=ID),
132 # method='delete')
131 # method='delete')
133 # url('permission', id=ID)
132 # url('permission', id=ID)
134
133
135 def show(self, id, format='html'):
134 def show(self, id, format='html'):
136 """GET /permissions/id: Show a specific item"""
135 """GET /permissions/id: Show a specific item"""
137 # url('permission', id=ID)
136 # url('permission', id=ID)
138
137
139 def edit(self, id, format='html'):
138 def edit(self, id, format='html'):
140 """GET /permissions/id/edit: Form to edit an existing item"""
139 """GET /permissions/id/edit: Form to edit an existing item"""
141 #url('edit_permission', id=ID)
140 #url('edit_permission', id=ID)
142 c.perms_choices = self.perms_choices
141 c.perms_choices = self.perms_choices
143 c.register_choices = self.register_choices
142 c.register_choices = self.register_choices
144 c.create_choices = self.create_choices
143 c.create_choices = self.create_choices
145
144
146 if id == 'default':
145 if id == 'default':
147 default_user = UserModel().get_by_username('default')
146 default_user = UserModel().get_by_username('default')
148 defaults = {'_method': 'put',
147 defaults = {'_method': 'put',
149 'anonymous': default_user.active}
148 'anonymous': default_user.active}
150
149
151 for p in default_user.user_perms:
150 for p in default_user.user_perms:
152 if p.permission.permission_name.startswith('repository.'):
151 if p.permission.permission_name.startswith('repository.'):
153 defaults['default_perm'] = p.permission.permission_name
152 defaults['default_perm'] = p.permission.permission_name
154
153
155 if p.permission.permission_name.startswith('hg.register.'):
154 if p.permission.permission_name.startswith('hg.register.'):
156 defaults['default_register'] = p.permission.permission_name
155 defaults['default_register'] = p.permission.permission_name
157
156
158 if p.permission.permission_name.startswith('hg.create.'):
157 if p.permission.permission_name.startswith('hg.create.'):
159 defaults['default_create'] = p.permission.permission_name
158 defaults['default_create'] = p.permission.permission_name
160
159
161 return htmlfill.render(
160 return htmlfill.render(
162 render('admin/permissions/permissions.html'),
161 render('admin/permissions/permissions.html'),
163 defaults=defaults,
162 defaults=defaults,
164 encoding="UTF-8",
163 encoding="UTF-8",
165 force_defaults=True,)
164 force_defaults=True,)
166 else:
165 else:
167 return redirect(url('admin_home'))
166 return redirect(url('admin_home'))
@@ -1,176 +1,207 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.admin.users
3 rhodecode.controllers.admin.users
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Users crud controller for pylons
6 Users crud controller for pylons
7
7
8 :created_on: Apr 4, 2010
8 :created_on: Apr 4, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2009-2011 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 from pylons import request, session, tmpl_context as c, url, config
31 from pylons import request, session, tmpl_context as c, url, config
32 from pylons.controllers.util import abort, redirect
32 from pylons.controllers.util import abort, redirect
33 from pylons.i18n.translation import _
33 from pylons.i18n.translation import _
34
34
35 from rhodecode.lib.exceptions import DefaultUserException, \
35 from rhodecode.lib.exceptions import DefaultUserException, \
36 UserOwnsReposException
36 UserOwnsReposException
37 from rhodecode.lib import helpers as h
37 from rhodecode.lib import helpers as h
38 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
38 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
39 from rhodecode.lib.base import BaseController, render
39 from rhodecode.lib.base import BaseController, render
40
40
41 from rhodecode.model.db import User
41 from rhodecode.model.db import User, RepoToPerm, UserToPerm, Permission
42 from rhodecode.model.forms import UserForm
42 from rhodecode.model.forms import UserForm
43 from rhodecode.model.user import UserModel
43 from rhodecode.model.user import UserModel
44
44
45 log = logging.getLogger(__name__)
45 log = logging.getLogger(__name__)
46
46
47
47
48 class UsersController(BaseController):
48 class UsersController(BaseController):
49 """REST Controller styled on the Atom Publishing Protocol"""
49 """REST Controller styled on the Atom Publishing Protocol"""
50 # To properly map this controller, ensure your config/routing.py
50 # To properly map this controller, ensure your config/routing.py
51 # file has a resource setup:
51 # file has a resource setup:
52 # map.resource('user', 'users')
52 # map.resource('user', 'users')
53
53
54 @LoginRequired()
54 @LoginRequired()
55 @HasPermissionAllDecorator('hg.admin')
55 @HasPermissionAllDecorator('hg.admin')
56 def __before__(self):
56 def __before__(self):
57 c.admin_user = session.get('admin_user')
57 c.admin_user = session.get('admin_user')
58 c.admin_username = session.get('admin_username')
58 c.admin_username = session.get('admin_username')
59 super(UsersController, self).__before__()
59 super(UsersController, self).__before__()
60 c.available_permissions = config['available_permissions']
60 c.available_permissions = config['available_permissions']
61
61
62 def index(self, format='html'):
62 def index(self, format='html'):
63 """GET /users: All items in the collection"""
63 """GET /users: All items in the collection"""
64 # url('users')
64 # url('users')
65
65
66 c.users_list = self.sa.query(User).all()
66 c.users_list = self.sa.query(User).all()
67 return render('admin/users/users.html')
67 return render('admin/users/users.html')
68
68
69 def create(self):
69 def create(self):
70 """POST /users: Create a new item"""
70 """POST /users: Create a new item"""
71 # url('users')
71 # url('users')
72
72
73 user_model = UserModel()
73 user_model = UserModel()
74 login_form = UserForm()()
74 login_form = UserForm()()
75 try:
75 try:
76 form_result = login_form.to_python(dict(request.POST))
76 form_result = login_form.to_python(dict(request.POST))
77 user_model.create(form_result)
77 user_model.create(form_result)
78 h.flash(_('created user %s') % form_result['username'],
78 h.flash(_('created user %s') % form_result['username'],
79 category='success')
79 category='success')
80 #action_logger(self.rhodecode_user, 'new_user', '', '', self.sa)
80 #action_logger(self.rhodecode_user, 'new_user', '', '', self.sa)
81 except formencode.Invalid, errors:
81 except formencode.Invalid, errors:
82 return htmlfill.render(
82 return htmlfill.render(
83 render('admin/users/user_add.html'),
83 render('admin/users/user_add.html'),
84 defaults=errors.value,
84 defaults=errors.value,
85 errors=errors.error_dict or {},
85 errors=errors.error_dict or {},
86 prefix_error=False,
86 prefix_error=False,
87 encoding="UTF-8")
87 encoding="UTF-8")
88 except Exception:
88 except Exception:
89 log.error(traceback.format_exc())
89 log.error(traceback.format_exc())
90 h.flash(_('error occurred during creation of user %s') \
90 h.flash(_('error occurred during creation of user %s') \
91 % request.POST.get('username'), category='error')
91 % request.POST.get('username'), category='error')
92 return redirect(url('users'))
92 return redirect(url('users'))
93
93
94 def new(self, format='html'):
94 def new(self, format='html'):
95 """GET /users/new: Form to create a new item"""
95 """GET /users/new: Form to create a new item"""
96 # url('new_user')
96 # url('new_user')
97 return render('admin/users/user_add.html')
97 return render('admin/users/user_add.html')
98
98
99 def update(self, id):
99 def update(self, id):
100 """PUT /users/id: Update an existing item"""
100 """PUT /users/id: Update an existing item"""
101 # Forms posted to this method should contain a hidden field:
101 # Forms posted to this method should contain a hidden field:
102 # <input type="hidden" name="_method" value="PUT" />
102 # <input type="hidden" name="_method" value="PUT" />
103 # Or using helpers:
103 # Or using helpers:
104 # h.form(url('user', id=ID),
104 # h.form(url('update_user', id=ID),
105 # method='put')
105 # method='put')
106 # url('user', id=ID)
106 # url('user', id=ID)
107 user_model = UserModel()
107 user_model = UserModel()
108 c.user = user_model.get(id)
108 c.user = user_model.get(id)
109
109
110 _form = UserForm(edit=True, old_data={'user_id': id,
110 _form = UserForm(edit=True, old_data={'user_id': id,
111 'email': c.user.email})()
111 'email': c.user.email})()
112 form_result = {}
112 form_result = {}
113 try:
113 try:
114 form_result = _form.to_python(dict(request.POST))
114 form_result = _form.to_python(dict(request.POST))
115 user_model.update(id, form_result)
115 user_model.update(id, form_result)
116 h.flash(_('User updated succesfully'), category='success')
116 h.flash(_('User updated successfully'), category='success')
117
117
118 except formencode.Invalid, errors:
118 except formencode.Invalid, errors:
119 e = errors.error_dict or {}
120 perm = Permission.get_by_key('hg.create.repository')
121 e.update({'create_repo_perm': UserToPerm.has_perm(id, perm)})
119 return htmlfill.render(
122 return htmlfill.render(
120 render('admin/users/user_edit.html'),
123 render('admin/users/user_edit.html'),
121 defaults=errors.value,
124 defaults=errors.value,
122 errors=errors.error_dict or {},
125 errors=e,
123 prefix_error=False,
126 prefix_error=False,
124 encoding="UTF-8")
127 encoding="UTF-8")
125 except Exception:
128 except Exception:
126 log.error(traceback.format_exc())
129 log.error(traceback.format_exc())
127 h.flash(_('error occurred during update of user %s') \
130 h.flash(_('error occurred during update of user %s') \
128 % form_result.get('username'), category='error')
131 % form_result.get('username'), category='error')
129
132
130 return redirect(url('users'))
133 return redirect(url('users'))
131
134
132 def delete(self, id):
135 def delete(self, id):
133 """DELETE /users/id: Delete an existing item"""
136 """DELETE /users/id: Delete an existing item"""
134 # Forms posted to this method should contain a hidden field:
137 # Forms posted to this method should contain a hidden field:
135 # <input type="hidden" name="_method" value="DELETE" />
138 # <input type="hidden" name="_method" value="DELETE" />
136 # Or using helpers:
139 # Or using helpers:
137 # h.form(url('user', id=ID),
140 # h.form(url('delete_user', id=ID),
138 # method='delete')
141 # method='delete')
139 # url('user', id=ID)
142 # url('user', id=ID)
140 user_model = UserModel()
143 user_model = UserModel()
141 try:
144 try:
142 user_model.delete(id)
145 user_model.delete(id)
143 h.flash(_('successfully deleted user'), category='success')
146 h.flash(_('successfully deleted user'), category='success')
144 except (UserOwnsReposException, DefaultUserException), e:
147 except (UserOwnsReposException, DefaultUserException), e:
145 h.flash(str(e), category='warning')
148 h.flash(str(e), category='warning')
146 except Exception:
149 except Exception:
147 h.flash(_('An error occurred during deletion of user'),
150 h.flash(_('An error occurred during deletion of user'),
148 category='error')
151 category='error')
149 return redirect(url('users'))
152 return redirect(url('users'))
150
153
151 def show(self, id, format='html'):
154 def show(self, id, format='html'):
152 """GET /users/id: Show a specific item"""
155 """GET /users/id: Show a specific item"""
153 # url('user', id=ID)
156 # url('user', id=ID)
154
157
155 def edit(self, id, format='html'):
158 def edit(self, id, format='html'):
156 """GET /users/id/edit: Form to edit an existing item"""
159 """GET /users/id/edit: Form to edit an existing item"""
157 # url('edit_user', id=ID)
160 # url('edit_user', id=ID)
158 user_model = UserModel()
161 user_model = UserModel()
159 c.user = user_model.get(id)
162 c.user = user_model.get(id)
160 if not c.user:
163 if not c.user:
161 return redirect(url('users'))
164 return redirect(url('users'))
162 if c.user.username == 'default':
165 if c.user.username == 'default':
163 h.flash(_("You can't edit this user"), category='warning')
166 h.flash(_("You can't edit this user"), category='warning')
164 return redirect(url('users'))
167 return redirect(url('users'))
165 c.user.permissions = {}
168 c.user.permissions = {}
166 c.granted_permissions = user_model.fill_perms(c.user)\
169 c.granted_permissions = user_model.fill_perms(c.user)\
167 .permissions['global']
170 .permissions['global']
168
171
169 defaults = c.user.get_dict()
172 defaults = c.user.get_dict()
173 perm = Permission.get_by_key('hg.create.repository')
174 defaults.update({'create_repo_perm': UserToPerm.has_perm(id, perm)})
170
175
171 return htmlfill.render(
176 return htmlfill.render(
172 render('admin/users/user_edit.html'),
177 render('admin/users/user_edit.html'),
173 defaults=defaults,
178 defaults=defaults,
174 encoding="UTF-8",
179 encoding="UTF-8",
175 force_defaults=False
180 force_defaults=False
176 )
181 )
182
183 def update_perm(self, id):
184 """PUT /users_perm/id: Update an existing item"""
185 # url('user_perm', id=ID, method='put')
186
187 grant_perm = request.POST.get('create_repo_perm', False)
188
189 if grant_perm:
190 perm = Permission.get_by_key('hg.create.none')
191 UserToPerm.revoke_perm(id, perm)
192
193 perm = Permission.get_by_key('hg.create.repository')
194 UserToPerm.grant_perm(id, perm)
195 h.flash(_("Granted 'repository create' permission to user"),
196 category='success')
197
198 else:
199 perm = Permission.get_by_key('hg.create.repository')
200 UserToPerm.revoke_perm(id, perm)
201
202 perm = Permission.get_by_key('hg.create.none')
203 UserToPerm.grant_perm(id, perm)
204 h.flash(_("Revoked 'repository create' permission to user"),
205 category='success')
206
207 return redirect(url('edit_user', id=id))
@@ -1,516 +1,514 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.lib.db_manage
3 rhodecode.lib.db_manage
4 ~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Database creation, and setup module for RhodeCode. Used for creation
6 Database creation, and setup module for RhodeCode. Used for creation
7 of database as well as for migration operations
7 of database as well as for migration operations
8
8
9 :created_on: Apr 10, 2010
9 :created_on: Apr 10, 2010
10 :author: marcink
10 :author: marcink
11 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
11 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
12 :license: GPLv3, see COPYING for more details.
12 :license: GPLv3, see COPYING for more details.
13 """
13 """
14 # This program is free software: you can redistribute it and/or modify
14 # This program is free software: you can redistribute it and/or modify
15 # it under the terms of the GNU General Public License as published by
15 # it under the terms of the GNU General Public License as published by
16 # the Free Software Foundation, either version 3 of the License, or
16 # the Free Software Foundation, either version 3 of the License, or
17 # (at your option) any later version.
17 # (at your option) any later version.
18 #
18 #
19 # This program is distributed in the hope that it will be useful,
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU General Public License for more details.
22 # GNU General Public License for more details.
23 #
23 #
24 # You should have received a copy of the GNU General Public License
24 # You should have received a copy of the GNU General Public License
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26
26
27 import os
27 import os
28 import sys
28 import sys
29 import uuid
29 import uuid
30 import logging
30 import logging
31 from os.path import dirname as dn, join as jn
31 from os.path import dirname as dn, join as jn
32
32
33 from rhodecode import __dbversion__
33 from rhodecode import __dbversion__
34 from rhodecode.model import meta
34 from rhodecode.model import meta
35
35
36 from rhodecode.lib.auth import get_crypt_password, generate_api_key
36 from rhodecode.lib.auth import get_crypt_password, generate_api_key
37 from rhodecode.lib.utils import ask_ok
37 from rhodecode.lib.utils import ask_ok
38 from rhodecode.model import init_model
38 from rhodecode.model import init_model
39 from rhodecode.model.db import User, Permission, RhodeCodeUi, RhodeCodeSettings, \
39 from rhodecode.model.db import User, Permission, RhodeCodeUi, \
40 UserToPerm, DbMigrateVersion
40 RhodeCodeSettings, UserToPerm, DbMigrateVersion
41
41
42 from sqlalchemy.engine import create_engine
42 from sqlalchemy.engine import create_engine
43
43
44 log = logging.getLogger(__name__)
44 log = logging.getLogger(__name__)
45
45
46
46 class DbManage(object):
47 class DbManage(object):
47 def __init__(self, log_sql, dbconf, root, tests=False):
48 def __init__(self, log_sql, dbconf, root, tests=False):
48 self.dbname = dbconf.split('/')[-1]
49 self.dbname = dbconf.split('/')[-1]
49 self.tests = tests
50 self.tests = tests
50 self.root = root
51 self.root = root
51 self.dburi = dbconf
52 self.dburi = dbconf
52 self.log_sql = log_sql
53 self.log_sql = log_sql
53 self.db_exists = False
54 self.db_exists = False
54 self.init_db()
55 self.init_db()
55
56
56 def init_db(self):
57 def init_db(self):
57 engine = create_engine(self.dburi, echo=self.log_sql)
58 engine = create_engine(self.dburi, echo=self.log_sql)
58 init_model(engine)
59 init_model(engine)
59 self.sa = meta.Session()
60 self.sa = meta.Session()
60
61
61 def create_tables(self, override=False):
62 def create_tables(self, override=False):
62 """Create a auth database
63 """Create a auth database
63 """
64 """
64
65
65 log.info("Any existing database is going to be destroyed")
66 log.info("Any existing database is going to be destroyed")
66 if self.tests:
67 if self.tests:
67 destroy = True
68 destroy = True
68 else:
69 else:
69 destroy = ask_ok('Are you sure to destroy old database ? [y/n]')
70 destroy = ask_ok('Are you sure to destroy old database ? [y/n]')
70 if not destroy:
71 if not destroy:
71 sys.exit()
72 sys.exit()
72 if destroy:
73 if destroy:
73 meta.Base.metadata.drop_all()
74 meta.Base.metadata.drop_all()
74
75
75 checkfirst = not override
76 checkfirst = not override
76 meta.Base.metadata.create_all(checkfirst=checkfirst)
77 meta.Base.metadata.create_all(checkfirst=checkfirst)
77 log.info('Created tables for %s', self.dbname)
78 log.info('Created tables for %s', self.dbname)
78
79
79
80
81 def set_db_version(self):
80 def set_db_version(self):
82 try:
81 try:
83 ver = DbMigrateVersion()
82 ver = DbMigrateVersion()
84 ver.version = __dbversion__
83 ver.version = __dbversion__
85 ver.repository_id = 'rhodecode_db_migrations'
84 ver.repository_id = 'rhodecode_db_migrations'
86 ver.repository_path = 'versions'
85 ver.repository_path = 'versions'
87 self.sa.add(ver)
86 self.sa.add(ver)
88 self.sa.commit()
87 self.sa.commit()
89 except:
88 except:
90 self.sa.rollback()
89 self.sa.rollback()
91 raise
90 raise
92 log.info('db version set to: %s', __dbversion__)
91 log.info('db version set to: %s', __dbversion__)
93
92
94
95 def upgrade(self):
93 def upgrade(self):
96 """Upgrades given database schema to given revision following
94 """Upgrades given database schema to given revision following
97 all needed steps, to perform the upgrade
95 all needed steps, to perform the upgrade
98
96
99 """
97 """
100
98
101 from rhodecode.lib.dbmigrate.migrate.versioning import api
99 from rhodecode.lib.dbmigrate.migrate.versioning import api
102 from rhodecode.lib.dbmigrate.migrate.exceptions import \
100 from rhodecode.lib.dbmigrate.migrate.exceptions import \
103 DatabaseNotControlledError
101 DatabaseNotControlledError
104
102
105 upgrade = ask_ok('You are about to perform database upgrade, make '
103 upgrade = ask_ok('You are about to perform database upgrade, make '
106 'sure You backed up your database before. '
104 'sure You backed up your database before. '
107 'Continue ? [y/n]')
105 'Continue ? [y/n]')
108 if not upgrade:
106 if not upgrade:
109 sys.exit('Nothing done')
107 sys.exit('Nothing done')
110
108
111 repository_path = jn(dn(dn(dn(os.path.realpath(__file__)))),
109 repository_path = jn(dn(dn(dn(os.path.realpath(__file__)))),
112 'rhodecode/lib/dbmigrate')
110 'rhodecode/lib/dbmigrate')
113 db_uri = self.dburi
111 db_uri = self.dburi
114
112
115 try:
113 try:
116 curr_version = api.db_version(db_uri, repository_path)
114 curr_version = api.db_version(db_uri, repository_path)
117 msg = ('Found current database under version'
115 msg = ('Found current database under version'
118 ' control with version %s' % curr_version)
116 ' control with version %s' % curr_version)
119
117
120 except (RuntimeError, DatabaseNotControlledError), e:
118 except (RuntimeError, DatabaseNotControlledError), e:
121 curr_version = 1
119 curr_version = 1
122 msg = ('Current database is not under version control. Setting'
120 msg = ('Current database is not under version control. Setting'
123 ' as version %s' % curr_version)
121 ' as version %s' % curr_version)
124 api.version_control(db_uri, repository_path, curr_version)
122 api.version_control(db_uri, repository_path, curr_version)
125
123
126 print (msg)
124 print (msg)
127
125
128 if curr_version == __dbversion__:
126 if curr_version == __dbversion__:
129 sys.exit('This database is already at the newest version')
127 sys.exit('This database is already at the newest version')
130
128
131 #======================================================================
129 #======================================================================
132 # UPGRADE STEPS
130 # UPGRADE STEPS
133 #======================================================================
131 #======================================================================
134 class UpgradeSteps(object):
132 class UpgradeSteps(object):
135 """Those steps follow schema versions so for example schema
133 """Those steps follow schema versions so for example schema
136 for example schema with seq 002 == step_2 and so on.
134 for example schema with seq 002 == step_2 and so on.
137 """
135 """
138
136
139 def __init__(self, klass):
137 def __init__(self, klass):
140 self.klass = klass
138 self.klass = klass
141
139
142 def step_0(self):
140 def step_0(self):
143 #step 0 is the schema upgrade, and than follow proper upgrades
141 #step 0 is the schema upgrade, and than follow proper upgrades
144 print ('attempting to do database upgrade to version %s' \
142 print ('attempting to do database upgrade to version %s' \
145 % __dbversion__)
143 % __dbversion__)
146 api.upgrade(db_uri, repository_path, __dbversion__)
144 api.upgrade(db_uri, repository_path, __dbversion__)
147 print ('Schema upgrade completed')
145 print ('Schema upgrade completed')
148
146
149 def step_1(self):
147 def step_1(self):
150 pass
148 pass
151
149
152 def step_2(self):
150 def step_2(self):
153 print ('Patching repo paths for newer version of RhodeCode')
151 print ('Patching repo paths for newer version of RhodeCode')
154 self.klass.fix_repo_paths()
152 self.klass.fix_repo_paths()
155
153
156 print ('Patching default user of RhodeCode')
154 print ('Patching default user of RhodeCode')
157 self.klass.fix_default_user()
155 self.klass.fix_default_user()
158
156
159 log.info('Changing ui settings')
157 log.info('Changing ui settings')
160 self.klass.create_ui_settings()
158 self.klass.create_ui_settings()
161
159
162 def step_3(self):
160 def step_3(self):
163 print ('Adding additional settings into RhodeCode db')
161 print ('Adding additional settings into RhodeCode db')
164 self.klass.fix_settings()
162 self.klass.fix_settings()
165
163
166 upgrade_steps = [0] + range(curr_version + 1, __dbversion__ + 1)
164 upgrade_steps = [0] + range(curr_version + 1, __dbversion__ + 1)
167
165
168 #CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE
166 #CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE
169 for step in upgrade_steps:
167 for step in upgrade_steps:
170 print ('performing upgrade step %s' % step)
168 print ('performing upgrade step %s' % step)
171 callable = getattr(UpgradeSteps(self), 'step_%s' % step)()
169 callable = getattr(UpgradeSteps(self), 'step_%s' % step)()
172
170
173
174
175 def fix_repo_paths(self):
171 def fix_repo_paths(self):
176 """Fixes a old rhodecode version path into new one without a '*'
172 """Fixes a old rhodecode version path into new one without a '*'
177 """
173 """
178
174
179 paths = self.sa.query(RhodeCodeUi)\
175 paths = self.sa.query(RhodeCodeUi)\
180 .filter(RhodeCodeUi.ui_key == '/')\
176 .filter(RhodeCodeUi.ui_key == '/')\
181 .scalar()
177 .scalar()
182
178
183 paths.ui_value = paths.ui_value.replace('*', '')
179 paths.ui_value = paths.ui_value.replace('*', '')
184
180
185 try:
181 try:
186 self.sa.add(paths)
182 self.sa.add(paths)
187 self.sa.commit()
183 self.sa.commit()
188 except:
184 except:
189 self.sa.rollback()
185 self.sa.rollback()
190 raise
186 raise
191
187
192 def fix_default_user(self):
188 def fix_default_user(self):
193 """Fixes a old default user with some 'nicer' default values,
189 """Fixes a old default user with some 'nicer' default values,
194 used mostly for anonymous access
190 used mostly for anonymous access
195 """
191 """
196 def_user = self.sa.query(User)\
192 def_user = self.sa.query(User)\
197 .filter(User.username == 'default')\
193 .filter(User.username == 'default')\
198 .one()
194 .one()
199
195
200 def_user.name = 'Anonymous'
196 def_user.name = 'Anonymous'
201 def_user.lastname = 'User'
197 def_user.lastname = 'User'
202 def_user.email = 'anonymous@rhodecode.org'
198 def_user.email = 'anonymous@rhodecode.org'
203
199
204 try:
200 try:
205 self.sa.add(def_user)
201 self.sa.add(def_user)
206 self.sa.commit()
202 self.sa.commit()
207 except:
203 except:
208 self.sa.rollback()
204 self.sa.rollback()
209 raise
205 raise
210
206
211 def fix_settings(self):
207 def fix_settings(self):
212 """Fixes rhodecode settings adds ga_code key for google analytics
208 """Fixes rhodecode settings adds ga_code key for google analytics
213 """
209 """
214
210
215 hgsettings3 = RhodeCodeSettings('ga_code', '')
211 hgsettings3 = RhodeCodeSettings('ga_code', '')
216
212
217 try:
213 try:
218 self.sa.add(hgsettings3)
214 self.sa.add(hgsettings3)
219 self.sa.commit()
215 self.sa.commit()
220 except:
216 except:
221 self.sa.rollback()
217 self.sa.rollback()
222 raise
218 raise
223
219
224 def admin_prompt(self, second=False):
220 def admin_prompt(self, second=False):
225 if not self.tests:
221 if not self.tests:
226 import getpass
222 import getpass
227
223
228
229 def get_password():
224 def get_password():
230 password = getpass.getpass('Specify admin password (min 6 chars):')
225 password = getpass.getpass('Specify admin password '
226 '(min 6 chars):')
231 confirm = getpass.getpass('Confirm password:')
227 confirm = getpass.getpass('Confirm password:')
232
228
233 if password != confirm:
229 if password != confirm:
234 log.error('passwords mismatch')
230 log.error('passwords mismatch')
235 return False
231 return False
236 if len(password) < 6:
232 if len(password) < 6:
237 log.error('password is to short use at least 6 characters')
233 log.error('password is to short use at least 6 characters')
238 return False
234 return False
239
235
240 return password
236 return password
241
237
242 username = raw_input('Specify admin username:')
238 username = raw_input('Specify admin username:')
243
239
244 password = get_password()
240 password = get_password()
245 if not password:
241 if not password:
246 #second try
242 #second try
247 password = get_password()
243 password = get_password()
248 if not password:
244 if not password:
249 sys.exit()
245 sys.exit()
250
246
251 email = raw_input('Specify admin email:')
247 email = raw_input('Specify admin email:')
252 self.create_user(username, password, email, True)
248 self.create_user(username, password, email, True)
253 else:
249 else:
254 log.info('creating admin and regular test users')
250 log.info('creating admin and regular test users')
255 self.create_user('test_admin', 'test12', 'test_admin@mail.com', True)
251 self.create_user('test_admin', 'test12',
256 self.create_user('test_regular', 'test12', 'test_regular@mail.com', False)
252 'test_admin@mail.com', True)
257 self.create_user('test_regular2', 'test12', 'test_regular2@mail.com', False)
253 self.create_user('test_regular', 'test12',
254 'test_regular@mail.com', False)
255 self.create_user('test_regular2', 'test12',
256 'test_regular2@mail.com', False)
258
257
259 def create_ui_settings(self):
258 def create_ui_settings(self):
260 """Creates ui settings, fills out hooks
259 """Creates ui settings, fills out hooks
261 and disables dotencode
260 and disables dotencode
262
261
263 """
262 """
264 #HOOKS
263 #HOOKS
265 hooks1_key = 'changegroup.update'
264 hooks1_key = 'changegroup.update'
266 hooks1_ = self.sa.query(RhodeCodeUi)\
265 hooks1_ = self.sa.query(RhodeCodeUi)\
267 .filter(RhodeCodeUi.ui_key == hooks1_key).scalar()
266 .filter(RhodeCodeUi.ui_key == hooks1_key).scalar()
268
267
269 hooks1 = RhodeCodeUi() if hooks1_ is None else hooks1_
268 hooks1 = RhodeCodeUi() if hooks1_ is None else hooks1_
270 hooks1.ui_section = 'hooks'
269 hooks1.ui_section = 'hooks'
271 hooks1.ui_key = hooks1_key
270 hooks1.ui_key = hooks1_key
272 hooks1.ui_value = 'hg update >&2'
271 hooks1.ui_value = 'hg update >&2'
273 hooks1.ui_active = False
272 hooks1.ui_active = False
274
273
275 hooks2_key = 'changegroup.repo_size'
274 hooks2_key = 'changegroup.repo_size'
276 hooks2_ = self.sa.query(RhodeCodeUi)\
275 hooks2_ = self.sa.query(RhodeCodeUi)\
277 .filter(RhodeCodeUi.ui_key == hooks2_key).scalar()
276 .filter(RhodeCodeUi.ui_key == hooks2_key).scalar()
278
277
279 hooks2 = RhodeCodeUi() if hooks2_ is None else hooks2_
278 hooks2 = RhodeCodeUi() if hooks2_ is None else hooks2_
280 hooks2.ui_section = 'hooks'
279 hooks2.ui_section = 'hooks'
281 hooks2.ui_key = hooks2_key
280 hooks2.ui_key = hooks2_key
282 hooks2.ui_value = 'python:rhodecode.lib.hooks.repo_size'
281 hooks2.ui_value = 'python:rhodecode.lib.hooks.repo_size'
283
282
284 hooks3 = RhodeCodeUi()
283 hooks3 = RhodeCodeUi()
285 hooks3.ui_section = 'hooks'
284 hooks3.ui_section = 'hooks'
286 hooks3.ui_key = 'pretxnchangegroup.push_logger'
285 hooks3.ui_key = 'pretxnchangegroup.push_logger'
287 hooks3.ui_value = 'python:rhodecode.lib.hooks.log_push_action'
286 hooks3.ui_value = 'python:rhodecode.lib.hooks.log_push_action'
288
287
289 hooks4 = RhodeCodeUi()
288 hooks4 = RhodeCodeUi()
290 hooks4.ui_section = 'hooks'
289 hooks4.ui_section = 'hooks'
291 hooks4.ui_key = 'preoutgoing.pull_logger'
290 hooks4.ui_key = 'preoutgoing.pull_logger'
292 hooks4.ui_value = 'python:rhodecode.lib.hooks.log_pull_action'
291 hooks4.ui_value = 'python:rhodecode.lib.hooks.log_pull_action'
293
292
294 #For mercurial 1.7 set backward comapatibility with format
293 #For mercurial 1.7 set backward comapatibility with format
295 dotencode_disable = RhodeCodeUi()
294 dotencode_disable = RhodeCodeUi()
296 dotencode_disable.ui_section = 'format'
295 dotencode_disable.ui_section = 'format'
297 dotencode_disable.ui_key = 'dotencode'
296 dotencode_disable.ui_key = 'dotencode'
298 dotencode_disable.ui_value = 'false'
297 dotencode_disable.ui_value = 'false'
299
298
300 try:
299 try:
301 self.sa.add(hooks1)
300 self.sa.add(hooks1)
302 self.sa.add(hooks2)
301 self.sa.add(hooks2)
303 self.sa.add(hooks3)
302 self.sa.add(hooks3)
304 self.sa.add(hooks4)
303 self.sa.add(hooks4)
305 self.sa.add(dotencode_disable)
304 self.sa.add(dotencode_disable)
306 self.sa.commit()
305 self.sa.commit()
307 except:
306 except:
308 self.sa.rollback()
307 self.sa.rollback()
309 raise
308 raise
310
309
311
312 def create_ldap_options(self):
310 def create_ldap_options(self):
313 """Creates ldap settings"""
311 """Creates ldap settings"""
314
312
315 try:
313 try:
316 for k, v in [('ldap_active', 'false'), ('ldap_host', ''),
314 for k, v in [('ldap_active', 'false'), ('ldap_host', ''),
317 ('ldap_port', '389'), ('ldap_ldaps', 'false'),
315 ('ldap_port', '389'), ('ldap_ldaps', 'false'),
318 ('ldap_tls_reqcert', ''), ('ldap_dn_user', ''),
316 ('ldap_tls_reqcert', ''), ('ldap_dn_user', ''),
319 ('ldap_dn_pass', ''), ('ldap_base_dn', ''),
317 ('ldap_dn_pass', ''), ('ldap_base_dn', ''),
320 ('ldap_filter', ''), ('ldap_search_scope', ''),
318 ('ldap_filter', ''), ('ldap_search_scope', ''),
321 ('ldap_attr_login', ''), ('ldap_attr_firstname', ''),
319 ('ldap_attr_login', ''), ('ldap_attr_firstname', ''),
322 ('ldap_attr_lastname', ''), ('ldap_attr_email', '')]:
320 ('ldap_attr_lastname', ''), ('ldap_attr_email', '')]:
323
321
324
325 setting = RhodeCodeSettings(k, v)
322 setting = RhodeCodeSettings(k, v)
326 self.sa.add(setting)
323 self.sa.add(setting)
327 self.sa.commit()
324 self.sa.commit()
328 except:
325 except:
329 self.sa.rollback()
326 self.sa.rollback()
330 raise
327 raise
331
328
332 def config_prompt(self, test_repo_path='', retries=3):
329 def config_prompt(self, test_repo_path='', retries=3):
333 if retries == 3:
330 if retries == 3:
334 log.info('Setting up repositories config')
331 log.info('Setting up repositories config')
335
332
336 if not self.tests and not test_repo_path:
333 if not self.tests and not test_repo_path:
337 path = raw_input('Specify valid full path to your repositories'
334 path = raw_input('Specify valid full path to your repositories'
338 ' you can change this later in application settings:')
335 ' you can change this later in application settings:')
339 else:
336 else:
340 path = test_repo_path
337 path = test_repo_path
341 path_ok = True
338 path_ok = True
342
339
343 #check proper dir
340 #check proper dir
344 if not os.path.isdir(path):
341 if not os.path.isdir(path):
345 path_ok = False
342 path_ok = False
346 log.error('Entered path is not a valid directory: %s [%s/3]',
343 log.error('Entered path is not a valid directory: %s [%s/3]',
347 path, retries)
344 path, retries)
348
345
349 #check write access
346 #check write access
350 if not os.access(path, os.W_OK):
347 if not os.access(path, os.W_OK):
351 path_ok = False
348 path_ok = False
352
349
353 log.error('No write permission to given path: %s [%s/3]',
350 log.error('No write permission to given path: %s [%s/3]',
354 path, retries)
351 path, retries)
355
352
356
357 if retries == 0:
353 if retries == 0:
358 sys.exit()
354 sys.exit()
359 if path_ok is False:
355 if path_ok is False:
360 retries -= 1
356 retries -= 1
361 return self.config_prompt(test_repo_path, retries)
357 return self.config_prompt(test_repo_path, retries)
362
358
363
364 return path
359 return path
365
360
366 def create_settings(self, path):
361 def create_settings(self, path):
367
362
368 self.create_ui_settings()
363 self.create_ui_settings()
369
364
370 #HG UI OPTIONS
365 #HG UI OPTIONS
371 web1 = RhodeCodeUi()
366 web1 = RhodeCodeUi()
372 web1.ui_section = 'web'
367 web1.ui_section = 'web'
373 web1.ui_key = 'push_ssl'
368 web1.ui_key = 'push_ssl'
374 web1.ui_value = 'false'
369 web1.ui_value = 'false'
375
370
376 web2 = RhodeCodeUi()
371 web2 = RhodeCodeUi()
377 web2.ui_section = 'web'
372 web2.ui_section = 'web'
378 web2.ui_key = 'allow_archive'
373 web2.ui_key = 'allow_archive'
379 web2.ui_value = 'gz zip bz2'
374 web2.ui_value = 'gz zip bz2'
380
375
381 web3 = RhodeCodeUi()
376 web3 = RhodeCodeUi()
382 web3.ui_section = 'web'
377 web3.ui_section = 'web'
383 web3.ui_key = 'allow_push'
378 web3.ui_key = 'allow_push'
384 web3.ui_value = '*'
379 web3.ui_value = '*'
385
380
386 web4 = RhodeCodeUi()
381 web4 = RhodeCodeUi()
387 web4.ui_section = 'web'
382 web4.ui_section = 'web'
388 web4.ui_key = 'baseurl'
383 web4.ui_key = 'baseurl'
389 web4.ui_value = '/'
384 web4.ui_value = '/'
390
385
391 paths = RhodeCodeUi()
386 paths = RhodeCodeUi()
392 paths.ui_section = 'paths'
387 paths.ui_section = 'paths'
393 paths.ui_key = '/'
388 paths.ui_key = '/'
394 paths.ui_value = path
389 paths.ui_value = path
395
390
396
397 hgsettings1 = RhodeCodeSettings('realm', 'RhodeCode authentication')
391 hgsettings1 = RhodeCodeSettings('realm', 'RhodeCode authentication')
398 hgsettings2 = RhodeCodeSettings('title', 'RhodeCode')
392 hgsettings2 = RhodeCodeSettings('title', 'RhodeCode')
399 hgsettings3 = RhodeCodeSettings('ga_code', '')
393 hgsettings3 = RhodeCodeSettings('ga_code', '')
400
394
401
402 try:
395 try:
403 self.sa.add(web1)
396 self.sa.add(web1)
404 self.sa.add(web2)
397 self.sa.add(web2)
405 self.sa.add(web3)
398 self.sa.add(web3)
406 self.sa.add(web4)
399 self.sa.add(web4)
407 self.sa.add(paths)
400 self.sa.add(paths)
408 self.sa.add(hgsettings1)
401 self.sa.add(hgsettings1)
409 self.sa.add(hgsettings2)
402 self.sa.add(hgsettings2)
410 self.sa.add(hgsettings3)
403 self.sa.add(hgsettings3)
411
404
412 self.sa.commit()
405 self.sa.commit()
413 except:
406 except:
414 self.sa.rollback()
407 self.sa.rollback()
415 raise
408 raise
416
409
417 self.create_ldap_options()
410 self.create_ldap_options()
418
411
419 log.info('created ui config')
412 log.info('created ui config')
420
413
421 def create_user(self, username, password, email='', admin=False):
414 def create_user(self, username, password, email='', admin=False):
422 log.info('creating administrator user %s', username)
415 log.info('creating administrator user %s', username)
423 new_user = User()
416 new_user = User()
424 new_user.username = username
417 new_user.username = username
425 new_user.password = get_crypt_password(password)
418 new_user.password = get_crypt_password(password)
426 new_user.api_key = generate_api_key(username)
419 new_user.api_key = generate_api_key(username)
427 new_user.name = 'RhodeCode'
420 new_user.name = 'RhodeCode'
428 new_user.lastname = 'Admin'
421 new_user.lastname = 'Admin'
429 new_user.email = email
422 new_user.email = email
430 new_user.admin = admin
423 new_user.admin = admin
431 new_user.active = True
424 new_user.active = True
432
425
433 try:
426 try:
434 self.sa.add(new_user)
427 self.sa.add(new_user)
435 self.sa.commit()
428 self.sa.commit()
436 except:
429 except:
437 self.sa.rollback()
430 self.sa.rollback()
438 raise
431 raise
439
432
440 def create_default_user(self):
433 def create_default_user(self):
441 log.info('creating default user')
434 log.info('creating default user')
442 #create default user for handling default permissions.
435 #create default user for handling default permissions.
443 def_user = User()
436 def_user = User()
444 def_user.username = 'default'
437 def_user.username = 'default'
445 def_user.password = get_crypt_password(str(uuid.uuid1())[:8])
438 def_user.password = get_crypt_password(str(uuid.uuid1())[:8])
446 def_user.api_key = generate_api_key('default')
439 def_user.api_key = generate_api_key('default')
447 def_user.name = 'Anonymous'
440 def_user.name = 'Anonymous'
448 def_user.lastname = 'User'
441 def_user.lastname = 'User'
449 def_user.email = 'anonymous@rhodecode.org'
442 def_user.email = 'anonymous@rhodecode.org'
450 def_user.admin = False
443 def_user.admin = False
451 def_user.active = False
444 def_user.active = False
452 try:
445 try:
453 self.sa.add(def_user)
446 self.sa.add(def_user)
454 self.sa.commit()
447 self.sa.commit()
455 except:
448 except:
456 self.sa.rollback()
449 self.sa.rollback()
457 raise
450 raise
458
451
459 def create_permissions(self):
452 def create_permissions(self):
460 #module.(access|create|change|delete)_[name]
453 #module.(access|create|change|delete)_[name]
461 #module.(read|write|owner)
454 #module.(read|write|owner)
462 perms = [('repository.none', 'Repository no access'),
455 perms = [('repository.none', 'Repository no access'),
463 ('repository.read', 'Repository read access'),
456 ('repository.read', 'Repository read access'),
464 ('repository.write', 'Repository write access'),
457 ('repository.write', 'Repository write access'),
465 ('repository.admin', 'Repository admin access'),
458 ('repository.admin', 'Repository admin access'),
466 ('hg.admin', 'Hg Administrator'),
459 ('hg.admin', 'Hg Administrator'),
467 ('hg.create.repository', 'Repository create'),
460 ('hg.create.repository', 'Repository create'),
468 ('hg.create.none', 'Repository creation disabled'),
461 ('hg.create.none', 'Repository creation disabled'),
469 ('hg.register.none', 'Register disabled'),
462 ('hg.register.none', 'Register disabled'),
470 ('hg.register.manual_activate', 'Register new user with RhodeCode without manual activation'),
463 ('hg.register.manual_activate', 'Register new user with '
471 ('hg.register.auto_activate', 'Register new user with RhodeCode without auto activation'),
464 'RhodeCode without manual'
465 'activation'),
466
467 ('hg.register.auto_activate', 'Register new user with '
468 'RhodeCode without auto '
469 'activation'),
472 ]
470 ]
473
471
474 for p in perms:
472 for p in perms:
475 new_perm = Permission()
473 new_perm = Permission()
476 new_perm.permission_name = p[0]
474 new_perm.permission_name = p[0]
477 new_perm.permission_longname = p[1]
475 new_perm.permission_longname = p[1]
478 try:
476 try:
479 self.sa.add(new_perm)
477 self.sa.add(new_perm)
480 self.sa.commit()
478 self.sa.commit()
481 except:
479 except:
482 self.sa.rollback()
480 self.sa.rollback()
483 raise
481 raise
484
482
485 def populate_default_permissions(self):
483 def populate_default_permissions(self):
486 log.info('creating default user permissions')
484 log.info('creating default user permissions')
487
485
488 default_user = self.sa.query(User)\
486 default_user = self.sa.query(User)\
489 .filter(User.username == 'default').scalar()
487 .filter(User.username == 'default').scalar()
490
488
491 reg_perm = UserToPerm()
489 reg_perm = UserToPerm()
492 reg_perm.user = default_user
490 reg_perm.user = default_user
493 reg_perm.permission = self.sa.query(Permission)\
491 reg_perm.permission = self.sa.query(Permission)\
494 .filter(Permission.permission_name == 'hg.register.manual_activate')\
492 .filter(Permission.permission_name == 'hg.register.manual_activate')\
495 .scalar()
493 .scalar()
496
494
497 create_repo_perm = UserToPerm()
495 create_repo_perm = UserToPerm()
498 create_repo_perm.user = default_user
496 create_repo_perm.user = default_user
499 create_repo_perm.permission = self.sa.query(Permission)\
497 create_repo_perm.permission = self.sa.query(Permission)\
500 .filter(Permission.permission_name == 'hg.create.repository')\
498 .filter(Permission.permission_name == 'hg.create.repository')\
501 .scalar()
499 .scalar()
502
500
503 default_repo_perm = UserToPerm()
501 default_repo_perm = UserToPerm()
504 default_repo_perm.user = default_user
502 default_repo_perm.user = default_user
505 default_repo_perm.permission = self.sa.query(Permission)\
503 default_repo_perm.permission = self.sa.query(Permission)\
506 .filter(Permission.permission_name == 'repository.read')\
504 .filter(Permission.permission_name == 'repository.read')\
507 .scalar()
505 .scalar()
508
506
509 try:
507 try:
510 self.sa.add(reg_perm)
508 self.sa.add(reg_perm)
511 self.sa.add(create_repo_perm)
509 self.sa.add(create_repo_perm)
512 self.sa.add(default_repo_perm)
510 self.sa.add(default_repo_perm)
513 self.sa.commit()
511 self.sa.commit()
514 except:
512 except:
515 self.sa.rollback()
513 self.sa.rollback()
516 raise
514 raise
@@ -1,387 +1,456 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.model.db
3 rhodecode.model.db
4 ~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~
5
5
6 Database Models for RhodeCode
6 Database Models for RhodeCode
7
7
8 :created_on: Apr 08, 2010
8 :created_on: Apr 08, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2009-2011 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 datetime
28 import datetime
29 from datetime import date
29 from datetime import date
30
30
31 from sqlalchemy import *
31 from sqlalchemy import *
32 from sqlalchemy.exc import DatabaseError
32 from sqlalchemy.exc import DatabaseError
33 from sqlalchemy.orm import relationship, backref
33 from sqlalchemy.orm import relationship, backref
34 from sqlalchemy.orm.interfaces import MapperExtension
34 from sqlalchemy.orm.interfaces import MapperExtension
35
35
36 from rhodecode.lib import str2bool
36 from rhodecode.model.meta import Base, Session
37 from rhodecode.model.meta import Base, Session
38 from rhodecode.model.caching_query import FromCache
37
39
38 log = logging.getLogger(__name__)
40 log = logging.getLogger(__name__)
39
41
40 #==============================================================================
42 #==============================================================================
41 # MAPPER EXTENSIONS
43 # MAPPER EXTENSIONS
42 #==============================================================================
44 #==============================================================================
43
45
44 class RepositoryMapper(MapperExtension):
46 class RepositoryMapper(MapperExtension):
45 def after_update(self, mapper, connection, instance):
47 def after_update(self, mapper, connection, instance):
46 pass
48 pass
47
49
48
50
49 class RhodeCodeSettings(Base):
51 class RhodeCodeSettings(Base):
50 __tablename__ = 'rhodecode_settings'
52 __tablename__ = 'rhodecode_settings'
51 __table_args__ = (UniqueConstraint('app_settings_name'), {'useexisting':True})
53 __table_args__ = (UniqueConstraint('app_settings_name'), {'useexisting':True})
52 app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
54 app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
53 app_settings_name = Column("app_settings_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
55 app_settings_name = Column("app_settings_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
54 app_settings_value = Column("app_settings_value", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
56 app_settings_value = Column("app_settings_value", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
55
57
56 def __init__(self, k='', v=''):
58 def __init__(self, k='', v=''):
57 self.app_settings_name = k
59 self.app_settings_name = k
58 self.app_settings_value = v
60 self.app_settings_value = v
59
61
60 def __repr__(self):
62 def __repr__(self):
61 return "<%s('%s:%s')>" % (self.__class__.__name__,
63 return "<%s('%s:%s')>" % (self.__class__.__name__,
62 self.app_settings_name, self.app_settings_value)
64 self.app_settings_name, self.app_settings_value)
63
65
66
67 @classmethod
68 def get_app_settings(cls, cache=False):
69
70 ret = Session.query(cls)
71
72 if cache:
73 ret = ret.options(FromCache("sql_cache_short", "get_hg_settings"))
74
75 if not ret:
76 raise Exception('Could not get application settings !')
77 settings = {}
78 for each in ret:
79 settings['rhodecode_' + each.app_settings_name] = \
80 each.app_settings_value
81
82 return settings
83
84 @classmethod
85 def get_ldap_settings(cls, cache=False):
86 ret = Session.query(cls)\
87 .filter(cls.app_settings_name.startswith('ldap_'))\
88 .all()
89 fd = {}
90 for row in ret:
91 fd.update({row.app_settings_name:str2bool(row.app_settings_value)})
92 return fd
93
94
64 class RhodeCodeUi(Base):
95 class RhodeCodeUi(Base):
65 __tablename__ = 'rhodecode_ui'
96 __tablename__ = 'rhodecode_ui'
66 __table_args__ = {'useexisting':True}
97 __table_args__ = {'useexisting':True}
67 ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
98 ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
68 ui_section = Column("ui_section", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
99 ui_section = Column("ui_section", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
69 ui_key = Column("ui_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
100 ui_key = Column("ui_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
70 ui_value = Column("ui_value", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
101 ui_value = Column("ui_value", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
71 ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True)
102 ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True)
72
103
73
104
74 class User(Base):
105 class User(Base):
75 __tablename__ = 'users'
106 __tablename__ = 'users'
76 __table_args__ = (UniqueConstraint('username'), UniqueConstraint('email'), {'useexisting':True})
107 __table_args__ = (UniqueConstraint('username'), UniqueConstraint('email'), {'useexisting':True})
77 user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
108 user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
78 username = Column("username", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
109 username = Column("username", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
79 password = Column("password", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
110 password = Column("password", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
80 active = Column("active", Boolean(), nullable=True, unique=None, default=None)
111 active = Column("active", Boolean(), nullable=True, unique=None, default=None)
81 admin = Column("admin", Boolean(), nullable=True, unique=None, default=False)
112 admin = Column("admin", Boolean(), nullable=True, unique=None, default=False)
82 name = Column("name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
113 name = Column("name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
83 lastname = Column("lastname", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
114 lastname = Column("lastname", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
84 email = Column("email", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
115 email = Column("email", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
85 last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None)
116 last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None)
86 ldap_dn = Column("ldap_dn", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
117 ldap_dn = Column("ldap_dn", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
87 api_key = Column("api_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
118 api_key = Column("api_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
88
119
89 user_log = relationship('UserLog', cascade='all')
120 user_log = relationship('UserLog', cascade='all')
90 user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all')
121 user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all')
91
122
92 repositories = relationship('Repository')
123 repositories = relationship('Repository')
93 user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all')
124 user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all')
94
125
95 group_member = relationship('UsersGroupMember', cascade='all')
126 group_member = relationship('UsersGroupMember', cascade='all')
96
127
97 @property
128 @property
98 def full_contact(self):
129 def full_contact(self):
99 return '%s %s <%s>' % (self.name, self.lastname, self.email)
130 return '%s %s <%s>' % (self.name, self.lastname, self.email)
100
131
101 @property
132 @property
102 def short_contact(self):
133 def short_contact(self):
103 return '%s %s' % (self.name, self.lastname)
134 return '%s %s' % (self.name, self.lastname)
104
135
105
136
106 @property
137 @property
107 def is_admin(self):
138 def is_admin(self):
108 return self.admin
139 return self.admin
109
140
110 def __repr__(self):
141 def __repr__(self):
111 return "<%s('id:%s:%s')>" % (self.__class__.__name__,
142 return "<%s('id:%s:%s')>" % (self.__class__.__name__,
112 self.user_id, self.username)
143 self.user_id, self.username)
113
144
114 @classmethod
145 @classmethod
115 def by_username(cls, username):
146 def by_username(cls, username):
116 return Session.query(cls).filter(cls.username == username).one()
147 return Session.query(cls).filter(cls.username == username).one()
117
148
118
149
119 def update_lastlogin(self):
150 def update_lastlogin(self):
120 """Update user lastlogin"""
151 """Update user lastlogin"""
121
152
122 try:
153 try:
123 session = Session.object_session(self)
154 session = Session.object_session(self)
124 self.last_login = datetime.datetime.now()
155 self.last_login = datetime.datetime.now()
125 session.add(self)
156 session.add(self)
126 session.commit()
157 session.commit()
127 log.debug('updated user %s lastlogin', self.username)
158 log.debug('updated user %s lastlogin', self.username)
128 except (DatabaseError,):
159 except (DatabaseError,):
129 session.rollback()
160 session.rollback()
130
161
131
162
132 class UserLog(Base):
163 class UserLog(Base):
133 __tablename__ = 'user_logs'
164 __tablename__ = 'user_logs'
134 __table_args__ = {'useexisting':True}
165 __table_args__ = {'useexisting':True}
135 user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
166 user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
136 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
167 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
137 repository_id = Column("repository_id", Integer(length=None, convert_unicode=False, assert_unicode=None), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
168 repository_id = Column("repository_id", Integer(length=None, convert_unicode=False, assert_unicode=None), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
138 repository_name = Column("repository_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
169 repository_name = Column("repository_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
139 user_ip = Column("user_ip", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
170 user_ip = Column("user_ip", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
140 action = Column("action", UnicodeText(length=1200000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
171 action = Column("action", UnicodeText(length=1200000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
141 action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None)
172 action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None)
142
173
143 @property
174 @property
144 def action_as_day(self):
175 def action_as_day(self):
145 return date(*self.action_date.timetuple()[:3])
176 return date(*self.action_date.timetuple()[:3])
146
177
147 user = relationship('User')
178 user = relationship('User')
148 repository = relationship('Repository')
179 repository = relationship('Repository')
149
180
150
181
151 class UsersGroup(Base):
182 class UsersGroup(Base):
152 __tablename__ = 'users_groups'
183 __tablename__ = 'users_groups'
153 __table_args__ = {'useexisting':True}
184 __table_args__ = {'useexisting':True}
154
185
155 users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
186 users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
156 users_group_name = Column("users_group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
187 users_group_name = Column("users_group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
157 users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None)
188 users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None)
158
189
159 members = relationship('UsersGroupMember', cascade="all, delete, delete-orphan", lazy="joined")
190 members = relationship('UsersGroupMember', cascade="all, delete, delete-orphan", lazy="joined")
160
191
161 class UsersGroupMember(Base):
192 class UsersGroupMember(Base):
162 __tablename__ = 'users_groups_members'
193 __tablename__ = 'users_groups_members'
163 __table_args__ = {'useexisting':True}
194 __table_args__ = {'useexisting':True}
164
195
165 users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
196 users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
166 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
197 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
167 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
198 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
168
199
169 user = relationship('User', lazy='joined')
200 user = relationship('User', lazy='joined')
170 users_group = relationship('UsersGroup')
201 users_group = relationship('UsersGroup')
171
202
172 def __init__(self, gr_id='', u_id=''):
203 def __init__(self, gr_id='', u_id=''):
173 self.users_group_id = gr_id
204 self.users_group_id = gr_id
174 self.user_id = u_id
205 self.user_id = u_id
175
206
176 class Repository(Base):
207 class Repository(Base):
177 __tablename__ = 'repositories'
208 __tablename__ = 'repositories'
178 __table_args__ = (UniqueConstraint('repo_name'), {'useexisting':True},)
209 __table_args__ = (UniqueConstraint('repo_name'), {'useexisting':True},)
179 __mapper_args__ = {'extension':RepositoryMapper()}
210 __mapper_args__ = {'extension':RepositoryMapper()}
180
211
181 repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
212 repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
182 repo_name = Column("repo_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
213 repo_name = Column("repo_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
183 clone_uri = Column("clone_uri", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=False, default=None)
214 clone_uri = Column("clone_uri", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=False, default=None)
184 repo_type = Column("repo_type", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=False, default='hg')
215 repo_type = Column("repo_type", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=False, default='hg')
185 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None)
216 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None)
186 private = Column("private", Boolean(), nullable=True, unique=None, default=None)
217 private = Column("private", Boolean(), nullable=True, unique=None, default=None)
187 enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True)
218 enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True)
188 enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True)
219 enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True)
189 description = Column("description", String(length=10000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
220 description = Column("description", String(length=10000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
190 fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None)
221 fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None)
191 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None)
222 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None)
192
223
193
224
194 user = relationship('User')
225 user = relationship('User')
195 fork = relationship('Repository', remote_side=repo_id)
226 fork = relationship('Repository', remote_side=repo_id)
196 group = relationship('Group')
227 group = relationship('Group')
197 repo_to_perm = relationship('RepoToPerm', cascade='all', order_by='RepoToPerm.repo_to_perm_id')
228 repo_to_perm = relationship('RepoToPerm', cascade='all', order_by='RepoToPerm.repo_to_perm_id')
198 users_group_to_perm = relationship('UsersGroupToPerm', cascade='all')
229 users_group_to_perm = relationship('UsersGroupToPerm', cascade='all')
199 stats = relationship('Statistics', cascade='all', uselist=False)
230 stats = relationship('Statistics', cascade='all', uselist=False)
200
231
201 followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all')
232 followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all')
202
233
203 logs = relationship('UserLog', cascade='all')
234 logs = relationship('UserLog', cascade='all')
204
235
205 def __repr__(self):
236 def __repr__(self):
206 return "<%s('%s:%s')>" % (self.__class__.__name__,
237 return "<%s('%s:%s')>" % (self.__class__.__name__,
207 self.repo_id, self.repo_name)
238 self.repo_id, self.repo_name)
208
239
209 @classmethod
240 @classmethod
210 def by_repo_name(cls, repo_name):
241 def by_repo_name(cls, repo_name):
211 return Session.query(cls).filter(cls.repo_name == repo_name).one()
242 return Session.query(cls).filter(cls.repo_name == repo_name).one()
212
243
213 @property
244 @property
214 def just_name(self):
245 def just_name(self):
215 return self.repo_name.split(os.sep)[-1]
246 return self.repo_name.split(os.sep)[-1]
216
247
217 @property
248 @property
218 def groups_with_parents(self):
249 def groups_with_parents(self):
219 groups = []
250 groups = []
220 if self.group is None:
251 if self.group is None:
221 return groups
252 return groups
222
253
223 cur_gr = self.group
254 cur_gr = self.group
224 groups.insert(0, cur_gr)
255 groups.insert(0, cur_gr)
225 while 1:
256 while 1:
226 gr = getattr(cur_gr, 'parent_group', None)
257 gr = getattr(cur_gr, 'parent_group', None)
227 cur_gr = cur_gr.parent_group
258 cur_gr = cur_gr.parent_group
228 if gr is None:
259 if gr is None:
229 break
260 break
230 groups.insert(0, gr)
261 groups.insert(0, gr)
231
262
232 return groups
263 return groups
233
264
234 @property
265 @property
235 def groups_and_repo(self):
266 def groups_and_repo(self):
236 return self.groups_with_parents, self.just_name
267 return self.groups_with_parents, self.just_name
237
268
238
269
239 class Group(Base):
270 class Group(Base):
240 __tablename__ = 'groups'
271 __tablename__ = 'groups'
241 __table_args__ = (UniqueConstraint('group_name'), {'useexisting':True},)
272 __table_args__ = (UniqueConstraint('group_name'), {'useexisting':True},)
242
273
243 group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
274 group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
244 group_name = Column("group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
275 group_name = Column("group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
245 group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None)
276 group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None)
246
277
247 parent_group = relationship('Group', remote_side=group_id)
278 parent_group = relationship('Group', remote_side=group_id)
248
279
249
280
250 def __init__(self, group_name='', parent_group=None):
281 def __init__(self, group_name='', parent_group=None):
251 self.group_name = group_name
282 self.group_name = group_name
252 self.parent_group = parent_group
283 self.parent_group = parent_group
253
284
254 def __repr__(self):
285 def __repr__(self):
255 return "<%s('%s:%s')>" % (self.__class__.__name__, self.group_id,
286 return "<%s('%s:%s')>" % (self.__class__.__name__, self.group_id,
256 self.group_name)
287 self.group_name)
257
288
258 @property
289 @property
259 def parents(self):
290 def parents(self):
260 groups = []
291 groups = []
261 if self.parent_group is None:
292 if self.parent_group is None:
262 return groups
293 return groups
263 cur_gr = self.parent_group
294 cur_gr = self.parent_group
264 groups.insert(0, cur_gr)
295 groups.insert(0, cur_gr)
265 while 1:
296 while 1:
266 gr = getattr(cur_gr, 'parent_group', None)
297 gr = getattr(cur_gr, 'parent_group', None)
267 cur_gr = cur_gr.parent_group
298 cur_gr = cur_gr.parent_group
268 if gr is None:
299 if gr is None:
269 break
300 break
270 groups.insert(0, gr)
301 groups.insert(0, gr)
271 return groups
302 return groups
272
303
273 @property
304 @property
274 def repositories(self):
305 def repositories(self):
275 return Session.query(Repository).filter(Repository.group == self).all()
306 return Session.query(Repository).filter(Repository.group == self).all()
276
307
277 class Permission(Base):
308 class Permission(Base):
278 __tablename__ = 'permissions'
309 __tablename__ = 'permissions'
279 __table_args__ = {'useexisting':True}
310 __table_args__ = {'useexisting':True}
280 permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
311 permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
281 permission_name = Column("permission_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
312 permission_name = Column("permission_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
282 permission_longname = Column("permission_longname", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
313 permission_longname = Column("permission_longname", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
283
314
284 def __repr__(self):
315 def __repr__(self):
285 return "<%s('%s:%s')>" % (self.__class__.__name__,
316 return "<%s('%s:%s')>" % (self.__class__.__name__,
286 self.permission_id, self.permission_name)
317 self.permission_id, self.permission_name)
287
318
319 @classmethod
320 def get_by_key(cls, key):
321 return Session.query(cls).filter(cls.permission_name == key).scalar()
322
288 class RepoToPerm(Base):
323 class RepoToPerm(Base):
289 __tablename__ = 'repo_to_perm'
324 __tablename__ = 'repo_to_perm'
290 __table_args__ = (UniqueConstraint('user_id', 'repository_id'), {'useexisting':True})
325 __table_args__ = (UniqueConstraint('user_id', 'repository_id'), {'useexisting':True})
291 repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
326 repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
292 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
327 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
293 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
328 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
294 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
329 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
295
330
296 user = relationship('User')
331 user = relationship('User')
297 permission = relationship('Permission')
332 permission = relationship('Permission')
298 repository = relationship('Repository')
333 repository = relationship('Repository')
299
334
300 class UserToPerm(Base):
335 class UserToPerm(Base):
301 __tablename__ = 'user_to_perm'
336 __tablename__ = 'user_to_perm'
302 __table_args__ = (UniqueConstraint('user_id', 'permission_id'), {'useexisting':True})
337 __table_args__ = (UniqueConstraint('user_id', 'permission_id'), {'useexisting':True})
303 user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
338 user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
304 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
339 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
305 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
340 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
306
341
307 user = relationship('User')
342 user = relationship('User')
308 permission = relationship('Permission')
343 permission = relationship('Permission')
309
344
345 @classmethod
346 def has_perm(cls, user_id, perm):
347 if not isinstance(perm, Permission):
348 raise Exception('perm needs to be an instance of Permission class')
349
350 return Session.query(cls).filter(cls.user_id == user_id)\
351 .filter(cls.permission == perm).scalar() is not None
352
353 @classmethod
354 def grant_perm(cls, user_id, perm):
355 if not isinstance(perm, Permission):
356 raise Exception('perm needs to be an instance of Permission class')
357
358 new = cls()
359 new.user_id = user_id
360 new.permission = perm
361 try:
362 Session.add(new)
363 Session.commit()
364 except:
365 Session.rollback()
366
367
368 @classmethod
369 def revoke_perm(cls, user_id, perm):
370 if not isinstance(perm, Permission):
371 raise Exception('perm needs to be an instance of Permission class')
372
373 try:
374 Session.query(cls).filter(cls.user_id == user_id)\
375 .filter(cls.permission == perm).delete()
376 Session.commit()
377 except:
378 Session.rollback()
310
379
311 class UsersGroupToPerm(Base):
380 class UsersGroupToPerm(Base):
312 __tablename__ = 'users_group_to_perm'
381 __tablename__ = 'users_group_to_perm'
313 __table_args__ = (UniqueConstraint('users_group_id', 'permission_id'), {'useexisting':True})
382 __table_args__ = (UniqueConstraint('users_group_id', 'permission_id'), {'useexisting':True})
314 users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
383 users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
315 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
384 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
316 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
385 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
317 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
386 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
318
387
319 users_group = relationship('UsersGroup')
388 users_group = relationship('UsersGroup')
320 permission = relationship('Permission')
389 permission = relationship('Permission')
321 repository = relationship('Repository')
390 repository = relationship('Repository')
322
391
323 class GroupToPerm(Base):
392 class GroupToPerm(Base):
324 __tablename__ = 'group_to_perm'
393 __tablename__ = 'group_to_perm'
325 __table_args__ = (UniqueConstraint('group_id', 'permission_id'), {'useexisting':True})
394 __table_args__ = (UniqueConstraint('group_id', 'permission_id'), {'useexisting':True})
326
395
327 group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
396 group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
328 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
397 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
329 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
398 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
330 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None)
399 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None)
331
400
332 user = relationship('User')
401 user = relationship('User')
333 permission = relationship('Permission')
402 permission = relationship('Permission')
334 group = relationship('Group')
403 group = relationship('Group')
335
404
336 class Statistics(Base):
405 class Statistics(Base):
337 __tablename__ = 'statistics'
406 __tablename__ = 'statistics'
338 __table_args__ = (UniqueConstraint('repository_id'), {'useexisting':True})
407 __table_args__ = (UniqueConstraint('repository_id'), {'useexisting':True})
339 stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
408 stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
340 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None)
409 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None)
341 stat_on_revision = Column("stat_on_revision", Integer(), nullable=False)
410 stat_on_revision = Column("stat_on_revision", Integer(), nullable=False)
342 commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data
411 commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data
343 commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data
412 commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data
344 languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data
413 languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data
345
414
346 repository = relationship('Repository', single_parent=True)
415 repository = relationship('Repository', single_parent=True)
347
416
348 class UserFollowing(Base):
417 class UserFollowing(Base):
349 __tablename__ = 'user_followings'
418 __tablename__ = 'user_followings'
350 __table_args__ = (UniqueConstraint('user_id', 'follows_repository_id'),
419 __table_args__ = (UniqueConstraint('user_id', 'follows_repository_id'),
351 UniqueConstraint('user_id', 'follows_user_id')
420 UniqueConstraint('user_id', 'follows_user_id')
352 , {'useexisting':True})
421 , {'useexisting':True})
353
422
354 user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
423 user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
355 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
424 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
356 follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None)
425 follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None)
357 follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
426 follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
358
427
359 user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id')
428 user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id')
360
429
361 follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id')
430 follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id')
362 follows_repository = relationship('Repository', order_by='Repository.repo_name')
431 follows_repository = relationship('Repository', order_by='Repository.repo_name')
363
432
364 class CacheInvalidation(Base):
433 class CacheInvalidation(Base):
365 __tablename__ = 'cache_invalidation'
434 __tablename__ = 'cache_invalidation'
366 __table_args__ = (UniqueConstraint('cache_key'), {'useexisting':True})
435 __table_args__ = (UniqueConstraint('cache_key'), {'useexisting':True})
367 cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
436 cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
368 cache_key = Column("cache_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
437 cache_key = Column("cache_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
369 cache_args = Column("cache_args", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
438 cache_args = Column("cache_args", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
370 cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False)
439 cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False)
371
440
372
441
373 def __init__(self, cache_key, cache_args=''):
442 def __init__(self, cache_key, cache_args=''):
374 self.cache_key = cache_key
443 self.cache_key = cache_key
375 self.cache_args = cache_args
444 self.cache_args = cache_args
376 self.cache_active = False
445 self.cache_active = False
377
446
378 def __repr__(self):
447 def __repr__(self):
379 return "<%s('%s:%s')>" % (self.__class__.__name__,
448 return "<%s('%s:%s')>" % (self.__class__.__name__,
380 self.cache_id, self.cache_key)
449 self.cache_id, self.cache_key)
381
450
382 class DbMigrateVersion(Base):
451 class DbMigrateVersion(Base):
383 __tablename__ = 'db_migrate_version'
452 __tablename__ = 'db_migrate_version'
384 __table_args__ = {'useexisting':True}
453 __table_args__ = {'useexisting':True}
385 repository_id = Column('repository_id', String(250), primary_key=True)
454 repository_id = Column('repository_id', String(250), primary_key=True)
386 repository_path = Column('repository_path', Text)
455 repository_path = Column('repository_path', Text)
387 version = Column('version', Integer)
456 version = Column('version', Integer)
@@ -1,149 +1,149 b''
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 &raquo;
10 &raquo;
11 ${h.link_to(_('Users'),h.url('users'))}
11 ${h.link_to(_('Users'),h.url('users'))}
12 &raquo;
12 &raquo;
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('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 <strong>Change your avatar at <a href="http://gravatar.com">gravatar.com</a></strong><br/>
33 <strong>Change your avatar at <a href="http://gravatar.com">gravatar.com</a></strong><br/>
34 ${_('Using')} ${c.user.email}
34 ${_('Using')} ${c.user.email}
35 </p>
35 </p>
36 </div>
36 </div>
37 </div>
37 </div>
38 <div class="field">
38 <div class="field">
39 <div class="label">
39 <div class="label">
40 <label>${_('API key')}</label> ${c.user.api_key}
40 <label>${_('API key')}</label> ${c.user.api_key}
41 </div>
41 </div>
42 </div>
42 </div>
43
43
44 <div class="fields">
44 <div class="fields">
45 <div class="field">
45 <div class="field">
46 <div class="label">
46 <div class="label">
47 <label for="username">${_('Username')}:</label>
47 <label for="username">${_('Username')}:</label>
48 </div>
48 </div>
49 <div class="input">
49 <div class="input">
50 ${h.text('username',class_='medium')}
50 ${h.text('username',class_='medium')}
51 </div>
51 </div>
52 </div>
52 </div>
53
53
54 <div class="field">
54 <div class="field">
55 <div class="label">
55 <div class="label">
56 <label for="ldap_dn">${_('LDAP DN')}:</label>
56 <label for="ldap_dn">${_('LDAP DN')}:</label>
57 </div>
57 </div>
58 <div class="input">
58 <div class="input">
59 ${h.text('ldap_dn',class_='medium')}
59 ${h.text('ldap_dn',class_='medium')}
60 </div>
60 </div>
61 </div>
61 </div>
62
62
63 <div class="field">
63 <div class="field">
64 <div class="label">
64 <div class="label">
65 <label for="new_password">${_('New password')}:</label>
65 <label for="new_password">${_('New password')}:</label>
66 </div>
66 </div>
67 <div class="input">
67 <div class="input">
68 ${h.password('new_password',class_='medium')}
68 ${h.password('new_password',class_='medium')}
69 </div>
69 </div>
70 </div>
70 </div>
71
71
72 <div class="field">
72 <div class="field">
73 <div class="label">
73 <div class="label">
74 <label for="name">${_('First Name')}:</label>
74 <label for="name">${_('First Name')}:</label>
75 </div>
75 </div>
76 <div class="input">
76 <div class="input">
77 ${h.text('name',class_='medium')}
77 ${h.text('name',class_='medium')}
78 </div>
78 </div>
79 </div>
79 </div>
80
80
81 <div class="field">
81 <div class="field">
82 <div class="label">
82 <div class="label">
83 <label for="lastname">${_('Last Name')}:</label>
83 <label for="lastname">${_('Last Name')}:</label>
84 </div>
84 </div>
85 <div class="input">
85 <div class="input">
86 ${h.text('lastname',class_='medium')}
86 ${h.text('lastname',class_='medium')}
87 </div>
87 </div>
88 </div>
88 </div>
89
89
90 <div class="field">
90 <div class="field">
91 <div class="label">
91 <div class="label">
92 <label for="email">${_('Email')}:</label>
92 <label for="email">${_('Email')}:</label>
93 </div>
93 </div>
94 <div class="input">
94 <div class="input">
95 ${h.text('email',class_='medium')}
95 ${h.text('email',class_='medium')}
96 </div>
96 </div>
97 </div>
97 </div>
98
98
99 <div class="field">
99 <div class="field">
100 <div class="label label-checkbox">
100 <div class="label label-checkbox">
101 <label for="active">${_('Active')}:</label>
101 <label for="active">${_('Active')}:</label>
102 </div>
102 </div>
103 <div class="checkboxes">
103 <div class="checkboxes">
104 ${h.checkbox('active',value=True)}
104 ${h.checkbox('active',value=True)}
105 </div>
105 </div>
106 </div>
106 </div>
107
107
108 <div class="field">
108 <div class="field">
109 <div class="label label-checkbox">
109 <div class="label label-checkbox">
110 <label for="admin">${_('Admin')}:</label>
110 <label for="admin">${_('Admin')}:</label>
111 </div>
111 </div>
112 <div class="checkboxes">
112 <div class="checkboxes">
113 ${h.checkbox('admin',value=True)}
113 ${h.checkbox('admin',value=True)}
114 </div>
114 </div>
115 </div>
115 </div>
116 <div class="buttons">
116 <div class="buttons">
117 ${h.submit('save','Save',class_="ui-button")}
117 ${h.submit('save','Save',class_="ui-button")}
118 ${h.reset('reset','Reset',class_="ui-button")}
118 ${h.reset('reset','Reset',class_="ui-button")}
119 </div>
119 </div>
120 </div>
120 </div>
121 </div>
121 </div>
122 ${h.end_form()}
122 ${h.end_form()}
123 </div>
123 </div>
124 <div class="box box-right">
124 <div class="box box-right">
125 <!-- box / title -->
125 <!-- box / title -->
126 <div class="title">
126 <div class="title">
127 <h5>${_('Permissions')}</h5>
127 <h5>${_('Permissions')}</h5>
128 </div>
128 </div>
129 ${h.form(url('user', id=c.user.user_id),method='put')}
129 ${h.form(url('user_perm', id=c.user.user_id),method='put')}
130 <div class="form">
130 <div class="form">
131 <!-- fields -->
131 <!-- fields -->
132 <div class="fields">
132 <div class="fields">
133 <div class="field">
133 <div class="field">
134 <div class="label label-checkbox">
134 <div class="label label-checkbox">
135 <label for="">${_('Create repositories')}:</label>
135 <label for="">${_('Create repositories')}:</label>
136 </div>
136 </div>
137 <div class="checkboxes">
137 <div class="checkboxes">
138 ${h.checkbox('create',value=True)}
138 ${h.checkbox('create_repo_perm',value=True)}
139 </div>
139 </div>
140 </div>
140 </div>
141 <div class="buttons">
141 <div class="buttons">
142 ${h.submit('save','Save',class_="ui-button")}
142 ${h.submit('save','Save',class_="ui-button")}
143 ${h.reset('reset','Reset',class_="ui-button")}
143 ${h.reset('reset','Reset',class_="ui-button")}
144 </div>
144 </div>
145 </div>
145 </div>
146 </div>
146 </div>
147 ${h.end_form()}
147 ${h.end_form()}
148 </div>
148 </div>
149 </%def>
149 </%def>
@@ -1,65 +1,65 b''
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 ${_('Users administration')} - ${c.rhodecode_name}
5 ${_('Users administration')} - ${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'))} &raquo; ${_('Users')}
9 ${h.link_to(_('Admin'),h.url('admin_home'))} &raquo; ${_('Users')}
10 </%def>
10 </%def>
11
11
12 <%def name="page_nav()">
12 <%def name="page_nav()">
13 ${self.menu('admin')}
13 ${self.menu('admin')}
14 </%def>
14 </%def>
15
15
16 <%def name="main()">
16 <%def name="main()">
17 <div class="box">
17 <div class="box">
18 <!-- box / title -->
18 <!-- box / title -->
19 <div class="title">
19 <div class="title">
20 ${self.breadcrumbs()}
20 ${self.breadcrumbs()}
21 <ul class="links">
21 <ul class="links">
22 <li>
22 <li>
23 <span>${h.link_to(u'ADD NEW USER',h.url('new_user'))}</span>
23 <span>${h.link_to(u'ADD NEW USER',h.url('new_user'))}</span>
24 </li>
24 </li>
25
25
26 </ul>
26 </ul>
27 </div>
27 </div>
28 <!-- end box / title -->
28 <!-- end box / title -->
29 <div class="table">
29 <div class="table">
30 <table class="table_disp">
30 <table class="table_disp">
31 <tr class="header">
31 <tr class="header">
32 <th></th>
32 <th></th>
33 <th class="left">${_('username')}</th>
33 <th class="left">${_('username')}</th>
34 <th class="left">${_('name')}</th>
34 <th class="left">${_('name')}</th>
35 <th class="left">${_('lastname')}</th>
35 <th class="left">${_('lastname')}</th>
36 <th class="left">${_('last login')}</th>
36 <th class="left">${_('last login')}</th>
37 <th class="left">${_('active')}</th>
37 <th class="left">${_('active')}</th>
38 <th class="left">${_('admin')}</th>
38 <th class="left">${_('admin')}</th>
39 <th class="left">${_('ldap')}</th>
39 <th class="left">${_('ldap')}</th>
40 <th class="left">${_('action')}</th>
40 <th class="left">${_('action')}</th>
41 </tr>
41 </tr>
42 %for cnt,user in enumerate(c.users_list):
42 %for cnt,user in enumerate(c.users_list):
43 %if user.name !='default':
43 %if user.name !='default':
44 <tr class="parity${cnt%2}">
44 <tr class="parity${cnt%2}">
45 <td><div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(user.email,24)}"/> </div></td>
45 <td><div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(user.email,24)}"/> </div></td>
46 <td>${h.link_to(user.username,h.url('edit_user', id=user.user_id))}</td>
46 <td>${h.link_to(user.username,h.url('edit_user', id=user.user_id))}</td>
47 <td>${user.name}</td>
47 <td>${user.name}</td>
48 <td>${user.lastname}</td>
48 <td>${user.lastname}</td>
49 <td>${user.last_login}</td>
49 <td>${user.last_login}</td>
50 <td>${h.bool2icon(user.active)}</td>
50 <td>${h.bool2icon(user.active)}</td>
51 <td>${h.bool2icon(user.admin)}</td>
51 <td>${h.bool2icon(user.admin)}</td>
52 <td>${h.bool2icon(bool(user.ldap_dn))}</td>
52 <td>${h.bool2icon(bool(user.ldap_dn))}</td>
53 <td>
53 <td>
54 ${h.form(url('user', id=user.user_id),method='delete')}
54 ${h.form(url('delete_user', id=user.user_id),method='delete')}
55 ${h.submit('remove_','delete',id="remove_user_%s" % user.user_id,
55 ${h.submit('remove_','delete',id="remove_user_%s" % user.user_id,
56 class_="delete_icon action_button",onclick="return confirm('Confirm to delete this user');")}
56 class_="delete_icon action_button",onclick="return confirm('Confirm to delete this user');")}
57 ${h.end_form()}
57 ${h.end_form()}
58 </td>
58 </td>
59 </tr>
59 </tr>
60 %endif
60 %endif
61 %endfor
61 %endfor
62 </table>
62 </table>
63 </div>
63 </div>
64 </div>
64 </div>
65 </%def>
65 </%def>
@@ -1,270 +1,270 b''
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 users group')} ${c.users_group.users_group_name} - ${c.rhodecode_name}
5 ${_('Edit users group')} ${c.users_group.users_group_name} - ${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 &raquo;
10 &raquo;
11 ${h.link_to(_('UsersGroups'),h.url('users_groups'))}
11 ${h.link_to(_('UsersGroups'),h.url('users_groups'))}
12 &raquo;
12 &raquo;
13 ${_('edit')} "${c.users_group.users_group_name}"
13 ${_('edit')} "${c.users_group.users_group_name}"
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('users_group', id=c.users_group.users_group_id),method='put', id='edit_users_group')}
27 ${h.form(url('users_group', id=c.users_group.users_group_id),method='put', id='edit_users_group')}
28 <div class="form">
28 <div class="form">
29 <!-- fields -->
29 <!-- fields -->
30 <div class="fields">
30 <div class="fields">
31 <div class="field">
31 <div class="field">
32 <div class="label">
32 <div class="label">
33 <label for="users_group_name">${_('Group name')}:</label>
33 <label for="users_group_name">${_('Group name')}:</label>
34 </div>
34 </div>
35 <div class="input">
35 <div class="input">
36 ${h.text('users_group_name',class_='small')}
36 ${h.text('users_group_name',class_='small')}
37 </div>
37 </div>
38 </div>
38 </div>
39
39
40 <div class="field">
40 <div class="field">
41 <div class="label label-checkbox">
41 <div class="label label-checkbox">
42 <label for="users_group_active">${_('Active')}:</label>
42 <label for="users_group_active">${_('Active')}:</label>
43 </div>
43 </div>
44 <div class="checkboxes">
44 <div class="checkboxes">
45 ${h.checkbox('users_group_active',value=True)}
45 ${h.checkbox('users_group_active',value=True)}
46 </div>
46 </div>
47 </div>
47 </div>
48 <div class="field">
48 <div class="field">
49 <div class="label">
49 <div class="label">
50 <label for="users_group_active">${_('Members')}:</label>
50 <label for="users_group_active">${_('Members')}:</label>
51 </div>
51 </div>
52 <div class="select">
52 <div class="select">
53 <table>
53 <table>
54 <tr>
54 <tr>
55 <td>
55 <td>
56 <div>
56 <div>
57 <div style="float:left">
57 <div style="float:left">
58 <div class="text" style="padding: 0px 0px 6px;">${_('Choosen group members')}</div>
58 <div class="text" style="padding: 0px 0px 6px;">${_('Choosen group members')}</div>
59 ${h.select('users_group_members',[x[0] for x in c.group_members],c.group_members,multiple=True,size=8,style="min-width:210px")}
59 ${h.select('users_group_members',[x[0] for x in c.group_members],c.group_members,multiple=True,size=8,style="min-width:210px")}
60 <div id="remove_all_elements" style="cursor:pointer;text-align:center">
60 <div id="remove_all_elements" style="cursor:pointer;text-align:center">
61 ${_('Remove all elements')}
61 ${_('Remove all elements')}
62 <img alt="remove" style="vertical-align:text-bottom" src="${h.url("/images/icons/arrow_right.png")}"/>
62 <img alt="remove" style="vertical-align:text-bottom" src="${h.url("/images/icons/arrow_right.png")}"/>
63 </div>
63 </div>
64 </div>
64 </div>
65 <div style="float:left;width:20px;padding-top:50px">
65 <div style="float:left;width:20px;padding-top:50px">
66 <img alt="add" id="add_element"
66 <img alt="add" id="add_element"
67 style="padding:2px;cursor:pointer"
67 style="padding:2px;cursor:pointer"
68 src="${h.url("/images/icons/arrow_left.png")}"/>
68 src="${h.url("/images/icons/arrow_left.png")}"/>
69 <br />
69 <br />
70 <img alt="remove" id="remove_element"
70 <img alt="remove" id="remove_element"
71 style="padding:2px;cursor:pointer"
71 style="padding:2px;cursor:pointer"
72 src="${h.url("/images/icons/arrow_right.png")}"/>
72 src="${h.url("/images/icons/arrow_right.png")}"/>
73 </div>
73 </div>
74 <div style="float:left">
74 <div style="float:left">
75 <div class="text" style="padding: 0px 0px 6px;">${_('Available members')}</div>
75 <div class="text" style="padding: 0px 0px 6px;">${_('Available members')}</div>
76 ${h.select('available_members',[],c.available_members,multiple=True,size=8,style="min-width:210px")}
76 ${h.select('available_members',[],c.available_members,multiple=True,size=8,style="min-width:210px")}
77 <div id="add_all_elements" style="cursor:pointer;text-align:center">
77 <div id="add_all_elements" style="cursor:pointer;text-align:center">
78 <img alt="add" style="vertical-align:text-bottom" src="${h.url("/images/icons/arrow_left.png")}"/>
78 <img alt="add" style="vertical-align:text-bottom" src="${h.url("/images/icons/arrow_left.png")}"/>
79 ${_('Add all elements')}
79 ${_('Add all elements')}
80 </div>
80 </div>
81 </div>
81 </div>
82 </div>
82 </div>
83 </td>
83 </td>
84 </tr>
84 </tr>
85 </table>
85 </table>
86 </div>
86 </div>
87
87
88 </div>
88 </div>
89 <div class="buttons">
89 <div class="buttons">
90 ${h.submit('save','save',class_="ui-button")}
90 ${h.submit('save','save',class_="ui-button")}
91 </div>
91 </div>
92 </div>
92 </div>
93 </div>
93 </div>
94 ${h.end_form()}
94 ${h.end_form()}
95 </div>
95 </div>
96
96
97 <script type="text/javascript">
97 <script type="text/javascript">
98 YAHOO.util.Event.onDOMReady(function(){
98 YAHOO.util.Event.onDOMReady(function(){
99 var D = YAHOO.util.Dom;
99 var D = YAHOO.util.Dom;
100 var E = YAHOO.util.Event;
100 var E = YAHOO.util.Event;
101
101
102 //definition of containers ID's
102 //definition of containers ID's
103 var available_container = 'available_members';
103 var available_container = 'available_members';
104 var selected_container = 'users_group_members';
104 var selected_container = 'users_group_members';
105
105
106 //form containing containers id
106 //form containing containers id
107 var form_id = 'edit_users_group';
107 var form_id = 'edit_users_group';
108
108
109 //temp container for selected storage.
109 //temp container for selected storage.
110 var cache = new Array();
110 var cache = new Array();
111 var av_cache = new Array();
111 var av_cache = new Array();
112 var c = D.get(selected_container);
112 var c = D.get(selected_container);
113 var ac = D.get(available_container);
113 var ac = D.get(available_container);
114
114
115 //get only selected options for further fullfilment
115 //get only selected options for further fullfilment
116 for(var i = 0;node =c.options[i];i++){
116 for(var i = 0;node =c.options[i];i++){
117 if(node.selected){
117 if(node.selected){
118 //push selected to my temp storage left overs :)
118 //push selected to my temp storage left overs :)
119 cache.push(node);
119 cache.push(node);
120 }
120 }
121 }
121 }
122
122
123 //clear 'selected' select
123 //clear 'selected' select
124 //c.options.length = 0;
124 //c.options.length = 0;
125
125
126 //fill it with remembered options
126 //fill it with remembered options
127 //for(var i = 0;node = cache[i];i++){
127 //for(var i = 0;node = cache[i];i++){
128 // c.options[i]=new Option(node.text, node.value, false, false);
128 // c.options[i]=new Option(node.text, node.value, false, false);
129 //}
129 //}
130
130
131
131
132 //get all available options to cache
132 //get all available options to cache
133 for(var i = 0;node =ac.options[i];i++){
133 for(var i = 0;node =ac.options[i];i++){
134 //push selected to my temp storage left overs :)
134 //push selected to my temp storage left overs :)
135 av_cache.push(node);
135 av_cache.push(node);
136 }
136 }
137
137
138 //fill available only with those not in choosen
138 //fill available only with those not in choosen
139 ac.options.length=0;
139 ac.options.length=0;
140 tmp_cache = new Array();
140 tmp_cache = new Array();
141
141
142 for(var i = 0;node = av_cache[i];i++){
142 for(var i = 0;node = av_cache[i];i++){
143 var add = true;
143 var add = true;
144 for(var i2 = 0;node_2 = cache[i2];i2++){
144 for(var i2 = 0;node_2 = cache[i2];i2++){
145 if(node.value == node_2.value){
145 if(node.value == node_2.value){
146 add=false;
146 add=false;
147 break;
147 break;
148 }
148 }
149 }
149 }
150 if(add){
150 if(add){
151 tmp_cache.push(new Option(node.text, node.value, false, false));
151 tmp_cache.push(new Option(node.text, node.value, false, false));
152 }
152 }
153 }
153 }
154
154
155 for(var i = 0;node = tmp_cache[i];i++){
155 for(var i = 0;node = tmp_cache[i];i++){
156 ac.options[i] = node;
156 ac.options[i] = node;
157 }
157 }
158
158
159 function prompts_action_callback(e){
159 function prompts_action_callback(e){
160
160
161 var choosen = D.get(selected_container);
161 var choosen = D.get(selected_container);
162 var available = D.get(available_container);
162 var available = D.get(available_container);
163
163
164 //get checked and unchecked options from field
164 //get checked and unchecked options from field
165 function get_checked(from_field){
165 function get_checked(from_field){
166 //temp container for storage.
166 //temp container for storage.
167 var sel_cache = new Array();
167 var sel_cache = new Array();
168 var oth_cache = new Array();
168 var oth_cache = new Array();
169
169
170 for(var i = 0;node = from_field.options[i];i++){
170 for(var i = 0;node = from_field.options[i];i++){
171 if(node.selected){
171 if(node.selected){
172 //push selected fields :)
172 //push selected fields :)
173 sel_cache.push(node);
173 sel_cache.push(node);
174 }
174 }
175 else{
175 else{
176 oth_cache.push(node)
176 oth_cache.push(node)
177 }
177 }
178 }
178 }
179
179
180 return [sel_cache,oth_cache]
180 return [sel_cache,oth_cache]
181 }
181 }
182
182
183 //fill the field with given options
183 //fill the field with given options
184 function fill_with(field,options){
184 function fill_with(field,options){
185 //clear firtst
185 //clear firtst
186 field.options.length=0;
186 field.options.length=0;
187 for(var i = 0;node = options[i];i++){
187 for(var i = 0;node = options[i];i++){
188 field.options[i]=new Option(node.text, node.value,
188 field.options[i]=new Option(node.text, node.value,
189 false, false);
189 false, false);
190 }
190 }
191
191
192 }
192 }
193 //adds to current field
193 //adds to current field
194 function add_to(field,options){
194 function add_to(field,options){
195 for(var i = 0;node = options[i];i++){
195 for(var i = 0;node = options[i];i++){
196 field.appendChild(new Option(node.text, node.value,
196 field.appendChild(new Option(node.text, node.value,
197 false, false));
197 false, false));
198 }
198 }
199 }
199 }
200
200
201 // add action
201 // add action
202 if (this.id=='add_element'){
202 if (this.id=='add_element'){
203 var c = get_checked(available);
203 var c = get_checked(available);
204 add_to(choosen,c[0]);
204 add_to(choosen,c[0]);
205 fill_with(available,c[1]);
205 fill_with(available,c[1]);
206 }
206 }
207 // remove action
207 // remove action
208 if (this.id=='remove_element'){
208 if (this.id=='remove_element'){
209 var c = get_checked(choosen);
209 var c = get_checked(choosen);
210 add_to(available,c[0]);
210 add_to(available,c[0]);
211 fill_with(choosen,c[1]);
211 fill_with(choosen,c[1]);
212 }
212 }
213 // add all elements
213 // add all elements
214 if(this.id=='add_all_elements'){
214 if(this.id=='add_all_elements'){
215 for(var i=0; node = available.options[i];i++){
215 for(var i=0; node = available.options[i];i++){
216 choosen.appendChild(new Option(node.text,
216 choosen.appendChild(new Option(node.text,
217 node.value, false, false));
217 node.value, false, false));
218 }
218 }
219 available.options.length = 0;
219 available.options.length = 0;
220 }
220 }
221 //remove all elements
221 //remove all elements
222 if(this.id=='remove_all_elements'){
222 if(this.id=='remove_all_elements'){
223 for(var i=0; node = choosen.options[i];i++){
223 for(var i=0; node = choosen.options[i];i++){
224 available.appendChild(new Option(node.text,
224 available.appendChild(new Option(node.text,
225 node.value, false, false));
225 node.value, false, false));
226 }
226 }
227 choosen.options.length = 0;
227 choosen.options.length = 0;
228 }
228 }
229
229
230 }
230 }
231
231
232
232
233 E.addListener(['add_element','remove_element',
233 E.addListener(['add_element','remove_element',
234 'add_all_elements','remove_all_elements'],'click',
234 'add_all_elements','remove_all_elements'],'click',
235 prompts_action_callback)
235 prompts_action_callback)
236
236
237 E.addListener(form_id,'submit',function(){
237 E.addListener(form_id,'submit',function(){
238 var choosen = D.get(selected_container);
238 var choosen = D.get(selected_container);
239 for (var i = 0; i < choosen.options.length; i++) {
239 for (var i = 0; i < choosen.options.length; i++) {
240 choosen.options[i].selected = 'selected';
240 choosen.options[i].selected = 'selected';
241 }
241 }
242 })
242 })
243 });
243 });
244 </script>
244 </script>
245 <div class="box box-right">
245 <div class="box box-right">
246 <!-- box / title -->
246 <!-- box / title -->
247 <div class="title">
247 <div class="title">
248 <h5>${_('Permissions')}</h5>
248 <h5>${_('Permissions')}</h5>
249 </div>
249 </div>
250 ${h.form(url('user', id=''),method='put')}
250 ${h.form(url('xxx', id=''),method='put')}
251 <div class="form">
251 <div class="form">
252 <!-- fields -->
252 <!-- fields -->
253 <div class="fields">
253 <div class="fields">
254 <div class="field">
254 <div class="field">
255 <div class="label label-checkbox">
255 <div class="label label-checkbox">
256 <label for="">${_('Create repositories')}:</label>
256 <label for="">${_('Create repositories')}:</label>
257 </div>
257 </div>
258 <div class="checkboxes">
258 <div class="checkboxes">
259 ${h.checkbox('create',value=True)}
259 ${h.checkbox('create',value=True)}
260 </div>
260 </div>
261 </div>
261 </div>
262 <div class="buttons">
262 <div class="buttons">
263 ${h.submit('save','Save',class_="ui-button")}
263 ${h.submit('save','Save',class_="ui-button")}
264 ${h.reset('reset','Reset',class_="ui-button")}
264 ${h.reset('reset','Reset',class_="ui-button")}
265 </div>
265 </div>
266 </div>
266 </div>
267 </div>
267 </div>
268 ${h.end_form()}
268 ${h.end_form()}
269 </div>
269 </div>
270 </%def> No newline at end of file
270 </%def>
General Comments 0
You need to be logged in to leave comments. Login now