##// END OF EJS Templates
Added repository followers to the get_repo api function result.
aparkar -
r3195:a50901f2 beta
parent child Browse files
Show More
@@ -1,927 +1,932 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 from pylons.controllers.util import abort
31 31
32 32 from rhodecode.controllers.api import JSONRPCController, JSONRPCError
33 33 from rhodecode.lib.auth import PasswordGenerator, AuthUser, \
34 34 HasPermissionAllDecorator, HasPermissionAnyDecorator, \
35 35 HasPermissionAnyApi, HasRepoPermissionAnyApi
36 36 from rhodecode.lib.utils import map_groups, repo2db_mapper
37 37 from rhodecode.model.meta import Session
38 38 from rhodecode.model.scm import ScmModel
39 39 from rhodecode.model.repo import RepoModel
40 40 from rhodecode.model.user import UserModel
41 41 from rhodecode.model.users_group import UsersGroupModel
42 42 from rhodecode.model.permission import PermissionModel
43 43 from rhodecode.model.db import Repository, RhodeCodeSetting, UserIpMap
44 44
45 45 log = logging.getLogger(__name__)
46 46
47 47
48 48 class OptionalAttr(object):
49 49 """
50 50 Special Optional Option that defines other attribute
51 51 """
52 52 def __init__(self, attr_name):
53 53 self.attr_name = attr_name
54 54
55 55 def __repr__(self):
56 56 return '<OptionalAttr:%s>' % self.attr_name
57 57
58 58 def __call__(self):
59 59 return self
60 60 #alias
61 61 OAttr = OptionalAttr
62 62
63 63
64 64 class Optional(object):
65 65 """
66 66 Defines an optional parameter::
67 67
68 68 param = param.getval() if isinstance(param, Optional) else param
69 69 param = param() if isinstance(param, Optional) else param
70 70
71 71 is equivalent of::
72 72
73 73 param = Optional.extract(param)
74 74
75 75 """
76 76 def __init__(self, type_):
77 77 self.type_ = type_
78 78
79 79 def __repr__(self):
80 80 return '<Optional:%s>' % self.type_.__repr__()
81 81
82 82 def __call__(self):
83 83 return self.getval()
84 84
85 85 def getval(self):
86 86 """
87 87 returns value from this Optional instance
88 88 """
89 89 return self.type_
90 90
91 91 @classmethod
92 92 def extract(cls, val):
93 93 if isinstance(val, cls):
94 94 return val.getval()
95 95 return val
96 96
97 97
98 98 def get_user_or_error(userid):
99 99 """
100 100 Get user by id or name or return JsonRPCError if not found
101 101
102 102 :param userid:
103 103 """
104 104 user = UserModel().get_user(userid)
105 105 if user is None:
106 106 raise JSONRPCError("user `%s` does not exist" % userid)
107 107 return user
108 108
109 109
110 110 def get_repo_or_error(repoid):
111 111 """
112 112 Get repo by id or name or return JsonRPCError if not found
113 113
114 114 :param userid:
115 115 """
116 116 repo = RepoModel().get_repo(repoid)
117 117 if repo is None:
118 118 raise JSONRPCError('repository `%s` does not exist' % (repoid))
119 119 return repo
120 120
121 121
122 122 def get_users_group_or_error(usersgroupid):
123 123 """
124 124 Get users group by id or name or return JsonRPCError if not found
125 125
126 126 :param userid:
127 127 """
128 128 users_group = UsersGroupModel().get_group(usersgroupid)
129 129 if users_group is None:
130 130 raise JSONRPCError('users group `%s` does not exist' % usersgroupid)
131 131 return users_group
132 132
133 133
134 134 def get_perm_or_error(permid):
135 135 """
136 136 Get permission by id or name or return JsonRPCError if not found
137 137
138 138 :param userid:
139 139 """
140 140 perm = PermissionModel().get_permission_by_name(permid)
141 141 if perm is None:
142 142 raise JSONRPCError('permission `%s` does not exist' % (permid))
143 143 return perm
144 144
145 145
146 146 class ApiController(JSONRPCController):
147 147 """
148 148 API Controller
149 149
150 150
151 151 Each method needs to have USER as argument this is then based on given
152 152 API_KEY propagated as instance of user object
153 153
154 154 Preferably this should be first argument also
155 155
156 156
157 157 Each function should also **raise** JSONRPCError for any
158 158 errors that happens
159 159
160 160 """
161 161
162 162 @HasPermissionAllDecorator('hg.admin')
163 163 def pull(self, apiuser, repoid):
164 164 """
165 165 Dispatch pull action on given repo
166 166
167 167 :param apiuser:
168 168 :param repoid:
169 169 """
170 170
171 171 repo = get_repo_or_error(repoid)
172 172
173 173 try:
174 174 ScmModel().pull_changes(repo.repo_name,
175 175 self.rhodecode_user.username)
176 176 return 'Pulled from `%s`' % repo.repo_name
177 177 except Exception:
178 178 log.error(traceback.format_exc())
179 179 raise JSONRPCError(
180 180 'Unable to pull changes from `%s`' % repo.repo_name
181 181 )
182 182
183 183 @HasPermissionAllDecorator('hg.admin')
184 184 def rescan_repos(self, apiuser, remove_obsolete=Optional(False)):
185 185 """
186 186 Dispatch rescan repositories action. If remove_obsolete is set
187 187 than also delete repos that are in database but not in the filesystem.
188 188 aka "clean zombies"
189 189
190 190 :param apiuser:
191 191 :param remove_obsolete:
192 192 """
193 193
194 194 try:
195 195 rm_obsolete = Optional.extract(remove_obsolete)
196 196 added, removed = repo2db_mapper(ScmModel().repo_scan(),
197 197 remove_obsolete=rm_obsolete)
198 198 return {'added': added, 'removed': removed}
199 199 except Exception:
200 200 log.error(traceback.format_exc())
201 201 raise JSONRPCError(
202 202 'Error occurred during rescan repositories action'
203 203 )
204 204
205 205 def lock(self, apiuser, repoid, locked, userid=Optional(OAttr('apiuser'))):
206 206 """
207 207 Set locking state on particular repository by given user, if
208 208 this command is runned by non-admin account userid is set to user
209 209 who is calling this method
210 210
211 211 :param apiuser:
212 212 :param repoid:
213 213 :param userid:
214 214 :param locked:
215 215 """
216 216 repo = get_repo_or_error(repoid)
217 217 if HasPermissionAnyApi('hg.admin')(user=apiuser):
218 218 pass
219 219 elif HasRepoPermissionAnyApi('repository.admin',
220 220 'repository.write')(user=apiuser,
221 221 repo_name=repo.repo_name):
222 222 #make sure normal user does not pass someone else userid,
223 223 #he is not allowed to do that
224 224 if not isinstance(userid, Optional) and userid != apiuser.user_id:
225 225 raise JSONRPCError(
226 226 'userid is not the same as your user'
227 227 )
228 228 else:
229 229 raise JSONRPCError('repository `%s` does not exist' % (repoid))
230 230
231 231 if isinstance(userid, Optional):
232 232 userid = apiuser.user_id
233 233 user = get_user_or_error(userid)
234 234 locked = bool(locked)
235 235 try:
236 236 if locked:
237 237 Repository.lock(repo, user.user_id)
238 238 else:
239 239 Repository.unlock(repo)
240 240
241 241 return ('User `%s` set lock state for repo `%s` to `%s`'
242 242 % (user.username, repo.repo_name, locked))
243 243 except Exception:
244 244 log.error(traceback.format_exc())
245 245 raise JSONRPCError(
246 246 'Error occurred locking repository `%s`' % repo.repo_name
247 247 )
248 248
249 249 @HasPermissionAllDecorator('hg.admin')
250 250 def show_ip(self, apiuser, userid):
251 251 """
252 252 Shows IP address as seen from RhodeCode server, together with all
253 253 defined IP addresses for given user
254 254
255 255 :param apiuser:
256 256 :param userid:
257 257 """
258 258 user = get_user_or_error(userid)
259 259 ips = UserIpMap.query().filter(UserIpMap.user == user).all()
260 260 return dict(
261 261 ip_addr_server=self.ip_addr,
262 262 user_ips=ips
263 263 )
264 264
265 265 def get_user(self, apiuser, userid=Optional(OAttr('apiuser'))):
266 266 """"
267 267 Get a user by username, or userid, if userid is given
268 268
269 269 :param apiuser:
270 270 :param userid:
271 271 """
272 272 if HasPermissionAnyApi('hg.admin')(user=apiuser) is False:
273 273 #make sure normal user does not pass someone else userid,
274 274 #he is not allowed to do that
275 275 if not isinstance(userid, Optional) and userid != apiuser.user_id:
276 276 raise JSONRPCError(
277 277 'userid is not the same as your user'
278 278 )
279 279
280 280 if isinstance(userid, Optional):
281 281 userid = apiuser.user_id
282 282
283 283 user = get_user_or_error(userid)
284 284 data = user.get_api_data()
285 285 data['permissions'] = AuthUser(user_id=user.user_id).permissions
286 286 return data
287 287
288 288 @HasPermissionAllDecorator('hg.admin')
289 289 def get_users(self, apiuser):
290 290 """"
291 291 Get all users
292 292
293 293 :param apiuser:
294 294 """
295 295
296 296 result = []
297 297 for user in UserModel().get_all():
298 298 result.append(user.get_api_data())
299 299 return result
300 300
301 301 @HasPermissionAllDecorator('hg.admin')
302 302 def create_user(self, apiuser, username, email, password,
303 303 firstname=Optional(None), lastname=Optional(None),
304 304 active=Optional(True), admin=Optional(False),
305 305 ldap_dn=Optional(None)):
306 306 """
307 307 Create new user
308 308
309 309 :param apiuser:
310 310 :param username:
311 311 :param email:
312 312 :param password:
313 313 :param firstname:
314 314 :param lastname:
315 315 :param active:
316 316 :param admin:
317 317 :param ldap_dn:
318 318 """
319 319
320 320 if UserModel().get_by_username(username):
321 321 raise JSONRPCError("user `%s` already exist" % username)
322 322
323 323 if UserModel().get_by_email(email, case_insensitive=True):
324 324 raise JSONRPCError("email `%s` already exist" % email)
325 325
326 326 if Optional.extract(ldap_dn):
327 327 # generate temporary password if ldap_dn
328 328 password = PasswordGenerator().gen_password(length=8)
329 329
330 330 try:
331 331 user = UserModel().create_or_update(
332 332 username=Optional.extract(username),
333 333 password=Optional.extract(password),
334 334 email=Optional.extract(email),
335 335 firstname=Optional.extract(firstname),
336 336 lastname=Optional.extract(lastname),
337 337 active=Optional.extract(active),
338 338 admin=Optional.extract(admin),
339 339 ldap_dn=Optional.extract(ldap_dn)
340 340 )
341 341 Session().commit()
342 342 return dict(
343 343 msg='created new user `%s`' % username,
344 344 user=user.get_api_data()
345 345 )
346 346 except Exception:
347 347 log.error(traceback.format_exc())
348 348 raise JSONRPCError('failed to create user `%s`' % username)
349 349
350 350 @HasPermissionAllDecorator('hg.admin')
351 351 def update_user(self, apiuser, userid, username=Optional(None),
352 352 email=Optional(None), firstname=Optional(None),
353 353 lastname=Optional(None), active=Optional(None),
354 354 admin=Optional(None), ldap_dn=Optional(None),
355 355 password=Optional(None)):
356 356 """
357 357 Updates given user
358 358
359 359 :param apiuser:
360 360 :param userid:
361 361 :param username:
362 362 :param email:
363 363 :param firstname:
364 364 :param lastname:
365 365 :param active:
366 366 :param admin:
367 367 :param ldap_dn:
368 368 :param password:
369 369 """
370 370
371 371 user = get_user_or_error(userid)
372 372
373 373 # call function and store only updated arguments
374 374 updates = {}
375 375
376 376 def store_update(attr, name):
377 377 if not isinstance(attr, Optional):
378 378 updates[name] = attr
379 379
380 380 try:
381 381
382 382 store_update(username, 'username')
383 383 store_update(password, 'password')
384 384 store_update(email, 'email')
385 385 store_update(firstname, 'name')
386 386 store_update(lastname, 'lastname')
387 387 store_update(active, 'active')
388 388 store_update(admin, 'admin')
389 389 store_update(ldap_dn, 'ldap_dn')
390 390
391 391 user = UserModel().update_user(user, **updates)
392 392 Session().commit()
393 393 return dict(
394 394 msg='updated user ID:%s %s' % (user.user_id, user.username),
395 395 user=user.get_api_data()
396 396 )
397 397 except Exception:
398 398 log.error(traceback.format_exc())
399 399 raise JSONRPCError('failed to update user `%s`' % userid)
400 400
401 401 @HasPermissionAllDecorator('hg.admin')
402 402 def delete_user(self, apiuser, userid):
403 403 """"
404 404 Deletes an user
405 405
406 406 :param apiuser:
407 407 :param userid:
408 408 """
409 409 user = get_user_or_error(userid)
410 410
411 411 try:
412 412 UserModel().delete(userid)
413 413 Session().commit()
414 414 return dict(
415 415 msg='deleted user ID:%s %s' % (user.user_id, user.username),
416 416 user=None
417 417 )
418 418 except Exception:
419 419 log.error(traceback.format_exc())
420 420 raise JSONRPCError('failed to delete ID:%s %s' % (user.user_id,
421 421 user.username))
422 422
423 423 @HasPermissionAllDecorator('hg.admin')
424 424 def get_users_group(self, apiuser, usersgroupid):
425 425 """"
426 426 Get users group by name or id
427 427
428 428 :param apiuser:
429 429 :param usersgroupid:
430 430 """
431 431 users_group = get_users_group_or_error(usersgroupid)
432 432
433 433 data = users_group.get_api_data()
434 434
435 435 members = []
436 436 for user in users_group.members:
437 437 user = user.user
438 438 members.append(user.get_api_data())
439 439 data['members'] = members
440 440 return data
441 441
442 442 @HasPermissionAllDecorator('hg.admin')
443 443 def get_users_groups(self, apiuser):
444 444 """"
445 445 Get all users groups
446 446
447 447 :param apiuser:
448 448 """
449 449
450 450 result = []
451 451 for users_group in UsersGroupModel().get_all():
452 452 result.append(users_group.get_api_data())
453 453 return result
454 454
455 455 @HasPermissionAllDecorator('hg.admin')
456 456 def create_users_group(self, apiuser, group_name, active=Optional(True)):
457 457 """
458 458 Creates an new usergroup
459 459
460 460 :param apiuser:
461 461 :param group_name:
462 462 :param active:
463 463 """
464 464
465 465 if UsersGroupModel().get_by_name(group_name):
466 466 raise JSONRPCError("users group `%s` already exist" % group_name)
467 467
468 468 try:
469 469 active = Optional.extract(active)
470 470 ug = UsersGroupModel().create(name=group_name, active=active)
471 471 Session().commit()
472 472 return dict(
473 473 msg='created new users group `%s`' % group_name,
474 474 users_group=ug.get_api_data()
475 475 )
476 476 except Exception:
477 477 log.error(traceback.format_exc())
478 478 raise JSONRPCError('failed to create group `%s`' % group_name)
479 479
480 480 @HasPermissionAllDecorator('hg.admin')
481 481 def add_user_to_users_group(self, apiuser, usersgroupid, userid):
482 482 """"
483 483 Add a user to a users group
484 484
485 485 :param apiuser:
486 486 :param usersgroupid:
487 487 :param userid:
488 488 """
489 489 user = get_user_or_error(userid)
490 490 users_group = get_users_group_or_error(usersgroupid)
491 491
492 492 try:
493 493 ugm = UsersGroupModel().add_user_to_group(users_group, user)
494 494 success = True if ugm != True else False
495 495 msg = 'added member `%s` to users group `%s`' % (
496 496 user.username, users_group.users_group_name
497 497 )
498 498 msg = msg if success else 'User is already in that group'
499 499 Session().commit()
500 500
501 501 return dict(
502 502 success=success,
503 503 msg=msg
504 504 )
505 505 except Exception:
506 506 log.error(traceback.format_exc())
507 507 raise JSONRPCError(
508 508 'failed to add member to users group `%s`' % (
509 509 users_group.users_group_name
510 510 )
511 511 )
512 512
513 513 @HasPermissionAllDecorator('hg.admin')
514 514 def remove_user_from_users_group(self, apiuser, usersgroupid, userid):
515 515 """
516 516 Remove user from a group
517 517
518 518 :param apiuser:
519 519 :param usersgroupid:
520 520 :param userid:
521 521 """
522 522 user = get_user_or_error(userid)
523 523 users_group = get_users_group_or_error(usersgroupid)
524 524
525 525 try:
526 526 success = UsersGroupModel().remove_user_from_group(users_group,
527 527 user)
528 528 msg = 'removed member `%s` from users group `%s`' % (
529 529 user.username, users_group.users_group_name
530 530 )
531 531 msg = msg if success else "User wasn't in group"
532 532 Session().commit()
533 533 return dict(success=success, msg=msg)
534 534 except Exception:
535 535 log.error(traceback.format_exc())
536 536 raise JSONRPCError(
537 537 'failed to remove member from users group `%s`' % (
538 538 users_group.users_group_name
539 539 )
540 540 )
541 541
542 542 def get_repo(self, apiuser, repoid):
543 543 """"
544 544 Get repository by name
545 545
546 546 :param apiuser:
547 547 :param repoid:
548 548 """
549 549 repo = get_repo_or_error(repoid)
550 550
551 551 if HasPermissionAnyApi('hg.admin')(user=apiuser) is False:
552 552 # check if we have admin permission for this repo !
553 553 if HasRepoPermissionAnyApi('repository.admin')(user=apiuser,
554 554 repo_name=repo.repo_name) is False:
555 555 raise JSONRPCError('repository `%s` does not exist' % (repoid))
556 556
557 557 members = []
558 followers = []
558 559 for user in repo.repo_to_perm:
559 560 perm = user.permission.permission_name
560 561 user = user.user
561 562 user_data = user.get_api_data()
562 563 user_data['type'] = "user"
563 564 user_data['permission'] = perm
564 565 members.append(user_data)
565 566
566 567 for users_group in repo.users_group_to_perm:
567 568 perm = users_group.permission.permission_name
568 569 users_group = users_group.users_group
569 570 users_group_data = users_group.get_api_data()
570 571 users_group_data['type'] = "users_group"
571 572 users_group_data['permission'] = perm
572 573 members.append(users_group_data)
573 574
575 for user in repo.followers:
576 followers.append(user.user.get_api_data())
577
574 578 data = repo.get_api_data()
575 579 data['members'] = members
580 data['followers'] = followers
576 581 return data
577 582
578 583 def get_repos(self, apiuser):
579 584 """"
580 585 Get all repositories
581 586
582 587 :param apiuser:
583 588 """
584 589 result = []
585 590 if HasPermissionAnyApi('hg.admin')(user=apiuser) is False:
586 591 repos = RepoModel().get_all_user_repos(user=apiuser)
587 592 else:
588 593 repos = RepoModel().get_all()
589 594
590 595 for repo in repos:
591 596 result.append(repo.get_api_data())
592 597 return result
593 598
594 599 @HasPermissionAllDecorator('hg.admin')
595 600 def get_repo_nodes(self, apiuser, repoid, revision, root_path,
596 601 ret_type='all'):
597 602 """
598 603 returns a list of nodes and it's children
599 604 for a given path at given revision. It's possible to specify ret_type
600 605 to show only files or dirs
601 606
602 607 :param apiuser:
603 608 :param repoid: name or id of repository
604 609 :param revision: revision for which listing should be done
605 610 :param root_path: path from which start displaying
606 611 :param ret_type: return type 'all|files|dirs' nodes
607 612 """
608 613 repo = get_repo_or_error(repoid)
609 614 try:
610 615 _d, _f = ScmModel().get_nodes(repo, revision, root_path,
611 616 flat=False)
612 617 _map = {
613 618 'all': _d + _f,
614 619 'files': _f,
615 620 'dirs': _d,
616 621 }
617 622 return _map[ret_type]
618 623 except KeyError:
619 624 raise JSONRPCError('ret_type must be one of %s' % _map.keys())
620 625 except Exception:
621 626 log.error(traceback.format_exc())
622 627 raise JSONRPCError(
623 628 'failed to get repo: `%s` nodes' % repo.repo_name
624 629 )
625 630
626 631 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
627 632 def create_repo(self, apiuser, repo_name, owner=Optional(OAttr('apiuser')),
628 633 repo_type=Optional('hg'),
629 634 description=Optional(''), private=Optional(False),
630 635 clone_uri=Optional(None), landing_rev=Optional('tip'),
631 636 enable_statistics=Optional(False),
632 637 enable_locking=Optional(False),
633 638 enable_downloads=Optional(False)):
634 639 """
635 640 Create repository, if clone_url is given it makes a remote clone
636 641 if repo_name is within a group name the groups will be created
637 642 automatically if they aren't present
638 643
639 644 :param apiuser:
640 645 :param repo_name:
641 646 :param onwer:
642 647 :param repo_type:
643 648 :param description:
644 649 :param private:
645 650 :param clone_uri:
646 651 :param landing_rev:
647 652 """
648 653 if HasPermissionAnyApi('hg.admin')(user=apiuser) is False:
649 654 if not isinstance(owner, Optional):
650 655 #forbid setting owner for non-admins
651 656 raise JSONRPCError(
652 657 'Only RhodeCode admin can specify `owner` param'
653 658 )
654 659 if isinstance(owner, Optional):
655 660 owner = apiuser.user_id
656 661
657 662 owner = get_user_or_error(owner)
658 663
659 664 if RepoModel().get_by_repo_name(repo_name):
660 665 raise JSONRPCError("repo `%s` already exist" % repo_name)
661 666
662 667 defs = RhodeCodeSetting.get_default_repo_settings(strip_prefix=True)
663 668 if isinstance(private, Optional):
664 669 private = defs.get('repo_private') or Optional.extract(private)
665 670 if isinstance(repo_type, Optional):
666 671 repo_type = defs.get('repo_type')
667 672 if isinstance(enable_statistics, Optional):
668 673 enable_statistics = defs.get('repo_enable_statistics')
669 674 if isinstance(enable_locking, Optional):
670 675 enable_locking = defs.get('repo_enable_locking')
671 676 if isinstance(enable_downloads, Optional):
672 677 enable_downloads = defs.get('repo_enable_downloads')
673 678
674 679 clone_uri = Optional.extract(clone_uri)
675 680 description = Optional.extract(description)
676 681 landing_rev = Optional.extract(landing_rev)
677 682
678 683 try:
679 684 # create structure of groups and return the last group
680 685 group = map_groups(repo_name)
681 686
682 687 repo = RepoModel().create_repo(
683 688 repo_name=repo_name,
684 689 repo_type=repo_type,
685 690 description=description,
686 691 owner=owner,
687 692 private=private,
688 693 clone_uri=clone_uri,
689 694 repos_group=group,
690 695 landing_rev=landing_rev,
691 696 enable_statistics=enable_statistics,
692 697 enable_downloads=enable_downloads,
693 698 enable_locking=enable_locking
694 699 )
695 700
696 701 Session().commit()
697 702 return dict(
698 703 msg="Created new repository `%s`" % (repo.repo_name),
699 704 repo=repo.get_api_data()
700 705 )
701 706 except Exception:
702 707 log.error(traceback.format_exc())
703 708 raise JSONRPCError('failed to create repository `%s`' % repo_name)
704 709
705 710 @HasPermissionAnyDecorator('hg.admin', 'hg.fork.repository')
706 711 def fork_repo(self, apiuser, repoid, fork_name, owner=Optional(OAttr('apiuser')),
707 712 description=Optional(''), copy_permissions=Optional(False),
708 713 private=Optional(False), landing_rev=Optional('tip')):
709 714 repo = get_repo_or_error(repoid)
710 715 repo_name = repo.repo_name
711 716
712 717 _repo = RepoModel().get_by_repo_name(fork_name)
713 718 if _repo:
714 719 type_ = 'fork' if _repo.fork else 'repo'
715 720 raise JSONRPCError("%s `%s` already exist" % (type_, fork_name))
716 721
717 722 if HasPermissionAnyApi('hg.admin')(user=apiuser):
718 723 pass
719 724 elif HasRepoPermissionAnyApi('repository.admin',
720 725 'repository.write',
721 726 'repository.read')(user=apiuser,
722 727 repo_name=repo.repo_name):
723 728 if not isinstance(owner, Optional):
724 729 #forbid setting owner for non-admins
725 730 raise JSONRPCError(
726 731 'Only RhodeCode admin can specify `owner` param'
727 732 )
728 733 else:
729 734 raise JSONRPCError('repository `%s` does not exist' % (repoid))
730 735
731 736 if isinstance(owner, Optional):
732 737 owner = apiuser.user_id
733 738
734 739 owner = get_user_or_error(owner)
735 740
736 741 try:
737 742 # create structure of groups and return the last group
738 743 group = map_groups(fork_name)
739 744
740 745 form_data = dict(
741 746 repo_name=fork_name,
742 747 repo_name_full=fork_name,
743 748 repo_group=group,
744 749 repo_type=repo.repo_type,
745 750 description=Optional.extract(description),
746 751 private=Optional.extract(private),
747 752 copy_permissions=Optional.extract(copy_permissions),
748 753 landing_rev=Optional.extract(landing_rev),
749 754 update_after_clone=False,
750 755 fork_parent_id=repo.repo_id,
751 756 )
752 757 RepoModel().create_fork(form_data, cur_user=owner)
753 758 return dict(
754 759 msg='Created fork of `%s` as `%s`' % (repo.repo_name,
755 760 fork_name),
756 761 success=True # cannot return the repo data here since fork
757 762 # cann be done async
758 763 )
759 764 except Exception:
760 765 log.error(traceback.format_exc())
761 766 raise JSONRPCError(
762 767 'failed to fork repository `%s` as `%s`' % (repo_name,
763 768 fork_name)
764 769 )
765 770
766 771 def delete_repo(self, apiuser, repoid):
767 772 """
768 773 Deletes a given repository
769 774
770 775 :param apiuser:
771 776 :param repoid:
772 777 """
773 778 repo = get_repo_or_error(repoid)
774 779
775 780 if HasPermissionAnyApi('hg.admin')(user=apiuser) is False:
776 781 # check if we have admin permission for this repo !
777 782 if HasRepoPermissionAnyApi('repository.admin')(user=apiuser,
778 783 repo_name=repo.repo_name) is False:
779 784 raise JSONRPCError('repository `%s` does not exist' % (repoid))
780 785
781 786 try:
782 787 RepoModel().delete(repo)
783 788 Session().commit()
784 789 return dict(
785 790 msg='Deleted repository `%s`' % repo.repo_name,
786 791 success=True
787 792 )
788 793 except Exception:
789 794 log.error(traceback.format_exc())
790 795 raise JSONRPCError(
791 796 'failed to delete repository `%s`' % repo.repo_name
792 797 )
793 798
794 799 @HasPermissionAllDecorator('hg.admin')
795 800 def grant_user_permission(self, apiuser, repoid, userid, perm):
796 801 """
797 802 Grant permission for user on given repository, or update existing one
798 803 if found
799 804
800 805 :param repoid:
801 806 :param userid:
802 807 :param perm:
803 808 """
804 809 repo = get_repo_or_error(repoid)
805 810 user = get_user_or_error(userid)
806 811 perm = get_perm_or_error(perm)
807 812
808 813 try:
809 814
810 815 RepoModel().grant_user_permission(repo=repo, user=user, perm=perm)
811 816
812 817 Session().commit()
813 818 return dict(
814 819 msg='Granted perm: `%s` for user: `%s` in repo: `%s`' % (
815 820 perm.permission_name, user.username, repo.repo_name
816 821 ),
817 822 success=True
818 823 )
819 824 except Exception:
820 825 log.error(traceback.format_exc())
821 826 raise JSONRPCError(
822 827 'failed to edit permission for user: `%s` in repo: `%s`' % (
823 828 userid, repoid
824 829 )
825 830 )
826 831
827 832 @HasPermissionAllDecorator('hg.admin')
828 833 def revoke_user_permission(self, apiuser, repoid, userid):
829 834 """
830 835 Revoke permission for user on given repository
831 836
832 837 :param apiuser:
833 838 :param repoid:
834 839 :param userid:
835 840 """
836 841
837 842 repo = get_repo_or_error(repoid)
838 843 user = get_user_or_error(userid)
839 844 try:
840 845
841 846 RepoModel().revoke_user_permission(repo=repo, user=user)
842 847
843 848 Session().commit()
844 849 return dict(
845 850 msg='Revoked perm for user: `%s` in repo: `%s`' % (
846 851 user.username, repo.repo_name
847 852 ),
848 853 success=True
849 854 )
850 855 except Exception:
851 856 log.error(traceback.format_exc())
852 857 raise JSONRPCError(
853 858 'failed to edit permission for user: `%s` in repo: `%s`' % (
854 859 userid, repoid
855 860 )
856 861 )
857 862
858 863 @HasPermissionAllDecorator('hg.admin')
859 864 def grant_users_group_permission(self, apiuser, repoid, usersgroupid,
860 865 perm):
861 866 """
862 867 Grant permission for users group on given repository, or update
863 868 existing one if found
864 869
865 870 :param apiuser:
866 871 :param repoid:
867 872 :param usersgroupid:
868 873 :param perm:
869 874 """
870 875 repo = get_repo_or_error(repoid)
871 876 perm = get_perm_or_error(perm)
872 877 users_group = get_users_group_or_error(usersgroupid)
873 878
874 879 try:
875 880 RepoModel().grant_users_group_permission(repo=repo,
876 881 group_name=users_group,
877 882 perm=perm)
878 883
879 884 Session().commit()
880 885 return dict(
881 886 msg='Granted perm: `%s` for users group: `%s` in '
882 887 'repo: `%s`' % (
883 888 perm.permission_name, users_group.users_group_name,
884 889 repo.repo_name
885 890 ),
886 891 success=True
887 892 )
888 893 except Exception:
889 894 log.error(traceback.format_exc())
890 895 raise JSONRPCError(
891 896 'failed to edit permission for users group: `%s` in '
892 897 'repo: `%s`' % (
893 898 usersgroupid, repo.repo_name
894 899 )
895 900 )
896 901
897 902 @HasPermissionAllDecorator('hg.admin')
898 903 def revoke_users_group_permission(self, apiuser, repoid, usersgroupid):
899 904 """
900 905 Revoke permission for users group on given repository
901 906
902 907 :param apiuser:
903 908 :param repoid:
904 909 :param usersgroupid:
905 910 """
906 911 repo = get_repo_or_error(repoid)
907 912 users_group = get_users_group_or_error(usersgroupid)
908 913
909 914 try:
910 915 RepoModel().revoke_users_group_permission(repo=repo,
911 916 group_name=users_group)
912 917
913 918 Session().commit()
914 919 return dict(
915 920 msg='Revoked perm for users group: `%s` in repo: `%s`' % (
916 921 users_group.users_group_name, repo.repo_name
917 922 ),
918 923 success=True
919 924 )
920 925 except Exception:
921 926 log.error(traceback.format_exc())
922 927 raise JSONRPCError(
923 928 'failed to edit permission for users group: `%s` in '
924 929 'repo: `%s`' % (
925 930 users_group.users_group_name, repo.repo_name
926 931 )
927 932 )
General Comments 0
You need to be logged in to leave comments. Login now