##// END OF EJS Templates
API get_user and get_repo methods can fetch by id or names
marcink -
r2010:14dffcfe beta
parent child Browse files
Show More
@@ -1,627 +1,627 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 Get's an user by username, Returns empty result if user is not found.
90 Get's an user by username or user_id, 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 "username" : "<username>"
100 "userid" : "<username or user_id>"
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_dn" : "<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_dn" : "<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. 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 update_user
183 183 -----------
184 184
185 185 updates current one if such user exists. This command can
186 186 be executed only using api_key belonging to user with admin rights.
187 187
188 188
189 189 INPUT::
190 190
191 191 api_key : "<api_key>"
192 192 method : "update_user"
193 193 args : {
194 194 "userid" : "<user_id or username>",
195 195 "username" : "<username>",
196 196 "password" : "<password>",
197 197 "email" : "<useremail>",
198 198 "firstname" : "<firstname>",
199 199 "lastname" : "<lastname>",
200 200 "active" : "<bool>",
201 201 "admin" : "<bool>",
202 202 "ldap_dn" : "<ldap_dn>"
203 203 }
204 204
205 205 OUTPUT::
206 206
207 207 result: {
208 208 "id" : "<edited_user_id>",
209 209 "msg" : "updated user <username>"
210 210 }
211 211 error: null
212 212
213 213
214 214 get_users_group
215 215 ---------------
216 216
217 217 Gets an existing users group. This command can be executed only using api_key
218 218 belonging to user with admin rights.
219 219
220 220
221 221 INPUT::
222 222
223 223 api_key : "<api_key>"
224 224 method : "get_users_group"
225 225 args : {
226 226 "group_name" : "<name>"
227 227 }
228 228
229 229 OUTPUT::
230 230
231 231 result : None if group not exist
232 232 {
233 233 "id" : "<id>",
234 234 "group_name" : "<groupname>",
235 235 "active": "<bool>",
236 236 "members" : [
237 237 { "id" : "<userid>",
238 238 "username" : "<username>",
239 239 "firstname": "<firstname>",
240 240 "lastname" : "<lastname>",
241 241 "email" : "<email>",
242 242 "active" : "<bool>",
243 243 "admin" :Β  "<bool>",
244 244 "ldap" : "<ldap_dn>"
245 245 },
246 246 …
247 247 ]
248 248 }
249 249 error : null
250 250
251 251
252 252 get_users_groups
253 253 ----------------
254 254
255 255 Lists all existing users groups. This command can be executed only using
256 256 api_key belonging to user with admin rights.
257 257
258 258
259 259 INPUT::
260 260
261 261 api_key : "<api_key>"
262 262 method : "get_users_groups"
263 263 args : { }
264 264
265 265 OUTPUT::
266 266
267 267 result : [
268 268 {
269 269 "id" : "<id>",
270 270 "group_name" : "<groupname>",
271 271 "active": "<bool>",
272 272 "members" : [
273 273 {
274 274 "id" : "<userid>",
275 275 "username" : "<username>",
276 276 "firstname": "<firstname>",
277 277 "lastname" : "<lastname>",
278 278 "email" : "<email>",
279 279 "active" : "<bool>",
280 280 "admin" :Β  "<bool>",
281 281 "ldap" : "<ldap_dn>"
282 282 },
283 283 …
284 284 ]
285 285 }
286 286 ]
287 287 error : null
288 288
289 289
290 290 create_users_group
291 291 ------------------
292 292
293 293 Creates new users group. This command can be executed only using api_key
294 294 belonging to user with admin rights
295 295
296 296
297 297 INPUT::
298 298
299 299 api_key : "<api_key>"
300 300 method : "create_users_group"
301 301 args: {
302 302 "group_name": "<groupname>",
303 303 "active":"<bool> = True"
304 304 }
305 305
306 306 OUTPUT::
307 307
308 308 result: {
309 309 "id": "<newusersgroupid>",
310 310 "msg": "created new users group <groupname>"
311 311 }
312 312 error: null
313 313
314 314
315 315 add_user_to_users_group
316 316 -----------------------
317 317
318 318 Adds a user to a users group. If user exists in that group success will be
319 319 `false`. This command can be executed only using api_key
320 320 belonging to user with admin rights
321 321
322 322
323 323 INPUT::
324 324
325 325 api_key : "<api_key>"
326 326 method : "add_user_users_group"
327 327 args: {
328 328 "group_name" : "<groupname>",
329 329 "username" : "<username>"
330 330 }
331 331
332 332 OUTPUT::
333 333
334 334 result: {
335 335 "id": "<newusersgroupmemberid>",
336 336 "success": True|False # depends on if member is in group
337 337 "msg": "added member <username> to users group <groupname> |
338 338 User is already in that group"
339 339 }
340 340 error: null
341 341
342 342
343 343 remove_user_from_users_group
344 344 ----------------------------
345 345
346 346 Removes a user from a users group. If user is not in given group success will
347 347 be `false`. This command can be executed only
348 348 using api_key belonging to user with admin rights
349 349
350 350
351 351 INPUT::
352 352
353 353 api_key : "<api_key>"
354 354 method : "remove_user_from_users_group"
355 355 args: {
356 356 "group_name" : "<groupname>",
357 357 "username" : "<username>"
358 358 }
359 359
360 360 OUTPUT::
361 361
362 362 result: {
363 363 "success": True|False, # depends on if member is in group
364 364 "msg": "removed member <username> from users group <groupname> |
365 365 User wasn't in group"
366 366 }
367 367 error: null
368 368
369 369
370 370 get_repo
371 371 --------
372 372
373 Gets an existing repository. This command can be executed only using api_key
374 belonging to user with admin rights
373 Gets an existing repository by it's name or repository_id. This command can
374 be executed only using api_key belonging to user with admin rights.
375 375
376 376
377 377 INPUT::
378 378
379 379 api_key : "<api_key>"
380 380 method : "get_repo"
381 381 args: {
382 "repo_name" : "<reponame>"
382 "repoid" : "<reponame or repo_id>"
383 383 }
384 384
385 385 OUTPUT::
386 386
387 387 result: None if repository does not exist or
388 388 {
389 389 "id" : "<id>",
390 390 "repo_name" : "<reponame>"
391 391 "type" : "<type>",
392 392 "description" : "<description>",
393 393 "members" : [
394 394 { "id" : "<userid>",
395 395 "username" : "<username>",
396 396 "firstname": "<firstname>",
397 397 "lastname" : "<lastname>",
398 398 "email" : "<email>",
399 399 "active" : "<bool>",
400 400 "admin" :Β  "<bool>",
401 401 "ldap" : "<ldap_dn>",
402 402 "permission" : "repository.(read|write|admin)"
403 403 },
404 404 …
405 405 {
406 406 "id" : "<usersgroupid>",
407 407 "name" : "<usersgroupname>",
408 408 "active": "<bool>",
409 409 "permission" : "repository.(read|write|admin)"
410 410 },
411 411 …
412 412 ]
413 413 }
414 414 error: null
415 415
416 416
417 417 get_repos
418 418 ---------
419 419
420 420 Lists all existing repositories. This command can be executed only using api_key
421 421 belonging to user with admin rights
422 422
423 423
424 424 INPUT::
425 425
426 426 api_key : "<api_key>"
427 427 method : "get_repos"
428 428 args: { }
429 429
430 430 OUTPUT::
431 431
432 432 result: [
433 433 {
434 434 "id" : "<id>",
435 435 "repo_name" : "<reponame>"
436 436 "type" : "<type>",
437 437 "description" : "<description>"
438 438 },
439 439 …
440 440 ]
441 441 error: null
442 442
443 443
444 444 get_repo_nodes
445 445 --------------
446 446
447 447 returns a list of nodes and it's children in a flat list for a given path
448 448 at given revision. It's possible to specify ret_type to show only `files` or
449 449 `dirs`. This command can be executed only using api_key belonging to user
450 450 with admin rights
451 451
452 452
453 453 INPUT::
454 454
455 455 api_key : "<api_key>"
456 456 method : "get_repo_nodes"
457 457 args: {
458 458 "repo_name" : "<reponame>",
459 459 "revision" : "<revision>",
460 460 "root_path" : "<root_path>",
461 461 "ret_type" : "<ret_type>" = 'all'
462 462 }
463 463
464 464 OUTPUT::
465 465
466 466 result: [
467 467 {
468 468 "name" : "<name>"
469 469 "type" : "<type>",
470 470 },
471 471 …
472 472 ]
473 473 error: null
474 474
475 475
476 476 create_repo
477 477 -----------
478 478
479 479 Creates a repository. This command can be executed only using api_key
480 480 belonging to user with admin rights.
481 481 If repository name contains "/", all needed repository groups will be created.
482 482 For example "foo/bar/baz" will create groups "foo", "bar" (with "foo" as parent),
483 483 and create "baz" repository with "bar" as group.
484 484
485 485
486 486 INPUT::
487 487
488 488 api_key : "<api_key>"
489 489 method : "create_repo"
490 490 args: {
491 491 "repo_name" : "<reponame>",
492 492 "owner_name" : "<ownername>",
493 493 "description" : "<description> = ''",
494 494 "repo_type" : "<type> = 'hg'",
495 495 "private" : "<bool> = False",
496 496 "clone_uri" : "<clone_uri> = None",
497 497 }
498 498
499 499 OUTPUT::
500 500
501 501 result: {
502 502 "id": "<newrepoid>",
503 503 "msg": "Created new repository <reponame>",
504 504 }
505 505 error: null
506 506
507 507
508 508 delete_repo
509 509 -----------
510 510
511 511 Deletes a repository. This command can be executed only using api_key
512 512 belonging to user with admin rights.
513 513
514 514
515 515 INPUT::
516 516
517 517 api_key : "<api_key>"
518 518 method : "delete_repo"
519 519 args: {
520 520 "repo_name" : "<reponame>",
521 521 }
522 522
523 523 OUTPUT::
524 524
525 525 result: {
526 526 "msg": "Deleted repository <reponame>",
527 527 }
528 528 error: null
529 529
530 530
531 531 grant_user_permission
532 532 ---------------------
533 533
534 534 Grant permission for user on given repository, or update existing one
535 535 if found. This command can be executed only using api_key belonging to user
536 536 with admin rights.
537 537
538 538
539 539 INPUT::
540 540
541 541 api_key : "<api_key>"
542 542 method : "grant_user_permission"
543 543 args: {
544 544 "repo_name" : "<reponame>",
545 545 "username" : "<username>",
546 546 "perm" : "(repository.(none|read|write|admin))",
547 547 }
548 548
549 549 OUTPUT::
550 550
551 551 result: {
552 552 "msg" : "Granted perm: <perm> for user: <username> in repo: <reponame>"
553 553 }
554 554 error: null
555 555
556 556
557 557 revoke_user_permission
558 558 ----------------------
559 559
560 560 Revoke permission for user on given repository. This command can be executed
561 561 only using api_key belonging to user with admin rights.
562 562
563 563
564 564 INPUT::
565 565
566 566 api_key : "<api_key>"
567 567 method : "revoke_user_permission"
568 568 args: {
569 569 "repo_name" : "<reponame>",
570 570 "username" : "<username>",
571 571 }
572 572
573 573 OUTPUT::
574 574
575 575 result: {
576 576 "msg" : "Revoked perm for user: <suername> in repo: <reponame>"
577 577 }
578 578 error: null
579 579
580 580
581 581 grant_users_group_permission
582 582 ----------------------------
583 583
584 584 Grant permission for users group on given repository, or update
585 585 existing one if found. This command can be executed only using
586 586 api_key belonging to user with admin rights.
587 587
588 588
589 589 INPUT::
590 590
591 591 api_key : "<api_key>"
592 592 method : "grant_users_group_permission"
593 593 args: {
594 594 "repo_name" : "<reponame>",
595 595 "group_name" : "<usersgroupname>",
596 596 "perm" : "(repository.(none|read|write|admin))",
597 597 }
598 598
599 599 OUTPUT::
600 600
601 601 result: {
602 602 "msg" : "Granted perm: <perm> for group: <usersgroupname> in repo: <reponame>"
603 603 }
604 604 error: null
605 605
606 606
607 607 revoke_users_group_permission
608 608 -----------------------------
609 609
610 610 Revoke permission for users group on given repository.This command can be
611 611 executed only using api_key belonging to user with admin rights.
612 612
613 613 INPUT::
614 614
615 615 api_key : "<api_key>"
616 616 method : "revoke_users_group_permission"
617 617 args: {
618 618 "repo_name" : "<reponame>",
619 619 "users_group" : "<usersgroupname>",
620 620 }
621 621
622 622 OUTPUT::
623 623
624 624 result: {
625 625 "msg" : "Revoked perm for group: <usersgroupname> in repo: <reponame>"
626 626 }
627 627 error: null No newline at end of file
@@ -1,660 +1,660 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 rhodecode.controllers.api import JSONRPCController, JSONRPCError
32 32 from rhodecode.lib.auth import HasPermissionAllDecorator, \
33 33 HasPermissionAnyDecorator, PasswordGenerator
34 34
35 35 from rhodecode.model.meta import Session
36 36 from rhodecode.model.scm import ScmModel
37 37 from rhodecode.model.db import User, UsersGroup, RepoGroup, Repository
38 38 from rhodecode.model.repo import RepoModel
39 39 from rhodecode.model.user import UserModel
40 40 from rhodecode.model.users_group import UsersGroupModel
41 41 from rhodecode.model.repos_group import ReposGroupModel
42 42
43 43
44 44 log = logging.getLogger(__name__)
45 45
46 46
47 47 class ApiController(JSONRPCController):
48 48 """
49 49 API Controller
50 50
51 51
52 52 Each method needs to have USER as argument this is then based on given
53 53 API_KEY propagated as instance of user object
54 54
55 55 Preferably this should be first argument also
56 56
57 57
58 58 Each function should also **raise** JSONRPCError for any
59 59 errors that happens
60 60
61 61 """
62 62
63 63 @HasPermissionAllDecorator('hg.admin')
64 64 def pull(self, apiuser, repo_name):
65 65 """
66 66 Dispatch pull action on given repo
67 67
68 68
69 69 :param user:
70 70 :param repo_name:
71 71 """
72 72
73 73 if Repository.is_valid(repo_name) is False:
74 74 raise JSONRPCError('Unknown repo "%s"' % repo_name)
75 75
76 76 try:
77 77 ScmModel().pull_changes(repo_name, self.rhodecode_user.username)
78 78 return 'Pulled from %s' % repo_name
79 79 except Exception:
80 80 raise JSONRPCError('Unable to pull changes from "%s"' % repo_name)
81 81
82 82 @HasPermissionAllDecorator('hg.admin')
83 def get_user(self, apiuser, username):
83 def get_user(self, apiuser, userid):
84 84 """"
85 85 Get a user by username
86 86
87 87 :param apiuser:
88 88 :param username:
89 89 """
90 90
91 user = User.get_by_username(username)
91 user = UserModel().get_user(userid)
92 92 if user is None:
93 93 return user
94 94
95 95 return dict(
96 96 id=user.user_id,
97 97 username=user.username,
98 98 firstname=user.name,
99 99 lastname=user.lastname,
100 100 email=user.email,
101 101 active=user.active,
102 102 admin=user.admin,
103 103 ldap_dn=user.ldap_dn
104 104 )
105 105
106 106 @HasPermissionAllDecorator('hg.admin')
107 107 def get_users(self, apiuser):
108 108 """"
109 109 Get all users
110 110
111 111 :param apiuser:
112 112 """
113 113
114 114 result = []
115 115 for user in User.getAll():
116 116 result.append(
117 117 dict(
118 118 id=user.user_id,
119 119 username=user.username,
120 120 firstname=user.name,
121 121 lastname=user.lastname,
122 122 email=user.email,
123 123 active=user.active,
124 124 admin=user.admin,
125 125 ldap_dn=user.ldap_dn
126 126 )
127 127 )
128 128 return result
129 129
130 130 @HasPermissionAllDecorator('hg.admin')
131 131 def create_user(self, apiuser, username, email, password, firstname=None,
132 132 lastname=None, active=True, admin=False, ldap_dn=None):
133 133 """
134 134 Create new user
135 135
136 136 :param apiuser:
137 137 :param username:
138 138 :param password:
139 139 :param email:
140 140 :param name:
141 141 :param lastname:
142 142 :param active:
143 143 :param admin:
144 144 :param ldap_dn:
145 145 """
146 146 if User.get_by_username(username):
147 147 raise JSONRPCError("user %s already exist" % username)
148 148
149 149 if User.get_by_email(email, case_insensitive=True):
150 150 raise JSONRPCError("email %s already exist" % email)
151 151
152 152 if ldap_dn:
153 153 # generate temporary password if ldap_dn
154 154 password = PasswordGenerator().gen_password(length=8)
155 155
156 156 try:
157 157 usr = UserModel().create_or_update(
158 158 username, password, email, firstname,
159 159 lastname, active, admin, ldap_dn
160 160 )
161 161 Session.commit()
162 162 return dict(
163 163 id=usr.user_id,
164 164 msg='created new user %s' % username
165 165 )
166 166 except Exception:
167 167 log.error(traceback.format_exc())
168 168 raise JSONRPCError('failed to create user %s' % username)
169 169
170 170 @HasPermissionAllDecorator('hg.admin')
171 171 def update_user(self, apiuser, userid, username, password, email,
172 172 firstname, lastname, active, admin, ldap_dn):
173 173 """
174 174 Updates given user
175 175
176 176 :param apiuser:
177 177 :param username:
178 178 :param password:
179 179 :param email:
180 180 :param name:
181 181 :param lastname:
182 182 :param active:
183 183 :param admin:
184 184 :param ldap_dn:
185 185 """
186 186 if not UserModel().get_user(userid):
187 187 raise JSONRPCError("user %s does not exist" % username)
188 188
189 189 try:
190 190 usr = UserModel().create_or_update(
191 191 username, password, email, firstname,
192 192 lastname, active, admin, ldap_dn
193 193 )
194 194 Session.commit()
195 195 return dict(
196 196 id=usr.user_id,
197 197 msg='updated user %s' % username
198 198 )
199 199 except Exception:
200 200 log.error(traceback.format_exc())
201 201 raise JSONRPCError('failed to update user %s' % username)
202 202
203 203 @HasPermissionAllDecorator('hg.admin')
204 204 def get_users_group(self, apiuser, group_name):
205 205 """"
206 206 Get users group by name
207 207
208 208 :param apiuser:
209 209 :param group_name:
210 210 """
211 211
212 212 users_group = UsersGroup.get_by_group_name(group_name)
213 213 if not users_group:
214 214 return None
215 215
216 216 members = []
217 217 for user in users_group.members:
218 218 user = user.user
219 219 members.append(dict(id=user.user_id,
220 220 username=user.username,
221 221 firstname=user.name,
222 222 lastname=user.lastname,
223 223 email=user.email,
224 224 active=user.active,
225 225 admin=user.admin,
226 226 ldap=user.ldap_dn))
227 227
228 228 return dict(id=users_group.users_group_id,
229 229 group_name=users_group.users_group_name,
230 230 active=users_group.users_group_active,
231 231 members=members)
232 232
233 233 @HasPermissionAllDecorator('hg.admin')
234 234 def get_users_groups(self, apiuser):
235 235 """"
236 236 Get all users groups
237 237
238 238 :param apiuser:
239 239 """
240 240
241 241 result = []
242 242 for users_group in UsersGroup.getAll():
243 243 members = []
244 244 for user in users_group.members:
245 245 user = user.user
246 246 members.append(dict(id=user.user_id,
247 247 username=user.username,
248 248 firstname=user.name,
249 249 lastname=user.lastname,
250 250 email=user.email,
251 251 active=user.active,
252 252 admin=user.admin,
253 253 ldap=user.ldap_dn))
254 254
255 255 result.append(dict(id=users_group.users_group_id,
256 256 group_name=users_group.users_group_name,
257 257 active=users_group.users_group_active,
258 258 members=members))
259 259 return result
260 260
261 261 @HasPermissionAllDecorator('hg.admin')
262 262 def create_users_group(self, apiuser, group_name, active=True):
263 263 """
264 264 Creates an new usergroup
265 265
266 266 :param group_name:
267 267 :param active:
268 268 """
269 269
270 270 if self.get_users_group(apiuser, group_name):
271 271 raise JSONRPCError("users group %s already exist" % group_name)
272 272
273 273 try:
274 274 ug = UsersGroupModel().create(name=group_name, active=active)
275 275 Session.commit()
276 276 return dict(id=ug.users_group_id,
277 277 msg='created new users group %s' % group_name)
278 278 except Exception:
279 279 log.error(traceback.format_exc())
280 280 raise JSONRPCError('failed to create group %s' % group_name)
281 281
282 282 @HasPermissionAllDecorator('hg.admin')
283 283 def add_user_to_users_group(self, apiuser, group_name, username):
284 284 """"
285 285 Add a user to a group
286 286
287 287 :param apiuser:
288 288 :param group_name:
289 289 :param username:
290 290 """
291 291
292 292 try:
293 293 users_group = UsersGroup.get_by_group_name(group_name)
294 294 if not users_group:
295 295 raise JSONRPCError('unknown users group %s' % group_name)
296 296
297 297 user = User.get_by_username(username)
298 298 if user is None:
299 299 raise JSONRPCError('unknown user %s' % username)
300 300
301 301 ugm = UsersGroupModel().add_user_to_group(users_group, user)
302 302 success = True if ugm != True else False
303 303 msg = 'added member %s to users group %s' % (username, group_name)
304 304 msg = msg if success else 'User is already in that group'
305 305 Session.commit()
306 306
307 307 return dict(
308 308 id=ugm.users_group_member_id if ugm != True else None,
309 309 success=success,
310 310 msg=msg
311 311 )
312 312 except Exception:
313 313 log.error(traceback.format_exc())
314 314 raise JSONRPCError('failed to add users group member')
315 315
316 316 @HasPermissionAllDecorator('hg.admin')
317 317 def remove_user_from_users_group(self, apiuser, group_name, username):
318 318 """
319 319 Remove user from a group
320 320
321 321 :param apiuser
322 322 :param group_name
323 323 :param username
324 324 """
325 325
326 326 try:
327 327 users_group = UsersGroup.get_by_group_name(group_name)
328 328 if not users_group:
329 329 raise JSONRPCError('unknown users group %s' % group_name)
330 330
331 331 user = User.get_by_username(username)
332 332 if user is None:
333 333 raise JSONRPCError('unknown user %s' % username)
334 334
335 335 success = UsersGroupModel().remove_user_from_group(users_group, user)
336 336 msg = 'removed member %s from users group %s' % (username, group_name)
337 337 msg = msg if success else "User wasn't in group"
338 338 Session.commit()
339 339 return dict(success=success, msg=msg)
340 340 except Exception:
341 341 log.error(traceback.format_exc())
342 342 raise JSONRPCError('failed to remove user from group')
343 343
344 344 @HasPermissionAnyDecorator('hg.admin')
345 def get_repo(self, apiuser, repo_name):
345 def get_repo(self, apiuser, repoid):
346 346 """"
347 347 Get repository by name
348 348
349 349 :param apiuser:
350 350 :param repo_name:
351 351 """
352 352
353 repo = Repository.get_by_repo_name(repo_name)
353 repo = RepoModel().get_repo(repoid)
354 354 if repo is None:
355 355 raise JSONRPCError('unknown repository %s' % repo)
356 356
357 357 members = []
358 358 for user in repo.repo_to_perm:
359 359 perm = user.permission.permission_name
360 360 user = user.user
361 361 members.append(
362 362 dict(
363 363 type_="user",
364 364 id=user.user_id,
365 365 username=user.username,
366 366 firstname=user.name,
367 367 lastname=user.lastname,
368 368 email=user.email,
369 369 active=user.active,
370 370 admin=user.admin,
371 371 ldap=user.ldap_dn,
372 372 permission=perm
373 373 )
374 374 )
375 375 for users_group in repo.users_group_to_perm:
376 376 perm = users_group.permission.permission_name
377 377 users_group = users_group.users_group
378 378 members.append(
379 379 dict(
380 380 type_="users_group",
381 381 id=users_group.users_group_id,
382 382 name=users_group.users_group_name,
383 383 active=users_group.users_group_active,
384 384 permission=perm
385 385 )
386 386 )
387 387
388 388 return dict(
389 389 id=repo.repo_id,
390 390 repo_name=repo.repo_name,
391 391 type=repo.repo_type,
392 392 description=repo.description,
393 393 members=members
394 394 )
395 395
396 396 @HasPermissionAnyDecorator('hg.admin')
397 397 def get_repos(self, apiuser):
398 398 """"
399 399 Get all repositories
400 400
401 401 :param apiuser:
402 402 """
403 403
404 404 result = []
405 405 for repository in Repository.getAll():
406 406 result.append(
407 407 dict(
408 408 id=repository.repo_id,
409 409 repo_name=repository.repo_name,
410 410 type=repository.repo_type,
411 411 description=repository.description
412 412 )
413 413 )
414 414 return result
415 415
416 416 @HasPermissionAnyDecorator('hg.admin')
417 417 def get_repo_nodes(self, apiuser, repo_name, revision, root_path,
418 418 ret_type='all'):
419 419 """
420 420 returns a list of nodes and it's children
421 421 for a given path at given revision. It's possible to specify ret_type
422 422 to show only files or dirs
423 423
424 424 :param apiuser:
425 425 :param repo_name: name of repository
426 426 :param revision: revision for which listing should be done
427 427 :param root_path: path from which start displaying
428 428 :param ret_type: return type 'all|files|dirs' nodes
429 429 """
430 430 try:
431 431 _d, _f = ScmModel().get_nodes(repo_name, revision, root_path,
432 432 flat=False)
433 433 _map = {
434 434 'all': _d + _f,
435 435 'files': _f,
436 436 'dirs': _d,
437 437 }
438 438 return _map[ret_type]
439 439 except KeyError:
440 440 raise JSONRPCError('ret_type must be one of %s' % _map.keys())
441 441 except Exception, e:
442 442 raise JSONRPCError(e)
443 443
444 444 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
445 445 def create_repo(self, apiuser, repo_name, owner_name, description='',
446 446 repo_type='hg', private=False, clone_uri=None):
447 447 """
448 448 Create repository, if clone_url is given it makes a remote clone
449 449
450 450 :param apiuser:
451 451 :param repo_name:
452 452 :param owner_name:
453 453 :param description:
454 454 :param repo_type:
455 455 :param private:
456 456 :param clone_uri:
457 457 """
458 458
459 459 try:
460 460 owner = User.get_by_username(owner_name)
461 461 if owner is None:
462 462 raise JSONRPCError('unknown user %s' % owner_name)
463 463
464 464 if Repository.get_by_repo_name(repo_name):
465 465 raise JSONRPCError("repo %s already exist" % repo_name)
466 466
467 467 groups = repo_name.split('/')
468 468 real_name = groups[-1]
469 469 groups = groups[:-1]
470 470 parent_id = None
471 471 for g in groups:
472 472 group = RepoGroup.get_by_group_name(g)
473 473 if not group:
474 474 group = ReposGroupModel().create(g, '', parent_id)
475 475 parent_id = group.group_id
476 476
477 477 repo = RepoModel().create(
478 478 dict(
479 479 repo_name=real_name,
480 480 repo_name_full=repo_name,
481 481 description=description,
482 482 private=private,
483 483 repo_type=repo_type,
484 484 repo_group=parent_id,
485 485 clone_uri=clone_uri
486 486 ),
487 487 owner
488 488 )
489 489 Session.commit()
490 490
491 491 return dict(
492 492 id=repo.repo_id,
493 493 msg="Created new repository %s" % repo.repo_name
494 494 )
495 495
496 496 except Exception:
497 497 log.error(traceback.format_exc())
498 498 raise JSONRPCError('failed to create repository %s' % repo_name)
499 499
500 500 @HasPermissionAnyDecorator('hg.admin')
501 501 def delete_repo(self, apiuser, repo_name):
502 502 """
503 503 Deletes a given repository
504 504
505 505 :param repo_name:
506 506 """
507 507 if not Repository.get_by_repo_name(repo_name):
508 508 raise JSONRPCError("repo %s does not exist" % repo_name)
509 509 try:
510 510 RepoModel().delete(repo_name)
511 511 Session.commit()
512 512 return dict(
513 513 msg='Deleted repository %s' % repo_name
514 514 )
515 515 except Exception:
516 516 log.error(traceback.format_exc())
517 517 raise JSONRPCError('failed to delete repository %s' % repo_name)
518 518
519 519 @HasPermissionAnyDecorator('hg.admin')
520 520 def grant_user_permission(self, apiuser, repo_name, username, perm):
521 521 """
522 522 Grant permission for user on given repository, or update existing one
523 523 if found
524 524
525 525 :param repo_name:
526 526 :param username:
527 527 :param perm:
528 528 """
529 529
530 530 try:
531 531 repo = Repository.get_by_repo_name(repo_name)
532 532 if repo is None:
533 533 raise JSONRPCError('unknown repository %s' % repo)
534 534
535 535 user = User.get_by_username(username)
536 536 if user is None:
537 537 raise JSONRPCError('unknown user %s' % username)
538 538
539 539 RepoModel().grant_user_permission(repo=repo, user=user, perm=perm)
540 540
541 541 Session.commit()
542 542 return dict(
543 543 msg='Granted perm: %s for user: %s in repo: %s' % (
544 544 perm, username, repo_name
545 545 )
546 546 )
547 547 except Exception:
548 548 log.error(traceback.format_exc())
549 549 raise JSONRPCError(
550 550 'failed to edit permission %(repo)s for %(user)s' % dict(
551 551 user=username, repo=repo_name
552 552 )
553 553 )
554 554
555 555 @HasPermissionAnyDecorator('hg.admin')
556 556 def revoke_user_permission(self, apiuser, repo_name, username):
557 557 """
558 558 Revoke permission for user on given repository
559 559
560 560 :param repo_name:
561 561 :param username:
562 562 """
563 563
564 564 try:
565 565 repo = Repository.get_by_repo_name(repo_name)
566 566 if repo is None:
567 567 raise JSONRPCError('unknown repository %s' % repo)
568 568
569 569 user = User.get_by_username(username)
570 570 if user is None:
571 571 raise JSONRPCError('unknown user %s' % username)
572 572
573 573 RepoModel().revoke_user_permission(repo=repo_name, user=username)
574 574
575 575 Session.commit()
576 576 return dict(
577 577 msg='Revoked perm for user: %s in repo: %s' % (
578 578 username, repo_name
579 579 )
580 580 )
581 581 except Exception:
582 582 log.error(traceback.format_exc())
583 583 raise JSONRPCError(
584 584 'failed to edit permission %(repo)s for %(user)s' % dict(
585 585 user=username, repo=repo_name
586 586 )
587 587 )
588 588
589 589 @HasPermissionAnyDecorator('hg.admin')
590 590 def grant_users_group_permission(self, apiuser, repo_name, group_name, perm):
591 591 """
592 592 Grant permission for users group on given repository, or update
593 593 existing one if found
594 594
595 595 :param repo_name:
596 596 :param group_name:
597 597 :param perm:
598 598 """
599 599
600 600 try:
601 601 repo = Repository.get_by_repo_name(repo_name)
602 602 if repo is None:
603 603 raise JSONRPCError('unknown repository %s' % repo)
604 604
605 605 user_group = UsersGroup.get_by_group_name(group_name)
606 606 if user_group is None:
607 607 raise JSONRPCError('unknown users group %s' % user_group)
608 608
609 609 RepoModel().grant_users_group_permission(repo=repo_name,
610 610 group_name=group_name,
611 611 perm=perm)
612 612
613 613 Session.commit()
614 614 return dict(
615 615 msg='Granted perm: %s for group: %s in repo: %s' % (
616 616 perm, group_name, repo_name
617 617 )
618 618 )
619 619 except Exception:
620 620 log.error(traceback.format_exc())
621 621 raise JSONRPCError(
622 622 'failed to edit permission %(repo)s for %(usersgr)s' % dict(
623 623 usersgr=group_name, repo=repo_name
624 624 )
625 625 )
626 626
627 627 @HasPermissionAnyDecorator('hg.admin')
628 628 def revoke_users_group_permission(self, apiuser, repo_name, group_name):
629 629 """
630 630 Revoke permission for users group on given repository
631 631
632 632 :param repo_name:
633 633 :param group_name:
634 634 """
635 635
636 636 try:
637 637 repo = Repository.get_by_repo_name(repo_name)
638 638 if repo is None:
639 639 raise JSONRPCError('unknown repository %s' % repo)
640 640
641 641 user_group = UsersGroup.get_by_group_name(group_name)
642 642 if user_group is None:
643 643 raise JSONRPCError('unknown users group %s' % user_group)
644 644
645 645 RepoModel().revoke_users_group_permission(repo=repo_name,
646 646 group_name=group_name)
647 647
648 648 Session.commit()
649 649 return dict(
650 650 msg='Revoked perm for group: %s in repo: %s' % (
651 651 group_name, repo_name
652 652 )
653 653 )
654 654 except Exception:
655 655 log.error(traceback.format_exc())
656 656 raise JSONRPCError(
657 657 'failed to edit permission %(repo)s for %(usersgr)s' % dict(
658 658 usersgr=group_name, repo=repo_name
659 659 )
660 660 )
@@ -1,492 +1,495 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.model.repo
4 4 ~~~~~~~~~~~~~~~~~~~~
5 5
6 6 Repository model for rhodecode
7 7
8 8 :created_on: Jun 5, 2010
9 9 :author: marcink
10 10 :copyright: (C) 2010-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 modify
14 14 # it under the terms of the GNU General Public License as published by
15 15 # the Free Software Foundation, either version 3 of the License, or
16 16 # (at your option) any later version.
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, see <http://www.gnu.org/licenses/>.
25 25 import os
26 26 import shutil
27 27 import logging
28 28 import traceback
29 29 from datetime import datetime
30 30
31 31 from rhodecode.lib.vcs.backends import get_backend
32 32
33 33 from rhodecode.lib import LazyProperty
34 34 from rhodecode.lib import safe_str, safe_unicode
35 35 from rhodecode.lib.caching_query import FromCache
36 36 from rhodecode.lib.hooks import log_create_repository
37 37
38 38 from rhodecode.model import BaseModel
39 39 from rhodecode.model.db import Repository, UserRepoToPerm, User, Permission, \
40 40 Statistics, UsersGroup, UsersGroupRepoToPerm, RhodeCodeUi, RepoGroup
41 41
42 42
43 43 log = logging.getLogger(__name__)
44 44
45 45
46 46 class RepoModel(BaseModel):
47 47
48 48 def __get_user(self, user):
49 49 return self._get_instance(User, user, callback=User.get_by_username)
50 50
51 51 def __get_users_group(self, users_group):
52 52 return self._get_instance(UsersGroup, users_group,
53 53 callback=UsersGroup.get_by_group_name)
54 54
55 55 def __get_repos_group(self, repos_group):
56 56 return self._get_instance(RepoGroup, repos_group,
57 57 callback=RepoGroup.get_by_group_name)
58 58
59 59 def __get_repo(self, repository):
60 60 return self._get_instance(Repository, repository,
61 61 callback=Repository.get_by_repo_name)
62 62
63 63 def __get_perm(self, permission):
64 64 return self._get_instance(Permission, permission,
65 65 callback=Permission.get_by_key)
66 66
67 67 @LazyProperty
68 68 def repos_path(self):
69 69 """
70 70 Get's the repositories root path from database
71 71 """
72 72
73 73 q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
74 74 return q.ui_value
75 75
76 76 def get(self, repo_id, cache=False):
77 77 repo = self.sa.query(Repository)\
78 78 .filter(Repository.repo_id == repo_id)
79 79
80 80 if cache:
81 81 repo = repo.options(FromCache("sql_cache_short",
82 82 "get_repo_%s" % repo_id))
83 83 return repo.scalar()
84 84
85 def get_repo(self, repository):
86 return self.__get_repo(repository)
87
85 88 def get_by_repo_name(self, repo_name, cache=False):
86 89 repo = self.sa.query(Repository)\
87 90 .filter(Repository.repo_name == repo_name)
88 91
89 92 if cache:
90 93 repo = repo.options(FromCache("sql_cache_short",
91 94 "get_repo_%s" % repo_name))
92 95 return repo.scalar()
93 96
94 97 def get_users_js(self):
95 98
96 99 users = self.sa.query(User).filter(User.active == True).all()
97 100 u_tmpl = '''{id:%s, fname:"%s", lname:"%s", nname:"%s"},'''
98 101 users_array = '[%s]' % '\n'.join([u_tmpl % (u.user_id, u.name,
99 102 u.lastname, u.username)
100 103 for u in users])
101 104 return users_array
102 105
103 106 def get_users_groups_js(self):
104 107 users_groups = self.sa.query(UsersGroup)\
105 108 .filter(UsersGroup.users_group_active == True).all()
106 109
107 110 g_tmpl = '''{id:%s, grname:"%s",grmembers:"%s"},'''
108 111
109 112 users_groups_array = '[%s]' % '\n'.join([g_tmpl % \
110 113 (gr.users_group_id, gr.users_group_name,
111 114 len(gr.members))
112 115 for gr in users_groups])
113 116 return users_groups_array
114 117
115 118 def _get_defaults(self, repo_name):
116 119 """
117 120 Get's information about repository, and returns a dict for
118 121 usage in forms
119 122
120 123 :param repo_name:
121 124 """
122 125
123 126 repo_info = Repository.get_by_repo_name(repo_name)
124 127
125 128 if repo_info is None:
126 129 return None
127 130
128 131 defaults = repo_info.get_dict()
129 132 group, repo_name = repo_info.groups_and_repo
130 133 defaults['repo_name'] = repo_name
131 134 defaults['repo_group'] = getattr(group[-1] if group else None,
132 135 'group_id', None)
133 136
134 137 # fill owner
135 138 if repo_info.user:
136 139 defaults.update({'user': repo_info.user.username})
137 140 else:
138 141 replacement_user = User.query().filter(User.admin ==
139 142 True).first().username
140 143 defaults.update({'user': replacement_user})
141 144
142 145 # fill repository users
143 146 for p in repo_info.repo_to_perm:
144 147 defaults.update({'u_perm_%s' % p.user.username:
145 148 p.permission.permission_name})
146 149
147 150 # fill repository groups
148 151 for p in repo_info.users_group_to_perm:
149 152 defaults.update({'g_perm_%s' % p.users_group.users_group_name:
150 153 p.permission.permission_name})
151 154
152 155 return defaults
153 156
154 157 def update(self, repo_name, form_data):
155 158 try:
156 159 cur_repo = self.get_by_repo_name(repo_name, cache=False)
157 160
158 161 # update permissions
159 162 for member, perm, member_type in form_data['perms_updates']:
160 163 if member_type == 'user':
161 164 # this updates existing one
162 165 RepoModel().grant_user_permission(
163 166 repo=cur_repo, user=member, perm=perm
164 167 )
165 168 else:
166 169 RepoModel().grant_users_group_permission(
167 170 repo=cur_repo, group_name=member, perm=perm
168 171 )
169 172 # set new permissions
170 173 for member, perm, member_type in form_data['perms_new']:
171 174 if member_type == 'user':
172 175 RepoModel().grant_user_permission(
173 176 repo=cur_repo, user=member, perm=perm
174 177 )
175 178 else:
176 179 RepoModel().grant_users_group_permission(
177 180 repo=cur_repo, group_name=member, perm=perm
178 181 )
179 182
180 183 # update current repo
181 184 for k, v in form_data.items():
182 185 if k == 'user':
183 186 cur_repo.user = User.get_by_username(v)
184 187 elif k == 'repo_name':
185 188 pass
186 189 elif k == 'repo_group':
187 190 cur_repo.group = RepoGroup.get(v)
188 191
189 192 else:
190 193 setattr(cur_repo, k, v)
191 194
192 195 new_name = cur_repo.get_new_name(form_data['repo_name'])
193 196 cur_repo.repo_name = new_name
194 197
195 198 self.sa.add(cur_repo)
196 199
197 200 if repo_name != new_name:
198 201 # rename repository
199 202 self.__rename_repo(old=repo_name, new=new_name)
200 203
201 204 return cur_repo
202 205 except:
203 206 log.error(traceback.format_exc())
204 207 raise
205 208
206 209 def create(self, form_data, cur_user, just_db=False, fork=False):
207 210 from rhodecode.model.scm import ScmModel
208 211
209 212 try:
210 213 if fork:
211 214 fork_parent_id = form_data['fork_parent_id']
212 215
213 216 # repo name is just a name of repository
214 217 # while repo_name_full is a full qualified name that is combined
215 218 # with name and path of group
216 219 repo_name = form_data['repo_name']
217 220 repo_name_full = form_data['repo_name_full']
218 221
219 222 new_repo = Repository()
220 223 new_repo.enable_statistics = False
221 224
222 225 for k, v in form_data.items():
223 226 if k == 'repo_name':
224 227 v = repo_name_full
225 228 if k == 'repo_group':
226 229 k = 'group_id'
227 230 if k == 'description':
228 231 v = v or repo_name
229 232
230 233 setattr(new_repo, k, v)
231 234
232 235 if fork:
233 236 parent_repo = Repository.get(fork_parent_id)
234 237 new_repo.fork = parent_repo
235 238
236 239 new_repo.user_id = cur_user.user_id
237 240 self.sa.add(new_repo)
238 241
239 242 def _create_default_perms():
240 243 # create default permission
241 244 repo_to_perm = UserRepoToPerm()
242 245 default = 'repository.read'
243 246 for p in User.get_by_username('default').user_perms:
244 247 if p.permission.permission_name.startswith('repository.'):
245 248 default = p.permission.permission_name
246 249 break
247 250
248 251 default_perm = 'repository.none' if form_data['private'] else default
249 252
250 253 repo_to_perm.permission_id = self.sa.query(Permission)\
251 254 .filter(Permission.permission_name == default_perm)\
252 255 .one().permission_id
253 256
254 257 repo_to_perm.repository = new_repo
255 258 repo_to_perm.user_id = User.get_by_username('default').user_id
256 259
257 260 self.sa.add(repo_to_perm)
258 261
259 262 if fork:
260 263 if form_data.get('copy_permissions'):
261 264 repo = Repository.get(fork_parent_id)
262 265 user_perms = UserRepoToPerm.query()\
263 266 .filter(UserRepoToPerm.repository == repo).all()
264 267 group_perms = UsersGroupRepoToPerm.query()\
265 268 .filter(UsersGroupRepoToPerm.repository == repo).all()
266 269
267 270 for perm in user_perms:
268 271 UserRepoToPerm.create(perm.user, new_repo,
269 272 perm.permission)
270 273
271 274 for perm in group_perms:
272 275 UsersGroupRepoToPerm.create(perm.users_group, new_repo,
273 276 perm.permission)
274 277 else:
275 278 _create_default_perms()
276 279 else:
277 280 _create_default_perms()
278 281
279 282 if not just_db:
280 283 self.__create_repo(repo_name, form_data['repo_type'],
281 284 form_data['repo_group'],
282 285 form_data['clone_uri'])
283 286
284 287 # now automatically start following this repository as owner
285 288 ScmModel(self.sa).toggle_following_repo(new_repo.repo_id,
286 289 cur_user.user_id)
287 290 log_create_repository(new_repo.get_dict(),
288 291 created_by=cur_user.username)
289 292 return new_repo
290 293 except:
291 294 log.error(traceback.format_exc())
292 295 raise
293 296
294 297 def create_fork(self, form_data, cur_user):
295 298 """
296 299 Simple wrapper into executing celery task for fork creation
297 300
298 301 :param form_data:
299 302 :param cur_user:
300 303 """
301 304 from rhodecode.lib.celerylib import tasks, run_task
302 305 run_task(tasks.create_repo_fork, form_data, cur_user)
303 306
304 307 def delete(self, repo):
305 308 repo = self.__get_repo(repo)
306 309 try:
307 310 self.sa.delete(repo)
308 311 self.__delete_repo(repo)
309 312 except:
310 313 log.error(traceback.format_exc())
311 314 raise
312 315
313 316 def grant_user_permission(self, repo, user, perm):
314 317 """
315 318 Grant permission for user on given repository, or update existing one
316 319 if found
317 320
318 321 :param repo: Instance of Repository, repository_id, or repository name
319 322 :param user: Instance of User, user_id or username
320 323 :param perm: Instance of Permission, or permission_name
321 324 """
322 325 user = self.__get_user(user)
323 326 repo = self.__get_repo(repo)
324 327 permission = self.__get_perm(perm)
325 328
326 329 # check if we have that permission already
327 330 obj = self.sa.query(UserRepoToPerm)\
328 331 .filter(UserRepoToPerm.user == user)\
329 332 .filter(UserRepoToPerm.repository == repo)\
330 333 .scalar()
331 334 if obj is None:
332 335 # create new !
333 336 obj = UserRepoToPerm()
334 337 obj.repository = repo
335 338 obj.user = user
336 339 obj.permission = permission
337 340 self.sa.add(obj)
338 341
339 342 def revoke_user_permission(self, repo, user):
340 343 """
341 344 Revoke permission for user on given repository
342 345
343 346 :param repo: Instance of Repository, repository_id, or repository name
344 347 :param user: Instance of User, user_id or username
345 348 """
346 349 user = self.__get_user(user)
347 350 repo = self.__get_repo(repo)
348 351
349 352 obj = self.sa.query(UserRepoToPerm)\
350 353 .filter(UserRepoToPerm.repository == repo)\
351 354 .filter(UserRepoToPerm.user == user)\
352 355 .one()
353 356 self.sa.delete(obj)
354 357
355 358 def grant_users_group_permission(self, repo, group_name, perm):
356 359 """
357 360 Grant permission for users group on given repository, or update
358 361 existing one if found
359 362
360 363 :param repo: Instance of Repository, repository_id, or repository name
361 364 :param group_name: Instance of UserGroup, users_group_id,
362 365 or users group name
363 366 :param perm: Instance of Permission, or permission_name
364 367 """
365 368 repo = self.__get_repo(repo)
366 369 group_name = self.__get_users_group(group_name)
367 370 permission = self.__get_perm(perm)
368 371
369 372 # check if we have that permission already
370 373 obj = self.sa.query(UsersGroupRepoToPerm)\
371 374 .filter(UsersGroupRepoToPerm.users_group == group_name)\
372 375 .filter(UsersGroupRepoToPerm.repository == repo)\
373 376 .scalar()
374 377
375 378 if obj is None:
376 379 # create new
377 380 obj = UsersGroupRepoToPerm()
378 381
379 382 obj.repository = repo
380 383 obj.users_group = group_name
381 384 obj.permission = permission
382 385 self.sa.add(obj)
383 386
384 387 def revoke_users_group_permission(self, repo, group_name):
385 388 """
386 389 Revoke permission for users group on given repository
387 390
388 391 :param repo: Instance of Repository, repository_id, or repository name
389 392 :param group_name: Instance of UserGroup, users_group_id,
390 393 or users group name
391 394 """
392 395 repo = self.__get_repo(repo)
393 396 group_name = self.__get_users_group(group_name)
394 397
395 398 obj = self.sa.query(UsersGroupRepoToPerm)\
396 399 .filter(UsersGroupRepoToPerm.repository == repo)\
397 400 .filter(UsersGroupRepoToPerm.users_group == group_name)\
398 401 .one()
399 402 self.sa.delete(obj)
400 403
401 404 def delete_stats(self, repo_name):
402 405 """
403 406 removes stats for given repo
404 407
405 408 :param repo_name:
406 409 """
407 410 try:
408 411 obj = self.sa.query(Statistics)\
409 412 .filter(Statistics.repository ==
410 413 self.get_by_repo_name(repo_name))\
411 414 .one()
412 415 self.sa.delete(obj)
413 416 except:
414 417 log.error(traceback.format_exc())
415 418 raise
416 419
417 420 def __create_repo(self, repo_name, alias, new_parent_id, clone_uri=False):
418 421 """
419 422 makes repository on filesystem. It's group aware means it'll create
420 423 a repository within a group, and alter the paths accordingly of
421 424 group location
422 425
423 426 :param repo_name:
424 427 :param alias:
425 428 :param parent_id:
426 429 :param clone_uri:
427 430 """
428 431 from rhodecode.lib.utils import is_valid_repo, is_valid_repos_group
429 432
430 433 if new_parent_id:
431 434 paths = RepoGroup.get(new_parent_id)\
432 435 .full_path.split(RepoGroup.url_sep())
433 436 new_parent_path = os.sep.join(paths)
434 437 else:
435 438 new_parent_path = ''
436 439
437 440 # we need to make it str for mercurial
438 441 repo_path = os.path.join(*map(lambda x: safe_str(x),
439 442 [self.repos_path, new_parent_path, repo_name]))
440 443
441 444 # check if this path is not a repository
442 445 if is_valid_repo(repo_path, self.repos_path):
443 446 raise Exception('This path %s is a valid repository' % repo_path)
444 447
445 448 # check if this path is a group
446 449 if is_valid_repos_group(repo_path, self.repos_path):
447 450 raise Exception('This path %s is a valid group' % repo_path)
448 451
449 452 log.info('creating repo %s in %s @ %s' % (
450 453 repo_name, safe_unicode(repo_path), clone_uri
451 454 )
452 455 )
453 456 backend = get_backend(alias)
454 457
455 458 backend(repo_path, create=True, src_url=clone_uri)
456 459
457 460 def __rename_repo(self, old, new):
458 461 """
459 462 renames repository on filesystem
460 463
461 464 :param old: old name
462 465 :param new: new name
463 466 """
464 467 log.info('renaming repo from %s to %s' % (old, new))
465 468
466 469 old_path = os.path.join(self.repos_path, old)
467 470 new_path = os.path.join(self.repos_path, new)
468 471 if os.path.isdir(new_path):
469 472 raise Exception(
470 473 'Was trying to rename to already existing dir %s' % new_path
471 474 )
472 475 shutil.move(old_path, new_path)
473 476
474 477 def __delete_repo(self, repo):
475 478 """
476 479 removes repo from filesystem, the removal is acctually made by
477 480 added rm__ prefix into dir, and rename internat .hg/.git dirs so this
478 481 repository is no longer valid for rhodecode, can be undeleted later on
479 482 by reverting the renames on this repository
480 483
481 484 :param repo: repo object
482 485 """
483 486 rm_path = os.path.join(self.repos_path, repo.repo_name)
484 487 log.info("Removing %s" % (rm_path))
485 488 # disable hg/git
486 489 alias = repo.repo_type
487 490 shutil.move(os.path.join(rm_path, '.%s' % alias),
488 491 os.path.join(rm_path, 'rm__.%s' % alias))
489 492 # disable repo
490 493 _d = 'rm__%s__%s' % (datetime.now().strftime('%Y%m%d_%H%M%S_%f'),
491 494 repo.repo_name)
492 495 shutil.move(rm_path, os.path.join(self.repos_path, _d))
General Comments 0
You need to be logged in to leave comments. Login now