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