##// END OF EJS Templates
API updates...
marcink -
r2009:b63adad7 beta
parent child Browse files
Show More
@@ -1,626 +1,627
1 .. _api:
1 .. _api:
2
2
3
3
4 API
4 API
5 ===
5 ===
6
6
7
7
8 Starting from RhodeCode version 1.2 a simple API was implemented.
8 Starting from RhodeCode version 1.2 a simple API was implemented.
9 There's a single schema for calling all api methods. API is implemented
9 There's a single schema for calling all api methods. API is implemented
10 with JSON protocol both ways. An url to send API request in RhodeCode is
10 with JSON protocol both ways. An url to send API request in RhodeCode is
11 <your_server>/_admin/api
11 <your_server>/_admin/api
12
12
13 API ACCESS FOR WEB VIEWS
13 API ACCESS FOR WEB VIEWS
14 ++++++++++++++++++++++++
14 ++++++++++++++++++++++++
15
15
16 API access can also be turned on for each web view in RhodeCode that is
16 API access can also be turned on for each web view in RhodeCode that is
17 decorated with `@LoginRequired` decorator. To enable API access simple change
17 decorated with `@LoginRequired` decorator. To enable API access simple change
18 the standard login decorator to `@LoginRequired(api_access=True)`.
18 the standard login decorator to `@LoginRequired(api_access=True)`.
19 After this change, a rhodecode view can be accessed without login by adding a
19 After this change, a rhodecode view can be accessed without login by adding a
20 GET parameter `?api_key=<api_key>` to url. By default this is only
20 GET parameter `?api_key=<api_key>` to url. By default this is only
21 enabled on RSS/ATOM feed views.
21 enabled on RSS/ATOM feed views.
22
22
23
23
24 API ACCESS
24 API ACCESS
25 ++++++++++
25 ++++++++++
26
26
27 All clients are required to send JSON-RPC spec JSON data::
27 All clients are required to send JSON-RPC spec JSON data::
28
28
29 {
29 {
30 "id:<id>,
30 "id:<id>,
31 "api_key":"<api_key>",
31 "api_key":"<api_key>",
32 "method":"<method_name>",
32 "method":"<method_name>",
33 "args":{"<arg_key>":"<arg_val>"}
33 "args":{"<arg_key>":"<arg_val>"}
34 }
34 }
35
35
36 Example call for autopulling remotes repos using curl::
36 Example call for autopulling remotes repos using curl::
37 curl https://server.com/_admin/api -X POST -H 'content-type:text/plain' --data-binary '{"id":1,"api_key":"xe7cdb2v278e4evbdf5vs04v832v0efvcbcve4a3","method":"pull","args":{"repo":"CPython"}}'
37 curl https://server.com/_admin/api -X POST -H 'content-type:text/plain' --data-binary '{"id":1,"api_key":"xe7cdb2v278e4evbdf5vs04v832v0efvcbcve4a3","method":"pull","args":{"repo":"CPython"}}'
38
38
39 Simply provide
39 Simply provide
40 - *id* A value of any type, which is used to match the response with the request that it is replying to.
40 - *id* A value of any type, which is used to match the response with the request that it is replying to.
41 - *api_key* for access and permission validation.
41 - *api_key* for access and permission validation.
42 - *method* is name of method to call
42 - *method* is name of method to call
43 - *args* is an key:value list of arguments to pass to method
43 - *args* is an key:value list of arguments to pass to method
44
44
45 .. note::
45 .. note::
46
46
47 api_key can be found in your user account page
47 api_key can be found in your user account page
48
48
49
49
50 RhodeCode API will return always a JSON-RPC response::
50 RhodeCode API will return always a JSON-RPC response::
51
51
52 {
52 {
53 "id":<id>,
53 "id":<id>,
54 "result": "<result>",
54 "result": "<result>",
55 "error": null
55 "error": null
56 }
56 }
57
57
58 All responses from API will be `HTTP/1.0 200 OK`, if there's an error while
58 All responses from API will be `HTTP/1.0 200 OK`, if there's an error while
59 calling api *error* key from response will contain failure description
59 calling api *error* key from response will contain failure description
60 and result will be null.
60 and result will be null.
61
61
62 API METHODS
62 API METHODS
63 +++++++++++
63 +++++++++++
64
64
65
65
66 pull
66 pull
67 ----
67 ----
68
68
69 Pulls given repo from remote location. Can be used to automatically keep
69 Pulls given repo from remote location. Can be used to automatically keep
70 remote repos up to date. This command can be executed only using api_key
70 remote repos up to date. This command can be executed only using api_key
71 belonging to user with admin rights
71 belonging to user with admin rights
72
72
73 INPUT::
73 INPUT::
74
74
75 api_key : "<api_key>"
75 api_key : "<api_key>"
76 method : "pull"
76 method : "pull"
77 args : {
77 args : {
78 "repo_name" : "<reponame>"
78 "repo_name" : "<reponame>"
79 }
79 }
80
80
81 OUTPUT::
81 OUTPUT::
82
82
83 result : "Pulled from <reponame>"
83 result : "Pulled from <reponame>"
84 error : null
84 error : null
85
85
86
86
87 get_user
87 get_user
88 --------
88 --------
89
89
90 Get's an user by username, Returns empty result if user is not found.
90 Get's an user by username, Returns empty result if user is not found.
91 This command can be executed only using api_key belonging to user with admin
91 This command can be executed only using api_key belonging to user with admin
92 rights.
92 rights.
93
93
94
94
95 INPUT::
95 INPUT::
96
96
97 api_key : "<api_key>"
97 api_key : "<api_key>"
98 method : "get_user"
98 method : "get_user"
99 args : {
99 args : {
100 "username" : "<username>"
100 "username" : "<username>"
101 }
101 }
102
102
103 OUTPUT::
103 OUTPUT::
104
104
105 result: None if user does not exist or
105 result: None if user does not exist or
106 {
106 {
107 "id" : "<id>",
107 "id" : "<id>",
108 "username" : "<username>",
108 "username" : "<username>",
109 "firstname": "<firstname>",
109 "firstname": "<firstname>",
110 "lastname" : "<lastname>",
110 "lastname" : "<lastname>",
111 "email" : "<email>",
111 "email" : "<email>",
112 "active" : "<bool>",
112 "active" : "<bool>",
113 "admin" :Β  "<bool>",
113 "admin" :Β  "<bool>",
114 "ldap" : "<ldap_dn>"
114 "ldap_dn" : "<ldap_dn>"
115 }
115 }
116
116
117 error: null
117 error: null
118
118
119
119
120 get_users
120 get_users
121 ---------
121 ---------
122
122
123 Lists all existing users. This command can be executed only using api_key
123 Lists all existing users. This command can be executed only using api_key
124 belonging to user with admin rights.
124 belonging to user with admin rights.
125
125
126
126
127 INPUT::
127 INPUT::
128
128
129 api_key : "<api_key>"
129 api_key : "<api_key>"
130 method : "get_users"
130 method : "get_users"
131 args : { }
131 args : { }
132
132
133 OUTPUT::
133 OUTPUT::
134
134
135 result: [
135 result: [
136 {
136 {
137 "id" : "<id>",
137 "id" : "<id>",
138 "username" : "<username>",
138 "username" : "<username>",
139 "firstname": "<firstname>",
139 "firstname": "<firstname>",
140 "lastname" : "<lastname>",
140 "lastname" : "<lastname>",
141 "email" : "<email>",
141 "email" : "<email>",
142 "active" : "<bool>",
142 "active" : "<bool>",
143 "admin" :Β  "<bool>",
143 "admin" :Β  "<bool>",
144 "ldap" : "<ldap_dn>"
144 "ldap_dn" : "<ldap_dn>"
145 },
145 },
146 …
146 …
147 ]
147 ]
148 error: null
148 error: null
149
149
150
150
151 create_user
151 create_user
152 -----------
152 -----------
153
153
154 Creates new user. This command can
154 Creates new user. This command can
155 be executed only using api_key belonging to user with admin rights.
155 be executed only using api_key belonging to user with admin rights.
156
156
157
157
158 INPUT::
158 INPUT::
159
159
160 api_key : "<api_key>"
160 api_key : "<api_key>"
161 method : "create_user"
161 method : "create_user"
162 args : {
162 args : {
163 "username" : "<username>",
163 "username" : "<username>",
164 "password" : "<password>",
164 "password" : "<password>",
165 "email" : "<useremail>",
165 "email" : "<useremail>",
166 "firstname" : "<firstname> = None",
166 "firstname" : "<firstname> = None",
167 "lastname" : "<lastname> = None",
167 "lastname" : "<lastname> = None",
168 "active" : "<bool> = True",
168 "active" : "<bool> = True",
169 "admin" : "<bool> = False",
169 "admin" : "<bool> = False",
170 "ldap_dn" : "<ldap_dn> = None"
170 "ldap_dn" : "<ldap_dn> = None"
171 }
171 }
172
172
173 OUTPUT::
173 OUTPUT::
174
174
175 result: {
175 result: {
176 "id" : "<new_user_id>",
176 "id" : "<new_user_id>",
177 "msg" : "created new user <username>"
177 "msg" : "created new user <username>"
178 }
178 }
179 error: null
179 error: null
180
180
181
181
182 update_user
182 update_user
183 -----------
183 -----------
184
184
185 updates current one if such user exists. This command can
185 updates current one if such user exists. This command can
186 be executed only using api_key belonging to user with admin rights.
186 be executed only using api_key belonging to user with admin rights.
187
187
188
188
189 INPUT::
189 INPUT::
190
190
191 api_key : "<api_key>"
191 api_key : "<api_key>"
192 method : "update_user"
192 method : "update_user"
193 args : {
193 args : {
194 "userid" : "<user_id or username>",
194 "username" : "<username>",
195 "username" : "<username>",
195 "password" : "<password>",
196 "password" : "<password>",
196 "email" : "<useremail>",
197 "email" : "<useremail>",
197 "firstname" : "<firstname> = None",
198 "firstname" : "<firstname>",
198 "lastname" : "<lastname> = None",
199 "lastname" : "<lastname>",
199 "active" : "<bool> = True",
200 "active" : "<bool>",
200 "admin" : "<bool> = False",
201 "admin" : "<bool>",
201 "ldap_dn" : "<ldap_dn> = None"
202 "ldap_dn" : "<ldap_dn>"
202 }
203 }
203
204
204 OUTPUT::
205 OUTPUT::
205
206
206 result: {
207 result: {
207 "id" : "<edited_user_id>",
208 "id" : "<edited_user_id>",
208 "msg" : "updated user <username>"
209 "msg" : "updated user <username>"
209 }
210 }
210 error: null
211 error: null
211
212
212
213
213 get_users_group
214 get_users_group
214 ---------------
215 ---------------
215
216
216 Gets an existing users group. This command can be executed only using api_key
217 Gets an existing users group. This command can be executed only using api_key
217 belonging to user with admin rights.
218 belonging to user with admin rights.
218
219
219
220
220 INPUT::
221 INPUT::
221
222
222 api_key : "<api_key>"
223 api_key : "<api_key>"
223 method : "get_users_group"
224 method : "get_users_group"
224 args : {
225 args : {
225 "group_name" : "<name>"
226 "group_name" : "<name>"
226 }
227 }
227
228
228 OUTPUT::
229 OUTPUT::
229
230
230 result : None if group not exist
231 result : None if group not exist
231 {
232 {
232 "id" : "<id>",
233 "id" : "<id>",
233 "group_name" : "<groupname>",
234 "group_name" : "<groupname>",
234 "active": "<bool>",
235 "active": "<bool>",
235 "members" : [
236 "members" : [
236 { "id" : "<userid>",
237 { "id" : "<userid>",
237 "username" : "<username>",
238 "username" : "<username>",
238 "firstname": "<firstname>",
239 "firstname": "<firstname>",
239 "lastname" : "<lastname>",
240 "lastname" : "<lastname>",
240 "email" : "<email>",
241 "email" : "<email>",
241 "active" : "<bool>",
242 "active" : "<bool>",
242 "admin" :Β  "<bool>",
243 "admin" :Β  "<bool>",
243 "ldap" : "<ldap_dn>"
244 "ldap" : "<ldap_dn>"
244 },
245 },
245 …
246 …
246 ]
247 ]
247 }
248 }
248 error : null
249 error : null
249
250
250
251
251 get_users_groups
252 get_users_groups
252 ----------------
253 ----------------
253
254
254 Lists all existing users groups. This command can be executed only using
255 Lists all existing users groups. This command can be executed only using
255 api_key belonging to user with admin rights.
256 api_key belonging to user with admin rights.
256
257
257
258
258 INPUT::
259 INPUT::
259
260
260 api_key : "<api_key>"
261 api_key : "<api_key>"
261 method : "get_users_groups"
262 method : "get_users_groups"
262 args : { }
263 args : { }
263
264
264 OUTPUT::
265 OUTPUT::
265
266
266 result : [
267 result : [
267 {
268 {
268 "id" : "<id>",
269 "id" : "<id>",
269 "group_name" : "<groupname>",
270 "group_name" : "<groupname>",
270 "active": "<bool>",
271 "active": "<bool>",
271 "members" : [
272 "members" : [
272 {
273 {
273 "id" : "<userid>",
274 "id" : "<userid>",
274 "username" : "<username>",
275 "username" : "<username>",
275 "firstname": "<firstname>",
276 "firstname": "<firstname>",
276 "lastname" : "<lastname>",
277 "lastname" : "<lastname>",
277 "email" : "<email>",
278 "email" : "<email>",
278 "active" : "<bool>",
279 "active" : "<bool>",
279 "admin" :Β  "<bool>",
280 "admin" :Β  "<bool>",
280 "ldap" : "<ldap_dn>"
281 "ldap" : "<ldap_dn>"
281 },
282 },
282 …
283 …
283 ]
284 ]
284 }
285 }
285 ]
286 ]
286 error : null
287 error : null
287
288
288
289
289 create_users_group
290 create_users_group
290 ------------------
291 ------------------
291
292
292 Creates new users group. This command can be executed only using api_key
293 Creates new users group. This command can be executed only using api_key
293 belonging to user with admin rights
294 belonging to user with admin rights
294
295
295
296
296 INPUT::
297 INPUT::
297
298
298 api_key : "<api_key>"
299 api_key : "<api_key>"
299 method : "create_users_group"
300 method : "create_users_group"
300 args: {
301 args: {
301 "group_name": "<groupname>",
302 "group_name": "<groupname>",
302 "active":"<bool> = True"
303 "active":"<bool> = True"
303 }
304 }
304
305
305 OUTPUT::
306 OUTPUT::
306
307
307 result: {
308 result: {
308 "id": "<newusersgroupid>",
309 "id": "<newusersgroupid>",
309 "msg": "created new users group <groupname>"
310 "msg": "created new users group <groupname>"
310 }
311 }
311 error: null
312 error: null
312
313
313
314
314 add_user_to_users_group
315 add_user_to_users_group
315 -----------------------
316 -----------------------
316
317
317 Adds a user to a users group. If user exists in that group success will be
318 Adds a user to a users group. If user exists in that group success will be
318 `false`. This command can be executed only using api_key
319 `false`. This command can be executed only using api_key
319 belonging to user with admin rights
320 belonging to user with admin rights
320
321
321
322
322 INPUT::
323 INPUT::
323
324
324 api_key : "<api_key>"
325 api_key : "<api_key>"
325 method : "add_user_users_group"
326 method : "add_user_users_group"
326 args: {
327 args: {
327 "group_name" : "<groupname>",
328 "group_name" : "<groupname>",
328 "username" : "<username>"
329 "username" : "<username>"
329 }
330 }
330
331
331 OUTPUT::
332 OUTPUT::
332
333
333 result: {
334 result: {
334 "id": "<newusersgroupmemberid>",
335 "id": "<newusersgroupmemberid>",
335 "success": True|False # depends on if member is in group
336 "success": True|False # depends on if member is in group
336 "msg": "added member <username> to users group <groupname> |
337 "msg": "added member <username> to users group <groupname> |
337 User is already in that group"
338 User is already in that group"
338 }
339 }
339 error: null
340 error: null
340
341
341
342
342 remove_user_from_users_group
343 remove_user_from_users_group
343 ----------------------------
344 ----------------------------
344
345
345 Removes a user from a users group. If user is not in given group success will
346 Removes a user from a users group. If user is not in given group success will
346 be `false`. This command can be executed only
347 be `false`. This command can be executed only
347 using api_key belonging to user with admin rights
348 using api_key belonging to user with admin rights
348
349
349
350
350 INPUT::
351 INPUT::
351
352
352 api_key : "<api_key>"
353 api_key : "<api_key>"
353 method : "remove_user_from_users_group"
354 method : "remove_user_from_users_group"
354 args: {
355 args: {
355 "group_name" : "<groupname>",
356 "group_name" : "<groupname>",
356 "username" : "<username>"
357 "username" : "<username>"
357 }
358 }
358
359
359 OUTPUT::
360 OUTPUT::
360
361
361 result: {
362 result: {
362 "success": True|False, # depends on if member is in group
363 "success": True|False, # depends on if member is in group
363 "msg": "removed member <username> from users group <groupname> |
364 "msg": "removed member <username> from users group <groupname> |
364 User wasn't in group"
365 User wasn't in group"
365 }
366 }
366 error: null
367 error: null
367
368
368
369
369 get_repo
370 get_repo
370 --------
371 --------
371
372
372 Gets an existing repository. This command can be executed only using api_key
373 Gets an existing repository. This command can be executed only using api_key
373 belonging to user with admin rights
374 belonging to user with admin rights
374
375
375
376
376 INPUT::
377 INPUT::
377
378
378 api_key : "<api_key>"
379 api_key : "<api_key>"
379 method : "get_repo"
380 method : "get_repo"
380 args: {
381 args: {
381 "repo_name" : "<reponame>"
382 "repo_name" : "<reponame>"
382 }
383 }
383
384
384 OUTPUT::
385 OUTPUT::
385
386
386 result: None if repository does not exist or
387 result: None if repository does not exist or
387 {
388 {
388 "id" : "<id>",
389 "id" : "<id>",
389 "repo_name" : "<reponame>"
390 "repo_name" : "<reponame>"
390 "type" : "<type>",
391 "type" : "<type>",
391 "description" : "<description>",
392 "description" : "<description>",
392 "members" : [
393 "members" : [
393 { "id" : "<userid>",
394 { "id" : "<userid>",
394 "username" : "<username>",
395 "username" : "<username>",
395 "firstname": "<firstname>",
396 "firstname": "<firstname>",
396 "lastname" : "<lastname>",
397 "lastname" : "<lastname>",
397 "email" : "<email>",
398 "email" : "<email>",
398 "active" : "<bool>",
399 "active" : "<bool>",
399 "admin" :Β  "<bool>",
400 "admin" :Β  "<bool>",
400 "ldap" : "<ldap_dn>",
401 "ldap" : "<ldap_dn>",
401 "permission" : "repository.(read|write|admin)"
402 "permission" : "repository.(read|write|admin)"
402 },
403 },
403 …
404 …
404 {
405 {
405 "id" : "<usersgroupid>",
406 "id" : "<usersgroupid>",
406 "name" : "<usersgroupname>",
407 "name" : "<usersgroupname>",
407 "active": "<bool>",
408 "active": "<bool>",
408 "permission" : "repository.(read|write|admin)"
409 "permission" : "repository.(read|write|admin)"
409 },
410 },
410 …
411 …
411 ]
412 ]
412 }
413 }
413 error: null
414 error: null
414
415
415
416
416 get_repos
417 get_repos
417 ---------
418 ---------
418
419
419 Lists all existing repositories. This command can be executed only using api_key
420 Lists all existing repositories. This command can be executed only using api_key
420 belonging to user with admin rights
421 belonging to user with admin rights
421
422
422
423
423 INPUT::
424 INPUT::
424
425
425 api_key : "<api_key>"
426 api_key : "<api_key>"
426 method : "get_repos"
427 method : "get_repos"
427 args: { }
428 args: { }
428
429
429 OUTPUT::
430 OUTPUT::
430
431
431 result: [
432 result: [
432 {
433 {
433 "id" : "<id>",
434 "id" : "<id>",
434 "repo_name" : "<reponame>"
435 "repo_name" : "<reponame>"
435 "type" : "<type>",
436 "type" : "<type>",
436 "description" : "<description>"
437 "description" : "<description>"
437 },
438 },
438 …
439 …
439 ]
440 ]
440 error: null
441 error: null
441
442
442
443
443 get_repo_nodes
444 get_repo_nodes
444 --------------
445 --------------
445
446
446 returns a list of nodes and it's children in a flat list for a given path
447 returns a list of nodes and it's children in a flat list for a given path
447 at given revision. It's possible to specify ret_type to show only `files` or
448 at given revision. It's possible to specify ret_type to show only `files` or
448 `dirs`. This command can be executed only using api_key belonging to user
449 `dirs`. This command can be executed only using api_key belonging to user
449 with admin rights
450 with admin rights
450
451
451
452
452 INPUT::
453 INPUT::
453
454
454 api_key : "<api_key>"
455 api_key : "<api_key>"
455 method : "get_repo_nodes"
456 method : "get_repo_nodes"
456 args: {
457 args: {
457 "repo_name" : "<reponame>",
458 "repo_name" : "<reponame>",
458 "revision" : "<revision>",
459 "revision" : "<revision>",
459 "root_path" : "<root_path>",
460 "root_path" : "<root_path>",
460 "ret_type" : "<ret_type>" = 'all'
461 "ret_type" : "<ret_type>" = 'all'
461 }
462 }
462
463
463 OUTPUT::
464 OUTPUT::
464
465
465 result: [
466 result: [
466 {
467 {
467 "name" : "<name>"
468 "name" : "<name>"
468 "type" : "<type>",
469 "type" : "<type>",
469 },
470 },
470 …
471 …
471 ]
472 ]
472 error: null
473 error: null
473
474
474
475
475 create_repo
476 create_repo
476 -----------
477 -----------
477
478
478 Creates a repository. This command can be executed only using api_key
479 Creates a repository. This command can be executed only using api_key
479 belonging to user with admin rights.
480 belonging to user with admin rights.
480 If repository name contains "/", all needed repository groups will be created.
481 If repository name contains "/", all needed repository groups will be created.
481 For example "foo/bar/baz" will create groups "foo", "bar" (with "foo" as parent),
482 For example "foo/bar/baz" will create groups "foo", "bar" (with "foo" as parent),
482 and create "baz" repository with "bar" as group.
483 and create "baz" repository with "bar" as group.
483
484
484
485
485 INPUT::
486 INPUT::
486
487
487 api_key : "<api_key>"
488 api_key : "<api_key>"
488 method : "create_repo"
489 method : "create_repo"
489 args: {
490 args: {
490 "repo_name" : "<reponame>",
491 "repo_name" : "<reponame>",
491 "owner_name" : "<ownername>",
492 "owner_name" : "<ownername>",
492 "description" : "<description> = ''",
493 "description" : "<description> = ''",
493 "repo_type" : "<type> = 'hg'",
494 "repo_type" : "<type> = 'hg'",
494 "private" : "<bool> = False",
495 "private" : "<bool> = False",
495 "clone_uri" : "<clone_uri> = None",
496 "clone_uri" : "<clone_uri> = None",
496 }
497 }
497
498
498 OUTPUT::
499 OUTPUT::
499
500
500 result: {
501 result: {
501 "id": "<newrepoid>",
502 "id": "<newrepoid>",
502 "msg": "Created new repository <reponame>",
503 "msg": "Created new repository <reponame>",
503 }
504 }
504 error: null
505 error: null
505
506
506
507
507 delete_repo
508 delete_repo
508 -----------
509 -----------
509
510
510 Deletes a repository. This command can be executed only using api_key
511 Deletes a repository. This command can be executed only using api_key
511 belonging to user with admin rights.
512 belonging to user with admin rights.
512
513
513
514
514 INPUT::
515 INPUT::
515
516
516 api_key : "<api_key>"
517 api_key : "<api_key>"
517 method : "delete_repo"
518 method : "delete_repo"
518 args: {
519 args: {
519 "repo_name" : "<reponame>",
520 "repo_name" : "<reponame>",
520 }
521 }
521
522
522 OUTPUT::
523 OUTPUT::
523
524
524 result: {
525 result: {
525 "msg": "Deleted repository <reponame>",
526 "msg": "Deleted repository <reponame>",
526 }
527 }
527 error: null
528 error: null
528
529
529
530
530 grant_user_permission
531 grant_user_permission
531 ---------------------
532 ---------------------
532
533
533 Grant permission for user on given repository, or update existing one
534 Grant permission for user on given repository, or update existing one
534 if found. This command can be executed only using api_key belonging to user
535 if found. This command can be executed only using api_key belonging to user
535 with admin rights.
536 with admin rights.
536
537
537
538
538 INPUT::
539 INPUT::
539
540
540 api_key : "<api_key>"
541 api_key : "<api_key>"
541 method : "grant_user_permission"
542 method : "grant_user_permission"
542 args: {
543 args: {
543 "repo_name" : "<reponame>",
544 "repo_name" : "<reponame>",
544 "username" : "<username>",
545 "username" : "<username>",
545 "perm" : "(repository.(none|read|write|admin))",
546 "perm" : "(repository.(none|read|write|admin))",
546 }
547 }
547
548
548 OUTPUT::
549 OUTPUT::
549
550
550 result: {
551 result: {
551 "msg" : "Granted perm: <perm> for user: <username> in repo: <reponame>"
552 "msg" : "Granted perm: <perm> for user: <username> in repo: <reponame>"
552 }
553 }
553 error: null
554 error: null
554
555
555
556
556 revoke_user_permission
557 revoke_user_permission
557 ----------------------
558 ----------------------
558
559
559 Revoke permission for user on given repository. This command can be executed
560 Revoke permission for user on given repository. This command can be executed
560 only using api_key belonging to user with admin rights.
561 only using api_key belonging to user with admin rights.
561
562
562
563
563 INPUT::
564 INPUT::
564
565
565 api_key : "<api_key>"
566 api_key : "<api_key>"
566 method : "revoke_user_permission"
567 method : "revoke_user_permission"
567 args: {
568 args: {
568 "repo_name" : "<reponame>",
569 "repo_name" : "<reponame>",
569 "username" : "<username>",
570 "username" : "<username>",
570 }
571 }
571
572
572 OUTPUT::
573 OUTPUT::
573
574
574 result: {
575 result: {
575 "msg" : "Revoked perm for user: <suername> in repo: <reponame>"
576 "msg" : "Revoked perm for user: <suername> in repo: <reponame>"
576 }
577 }
577 error: null
578 error: null
578
579
579
580
580 grant_users_group_permission
581 grant_users_group_permission
581 ----------------------------
582 ----------------------------
582
583
583 Grant permission for users group on given repository, or update
584 Grant permission for users group on given repository, or update
584 existing one if found. This command can be executed only using
585 existing one if found. This command can be executed only using
585 api_key belonging to user with admin rights.
586 api_key belonging to user with admin rights.
586
587
587
588
588 INPUT::
589 INPUT::
589
590
590 api_key : "<api_key>"
591 api_key : "<api_key>"
591 method : "grant_users_group_permission"
592 method : "grant_users_group_permission"
592 args: {
593 args: {
593 "repo_name" : "<reponame>",
594 "repo_name" : "<reponame>",
594 "group_name" : "<usersgroupname>",
595 "group_name" : "<usersgroupname>",
595 "perm" : "(repository.(none|read|write|admin))",
596 "perm" : "(repository.(none|read|write|admin))",
596 }
597 }
597
598
598 OUTPUT::
599 OUTPUT::
599
600
600 result: {
601 result: {
601 "msg" : "Granted perm: <perm> for group: <usersgroupname> in repo: <reponame>"
602 "msg" : "Granted perm: <perm> for group: <usersgroupname> in repo: <reponame>"
602 }
603 }
603 error: null
604 error: null
604
605
605
606
606 revoke_users_group_permission
607 revoke_users_group_permission
607 -----------------------------
608 -----------------------------
608
609
609 Revoke permission for users group on given repository.This command can be
610 Revoke permission for users group on given repository.This command can be
610 executed only using api_key belonging to user with admin rights.
611 executed only using api_key belonging to user with admin rights.
611
612
612 INPUT::
613 INPUT::
613
614
614 api_key : "<api_key>"
615 api_key : "<api_key>"
615 method : "revoke_users_group_permission"
616 method : "revoke_users_group_permission"
616 args: {
617 args: {
617 "repo_name" : "<reponame>",
618 "repo_name" : "<reponame>",
618 "users_group" : "<usersgroupname>",
619 "users_group" : "<usersgroupname>",
619 }
620 }
620
621
621 OUTPUT::
622 OUTPUT::
622
623
623 result: {
624 result: {
624 "msg" : "Revoked perm for group: <usersgroupname> in repo: <reponame>"
625 "msg" : "Revoked perm for group: <usersgroupname> in repo: <reponame>"
625 }
626 }
626 error: null No newline at end of file
627 error: null
@@ -1,660 +1,660
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.api
3 rhodecode.controllers.api
4 ~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 API controller for RhodeCode
6 API controller for RhodeCode
7
7
8 :created_on: Aug 20, 2011
8 :created_on: Aug 20, 2011
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2011-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2011-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software; you can redistribute it and/or
13 # This program is free software; you can redistribute it and/or
14 # modify it under the terms of the GNU General Public License
14 # modify it under the terms of the GNU General Public License
15 # as published by the Free Software Foundation; version 2
15 # as published by the Free Software Foundation; version 2
16 # of the License or (at your opinion) any later version of the license.
16 # of the License or (at your opinion) any later version of the license.
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, write to the Free Software
24 # along with this program; if not, write to the Free Software
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 # MA 02110-1301, USA.
26 # MA 02110-1301, USA.
27
27
28 import traceback
28 import traceback
29 import logging
29 import logging
30
30
31 from rhodecode.controllers.api import JSONRPCController, JSONRPCError
31 from rhodecode.controllers.api import JSONRPCController, JSONRPCError
32 from rhodecode.lib.auth import HasPermissionAllDecorator, \
32 from rhodecode.lib.auth import HasPermissionAllDecorator, \
33 HasPermissionAnyDecorator, PasswordGenerator
33 HasPermissionAnyDecorator, PasswordGenerator
34
34
35 from rhodecode.model.meta import Session
35 from rhodecode.model.meta import Session
36 from rhodecode.model.scm import ScmModel
36 from rhodecode.model.scm import ScmModel
37 from rhodecode.model.db import User, UsersGroup, RepoGroup, Repository
37 from rhodecode.model.db import User, UsersGroup, RepoGroup, Repository
38 from rhodecode.model.repo import RepoModel
38 from rhodecode.model.repo import RepoModel
39 from rhodecode.model.user import UserModel
39 from rhodecode.model.user import UserModel
40 from rhodecode.model.users_group import UsersGroupModel
40 from rhodecode.model.users_group import UsersGroupModel
41 from rhodecode.model.repos_group import ReposGroupModel
41 from rhodecode.model.repos_group import ReposGroupModel
42
42
43
43
44 log = logging.getLogger(__name__)
44 log = logging.getLogger(__name__)
45
45
46
46
47 class ApiController(JSONRPCController):
47 class ApiController(JSONRPCController):
48 """
48 """
49 API Controller
49 API Controller
50
50
51
51
52 Each method needs to have USER as argument this is then based on given
52 Each method needs to have USER as argument this is then based on given
53 API_KEY propagated as instance of user object
53 API_KEY propagated as instance of user object
54
54
55 Preferably this should be first argument also
55 Preferably this should be first argument also
56
56
57
57
58 Each function should also **raise** JSONRPCError for any
58 Each function should also **raise** JSONRPCError for any
59 errors that happens
59 errors that happens
60
60
61 """
61 """
62
62
63 @HasPermissionAllDecorator('hg.admin')
63 @HasPermissionAllDecorator('hg.admin')
64 def pull(self, apiuser, repo_name):
64 def pull(self, apiuser, repo_name):
65 """
65 """
66 Dispatch pull action on given repo
66 Dispatch pull action on given repo
67
67
68
68
69 :param user:
69 :param user:
70 :param repo_name:
70 :param repo_name:
71 """
71 """
72
72
73 if Repository.is_valid(repo_name) is False:
73 if Repository.is_valid(repo_name) is False:
74 raise JSONRPCError('Unknown repo "%s"' % repo_name)
74 raise JSONRPCError('Unknown repo "%s"' % repo_name)
75
75
76 try:
76 try:
77 ScmModel().pull_changes(repo_name, self.rhodecode_user.username)
77 ScmModel().pull_changes(repo_name, self.rhodecode_user.username)
78 return 'Pulled from %s' % repo_name
78 return 'Pulled from %s' % repo_name
79 except Exception:
79 except Exception:
80 raise JSONRPCError('Unable to pull changes from "%s"' % repo_name)
80 raise JSONRPCError('Unable to pull changes from "%s"' % repo_name)
81
81
82 @HasPermissionAllDecorator('hg.admin')
82 @HasPermissionAllDecorator('hg.admin')
83 def get_user(self, apiuser, username):
83 def get_user(self, apiuser, username):
84 """"
84 """"
85 Get a user by username
85 Get a user by username
86
86
87 :param apiuser:
87 :param apiuser:
88 :param username:
88 :param username:
89 """
89 """
90
90
91 user = User.get_by_username(username)
91 user = User.get_by_username(username)
92 if user is None:
92 if user is None:
93 return user
93 return user
94
94
95 return dict(
95 return dict(
96 id=user.user_id,
96 id=user.user_id,
97 username=user.username,
97 username=user.username,
98 firstname=user.name,
98 firstname=user.name,
99 lastname=user.lastname,
99 lastname=user.lastname,
100 email=user.email,
100 email=user.email,
101 active=user.active,
101 active=user.active,
102 admin=user.admin,
102 admin=user.admin,
103 ldap=user.ldap_dn
103 ldap_dn=user.ldap_dn
104 )
104 )
105
105
106 @HasPermissionAllDecorator('hg.admin')
106 @HasPermissionAllDecorator('hg.admin')
107 def get_users(self, apiuser):
107 def get_users(self, apiuser):
108 """"
108 """"
109 Get all users
109 Get all users
110
110
111 :param apiuser:
111 :param apiuser:
112 """
112 """
113
113
114 result = []
114 result = []
115 for user in User.getAll():
115 for user in User.getAll():
116 result.append(
116 result.append(
117 dict(
117 dict(
118 id=user.user_id,
118 id=user.user_id,
119 username=user.username,
119 username=user.username,
120 firstname=user.name,
120 firstname=user.name,
121 lastname=user.lastname,
121 lastname=user.lastname,
122 email=user.email,
122 email=user.email,
123 active=user.active,
123 active=user.active,
124 admin=user.admin,
124 admin=user.admin,
125 ldap=user.ldap_dn
125 ldap_dn=user.ldap_dn
126 )
126 )
127 )
127 )
128 return result
128 return result
129
129
130 @HasPermissionAllDecorator('hg.admin')
130 @HasPermissionAllDecorator('hg.admin')
131 def create_user(self, apiuser, username, email, password, firstname=None,
131 def create_user(self, apiuser, username, email, password, firstname=None,
132 lastname=None, active=True, admin=False, ldap_dn=None):
132 lastname=None, active=True, admin=False, ldap_dn=None):
133 """
133 """
134 Create new user
134 Create new user
135
135
136 :param apiuser:
136 :param apiuser:
137 :param username:
137 :param username:
138 :param password:
138 :param password:
139 :param email:
139 :param email:
140 :param name:
140 :param name:
141 :param lastname:
141 :param lastname:
142 :param active:
142 :param active:
143 :param admin:
143 :param admin:
144 :param ldap_dn:
144 :param ldap_dn:
145 """
145 """
146 if User.get_by_username(username):
146 if User.get_by_username(username):
147 raise JSONRPCError("user %s already exist" % username)
147 raise JSONRPCError("user %s already exist" % username)
148
148
149 if User.get_by_email(email, case_insensitive=True):
149 if User.get_by_email(email, case_insensitive=True):
150 raise JSONRPCError("email %s already exist" % email)
150 raise JSONRPCError("email %s already exist" % email)
151
151
152 if ldap_dn:
152 if ldap_dn:
153 # generate temporary password if ldap_dn
153 # generate temporary password if ldap_dn
154 password = PasswordGenerator().gen_password(length=8)
154 password = PasswordGenerator().gen_password(length=8)
155
155
156 try:
156 try:
157 usr = UserModel().create_or_update(
157 usr = UserModel().create_or_update(
158 username, password, email, firstname,
158 username, password, email, firstname,
159 lastname, active, admin, ldap_dn
159 lastname, active, admin, ldap_dn
160 )
160 )
161 Session.commit()
161 Session.commit()
162 return dict(
162 return dict(
163 id=usr.user_id,
163 id=usr.user_id,
164 msg='created new user %s' % username
164 msg='created new user %s' % username
165 )
165 )
166 except Exception:
166 except Exception:
167 log.error(traceback.format_exc())
167 log.error(traceback.format_exc())
168 raise JSONRPCError('failed to create user %s' % username)
168 raise JSONRPCError('failed to create user %s' % username)
169
169
170 @HasPermissionAllDecorator('hg.admin')
170 @HasPermissionAllDecorator('hg.admin')
171 def update_user(self, apiuser, username, password, email, firstname=None,
171 def update_user(self, apiuser, userid, username, password, email,
172 lastname=None, active=True, admin=False, ldap_dn=None):
172 firstname, lastname, active, admin, ldap_dn):
173 """
173 """
174 Updates given user
174 Updates given user
175
175
176 :param apiuser:
176 :param apiuser:
177 :param username:
177 :param username:
178 :param password:
178 :param password:
179 :param email:
179 :param email:
180 :param name:
180 :param name:
181 :param lastname:
181 :param lastname:
182 :param active:
182 :param active:
183 :param admin:
183 :param admin:
184 :param ldap_dn:
184 :param ldap_dn:
185 """
185 """
186 if not User.get_by_username(username):
186 if not UserModel().get_user(userid):
187 raise JSONRPCError("user %s does not exist" % username)
187 raise JSONRPCError("user %s does not exist" % username)
188
188
189 try:
189 try:
190 usr = UserModel().create_or_update(
190 usr = UserModel().create_or_update(
191 username, password, email, firstname,
191 username, password, email, firstname,
192 lastname, active, admin, ldap_dn
192 lastname, active, admin, ldap_dn
193 )
193 )
194 Session.commit()
194 Session.commit()
195 return dict(
195 return dict(
196 id=usr.user_id,
196 id=usr.user_id,
197 msg='updated user %s' % username
197 msg='updated user %s' % username
198 )
198 )
199 except Exception:
199 except Exception:
200 log.error(traceback.format_exc())
200 log.error(traceback.format_exc())
201 raise JSONRPCError('failed to update user %s' % username)
201 raise JSONRPCError('failed to update user %s' % username)
202
202
203 @HasPermissionAllDecorator('hg.admin')
203 @HasPermissionAllDecorator('hg.admin')
204 def get_users_group(self, apiuser, group_name):
204 def get_users_group(self, apiuser, group_name):
205 """"
205 """"
206 Get users group by name
206 Get users group by name
207
207
208 :param apiuser:
208 :param apiuser:
209 :param group_name:
209 :param group_name:
210 """
210 """
211
211
212 users_group = UsersGroup.get_by_group_name(group_name)
212 users_group = UsersGroup.get_by_group_name(group_name)
213 if not users_group:
213 if not users_group:
214 return None
214 return None
215
215
216 members = []
216 members = []
217 for user in users_group.members:
217 for user in users_group.members:
218 user = user.user
218 user = user.user
219 members.append(dict(id=user.user_id,
219 members.append(dict(id=user.user_id,
220 username=user.username,
220 username=user.username,
221 firstname=user.name,
221 firstname=user.name,
222 lastname=user.lastname,
222 lastname=user.lastname,
223 email=user.email,
223 email=user.email,
224 active=user.active,
224 active=user.active,
225 admin=user.admin,
225 admin=user.admin,
226 ldap=user.ldap_dn))
226 ldap=user.ldap_dn))
227
227
228 return dict(id=users_group.users_group_id,
228 return dict(id=users_group.users_group_id,
229 group_name=users_group.users_group_name,
229 group_name=users_group.users_group_name,
230 active=users_group.users_group_active,
230 active=users_group.users_group_active,
231 members=members)
231 members=members)
232
232
233 @HasPermissionAllDecorator('hg.admin')
233 @HasPermissionAllDecorator('hg.admin')
234 def get_users_groups(self, apiuser):
234 def get_users_groups(self, apiuser):
235 """"
235 """"
236 Get all users groups
236 Get all users groups
237
237
238 :param apiuser:
238 :param apiuser:
239 """
239 """
240
240
241 result = []
241 result = []
242 for users_group in UsersGroup.getAll():
242 for users_group in UsersGroup.getAll():
243 members = []
243 members = []
244 for user in users_group.members:
244 for user in users_group.members:
245 user = user.user
245 user = user.user
246 members.append(dict(id=user.user_id,
246 members.append(dict(id=user.user_id,
247 username=user.username,
247 username=user.username,
248 firstname=user.name,
248 firstname=user.name,
249 lastname=user.lastname,
249 lastname=user.lastname,
250 email=user.email,
250 email=user.email,
251 active=user.active,
251 active=user.active,
252 admin=user.admin,
252 admin=user.admin,
253 ldap=user.ldap_dn))
253 ldap=user.ldap_dn))
254
254
255 result.append(dict(id=users_group.users_group_id,
255 result.append(dict(id=users_group.users_group_id,
256 group_name=users_group.users_group_name,
256 group_name=users_group.users_group_name,
257 active=users_group.users_group_active,
257 active=users_group.users_group_active,
258 members=members))
258 members=members))
259 return result
259 return result
260
260
261 @HasPermissionAllDecorator('hg.admin')
261 @HasPermissionAllDecorator('hg.admin')
262 def create_users_group(self, apiuser, group_name, active=True):
262 def create_users_group(self, apiuser, group_name, active=True):
263 """
263 """
264 Creates an new usergroup
264 Creates an new usergroup
265
265
266 :param group_name:
266 :param group_name:
267 :param active:
267 :param active:
268 """
268 """
269
269
270 if self.get_users_group(apiuser, group_name):
270 if self.get_users_group(apiuser, group_name):
271 raise JSONRPCError("users group %s already exist" % group_name)
271 raise JSONRPCError("users group %s already exist" % group_name)
272
272
273 try:
273 try:
274 ug = UsersGroupModel().create(name=group_name, active=active)
274 ug = UsersGroupModel().create(name=group_name, active=active)
275 Session.commit()
275 Session.commit()
276 return dict(id=ug.users_group_id,
276 return dict(id=ug.users_group_id,
277 msg='created new users group %s' % group_name)
277 msg='created new users group %s' % group_name)
278 except Exception:
278 except Exception:
279 log.error(traceback.format_exc())
279 log.error(traceback.format_exc())
280 raise JSONRPCError('failed to create group %s' % group_name)
280 raise JSONRPCError('failed to create group %s' % group_name)
281
281
282 @HasPermissionAllDecorator('hg.admin')
282 @HasPermissionAllDecorator('hg.admin')
283 def add_user_to_users_group(self, apiuser, group_name, username):
283 def add_user_to_users_group(self, apiuser, group_name, username):
284 """"
284 """"
285 Add a user to a group
285 Add a user to a group
286
286
287 :param apiuser:
287 :param apiuser:
288 :param group_name:
288 :param group_name:
289 :param username:
289 :param username:
290 """
290 """
291
291
292 try:
292 try:
293 users_group = UsersGroup.get_by_group_name(group_name)
293 users_group = UsersGroup.get_by_group_name(group_name)
294 if not users_group:
294 if not users_group:
295 raise JSONRPCError('unknown users group %s' % group_name)
295 raise JSONRPCError('unknown users group %s' % group_name)
296
296
297 user = User.get_by_username(username)
297 user = User.get_by_username(username)
298 if user is None:
298 if user is None:
299 raise JSONRPCError('unknown user %s' % username)
299 raise JSONRPCError('unknown user %s' % username)
300
300
301 ugm = UsersGroupModel().add_user_to_group(users_group, user)
301 ugm = UsersGroupModel().add_user_to_group(users_group, user)
302 success = True if ugm != True else False
302 success = True if ugm != True else False
303 msg = 'added member %s to users group %s' % (username, group_name)
303 msg = 'added member %s to users group %s' % (username, group_name)
304 msg = msg if success else 'User is already in that group'
304 msg = msg if success else 'User is already in that group'
305 Session.commit()
305 Session.commit()
306
306
307 return dict(
307 return dict(
308 id=ugm.users_group_member_id if ugm != True else None,
308 id=ugm.users_group_member_id if ugm != True else None,
309 success=success,
309 success=success,
310 msg=msg
310 msg=msg
311 )
311 )
312 except Exception:
312 except Exception:
313 log.error(traceback.format_exc())
313 log.error(traceback.format_exc())
314 raise JSONRPCError('failed to add users group member')
314 raise JSONRPCError('failed to add users group member')
315
315
316 @HasPermissionAllDecorator('hg.admin')
316 @HasPermissionAllDecorator('hg.admin')
317 def remove_user_from_users_group(self, apiuser, group_name, username):
317 def remove_user_from_users_group(self, apiuser, group_name, username):
318 """
318 """
319 Remove user from a group
319 Remove user from a group
320
320
321 :param apiuser
321 :param apiuser
322 :param group_name
322 :param group_name
323 :param username
323 :param username
324 """
324 """
325
325
326 try:
326 try:
327 users_group = UsersGroup.get_by_group_name(group_name)
327 users_group = UsersGroup.get_by_group_name(group_name)
328 if not users_group:
328 if not users_group:
329 raise JSONRPCError('unknown users group %s' % group_name)
329 raise JSONRPCError('unknown users group %s' % group_name)
330
330
331 user = User.get_by_username(username)
331 user = User.get_by_username(username)
332 if user is None:
332 if user is None:
333 raise JSONRPCError('unknown user %s' % username)
333 raise JSONRPCError('unknown user %s' % username)
334
334
335 success = UsersGroupModel().remove_user_from_group(users_group, user)
335 success = UsersGroupModel().remove_user_from_group(users_group, user)
336 msg = 'removed member %s from users group %s' % (username, group_name)
336 msg = 'removed member %s from users group %s' % (username, group_name)
337 msg = msg if success else "User wasn't in group"
337 msg = msg if success else "User wasn't in group"
338 Session.commit()
338 Session.commit()
339 return dict(success=success, msg=msg)
339 return dict(success=success, msg=msg)
340 except Exception:
340 except Exception:
341 log.error(traceback.format_exc())
341 log.error(traceback.format_exc())
342 raise JSONRPCError('failed to remove user from group')
342 raise JSONRPCError('failed to remove user from group')
343
343
344 @HasPermissionAnyDecorator('hg.admin')
344 @HasPermissionAnyDecorator('hg.admin')
345 def get_repo(self, apiuser, repo_name):
345 def get_repo(self, apiuser, repo_name):
346 """"
346 """"
347 Get repository by name
347 Get repository by name
348
348
349 :param apiuser:
349 :param apiuser:
350 :param repo_name:
350 :param repo_name:
351 """
351 """
352
352
353 repo = Repository.get_by_repo_name(repo_name)
353 repo = Repository.get_by_repo_name(repo_name)
354 if repo is None:
354 if repo is None:
355 raise JSONRPCError('unknown repository %s' % repo)
355 raise JSONRPCError('unknown repository %s' % repo)
356
356
357 members = []
357 members = []
358 for user in repo.repo_to_perm:
358 for user in repo.repo_to_perm:
359 perm = user.permission.permission_name
359 perm = user.permission.permission_name
360 user = user.user
360 user = user.user
361 members.append(
361 members.append(
362 dict(
362 dict(
363 type_="user",
363 type_="user",
364 id=user.user_id,
364 id=user.user_id,
365 username=user.username,
365 username=user.username,
366 firstname=user.name,
366 firstname=user.name,
367 lastname=user.lastname,
367 lastname=user.lastname,
368 email=user.email,
368 email=user.email,
369 active=user.active,
369 active=user.active,
370 admin=user.admin,
370 admin=user.admin,
371 ldap=user.ldap_dn,
371 ldap=user.ldap_dn,
372 permission=perm
372 permission=perm
373 )
373 )
374 )
374 )
375 for users_group in repo.users_group_to_perm:
375 for users_group in repo.users_group_to_perm:
376 perm = users_group.permission.permission_name
376 perm = users_group.permission.permission_name
377 users_group = users_group.users_group
377 users_group = users_group.users_group
378 members.append(
378 members.append(
379 dict(
379 dict(
380 type_="users_group",
380 type_="users_group",
381 id=users_group.users_group_id,
381 id=users_group.users_group_id,
382 name=users_group.users_group_name,
382 name=users_group.users_group_name,
383 active=users_group.users_group_active,
383 active=users_group.users_group_active,
384 permission=perm
384 permission=perm
385 )
385 )
386 )
386 )
387
387
388 return dict(
388 return dict(
389 id=repo.repo_id,
389 id=repo.repo_id,
390 repo_name=repo.repo_name,
390 repo_name=repo.repo_name,
391 type=repo.repo_type,
391 type=repo.repo_type,
392 description=repo.description,
392 description=repo.description,
393 members=members
393 members=members
394 )
394 )
395
395
396 @HasPermissionAnyDecorator('hg.admin')
396 @HasPermissionAnyDecorator('hg.admin')
397 def get_repos(self, apiuser):
397 def get_repos(self, apiuser):
398 """"
398 """"
399 Get all repositories
399 Get all repositories
400
400
401 :param apiuser:
401 :param apiuser:
402 """
402 """
403
403
404 result = []
404 result = []
405 for repository in Repository.getAll():
405 for repository in Repository.getAll():
406 result.append(
406 result.append(
407 dict(
407 dict(
408 id=repository.repo_id,
408 id=repository.repo_id,
409 repo_name=repository.repo_name,
409 repo_name=repository.repo_name,
410 type=repository.repo_type,
410 type=repository.repo_type,
411 description=repository.description
411 description=repository.description
412 )
412 )
413 )
413 )
414 return result
414 return result
415
415
416 @HasPermissionAnyDecorator('hg.admin')
416 @HasPermissionAnyDecorator('hg.admin')
417 def get_repo_nodes(self, apiuser, repo_name, revision, root_path,
417 def get_repo_nodes(self, apiuser, repo_name, revision, root_path,
418 ret_type='all'):
418 ret_type='all'):
419 """
419 """
420 returns a list of nodes and it's children
420 returns a list of nodes and it's children
421 for a given path at given revision. It's possible to specify ret_type
421 for a given path at given revision. It's possible to specify ret_type
422 to show only files or dirs
422 to show only files or dirs
423
423
424 :param apiuser:
424 :param apiuser:
425 :param repo_name: name of repository
425 :param repo_name: name of repository
426 :param revision: revision for which listing should be done
426 :param revision: revision for which listing should be done
427 :param root_path: path from which start displaying
427 :param root_path: path from which start displaying
428 :param ret_type: return type 'all|files|dirs' nodes
428 :param ret_type: return type 'all|files|dirs' nodes
429 """
429 """
430 try:
430 try:
431 _d, _f = ScmModel().get_nodes(repo_name, revision, root_path,
431 _d, _f = ScmModel().get_nodes(repo_name, revision, root_path,
432 flat=False)
432 flat=False)
433 _map = {
433 _map = {
434 'all': _d + _f,
434 'all': _d + _f,
435 'files': _f,
435 'files': _f,
436 'dirs': _d,
436 'dirs': _d,
437 }
437 }
438 return _map[ret_type]
438 return _map[ret_type]
439 except KeyError:
439 except KeyError:
440 raise JSONRPCError('ret_type must be one of %s' % _map.keys())
440 raise JSONRPCError('ret_type must be one of %s' % _map.keys())
441 except Exception, e:
441 except Exception, e:
442 raise JSONRPCError(e)
442 raise JSONRPCError(e)
443
443
444 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
444 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
445 def create_repo(self, apiuser, repo_name, owner_name, description='',
445 def create_repo(self, apiuser, repo_name, owner_name, description='',
446 repo_type='hg', private=False, clone_uri=None):
446 repo_type='hg', private=False, clone_uri=None):
447 """
447 """
448 Create repository, if clone_url is given it makes a remote clone
448 Create repository, if clone_url is given it makes a remote clone
449
449
450 :param apiuser:
450 :param apiuser:
451 :param repo_name:
451 :param repo_name:
452 :param owner_name:
452 :param owner_name:
453 :param description:
453 :param description:
454 :param repo_type:
454 :param repo_type:
455 :param private:
455 :param private:
456 :param clone_uri:
456 :param clone_uri:
457 """
457 """
458
458
459 try:
459 try:
460 owner = User.get_by_username(owner_name)
460 owner = User.get_by_username(owner_name)
461 if owner is None:
461 if owner is None:
462 raise JSONRPCError('unknown user %s' % owner_name)
462 raise JSONRPCError('unknown user %s' % owner_name)
463
463
464 if Repository.get_by_repo_name(repo_name):
464 if Repository.get_by_repo_name(repo_name):
465 raise JSONRPCError("repo %s already exist" % repo_name)
465 raise JSONRPCError("repo %s already exist" % repo_name)
466
466
467 groups = repo_name.split('/')
467 groups = repo_name.split('/')
468 real_name = groups[-1]
468 real_name = groups[-1]
469 groups = groups[:-1]
469 groups = groups[:-1]
470 parent_id = None
470 parent_id = None
471 for g in groups:
471 for g in groups:
472 group = RepoGroup.get_by_group_name(g)
472 group = RepoGroup.get_by_group_name(g)
473 if not group:
473 if not group:
474 group = ReposGroupModel().create(g, '', parent_id)
474 group = ReposGroupModel().create(g, '', parent_id)
475 parent_id = group.group_id
475 parent_id = group.group_id
476
476
477 repo = RepoModel().create(
477 repo = RepoModel().create(
478 dict(
478 dict(
479 repo_name=real_name,
479 repo_name=real_name,
480 repo_name_full=repo_name,
480 repo_name_full=repo_name,
481 description=description,
481 description=description,
482 private=private,
482 private=private,
483 repo_type=repo_type,
483 repo_type=repo_type,
484 repo_group=parent_id,
484 repo_group=parent_id,
485 clone_uri=clone_uri
485 clone_uri=clone_uri
486 ),
486 ),
487 owner
487 owner
488 )
488 )
489 Session.commit()
489 Session.commit()
490
490
491 return dict(
491 return dict(
492 id=repo.repo_id,
492 id=repo.repo_id,
493 msg="Created new repository %s" % repo.repo_name
493 msg="Created new repository %s" % repo.repo_name
494 )
494 )
495
495
496 except Exception:
496 except Exception:
497 log.error(traceback.format_exc())
497 log.error(traceback.format_exc())
498 raise JSONRPCError('failed to create repository %s' % repo_name)
498 raise JSONRPCError('failed to create repository %s' % repo_name)
499
499
500 @HasPermissionAnyDecorator('hg.admin')
500 @HasPermissionAnyDecorator('hg.admin')
501 def delete_repo(self, apiuser, repo_name):
501 def delete_repo(self, apiuser, repo_name):
502 """
502 """
503 Deletes a given repository
503 Deletes a given repository
504
504
505 :param repo_name:
505 :param repo_name:
506 """
506 """
507 if not Repository.get_by_repo_name(repo_name):
507 if not Repository.get_by_repo_name(repo_name):
508 raise JSONRPCError("repo %s does not exist" % repo_name)
508 raise JSONRPCError("repo %s does not exist" % repo_name)
509 try:
509 try:
510 RepoModel().delete(repo_name)
510 RepoModel().delete(repo_name)
511 Session.commit()
511 Session.commit()
512 return dict(
512 return dict(
513 msg='Deleted repository %s' % repo_name
513 msg='Deleted repository %s' % repo_name
514 )
514 )
515 except Exception:
515 except Exception:
516 log.error(traceback.format_exc())
516 log.error(traceback.format_exc())
517 raise JSONRPCError('failed to delete repository %s' % repo_name)
517 raise JSONRPCError('failed to delete repository %s' % repo_name)
518
518
519 @HasPermissionAnyDecorator('hg.admin')
519 @HasPermissionAnyDecorator('hg.admin')
520 def grant_user_permission(self, apiuser, repo_name, username, perm):
520 def grant_user_permission(self, apiuser, repo_name, username, perm):
521 """
521 """
522 Grant permission for user on given repository, or update existing one
522 Grant permission for user on given repository, or update existing one
523 if found
523 if found
524
524
525 :param repo_name:
525 :param repo_name:
526 :param username:
526 :param username:
527 :param perm:
527 :param perm:
528 """
528 """
529
529
530 try:
530 try:
531 repo = Repository.get_by_repo_name(repo_name)
531 repo = Repository.get_by_repo_name(repo_name)
532 if repo is None:
532 if repo is None:
533 raise JSONRPCError('unknown repository %s' % repo)
533 raise JSONRPCError('unknown repository %s' % repo)
534
534
535 user = User.get_by_username(username)
535 user = User.get_by_username(username)
536 if user is None:
536 if user is None:
537 raise JSONRPCError('unknown user %s' % username)
537 raise JSONRPCError('unknown user %s' % username)
538
538
539 RepoModel().grant_user_permission(repo=repo, user=user, perm=perm)
539 RepoModel().grant_user_permission(repo=repo, user=user, perm=perm)
540
540
541 Session.commit()
541 Session.commit()
542 return dict(
542 return dict(
543 msg='Granted perm: %s for user: %s in repo: %s' % (
543 msg='Granted perm: %s for user: %s in repo: %s' % (
544 perm, username, repo_name
544 perm, username, repo_name
545 )
545 )
546 )
546 )
547 except Exception:
547 except Exception:
548 log.error(traceback.format_exc())
548 log.error(traceback.format_exc())
549 raise JSONRPCError(
549 raise JSONRPCError(
550 'failed to edit permission %(repo)s for %(user)s' % dict(
550 'failed to edit permission %(repo)s for %(user)s' % dict(
551 user=username, repo=repo_name
551 user=username, repo=repo_name
552 )
552 )
553 )
553 )
554
554
555 @HasPermissionAnyDecorator('hg.admin')
555 @HasPermissionAnyDecorator('hg.admin')
556 def revoke_user_permission(self, apiuser, repo_name, username):
556 def revoke_user_permission(self, apiuser, repo_name, username):
557 """
557 """
558 Revoke permission for user on given repository
558 Revoke permission for user on given repository
559
559
560 :param repo_name:
560 :param repo_name:
561 :param username:
561 :param username:
562 """
562 """
563
563
564 try:
564 try:
565 repo = Repository.get_by_repo_name(repo_name)
565 repo = Repository.get_by_repo_name(repo_name)
566 if repo is None:
566 if repo is None:
567 raise JSONRPCError('unknown repository %s' % repo)
567 raise JSONRPCError('unknown repository %s' % repo)
568
568
569 user = User.get_by_username(username)
569 user = User.get_by_username(username)
570 if user is None:
570 if user is None:
571 raise JSONRPCError('unknown user %s' % username)
571 raise JSONRPCError('unknown user %s' % username)
572
572
573 RepoModel().revoke_user_permission(repo=repo_name, user=username)
573 RepoModel().revoke_user_permission(repo=repo_name, user=username)
574
574
575 Session.commit()
575 Session.commit()
576 return dict(
576 return dict(
577 msg='Revoked perm for user: %s in repo: %s' % (
577 msg='Revoked perm for user: %s in repo: %s' % (
578 username, repo_name
578 username, repo_name
579 )
579 )
580 )
580 )
581 except Exception:
581 except Exception:
582 log.error(traceback.format_exc())
582 log.error(traceback.format_exc())
583 raise JSONRPCError(
583 raise JSONRPCError(
584 'failed to edit permission %(repo)s for %(user)s' % dict(
584 'failed to edit permission %(repo)s for %(user)s' % dict(
585 user=username, repo=repo_name
585 user=username, repo=repo_name
586 )
586 )
587 )
587 )
588
588
589 @HasPermissionAnyDecorator('hg.admin')
589 @HasPermissionAnyDecorator('hg.admin')
590 def grant_users_group_permission(self, apiuser, repo_name, group_name, perm):
590 def grant_users_group_permission(self, apiuser, repo_name, group_name, perm):
591 """
591 """
592 Grant permission for users group on given repository, or update
592 Grant permission for users group on given repository, or update
593 existing one if found
593 existing one if found
594
594
595 :param repo_name:
595 :param repo_name:
596 :param group_name:
596 :param group_name:
597 :param perm:
597 :param perm:
598 """
598 """
599
599
600 try:
600 try:
601 repo = Repository.get_by_repo_name(repo_name)
601 repo = Repository.get_by_repo_name(repo_name)
602 if repo is None:
602 if repo is None:
603 raise JSONRPCError('unknown repository %s' % repo)
603 raise JSONRPCError('unknown repository %s' % repo)
604
604
605 user_group = UsersGroup.get_by_group_name(group_name)
605 user_group = UsersGroup.get_by_group_name(group_name)
606 if user_group is None:
606 if user_group is None:
607 raise JSONRPCError('unknown users group %s' % user_group)
607 raise JSONRPCError('unknown users group %s' % user_group)
608
608
609 RepoModel().grant_users_group_permission(repo=repo_name,
609 RepoModel().grant_users_group_permission(repo=repo_name,
610 group_name=group_name,
610 group_name=group_name,
611 perm=perm)
611 perm=perm)
612
612
613 Session.commit()
613 Session.commit()
614 return dict(
614 return dict(
615 msg='Granted perm: %s for group: %s in repo: %s' % (
615 msg='Granted perm: %s for group: %s in repo: %s' % (
616 perm, group_name, repo_name
616 perm, group_name, repo_name
617 )
617 )
618 )
618 )
619 except Exception:
619 except Exception:
620 log.error(traceback.format_exc())
620 log.error(traceback.format_exc())
621 raise JSONRPCError(
621 raise JSONRPCError(
622 'failed to edit permission %(repo)s for %(usersgr)s' % dict(
622 'failed to edit permission %(repo)s for %(usersgr)s' % dict(
623 usersgr=group_name, repo=repo_name
623 usersgr=group_name, repo=repo_name
624 )
624 )
625 )
625 )
626
626
627 @HasPermissionAnyDecorator('hg.admin')
627 @HasPermissionAnyDecorator('hg.admin')
628 def revoke_users_group_permission(self, apiuser, repo_name, group_name):
628 def revoke_users_group_permission(self, apiuser, repo_name, group_name):
629 """
629 """
630 Revoke permission for users group on given repository
630 Revoke permission for users group on given repository
631
631
632 :param repo_name:
632 :param repo_name:
633 :param group_name:
633 :param group_name:
634 """
634 """
635
635
636 try:
636 try:
637 repo = Repository.get_by_repo_name(repo_name)
637 repo = Repository.get_by_repo_name(repo_name)
638 if repo is None:
638 if repo is None:
639 raise JSONRPCError('unknown repository %s' % repo)
639 raise JSONRPCError('unknown repository %s' % repo)
640
640
641 user_group = UsersGroup.get_by_group_name(group_name)
641 user_group = UsersGroup.get_by_group_name(group_name)
642 if user_group is None:
642 if user_group is None:
643 raise JSONRPCError('unknown users group %s' % user_group)
643 raise JSONRPCError('unknown users group %s' % user_group)
644
644
645 RepoModel().revoke_users_group_permission(repo=repo_name,
645 RepoModel().revoke_users_group_permission(repo=repo_name,
646 group_name=group_name)
646 group_name=group_name)
647
647
648 Session.commit()
648 Session.commit()
649 return dict(
649 return dict(
650 msg='Revoked perm for group: %s in repo: %s' % (
650 msg='Revoked perm for group: %s in repo: %s' % (
651 group_name, repo_name
651 group_name, repo_name
652 )
652 )
653 )
653 )
654 except Exception:
654 except Exception:
655 log.error(traceback.format_exc())
655 log.error(traceback.format_exc())
656 raise JSONRPCError(
656 raise JSONRPCError(
657 'failed to edit permission %(repo)s for %(usersgr)s' % dict(
657 'failed to edit permission %(repo)s for %(usersgr)s' % dict(
658 usersgr=group_name, repo=repo_name
658 usersgr=group_name, repo=repo_name
659 )
659 )
660 )
660 )
@@ -1,549 +1,552
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.model.user
3 rhodecode.model.user
4 ~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~
5
5
6 users model for RhodeCode
6 users model for RhodeCode
7
7
8 :created_on: Apr 9, 2010
8 :created_on: Apr 9, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import logging
26 import logging
27 import traceback
27 import traceback
28
28
29 from pylons import url
29 from pylons import url
30 from pylons.i18n.translation import _
30 from pylons.i18n.translation import _
31
31
32 from rhodecode.lib import safe_unicode
32 from rhodecode.lib import safe_unicode
33 from rhodecode.lib.caching_query import FromCache
33 from rhodecode.lib.caching_query import FromCache
34
34
35 from rhodecode.model import BaseModel
35 from rhodecode.model import BaseModel
36 from rhodecode.model.db import User, UserRepoToPerm, Repository, Permission, \
36 from rhodecode.model.db import User, UserRepoToPerm, Repository, Permission, \
37 UserToPerm, UsersGroupRepoToPerm, UsersGroupToPerm, UsersGroupMember, \
37 UserToPerm, UsersGroupRepoToPerm, UsersGroupToPerm, UsersGroupMember, \
38 Notification, RepoGroup, UserRepoGroupToPerm, UsersGroup
38 Notification, RepoGroup, UserRepoGroupToPerm, UsersGroup
39 from rhodecode.lib.exceptions import DefaultUserException, \
39 from rhodecode.lib.exceptions import DefaultUserException, \
40 UserOwnsReposException
40 UserOwnsReposException
41
41
42 from sqlalchemy.exc import DatabaseError
42 from sqlalchemy.exc import DatabaseError
43 from rhodecode.lib import generate_api_key
43 from rhodecode.lib import generate_api_key
44 from sqlalchemy.orm import joinedload
44 from sqlalchemy.orm import joinedload
45
45
46 log = logging.getLogger(__name__)
46 log = logging.getLogger(__name__)
47
47
48
48
49 PERM_WEIGHTS = {
49 PERM_WEIGHTS = {
50 'repository.none': 0,
50 'repository.none': 0,
51 'repository.read': 1,
51 'repository.read': 1,
52 'repository.write': 3,
52 'repository.write': 3,
53 'repository.admin': 4,
53 'repository.admin': 4,
54 'group.none': 0,
54 'group.none': 0,
55 'group.read': 1,
55 'group.read': 1,
56 'group.write': 3,
56 'group.write': 3,
57 'group.admin': 4,
57 'group.admin': 4,
58 }
58 }
59
59
60
60
61 class UserModel(BaseModel):
61 class UserModel(BaseModel):
62
62
63 def __get_user(self, user):
63 def __get_user(self, user):
64 return self._get_instance(User, user, callback=User.get_by_username)
64 return self._get_instance(User, user, callback=User.get_by_username)
65
65
66 def __get_perm(self, permission):
66 def __get_perm(self, permission):
67 return self._get_instance(Permission, permission,
67 return self._get_instance(Permission, permission,
68 callback=Permission.get_by_key)
68 callback=Permission.get_by_key)
69
69
70 def get(self, user_id, cache=False):
70 def get(self, user_id, cache=False):
71 user = self.sa.query(User)
71 user = self.sa.query(User)
72 if cache:
72 if cache:
73 user = user.options(FromCache("sql_cache_short",
73 user = user.options(FromCache("sql_cache_short",
74 "get_user_%s" % user_id))
74 "get_user_%s" % user_id))
75 return user.get(user_id)
75 return user.get(user_id)
76
76
77 def get_user(self, user):
78 return self.__get_user(user)
79
77 def get_by_username(self, username, cache=False, case_insensitive=False):
80 def get_by_username(self, username, cache=False, case_insensitive=False):
78
81
79 if case_insensitive:
82 if case_insensitive:
80 user = self.sa.query(User).filter(User.username.ilike(username))
83 user = self.sa.query(User).filter(User.username.ilike(username))
81 else:
84 else:
82 user = self.sa.query(User)\
85 user = self.sa.query(User)\
83 .filter(User.username == username)
86 .filter(User.username == username)
84 if cache:
87 if cache:
85 user = user.options(FromCache("sql_cache_short",
88 user = user.options(FromCache("sql_cache_short",
86 "get_user_%s" % username))
89 "get_user_%s" % username))
87 return user.scalar()
90 return user.scalar()
88
91
89 def get_by_api_key(self, api_key, cache=False):
92 def get_by_api_key(self, api_key, cache=False):
90 return User.get_by_api_key(api_key, cache)
93 return User.get_by_api_key(api_key, cache)
91
94
92 def create(self, form_data):
95 def create(self, form_data):
93 try:
96 try:
94 new_user = User()
97 new_user = User()
95 for k, v in form_data.items():
98 for k, v in form_data.items():
96 setattr(new_user, k, v)
99 setattr(new_user, k, v)
97
100
98 new_user.api_key = generate_api_key(form_data['username'])
101 new_user.api_key = generate_api_key(form_data['username'])
99 self.sa.add(new_user)
102 self.sa.add(new_user)
100 return new_user
103 return new_user
101 except:
104 except:
102 log.error(traceback.format_exc())
105 log.error(traceback.format_exc())
103 raise
106 raise
104
107
105 def create_or_update(self, username, password, email, name, lastname,
108 def create_or_update(self, username, password, email, name, lastname,
106 active=True, admin=False, ldap_dn=None):
109 active=True, admin=False, ldap_dn=None):
107 """
110 """
108 Creates a new instance if not found, or updates current one
111 Creates a new instance if not found, or updates current one
109
112
110 :param username:
113 :param username:
111 :param password:
114 :param password:
112 :param email:
115 :param email:
113 :param active:
116 :param active:
114 :param name:
117 :param name:
115 :param lastname:
118 :param lastname:
116 :param active:
119 :param active:
117 :param admin:
120 :param admin:
118 :param ldap_dn:
121 :param ldap_dn:
119 """
122 """
120
123
121 from rhodecode.lib.auth import get_crypt_password
124 from rhodecode.lib.auth import get_crypt_password
122
125
123 log.debug('Checking for %s account in RhodeCode database' % username)
126 log.debug('Checking for %s account in RhodeCode database' % username)
124 user = User.get_by_username(username, case_insensitive=True)
127 user = User.get_by_username(username, case_insensitive=True)
125 if user is None:
128 if user is None:
126 log.debug('creating new user %s' % username)
129 log.debug('creating new user %s' % username)
127 new_user = User()
130 new_user = User()
128 else:
131 else:
129 log.debug('updating user %s' % username)
132 log.debug('updating user %s' % username)
130 new_user = user
133 new_user = user
131
134
132 try:
135 try:
133 new_user.username = username
136 new_user.username = username
134 new_user.admin = admin
137 new_user.admin = admin
135 new_user.password = get_crypt_password(password)
138 new_user.password = get_crypt_password(password)
136 new_user.api_key = generate_api_key(username)
139 new_user.api_key = generate_api_key(username)
137 new_user.email = email
140 new_user.email = email
138 new_user.active = active
141 new_user.active = active
139 new_user.ldap_dn = safe_unicode(ldap_dn) if ldap_dn else None
142 new_user.ldap_dn = safe_unicode(ldap_dn) if ldap_dn else None
140 new_user.name = name
143 new_user.name = name
141 new_user.lastname = lastname
144 new_user.lastname = lastname
142 self.sa.add(new_user)
145 self.sa.add(new_user)
143 return new_user
146 return new_user
144 except (DatabaseError,):
147 except (DatabaseError,):
145 log.error(traceback.format_exc())
148 log.error(traceback.format_exc())
146 raise
149 raise
147
150
148 def create_for_container_auth(self, username, attrs):
151 def create_for_container_auth(self, username, attrs):
149 """
152 """
150 Creates the given user if it's not already in the database
153 Creates the given user if it's not already in the database
151
154
152 :param username:
155 :param username:
153 :param attrs:
156 :param attrs:
154 """
157 """
155 if self.get_by_username(username, case_insensitive=True) is None:
158 if self.get_by_username(username, case_insensitive=True) is None:
156
159
157 # autogenerate email for container account without one
160 # autogenerate email for container account without one
158 generate_email = lambda usr: '%s@container_auth.account' % usr
161 generate_email = lambda usr: '%s@container_auth.account' % usr
159
162
160 try:
163 try:
161 new_user = User()
164 new_user = User()
162 new_user.username = username
165 new_user.username = username
163 new_user.password = None
166 new_user.password = None
164 new_user.api_key = generate_api_key(username)
167 new_user.api_key = generate_api_key(username)
165 new_user.email = attrs['email']
168 new_user.email = attrs['email']
166 new_user.active = attrs.get('active', True)
169 new_user.active = attrs.get('active', True)
167 new_user.name = attrs['name'] or generate_email(username)
170 new_user.name = attrs['name'] or generate_email(username)
168 new_user.lastname = attrs['lastname']
171 new_user.lastname = attrs['lastname']
169
172
170 self.sa.add(new_user)
173 self.sa.add(new_user)
171 return new_user
174 return new_user
172 except (DatabaseError,):
175 except (DatabaseError,):
173 log.error(traceback.format_exc())
176 log.error(traceback.format_exc())
174 self.sa.rollback()
177 self.sa.rollback()
175 raise
178 raise
176 log.debug('User %s already exists. Skipping creation of account'
179 log.debug('User %s already exists. Skipping creation of account'
177 ' for container auth.', username)
180 ' for container auth.', username)
178 return None
181 return None
179
182
180 def create_ldap(self, username, password, user_dn, attrs):
183 def create_ldap(self, username, password, user_dn, attrs):
181 """
184 """
182 Checks if user is in database, if not creates this user marked
185 Checks if user is in database, if not creates this user marked
183 as ldap user
186 as ldap user
184
187
185 :param username:
188 :param username:
186 :param password:
189 :param password:
187 :param user_dn:
190 :param user_dn:
188 :param attrs:
191 :param attrs:
189 """
192 """
190 from rhodecode.lib.auth import get_crypt_password
193 from rhodecode.lib.auth import get_crypt_password
191 log.debug('Checking for such ldap account in RhodeCode database')
194 log.debug('Checking for such ldap account in RhodeCode database')
192 if self.get_by_username(username, case_insensitive=True) is None:
195 if self.get_by_username(username, case_insensitive=True) is None:
193
196
194 # autogenerate email for ldap account without one
197 # autogenerate email for ldap account without one
195 generate_email = lambda usr: '%s@ldap.account' % usr
198 generate_email = lambda usr: '%s@ldap.account' % usr
196
199
197 try:
200 try:
198 new_user = User()
201 new_user = User()
199 username = username.lower()
202 username = username.lower()
200 # add ldap account always lowercase
203 # add ldap account always lowercase
201 new_user.username = username
204 new_user.username = username
202 new_user.password = get_crypt_password(password)
205 new_user.password = get_crypt_password(password)
203 new_user.api_key = generate_api_key(username)
206 new_user.api_key = generate_api_key(username)
204 new_user.email = attrs['email'] or generate_email(username)
207 new_user.email = attrs['email'] or generate_email(username)
205 new_user.active = attrs.get('active', True)
208 new_user.active = attrs.get('active', True)
206 new_user.ldap_dn = safe_unicode(user_dn)
209 new_user.ldap_dn = safe_unicode(user_dn)
207 new_user.name = attrs['name']
210 new_user.name = attrs['name']
208 new_user.lastname = attrs['lastname']
211 new_user.lastname = attrs['lastname']
209
212
210 self.sa.add(new_user)
213 self.sa.add(new_user)
211 return new_user
214 return new_user
212 except (DatabaseError,):
215 except (DatabaseError,):
213 log.error(traceback.format_exc())
216 log.error(traceback.format_exc())
214 self.sa.rollback()
217 self.sa.rollback()
215 raise
218 raise
216 log.debug('this %s user exists skipping creation of ldap account',
219 log.debug('this %s user exists skipping creation of ldap account',
217 username)
220 username)
218 return None
221 return None
219
222
220 def create_registration(self, form_data):
223 def create_registration(self, form_data):
221 from rhodecode.model.notification import NotificationModel
224 from rhodecode.model.notification import NotificationModel
222
225
223 try:
226 try:
224 new_user = User()
227 new_user = User()
225 for k, v in form_data.items():
228 for k, v in form_data.items():
226 if k != 'admin':
229 if k != 'admin':
227 setattr(new_user, k, v)
230 setattr(new_user, k, v)
228
231
229 self.sa.add(new_user)
232 self.sa.add(new_user)
230 self.sa.flush()
233 self.sa.flush()
231
234
232 # notification to admins
235 # notification to admins
233 subject = _('new user registration')
236 subject = _('new user registration')
234 body = ('New user registration\n'
237 body = ('New user registration\n'
235 '---------------------\n'
238 '---------------------\n'
236 '- Username: %s\n'
239 '- Username: %s\n'
237 '- Full Name: %s\n'
240 '- Full Name: %s\n'
238 '- Email: %s\n')
241 '- Email: %s\n')
239 body = body % (new_user.username, new_user.full_name,
242 body = body % (new_user.username, new_user.full_name,
240 new_user.email)
243 new_user.email)
241 edit_url = url('edit_user', id=new_user.user_id, qualified=True)
244 edit_url = url('edit_user', id=new_user.user_id, qualified=True)
242 kw = {'registered_user_url': edit_url}
245 kw = {'registered_user_url': edit_url}
243 NotificationModel().create(created_by=new_user, subject=subject,
246 NotificationModel().create(created_by=new_user, subject=subject,
244 body=body, recipients=None,
247 body=body, recipients=None,
245 type_=Notification.TYPE_REGISTRATION,
248 type_=Notification.TYPE_REGISTRATION,
246 email_kwargs=kw)
249 email_kwargs=kw)
247
250
248 except:
251 except:
249 log.error(traceback.format_exc())
252 log.error(traceback.format_exc())
250 raise
253 raise
251
254
252 def update(self, user_id, form_data):
255 def update(self, user_id, form_data):
253 try:
256 try:
254 user = self.get(user_id, cache=False)
257 user = self.get(user_id, cache=False)
255 if user.username == 'default':
258 if user.username == 'default':
256 raise DefaultUserException(
259 raise DefaultUserException(
257 _("You can't Edit this user since it's"
260 _("You can't Edit this user since it's"
258 " crucial for entire application"))
261 " crucial for entire application"))
259
262
260 for k, v in form_data.items():
263 for k, v in form_data.items():
261 if k == 'new_password' and v != '':
264 if k == 'new_password' and v != '':
262 user.password = v
265 user.password = v
263 user.api_key = generate_api_key(user.username)
266 user.api_key = generate_api_key(user.username)
264 else:
267 else:
265 setattr(user, k, v)
268 setattr(user, k, v)
266
269
267 self.sa.add(user)
270 self.sa.add(user)
268 except:
271 except:
269 log.error(traceback.format_exc())
272 log.error(traceback.format_exc())
270 raise
273 raise
271
274
272 def update_my_account(self, user_id, form_data):
275 def update_my_account(self, user_id, form_data):
273 try:
276 try:
274 user = self.get(user_id, cache=False)
277 user = self.get(user_id, cache=False)
275 if user.username == 'default':
278 if user.username == 'default':
276 raise DefaultUserException(
279 raise DefaultUserException(
277 _("You can't Edit this user since it's"
280 _("You can't Edit this user since it's"
278 " crucial for entire application"))
281 " crucial for entire application"))
279 for k, v in form_data.items():
282 for k, v in form_data.items():
280 if k == 'new_password' and v != '':
283 if k == 'new_password' and v != '':
281 user.password = v
284 user.password = v
282 user.api_key = generate_api_key(user.username)
285 user.api_key = generate_api_key(user.username)
283 else:
286 else:
284 if k not in ['admin', 'active']:
287 if k not in ['admin', 'active']:
285 setattr(user, k, v)
288 setattr(user, k, v)
286
289
287 self.sa.add(user)
290 self.sa.add(user)
288 except:
291 except:
289 log.error(traceback.format_exc())
292 log.error(traceback.format_exc())
290 raise
293 raise
291
294
292 def delete(self, user):
295 def delete(self, user):
293 user = self.__get_user(user)
296 user = self.__get_user(user)
294
297
295 try:
298 try:
296 if user.username == 'default':
299 if user.username == 'default':
297 raise DefaultUserException(
300 raise DefaultUserException(
298 _("You can't remove this user since it's"
301 _("You can't remove this user since it's"
299 " crucial for entire application"))
302 " crucial for entire application"))
300 if user.repositories:
303 if user.repositories:
301 raise UserOwnsReposException(_('This user still owns %s '
304 raise UserOwnsReposException(_('This user still owns %s '
302 'repositories and cannot be '
305 'repositories and cannot be '
303 'removed. Switch owners or '
306 'removed. Switch owners or '
304 'remove those repositories') \
307 'remove those repositories') \
305 % user.repositories)
308 % user.repositories)
306 self.sa.delete(user)
309 self.sa.delete(user)
307 except:
310 except:
308 log.error(traceback.format_exc())
311 log.error(traceback.format_exc())
309 raise
312 raise
310
313
311 def reset_password_link(self, data):
314 def reset_password_link(self, data):
312 from rhodecode.lib.celerylib import tasks, run_task
315 from rhodecode.lib.celerylib import tasks, run_task
313 run_task(tasks.send_password_link, data['email'])
316 run_task(tasks.send_password_link, data['email'])
314
317
315 def reset_password(self, data):
318 def reset_password(self, data):
316 from rhodecode.lib.celerylib import tasks, run_task
319 from rhodecode.lib.celerylib import tasks, run_task
317 run_task(tasks.reset_user_password, data['email'])
320 run_task(tasks.reset_user_password, data['email'])
318
321
319 def fill_data(self, auth_user, user_id=None, api_key=None):
322 def fill_data(self, auth_user, user_id=None, api_key=None):
320 """
323 """
321 Fetches auth_user by user_id,or api_key if present.
324 Fetches auth_user by user_id,or api_key if present.
322 Fills auth_user attributes with those taken from database.
325 Fills auth_user attributes with those taken from database.
323 Additionally set's is_authenitated if lookup fails
326 Additionally set's is_authenitated if lookup fails
324 present in database
327 present in database
325
328
326 :param auth_user: instance of user to set attributes
329 :param auth_user: instance of user to set attributes
327 :param user_id: user id to fetch by
330 :param user_id: user id to fetch by
328 :param api_key: api key to fetch by
331 :param api_key: api key to fetch by
329 """
332 """
330 if user_id is None and api_key is None:
333 if user_id is None and api_key is None:
331 raise Exception('You need to pass user_id or api_key')
334 raise Exception('You need to pass user_id or api_key')
332
335
333 try:
336 try:
334 if api_key:
337 if api_key:
335 dbuser = self.get_by_api_key(api_key)
338 dbuser = self.get_by_api_key(api_key)
336 else:
339 else:
337 dbuser = self.get(user_id)
340 dbuser = self.get(user_id)
338
341
339 if dbuser is not None and dbuser.active:
342 if dbuser is not None and dbuser.active:
340 log.debug('filling %s data' % dbuser)
343 log.debug('filling %s data' % dbuser)
341 for k, v in dbuser.get_dict().items():
344 for k, v in dbuser.get_dict().items():
342 setattr(auth_user, k, v)
345 setattr(auth_user, k, v)
343 else:
346 else:
344 return False
347 return False
345
348
346 except:
349 except:
347 log.error(traceback.format_exc())
350 log.error(traceback.format_exc())
348 auth_user.is_authenticated = False
351 auth_user.is_authenticated = False
349 return False
352 return False
350
353
351 return True
354 return True
352
355
353 def fill_perms(self, user):
356 def fill_perms(self, user):
354 """
357 """
355 Fills user permission attribute with permissions taken from database
358 Fills user permission attribute with permissions taken from database
356 works for permissions given for repositories, and for permissions that
359 works for permissions given for repositories, and for permissions that
357 are granted to groups
360 are granted to groups
358
361
359 :param user: user instance to fill his perms
362 :param user: user instance to fill his perms
360 """
363 """
361 RK = 'repositories'
364 RK = 'repositories'
362 GK = 'repositories_groups'
365 GK = 'repositories_groups'
363 GLOBAL = 'global'
366 GLOBAL = 'global'
364 user.permissions[RK] = {}
367 user.permissions[RK] = {}
365 user.permissions[GK] = {}
368 user.permissions[GK] = {}
366 user.permissions[GLOBAL] = set()
369 user.permissions[GLOBAL] = set()
367
370
368 #======================================================================
371 #======================================================================
369 # fetch default permissions
372 # fetch default permissions
370 #======================================================================
373 #======================================================================
371 default_user = User.get_by_username('default', cache=True)
374 default_user = User.get_by_username('default', cache=True)
372 default_user_id = default_user.user_id
375 default_user_id = default_user.user_id
373
376
374 default_repo_perms = Permission.get_default_perms(default_user_id)
377 default_repo_perms = Permission.get_default_perms(default_user_id)
375 default_repo_groups_perms = Permission.get_default_group_perms(default_user_id)
378 default_repo_groups_perms = Permission.get_default_group_perms(default_user_id)
376
379
377 if user.is_admin:
380 if user.is_admin:
378 #==================================================================
381 #==================================================================
379 # admin user have all default rights for repositories
382 # admin user have all default rights for repositories
380 # and groups set to admin
383 # and groups set to admin
381 #==================================================================
384 #==================================================================
382 user.permissions[GLOBAL].add('hg.admin')
385 user.permissions[GLOBAL].add('hg.admin')
383
386
384 # repositories
387 # repositories
385 for perm in default_repo_perms:
388 for perm in default_repo_perms:
386 r_k = perm.UserRepoToPerm.repository.repo_name
389 r_k = perm.UserRepoToPerm.repository.repo_name
387 p = 'repository.admin'
390 p = 'repository.admin'
388 user.permissions[RK][r_k] = p
391 user.permissions[RK][r_k] = p
389
392
390 # repositories groups
393 # repositories groups
391 for perm in default_repo_groups_perms:
394 for perm in default_repo_groups_perms:
392 rg_k = perm.UserRepoGroupToPerm.group.group_name
395 rg_k = perm.UserRepoGroupToPerm.group.group_name
393 p = 'group.admin'
396 p = 'group.admin'
394 user.permissions[GK][rg_k] = p
397 user.permissions[GK][rg_k] = p
395
398
396 else:
399 else:
397 #==================================================================
400 #==================================================================
398 # set default permissions first for repositories and groups
401 # set default permissions first for repositories and groups
399 #==================================================================
402 #==================================================================
400 uid = user.user_id
403 uid = user.user_id
401
404
402 # default global permissions
405 # default global permissions
403 default_global_perms = self.sa.query(UserToPerm)\
406 default_global_perms = self.sa.query(UserToPerm)\
404 .filter(UserToPerm.user_id == default_user_id)
407 .filter(UserToPerm.user_id == default_user_id)
405
408
406 for perm in default_global_perms:
409 for perm in default_global_perms:
407 user.permissions[GLOBAL].add(perm.permission.permission_name)
410 user.permissions[GLOBAL].add(perm.permission.permission_name)
408
411
409 # default for repositories
412 # default for repositories
410 for perm in default_repo_perms:
413 for perm in default_repo_perms:
411 r_k = perm.UserRepoToPerm.repository.repo_name
414 r_k = perm.UserRepoToPerm.repository.repo_name
412 if perm.Repository.private and not (perm.Repository.user_id == uid):
415 if perm.Repository.private and not (perm.Repository.user_id == uid):
413 # disable defaults for private repos,
416 # disable defaults for private repos,
414 p = 'repository.none'
417 p = 'repository.none'
415 elif perm.Repository.user_id == uid:
418 elif perm.Repository.user_id == uid:
416 # set admin if owner
419 # set admin if owner
417 p = 'repository.admin'
420 p = 'repository.admin'
418 else:
421 else:
419 p = perm.Permission.permission_name
422 p = perm.Permission.permission_name
420
423
421 user.permissions[RK][r_k] = p
424 user.permissions[RK][r_k] = p
422
425
423 # default for repositories groups
426 # default for repositories groups
424 for perm in default_repo_groups_perms:
427 for perm in default_repo_groups_perms:
425 rg_k = perm.UserRepoGroupToPerm.group.group_name
428 rg_k = perm.UserRepoGroupToPerm.group.group_name
426 p = perm.Permission.permission_name
429 p = perm.Permission.permission_name
427 user.permissions[GK][rg_k] = p
430 user.permissions[GK][rg_k] = p
428
431
429 #==================================================================
432 #==================================================================
430 # overwrite default with user permissions if any
433 # overwrite default with user permissions if any
431 #==================================================================
434 #==================================================================
432
435
433 # user global
436 # user global
434 user_perms = self.sa.query(UserToPerm)\
437 user_perms = self.sa.query(UserToPerm)\
435 .options(joinedload(UserToPerm.permission))\
438 .options(joinedload(UserToPerm.permission))\
436 .filter(UserToPerm.user_id == uid).all()
439 .filter(UserToPerm.user_id == uid).all()
437
440
438 for perm in user_perms:
441 for perm in user_perms:
439 user.permissions[GLOBAL].add(perm.permission.permission_name)
442 user.permissions[GLOBAL].add(perm.permission.permission_name)
440
443
441 # user repositories
444 # user repositories
442 user_repo_perms = \
445 user_repo_perms = \
443 self.sa.query(UserRepoToPerm, Permission, Repository)\
446 self.sa.query(UserRepoToPerm, Permission, Repository)\
444 .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\
447 .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\
445 .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\
448 .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\
446 .filter(UserRepoToPerm.user_id == uid)\
449 .filter(UserRepoToPerm.user_id == uid)\
447 .all()
450 .all()
448
451
449 for perm in user_repo_perms:
452 for perm in user_repo_perms:
450 # set admin if owner
453 # set admin if owner
451 r_k = perm.UserRepoToPerm.repository.repo_name
454 r_k = perm.UserRepoToPerm.repository.repo_name
452 if perm.Repository.user_id == uid:
455 if perm.Repository.user_id == uid:
453 p = 'repository.admin'
456 p = 'repository.admin'
454 else:
457 else:
455 p = perm.Permission.permission_name
458 p = perm.Permission.permission_name
456 user.permissions[RK][r_k] = p
459 user.permissions[RK][r_k] = p
457
460
458 #==================================================================
461 #==================================================================
459 # check if user is part of groups for this repository and fill in
462 # check if user is part of groups for this repository and fill in
460 # (or replace with higher) permissions
463 # (or replace with higher) permissions
461 #==================================================================
464 #==================================================================
462
465
463 # users group global
466 # users group global
464 user_perms_from_users_groups = self.sa.query(UsersGroupToPerm)\
467 user_perms_from_users_groups = self.sa.query(UsersGroupToPerm)\
465 .options(joinedload(UsersGroupToPerm.permission))\
468 .options(joinedload(UsersGroupToPerm.permission))\
466 .join((UsersGroupMember, UsersGroupToPerm.users_group_id ==
469 .join((UsersGroupMember, UsersGroupToPerm.users_group_id ==
467 UsersGroupMember.users_group_id))\
470 UsersGroupMember.users_group_id))\
468 .filter(UsersGroupMember.user_id == uid).all()
471 .filter(UsersGroupMember.user_id == uid).all()
469
472
470 for perm in user_perms_from_users_groups:
473 for perm in user_perms_from_users_groups:
471 user.permissions[GLOBAL].add(perm.permission.permission_name)
474 user.permissions[GLOBAL].add(perm.permission.permission_name)
472
475
473 # users group repositories
476 # users group repositories
474 user_repo_perms_from_users_groups = \
477 user_repo_perms_from_users_groups = \
475 self.sa.query(UsersGroupRepoToPerm, Permission, Repository,)\
478 self.sa.query(UsersGroupRepoToPerm, Permission, Repository,)\
476 .join((Repository, UsersGroupRepoToPerm.repository_id == Repository.repo_id))\
479 .join((Repository, UsersGroupRepoToPerm.repository_id == Repository.repo_id))\
477 .join((Permission, UsersGroupRepoToPerm.permission_id == Permission.permission_id))\
480 .join((Permission, UsersGroupRepoToPerm.permission_id == Permission.permission_id))\
478 .join((UsersGroupMember, UsersGroupRepoToPerm.users_group_id == UsersGroupMember.users_group_id))\
481 .join((UsersGroupMember, UsersGroupRepoToPerm.users_group_id == UsersGroupMember.users_group_id))\
479 .filter(UsersGroupMember.user_id == uid)\
482 .filter(UsersGroupMember.user_id == uid)\
480 .all()
483 .all()
481
484
482 for perm in user_repo_perms_from_users_groups:
485 for perm in user_repo_perms_from_users_groups:
483 r_k = perm.UsersGroupRepoToPerm.repository.repo_name
486 r_k = perm.UsersGroupRepoToPerm.repository.repo_name
484 p = perm.Permission.permission_name
487 p = perm.Permission.permission_name
485 cur_perm = user.permissions[RK][r_k]
488 cur_perm = user.permissions[RK][r_k]
486 # overwrite permission only if it's greater than permission
489 # overwrite permission only if it's greater than permission
487 # given from other sources
490 # given from other sources
488 if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]:
491 if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]:
489 user.permissions[RK][r_k] = p
492 user.permissions[RK][r_k] = p
490
493
491 #==================================================================
494 #==================================================================
492 # get access for this user for repos group and override defaults
495 # get access for this user for repos group and override defaults
493 #==================================================================
496 #==================================================================
494
497
495 # user repositories groups
498 # user repositories groups
496 user_repo_groups_perms = \
499 user_repo_groups_perms = \
497 self.sa.query(UserRepoGroupToPerm, Permission, RepoGroup)\
500 self.sa.query(UserRepoGroupToPerm, Permission, RepoGroup)\
498 .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\
501 .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\
499 .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id))\
502 .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id))\
500 .filter(UserRepoToPerm.user_id == uid)\
503 .filter(UserRepoToPerm.user_id == uid)\
501 .all()
504 .all()
502
505
503 for perm in user_repo_groups_perms:
506 for perm in user_repo_groups_perms:
504 rg_k = perm.UserRepoGroupToPerm.group.group_name
507 rg_k = perm.UserRepoGroupToPerm.group.group_name
505 p = perm.Permission.permission_name
508 p = perm.Permission.permission_name
506 cur_perm = user.permissions[GK][rg_k]
509 cur_perm = user.permissions[GK][rg_k]
507 if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]:
510 if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]:
508 user.permissions[GK][rg_k] = p
511 user.permissions[GK][rg_k] = p
509
512
510 return user
513 return user
511
514
512 def has_perm(self, user, perm):
515 def has_perm(self, user, perm):
513 if not isinstance(perm, Permission):
516 if not isinstance(perm, Permission):
514 raise Exception('perm needs to be an instance of Permission class '
517 raise Exception('perm needs to be an instance of Permission class '
515 'got %s instead' % type(perm))
518 'got %s instead' % type(perm))
516
519
517 user = self.__get_user(user)
520 user = self.__get_user(user)
518
521
519 return UserToPerm.query().filter(UserToPerm.user == user)\
522 return UserToPerm.query().filter(UserToPerm.user == user)\
520 .filter(UserToPerm.permission == perm).scalar() is not None
523 .filter(UserToPerm.permission == perm).scalar() is not None
521
524
522 def grant_perm(self, user, perm):
525 def grant_perm(self, user, perm):
523 """
526 """
524 Grant user global permissions
527 Grant user global permissions
525
528
526 :param user:
529 :param user:
527 :param perm:
530 :param perm:
528 """
531 """
529 user = self.__get_user(user)
532 user = self.__get_user(user)
530 perm = self.__get_perm(perm)
533 perm = self.__get_perm(perm)
531 new = UserToPerm()
534 new = UserToPerm()
532 new.user = user
535 new.user = user
533 new.permission = perm
536 new.permission = perm
534 self.sa.add(new)
537 self.sa.add(new)
535
538
536 def revoke_perm(self, user, perm):
539 def revoke_perm(self, user, perm):
537 """
540 """
538 Revoke users global permissions
541 Revoke users global permissions
539
542
540 :param user:
543 :param user:
541 :param perm:
544 :param perm:
542 """
545 """
543 user = self.__get_user(user)
546 user = self.__get_user(user)
544 perm = self.__get_perm(perm)
547 perm = self.__get_perm(perm)
545
548
546 obj = UserToPerm.query().filter(UserToPerm.user == user)\
549 obj = UserToPerm.query().filter(UserToPerm.user == user)\
547 .filter(UserToPerm.permission == perm).scalar()
550 .filter(UserToPerm.permission == perm).scalar()
548 if obj:
551 if obj:
549 self.sa.delete(obj)
552 self.sa.delete(obj)
General Comments 0
You need to be logged in to leave comments. Login now