##// END OF EJS Templates
enabled grant/revoke api functions for users and users groups
marcink -
r2004:f2b7bebc beta
parent child Browse files
Show More
@@ -1,655 +1,655
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 95 if user is None:
96 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
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 if User.get_by_username(username):
150 150 raise JSONRPCError("user %s already exist" % username)
151 151
152 152 try:
153 153 usr = UserModel().create_or_update(
154 154 username, password, email, firstname,
155 155 lastname, active, admin, ldap_dn
156 156 )
157 157 Session.commit()
158 158 return dict(
159 159 id=usr.user_id,
160 160 msg='created new user %s' % username
161 161 )
162 162 except Exception:
163 163 log.error(traceback.format_exc())
164 164 raise JSONRPCError('failed to create user %s' % username)
165 165
166 166 @HasPermissionAllDecorator('hg.admin')
167 167 def update_user(self, apiuser, username, password, email, firstname=None,
168 168 lastname=None, active=True, admin=False, ldap_dn=None):
169 169 """
170 170 Updates given user
171 171
172 172 :param apiuser:
173 173 :param username:
174 174 :param password:
175 175 :param email:
176 176 :param name:
177 177 :param lastname:
178 178 :param active:
179 179 :param admin:
180 180 :param ldap_dn:
181 181 """
182 182 if not User.get_by_username(username):
183 183 raise JSONRPCError("user %s does not exist" % username)
184 184
185 185 try:
186 186 usr = UserModel().create_or_update(
187 187 username, password, email, firstname,
188 188 lastname, active, admin, ldap_dn
189 189 )
190 190 Session.commit()
191 191 return dict(
192 192 id=usr.user_id,
193 193 msg='updated user %s' % username
194 194 )
195 195 except Exception:
196 196 log.error(traceback.format_exc())
197 197 raise JSONRPCError('failed to update user %s' % username)
198 198
199 199 @HasPermissionAllDecorator('hg.admin')
200 200 def get_users_group(self, apiuser, group_name):
201 201 """"
202 202 Get users group by name
203 203
204 204 :param apiuser:
205 205 :param group_name:
206 206 """
207 207
208 208 users_group = UsersGroup.get_by_group_name(group_name)
209 209 if not users_group:
210 210 return None
211 211
212 212 members = []
213 213 for user in users_group.members:
214 214 user = user.user
215 215 members.append(dict(id=user.user_id,
216 216 username=user.username,
217 217 firstname=user.name,
218 218 lastname=user.lastname,
219 219 email=user.email,
220 220 active=user.active,
221 221 admin=user.admin,
222 222 ldap=user.ldap_dn))
223 223
224 224 return dict(id=users_group.users_group_id,
225 225 group_name=users_group.users_group_name,
226 226 active=users_group.users_group_active,
227 227 members=members)
228 228
229 229 @HasPermissionAllDecorator('hg.admin')
230 230 def get_users_groups(self, apiuser):
231 231 """"
232 232 Get all users groups
233 233
234 234 :param apiuser:
235 235 """
236 236
237 237 result = []
238 238 for users_group in UsersGroup.getAll():
239 239 members = []
240 240 for user in users_group.members:
241 241 user = user.user
242 242 members.append(dict(id=user.user_id,
243 243 username=user.username,
244 244 firstname=user.name,
245 245 lastname=user.lastname,
246 246 email=user.email,
247 247 active=user.active,
248 248 admin=user.admin,
249 249 ldap=user.ldap_dn))
250 250
251 251 result.append(dict(id=users_group.users_group_id,
252 252 group_name=users_group.users_group_name,
253 253 active=users_group.users_group_active,
254 254 members=members))
255 255 return result
256 256
257 257 @HasPermissionAllDecorator('hg.admin')
258 258 def create_users_group(self, apiuser, group_name, active=True):
259 259 """
260 260 Creates an new usergroup
261 261
262 262 :param group_name:
263 263 :param active:
264 264 """
265 265
266 266 if self.get_users_group(apiuser, group_name):
267 267 raise JSONRPCError("users group %s already exist" % group_name)
268 268
269 269 try:
270 270 ug = UsersGroupModel().create(name=group_name, active=active)
271 271 Session.commit()
272 272 return dict(id=ug.users_group_id,
273 273 msg='created new users group %s' % group_name)
274 274 except Exception:
275 275 log.error(traceback.format_exc())
276 276 raise JSONRPCError('failed to create group %s' % group_name)
277 277
278 278 @HasPermissionAllDecorator('hg.admin')
279 279 def add_user_to_users_group(self, apiuser, group_name, username):
280 280 """"
281 281 Add a user to a group
282 282
283 283 :param apiuser:
284 284 :param group_name:
285 285 :param username:
286 286 """
287 287
288 288 try:
289 289 users_group = UsersGroup.get_by_group_name(group_name)
290 290 if not users_group:
291 291 raise JSONRPCError('unknown users group %s' % group_name)
292 292
293 293 user = User.get_by_username(username)
294 294 if user is None:
295 295 raise JSONRPCError('unknown user %s' % username)
296 296
297 297 ugm = UsersGroupModel().add_user_to_group(users_group, user)
298 298 success = True if ugm != True else False
299 299 msg = 'added member %s to users group %s' % (username, group_name)
300 300 msg = msg if success else 'User is already in that group'
301 301 Session.commit()
302 302
303 303 return dict(
304 304 id=ugm.users_group_member_id if ugm != True else None,
305 305 success=success,
306 306 msg=msg
307 307 )
308 308 except Exception:
309 309 log.error(traceback.format_exc())
310 310 raise JSONRPCError('failed to add users group member')
311 311
312 312 @HasPermissionAllDecorator('hg.admin')
313 313 def remove_user_from_users_group(self, apiuser, group_name, username):
314 314 """
315 315 Remove user from a group
316 316
317 317 :param apiuser
318 318 :param group_name
319 319 :param username
320 320 """
321 321
322 322 try:
323 323 users_group = UsersGroup.get_by_group_name(group_name)
324 324 if not users_group:
325 325 raise JSONRPCError('unknown users group %s' % group_name)
326 326
327 327 user = User.get_by_username(username)
328 328 if user is None:
329 329 raise JSONRPCError('unknown user %s' % username)
330 330
331 331 success = UsersGroupModel().remove_user_from_group(users_group, user)
332 332 msg = 'removed member %s from users group %s' % (username, group_name)
333 333 msg = msg if success else "User wasn't in group"
334 334 Session.commit()
335 335 return dict(success=success, msg=msg)
336 336 except Exception:
337 337 log.error(traceback.format_exc())
338 338 raise JSONRPCError('failed to remove user from group')
339 339
340 340 @HasPermissionAnyDecorator('hg.admin')
341 341 def get_repo(self, apiuser, repo_name):
342 342 """"
343 343 Get repository by name
344 344
345 345 :param apiuser:
346 346 :param repo_name:
347 347 """
348 348
349 349 repo = Repository.get_by_repo_name(repo_name)
350 350 if repo is None:
351 351 raise JSONRPCError('unknown repository %s' % repo)
352 352
353 353 members = []
354 354 for user in repo.repo_to_perm:
355 355 perm = user.permission.permission_name
356 356 user = user.user
357 357 members.append(
358 358 dict(
359 359 type_="user",
360 360 id=user.user_id,
361 361 username=user.username,
362 362 firstname=user.name,
363 363 lastname=user.lastname,
364 364 email=user.email,
365 365 active=user.active,
366 366 admin=user.admin,
367 367 ldap=user.ldap_dn,
368 368 permission=perm
369 369 )
370 370 )
371 371 for users_group in repo.users_group_to_perm:
372 372 perm = users_group.permission.permission_name
373 373 users_group = users_group.users_group
374 374 members.append(
375 375 dict(
376 376 type_="users_group",
377 377 id=users_group.users_group_id,
378 378 name=users_group.users_group_name,
379 379 active=users_group.users_group_active,
380 380 permission=perm
381 381 )
382 382 )
383 383
384 384 return dict(
385 385 id=repo.repo_id,
386 386 repo_name=repo.repo_name,
387 387 type=repo.repo_type,
388 388 description=repo.description,
389 389 members=members
390 390 )
391 391
392 392 @HasPermissionAnyDecorator('hg.admin')
393 393 def get_repos(self, apiuser):
394 394 """"
395 395 Get all repositories
396 396
397 397 :param apiuser:
398 398 """
399 399
400 400 result = []
401 401 for repository in Repository.getAll():
402 402 result.append(
403 403 dict(
404 404 id=repository.repo_id,
405 405 repo_name=repository.repo_name,
406 406 type=repository.repo_type,
407 407 description=repository.description
408 408 )
409 409 )
410 410 return result
411 411
412 412 @HasPermissionAnyDecorator('hg.admin')
413 413 def get_repo_nodes(self, apiuser, repo_name, revision, root_path,
414 414 ret_type='all'):
415 415 """
416 416 returns a list of nodes and it's children
417 417 for a given path at given revision. It's possible to specify ret_type
418 418 to show only files or dirs
419 419
420 420 :param apiuser:
421 421 :param repo_name: name of repository
422 422 :param revision: revision for which listing should be done
423 423 :param root_path: path from which start displaying
424 424 :param ret_type: return type 'all|files|dirs' nodes
425 425 """
426 426 try:
427 427 _d, _f = ScmModel().get_nodes(repo_name, revision, root_path,
428 428 flat=False)
429 429 _map = {
430 430 'all': _d + _f,
431 431 'files': _f,
432 432 'dirs': _d,
433 433 }
434 434 return _map[ret_type]
435 435 except KeyError:
436 436 raise JSONRPCError('ret_type must be one of %s' % _map.keys())
437 437 except Exception, e:
438 438 raise JSONRPCError(e)
439 439
440 440 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
441 441 def create_repo(self, apiuser, repo_name, owner_name, description='',
442 442 repo_type='hg', private=False):
443 443 """
444 444 Create a repository
445 445
446 446 :param apiuser:
447 447 :param repo_name:
448 448 :param description:
449 449 :param type:
450 450 :param private:
451 451 :param owner_name:
452 452 """
453 453
454 454 try:
455 455 owner = User.get_by_username(owner_name)
456 456 if owner is None:
457 457 raise JSONRPCError('unknown user %s' % owner_name)
458 458
459 459 if Repository.get_by_repo_name(repo_name):
460 460 raise JSONRPCError("repo %s already exist" % repo_name)
461 461
462 462 groups = repo_name.split('/')
463 463 real_name = groups[-1]
464 464 groups = groups[:-1]
465 465 parent_id = None
466 466 for g in groups:
467 467 group = RepoGroup.get_by_group_name(g)
468 468 if not group:
469 469 group = ReposGroupModel().create(g, '', parent_id)
470 470 parent_id = group.group_id
471 471
472 472 repo = RepoModel().create(
473 473 dict(
474 474 repo_name=real_name,
475 475 repo_name_full=repo_name,
476 476 description=description,
477 477 private=private,
478 478 repo_type=repo_type,
479 479 repo_group=parent_id,
480 480 clone_uri=None
481 481 ),
482 482 owner
483 483 )
484 484 Session.commit()
485 485
486 486 return dict(
487 487 id=repo.repo_id,
488 488 msg="Created new repository %s" % repo.repo_name
489 489 )
490 490
491 491 except Exception:
492 492 log.error(traceback.format_exc())
493 493 raise JSONRPCError('failed to create repository %s' % repo_name)
494 494
495 495 @HasPermissionAnyDecorator('hg.admin')
496 496 def delete_repo(self, apiuser, repo_name):
497 497 """
498 498 Deletes a given repository
499 499
500 500 :param repo_name:
501 501 """
502 502 if not Repository.get_by_repo_name(repo_name):
503 503 raise JSONRPCError("repo %s does not exist" % repo_name)
504 504 try:
505 505 RepoModel().delete(repo_name)
506 506 Session.commit()
507 507 return dict(
508 508 msg='Deleted repository %s' % repo_name
509 509 )
510 510 except Exception:
511 511 log.error(traceback.format_exc())
512 512 raise JSONRPCError('failed to delete repository %s' % repo_name)
513 513
514 514 @HasPermissionAnyDecorator('hg.admin')
515 def grant_user_permission(self, repo_name, username, perm):
515 def grant_user_permission(self, apiuser, repo_name, username, perm):
516 516 """
517 517 Grant permission for user on given repository, or update existing one
518 518 if found
519 519
520 520 :param repo_name:
521 521 :param username:
522 522 :param perm:
523 523 """
524 524
525 525 try:
526 526 repo = Repository.get_by_repo_name(repo_name)
527 527 if repo is None:
528 528 raise JSONRPCError('unknown repository %s' % repo)
529 529
530 530 user = User.get_by_username(username)
531 531 if user is None:
532 532 raise JSONRPCError('unknown user %s' % username)
533 533
534 534 RepoModel().grant_user_permission(repo=repo, user=user, perm=perm)
535 535
536 536 Session.commit()
537 537 return dict(
538 538 msg='Granted perm: %s for user: %s in repo: %s' % (
539 539 perm, username, repo_name
540 540 )
541 541 )
542 542 except Exception:
543 543 log.error(traceback.format_exc())
544 544 raise JSONRPCError(
545 545 'failed to edit permission %(repo)s for %(user)s' % dict(
546 546 user=username, repo=repo_name
547 547 )
548 548 )
549 549
550 550 @HasPermissionAnyDecorator('hg.admin')
551 def revoke_user_permission(self, repo_name, username):
551 def revoke_user_permission(self, apiuser, repo_name, username):
552 552 """
553 553 Revoke permission for user on given repository
554 554
555 555 :param repo_name:
556 556 :param username:
557 557 """
558 558
559 559 try:
560 560 repo = Repository.get_by_repo_name(repo_name)
561 561 if repo is None:
562 562 raise JSONRPCError('unknown repository %s' % repo)
563 563
564 564 user = User.get_by_username(username)
565 565 if user is None:
566 566 raise JSONRPCError('unknown user %s' % username)
567 567
568 568 RepoModel().revoke_user_permission(repo=repo_name, user=username)
569 569
570 570 Session.commit()
571 571 return dict(
572 572 msg='Revoked perm for user: %s in repo: %s' % (
573 573 username, repo_name
574 574 )
575 575 )
576 576 except Exception:
577 577 log.error(traceback.format_exc())
578 578 raise JSONRPCError(
579 579 'failed to edit permission %(repo)s for %(user)s' % dict(
580 580 user=username, repo=repo_name
581 581 )
582 582 )
583 583
584 584 @HasPermissionAnyDecorator('hg.admin')
585 def grant_users_group_permission(self, repo_name, group_name, perm):
585 def grant_users_group_permission(self, apiuser, repo_name, group_name, perm):
586 586 """
587 587 Grant permission for users group on given repository, or update
588 588 existing one if found
589 589
590 590 :param repo_name:
591 591 :param group_name:
592 592 :param perm:
593 593 """
594 594
595 595 try:
596 596 repo = Repository.get_by_repo_name(repo_name)
597 597 if repo is None:
598 598 raise JSONRPCError('unknown repository %s' % repo)
599 599
600 600 user_group = UsersGroup.get_by_group_name(group_name)
601 601 if user_group is None:
602 602 raise JSONRPCError('unknown users group %s' % user_group)
603 603
604 604 RepoModel().grant_users_group_permission(repo=repo_name,
605 605 group_name=group_name,
606 606 perm=perm)
607 607
608 608 Session.commit()
609 609 return dict(
610 610 msg='Granted perm: %s for group: %s in repo: %s' % (
611 611 perm, group_name, repo_name
612 612 )
613 613 )
614 614 except Exception:
615 615 log.error(traceback.format_exc())
616 616 raise JSONRPCError(
617 617 'failed to edit permission %(repo)s for %(usersgr)s' % dict(
618 618 usersgr=group_name, repo=repo_name
619 619 )
620 620 )
621 621
622 622 @HasPermissionAnyDecorator('hg.admin')
623 def revoke_users_group_permission(self, repo_name, group_name):
623 def revoke_users_group_permission(self, apiuser, repo_name, group_name):
624 624 """
625 625 Revoke permission for users group on given repository
626 626
627 627 :param repo_name:
628 628 :param group_name:
629 629 """
630 630
631 631 try:
632 632 repo = Repository.get_by_repo_name(repo_name)
633 633 if repo is None:
634 634 raise JSONRPCError('unknown repository %s' % repo)
635 635
636 636 user_group = UsersGroup.get_by_group_name(group_name)
637 637 if user_group is None:
638 638 raise JSONRPCError('unknown users group %s' % user_group)
639 639
640 640 RepoModel().revoke_users_group_permission(repo=repo_name,
641 641 group_name=group_name)
642 642
643 643 Session.commit()
644 644 return dict(
645 645 msg='Revoked perm for group: %s in repo: %s' % (
646 646 group_name, repo_name
647 647 )
648 648 )
649 649 except Exception:
650 650 log.error(traceback.format_exc())
651 651 raise JSONRPCError(
652 652 'failed to edit permission %(repo)s for %(usersgr)s' % dict(
653 653 usersgr=group_name, repo=repo_name
654 654 )
655 655 )
General Comments 0
You need to be logged in to leave comments. Login now