Show More
@@ -33,3 +33,4 b' List of contributors to RhodeCode projec' | |||||
33 | Philip Jameson <philip.j@hostdime.com> |
|
33 | Philip Jameson <philip.j@hostdime.com> | |
34 | Mads Kiilerich <madski@unity3d.com> |
|
34 | Mads Kiilerich <madski@unity3d.com> | |
35 | Dan Sheridan <djs@adelard.com> |
|
35 | Dan Sheridan <djs@adelard.com> | |
|
36 | Dennis Brakhane <brakhane@googlemail.com> |
@@ -75,7 +75,7 b' RhodeCode Features' | |||||
75 | - Supports http/https, LDAP, AD, proxy-pass authentication. |
|
75 | - Supports http/https, LDAP, AD, proxy-pass authentication. | |
76 | - Full permissions (private/read/write/admin) together with IP restrictions for each repository, |
|
76 | - Full permissions (private/read/write/admin) together with IP restrictions for each repository, | |
77 | additional explicit forking and repository creation permissions. |
|
77 | additional explicit forking and repository creation permissions. | |
78 |
- User |
|
78 | - User groups for easier permission management | |
79 | - Repository groups let you group repos and manage them easier. |
|
79 | - Repository groups let you group repos and manage them easier. | |
80 | - Users can fork other users repos, and compare them at any time. |
|
80 | - Users can fork other users repos, and compare them at any time. | |
81 | - Integrates easily with other systems, with custom created mappers you can connect it to almost |
|
81 | - Integrates easily with other systems, with custom created mappers you can connect it to almost |
@@ -436,7 +436,7 b' OUTPUT::' | |||||
436 | get_users_group |
|
436 | get_users_group | |
437 | --------------- |
|
437 | --------------- | |
438 |
|
438 | |||
439 |
Gets an existing user |
|
439 | Gets an existing user group. This command can be executed only using api_key | |
440 | belonging to user with admin rights. |
|
440 | belonging to user with admin rights. | |
441 |
|
441 | |||
442 |
|
442 | |||
@@ -446,7 +446,7 b' INPUT::' | |||||
446 | api_key : "<api_key>" |
|
446 | api_key : "<api_key>" | |
447 | method : "get_users_group" |
|
447 | method : "get_users_group" | |
448 | args : { |
|
448 | args : { | |
449 |
"usersgroupid" : "<user |
|
449 | "usersgroupid" : "<user group id or name>" | |
450 | } |
|
450 | } | |
451 |
|
451 | |||
452 | OUTPUT:: |
|
452 | OUTPUT:: | |
@@ -479,7 +479,7 b' OUTPUT::' | |||||
479 | get_users_groups |
|
479 | get_users_groups | |
480 | ---------------- |
|
480 | ---------------- | |
481 |
|
481 | |||
482 |
Lists all existing user |
|
482 | Lists all existing user groups. This command can be executed only using | |
483 | api_key belonging to user with admin rights. |
|
483 | api_key belonging to user with admin rights. | |
484 |
|
484 | |||
485 |
|
485 | |||
@@ -507,7 +507,7 b' OUTPUT::' | |||||
507 | create_users_group |
|
507 | create_users_group | |
508 | ------------------ |
|
508 | ------------------ | |
509 |
|
509 | |||
510 |
Creates new user |
|
510 | Creates new user group. This command can be executed only using api_key | |
511 | belonging to user with admin rights |
|
511 | belonging to user with admin rights | |
512 |
|
512 | |||
513 |
|
513 | |||
@@ -525,7 +525,7 b' OUTPUT::' | |||||
525 |
|
525 | |||
526 | id : <id_given_in_input> |
|
526 | id : <id_given_in_input> | |
527 | result: { |
|
527 | result: { | |
528 |
"msg": "created new user |
|
528 | "msg": "created new user group `<groupname>`", | |
529 | "users_group": { |
|
529 | "users_group": { | |
530 | "users_group_id" : "<id>", |
|
530 | "users_group_id" : "<id>", | |
531 | "group_name" : "<groupname>", |
|
531 | "group_name" : "<groupname>", | |
@@ -538,7 +538,7 b' OUTPUT::' | |||||
538 | add_user_to_users_group |
|
538 | add_user_to_users_group | |
539 | ----------------------- |
|
539 | ----------------------- | |
540 |
|
540 | |||
541 |
Adds a user to a user |
|
541 | Adds a user to a user group. If user exists in that group success will be | |
542 | `false`. This command can be executed only using api_key |
|
542 | `false`. This command can be executed only using api_key | |
543 | belonging to user with admin rights |
|
543 | belonging to user with admin rights | |
544 |
|
544 | |||
@@ -549,7 +549,7 b' INPUT::' | |||||
549 | api_key : "<api_key>" |
|
549 | api_key : "<api_key>" | |
550 | method : "add_user_users_group" |
|
550 | method : "add_user_users_group" | |
551 | args: { |
|
551 | args: { | |
552 |
"usersgroupid" : "<user |
|
552 | "usersgroupid" : "<user group id or name>", | |
553 | "userid" : "<user_id or username>", |
|
553 | "userid" : "<user_id or username>", | |
554 | } |
|
554 | } | |
555 |
|
555 | |||
@@ -558,7 +558,7 b' OUTPUT::' | |||||
558 | id : <id_given_in_input> |
|
558 | id : <id_given_in_input> | |
559 | result: { |
|
559 | result: { | |
560 | "success": True|False # depends on if member is in group |
|
560 | "success": True|False # depends on if member is in group | |
561 |
"msg": "added member `<username>` to user |
|
561 | "msg": "added member `<username>` to user group `<groupname>` | | |
562 | User is already in that group" |
|
562 | User is already in that group" | |
563 | } |
|
563 | } | |
564 | error: null |
|
564 | error: null | |
@@ -567,7 +567,7 b' OUTPUT::' | |||||
567 | remove_user_from_users_group |
|
567 | remove_user_from_users_group | |
568 | ---------------------------- |
|
568 | ---------------------------- | |
569 |
|
569 | |||
570 |
Removes a user from a user |
|
570 | Removes a user from a user group. If user is not in given group success will | |
571 | be `false`. This command can be executed only |
|
571 | be `false`. This command can be executed only | |
572 | using api_key belonging to user with admin rights |
|
572 | using api_key belonging to user with admin rights | |
573 |
|
573 | |||
@@ -578,7 +578,7 b' INPUT::' | |||||
578 | api_key : "<api_key>" |
|
578 | api_key : "<api_key>" | |
579 | method : "remove_user_from_users_group" |
|
579 | method : "remove_user_from_users_group" | |
580 | args: { |
|
580 | args: { | |
581 |
"usersgroupid" : "<user |
|
581 | "usersgroupid" : "<user group id or name>", | |
582 | "userid" : "<user_id or username>", |
|
582 | "userid" : "<user_id or username>", | |
583 | } |
|
583 | } | |
584 |
|
584 | |||
@@ -587,7 +587,7 b' OUTPUT::' | |||||
587 | id : <id_given_in_input> |
|
587 | id : <id_given_in_input> | |
588 | result: { |
|
588 | result: { | |
589 | "success": True|False, # depends on if member is in group |
|
589 | "success": True|False, # depends on if member is in group | |
590 |
"msg": "removed member <username> from user |
|
590 | "msg": "removed member <username> from user group <groupname> | | |
591 | User wasn't in group" |
|
591 | User wasn't in group" | |
592 | } |
|
592 | } | |
593 | error: null |
|
593 | error: null | |
@@ -929,7 +929,7 b' OUTPUT::' | |||||
929 | grant_users_group_permission |
|
929 | grant_users_group_permission | |
930 | ---------------------------- |
|
930 | ---------------------------- | |
931 |
|
931 | |||
932 |
Grant permission for user |
|
932 | Grant permission for user group on given repository, or update | |
933 | existing one if found. This command can be executed only using |
|
933 | existing one if found. This command can be executed only using | |
934 | api_key belonging to user with admin rights. |
|
934 | api_key belonging to user with admin rights. | |
935 |
|
935 | |||
@@ -941,7 +941,7 b' INPUT::' | |||||
941 | method : "grant_users_group_permission" |
|
941 | method : "grant_users_group_permission" | |
942 | args: { |
|
942 | args: { | |
943 | "repoid" : "<reponame or repo_id>" |
|
943 | "repoid" : "<reponame or repo_id>" | |
944 |
"usersgroupid" : "<user |
|
944 | "usersgroupid" : "<user group id or name>" | |
945 | "perm" : "(repository.(none|read|write|admin))", |
|
945 | "perm" : "(repository.(none|read|write|admin))", | |
946 | } |
|
946 | } | |
947 |
|
947 | |||
@@ -958,7 +958,7 b' OUTPUT::' | |||||
958 | revoke_users_group_permission |
|
958 | revoke_users_group_permission | |
959 | ----------------------------- |
|
959 | ----------------------------- | |
960 |
|
960 | |||
961 |
Revoke permission for user |
|
961 | Revoke permission for user group on given repository.This command can be | |
962 | executed only using api_key belonging to user with admin rights. |
|
962 | executed only using api_key belonging to user with admin rights. | |
963 |
|
963 | |||
964 | INPUT:: |
|
964 | INPUT:: | |
@@ -968,7 +968,7 b' INPUT::' | |||||
968 | method : "revoke_users_group_permission" |
|
968 | method : "revoke_users_group_permission" | |
969 | args: { |
|
969 | args: { | |
970 | "repoid" : "<reponame or repo_id>" |
|
970 | "repoid" : "<reponame or repo_id>" | |
971 |
"usersgroupid" : "<user |
|
971 | "usersgroupid" : "<user group id or name>" | |
972 | } |
|
972 | } | |
973 |
|
973 | |||
974 | OUTPUT:: |
|
974 | OUTPUT:: |
@@ -196,7 +196,7 b' news' | |||||
196 | fixes |
|
196 | fixes | |
197 | +++++ |
|
197 | +++++ | |
198 |
|
198 | |||
199 |
- fixed #570 explicit user |
|
199 | - fixed #570 explicit user group permissions can overwrite owner permissions | |
200 | - fixed #578 set proper PATH with current Python for Git |
|
200 | - fixed #578 set proper PATH with current Python for Git | |
201 | hooks to execute within same Python as RhodeCode |
|
201 | hooks to execute within same Python as RhodeCode | |
202 | - fixed issue with Git bare repos that ends with .git in name |
|
202 | - fixed issue with Git bare repos that ends with .git in name | |
@@ -385,7 +385,7 b' news' | |||||
385 | - created rcextensions module with additional mappings (ref #322) and |
|
385 | - created rcextensions module with additional mappings (ref #322) and | |
386 | post push/pull/create repo hooks callbacks |
|
386 | post push/pull/create repo hooks callbacks | |
387 | - implemented #377 Users view for his own permissions on account page |
|
387 | - implemented #377 Users view for his own permissions on account page | |
388 |
- #399 added inheritance of permissions for user |
|
388 | - #399 added inheritance of permissions for user group on repos groups | |
389 | - #401 repository group is automatically pre-selected when adding repos |
|
389 | - #401 repository group is automatically pre-selected when adding repos | |
390 | inside a repository group |
|
390 | inside a repository group | |
391 | - added alternative HTTP 403 response when client failed to authenticate. Helps |
|
391 | - added alternative HTTP 403 response when client failed to authenticate. Helps | |
@@ -520,7 +520,7 b' fixes' | |||||
520 | and groups |
|
520 | and groups | |
521 | - fixes #271 rare JSON serialization problem with statistics |
|
521 | - fixes #271 rare JSON serialization problem with statistics | |
522 | - fixes #337 missing validation check for conflicting names of a group with a |
|
522 | - fixes #337 missing validation check for conflicting names of a group with a | |
523 |
repositor |
|
523 | repository group | |
524 | - #340 fixed session problem for mysql and celery tasks |
|
524 | - #340 fixed session problem for mysql and celery tasks | |
525 | - fixed #331 RhodeCode mangles repository names if the a repository group |
|
525 | - fixed #331 RhodeCode mangles repository names if the a repository group | |
526 | contains the "full path" to the repositories |
|
526 | contains the "full path" to the repositories | |
@@ -654,7 +654,7 b' news' | |||||
654 | - implemented #93 customizable changelog on combined revision ranges - |
|
654 | - implemented #93 customizable changelog on combined revision ranges - | |
655 | equivalent of githubs compare view |
|
655 | equivalent of githubs compare view | |
656 | - implemented #108 extended and more powerful LDAP configuration |
|
656 | - implemented #108 extended and more powerful LDAP configuration | |
657 |
- implemented #56 user |
|
657 | - implemented #56 user groups | |
658 | - major code rewrites optimized codes for speed and memory usage |
|
658 | - major code rewrites optimized codes for speed and memory usage | |
659 | - raw and diff downloads are now in git format |
|
659 | - raw and diff downloads are now in git format | |
660 | - setup command checks for write access to given path |
|
660 | - setup command checks for write access to given path |
@@ -47,7 +47,7 b' choose "Visual C++ 2008 Express" when in' | |||||
47 | required, you can uncheck them |
|
47 | required, you can uncheck them | |
48 |
|
48 | |||
49 | .. note:: |
|
49 | .. note:: | |
50 |
|
50 | |||
51 | 64bit: You also need to install the Microsoft Windows SDK for .NET 3.5 SP1 (.NET 4.0 won't work). |
|
51 | 64bit: You also need to install the Microsoft Windows SDK for .NET 3.5 SP1 (.NET 4.0 won't work). | |
52 | Download from: http://www.microsoft.com/en-us/download/details.aspx?id=3138 |
|
52 | Download from: http://www.microsoft.com/en-us/download/details.aspx?id=3138 | |
53 |
|
53 | |||
@@ -90,7 +90,7 b' http://sourceforge.net/projects/pywin32/' | |||||
90 | .. note:: |
|
90 | .. note:: | |
91 |
|
91 | |||
92 | 64bit: Download and install the 64bit version. |
|
92 | 64bit: Download and install the 64bit version. | |
93 |
At the time of writing you can find this at: |
|
93 | At the time of writing you can find this at: | |
94 | http://sourceforge.net/projects/pywin32/files/pywin32/Build%20218/pywin32-218.win-amd64-py2.7.exe/download |
|
94 | http://sourceforge.net/projects/pywin32/files/pywin32/Build%20218/pywin32-218.win-amd64-py2.7.exe/download | |
95 |
|
95 | |||
96 | Step4 - Python BIN |
|
96 | Step4 - Python BIN |
@@ -51,4 +51,4 b'' | |||||
51 | .vc { color: #ff99ff } /* Name.Variable.Class */ |
|
51 | .vc { color: #ff99ff } /* Name.Variable.Class */ | |
52 | .vg { color: #ff99ff } /* Name.Variable.Global */ |
|
52 | .vg { color: #ff99ff } /* Name.Variable.Global */ | |
53 | .vi { color: #ff99ff } /* Name.Variable.Instance */ |
|
53 | .vi { color: #ff99ff } /* Name.Variable.Instance */ | |
54 | .il { color: #009999 } /* Literal.Number.Integer.Long */ No newline at end of file |
|
54 | .il { color: #009999 } /* Literal.Number.Integer.Long */ |
@@ -46,19 +46,17 b' 3. Scale RhodeCode horizontally' | |||||
46 | large traffic (large amount of users, CI servers etc). RhodeCode can be |
|
46 | large traffic (large amount of users, CI servers etc). RhodeCode can be | |
47 | scaled horizontally on one (recommended) or multiple machines. In order |
|
47 | scaled horizontally on one (recommended) or multiple machines. In order | |
48 | to scale horizontally you need to do the following: |
|
48 | to scale horizontally you need to do the following: | |
49 |
|
49 | |||
50 | - each instance needs it's own .ini file and unique `instance_id` set in them |
|
50 | - each instance needs it's own .ini file and unique `instance_id` set in them | |
51 |
- each instance `data` storage needs to be configured to be stored on a |
|
51 | - each instance `data` storage needs to be configured to be stored on a | |
52 | shared disk storage, preferably together with repositories. This `data` |
|
52 | shared disk storage, preferably together with repositories. This `data` | |
53 | dir contains template caches, sessions, whoosh index and it's used for |
|
53 | dir contains template caches, sessions, whoosh index and it's used for | |
54 | tasks locking (so it's safe across multiple instances). Set the |
|
54 | tasks locking (so it's safe across multiple instances). Set the | |
55 | `cache_dir`, `index_dir`, `beaker.cache.data_dir`, `beaker.cache.lock_dir` |
|
55 | `cache_dir`, `index_dir`, `beaker.cache.data_dir`, `beaker.cache.lock_dir` | |
56 |
variables in each .ini file to shared location across RhodeCode instances |
|
56 | variables in each .ini file to shared location across RhodeCode instances | |
57 | - if celery is used each instance should run separate celery instance, but |
|
57 | - if celery is used each instance should run separate celery instance, but | |
58 | the message broken should be common to all of them (ex one rabbitmq |
|
58 | the message broken should be common to all of them (ex one rabbitmq | |
59 |
shared server) |
|
59 | shared server) | |
60 | - load balance using round robin or ip hash, recommended is writing LB rules |
|
60 | - load balance using round robin or ip hash, recommended is writing LB rules | |
61 | that will separate regular user traffic from automated processes like CI |
|
61 | that will separate regular user traffic from automated processes like CI | |
62 | servers or build bots. |
|
62 | servers or build bots. | |
63 |
|
||||
64 |
|
@@ -48,7 +48,7 b' def make_map(config):' | |||||
48 |
|
48 | |||
49 | def check_group(environ, match_dict): |
|
49 | def check_group(environ, match_dict): | |
50 | """ |
|
50 | """ | |
51 |
check for valid repositor |
|
51 | check for valid repository group for proper 404 handling | |
52 |
|
52 | |||
53 | :param environ: |
|
53 | :param environ: | |
54 | :param match_dict: |
|
54 | :param match_dict: | |
@@ -235,7 +235,7 b' def make_map(config):' | |||||
235 | m.connect("user_ips_delete", "/users_ips/{id}", |
|
235 | m.connect("user_ips_delete", "/users_ips/{id}", | |
236 | action="delete_ip", conditions=dict(method=["DELETE"])) |
|
236 | action="delete_ip", conditions=dict(method=["DELETE"])) | |
237 |
|
237 | |||
238 |
#ADMIN USER |
|
238 | #ADMIN USER GROUPS REST ROUTES | |
239 | with rmap.submapper(path_prefix=ADMIN_PREFIX, |
|
239 | with rmap.submapper(path_prefix=ADMIN_PREFIX, | |
240 | controller='admin/users_groups') as m: |
|
240 | controller='admin/users_groups') as m: | |
241 | m.connect("users_groups", "/users_groups", |
|
241 | m.connect("users_groups", "/users_groups", |
@@ -28,7 +28,7 b' import traceback' | |||||
28 |
|
28 | |||
29 | from pylons import request |
|
29 | from pylons import request | |
30 | from pylons import tmpl_context as c, url |
|
30 | from pylons import tmpl_context as c, url | |
31 | from pylons.controllers.util import redirect |
|
31 | from pylons.controllers.util import redirect, abort | |
32 |
|
32 | |||
33 | from webhelpers.paginate import Page |
|
33 | from webhelpers.paginate import Page | |
34 |
|
34 | |||
@@ -117,7 +117,7 b' class NotificationsController(BaseContro' | |||||
117 | Session().commit() |
|
117 | Session().commit() | |
118 | return 'ok' |
|
118 | return 'ok' | |
119 | except Exception: |
|
119 | except Exception: | |
120 | Session.rollback() |
|
120 | Session().rollback() | |
121 | log.error(traceback.format_exc()) |
|
121 | log.error(traceback.format_exc()) | |
122 | return 'fail' |
|
122 | return 'fail' | |
123 |
|
123 | |||
@@ -139,7 +139,7 b' class NotificationsController(BaseContro' | |||||
139 | Session().commit() |
|
139 | Session().commit() | |
140 | return 'ok' |
|
140 | return 'ok' | |
141 | except Exception: |
|
141 | except Exception: | |
142 | Session.rollback() |
|
142 | Session().rollback() | |
143 | log.error(traceback.format_exc()) |
|
143 | log.error(traceback.format_exc()) | |
144 | return 'fail' |
|
144 | return 'fail' | |
145 |
|
145 | |||
@@ -149,8 +149,9 b' class NotificationsController(BaseContro' | |||||
149 | c.user = self.rhodecode_user |
|
149 | c.user = self.rhodecode_user | |
150 | no = Notification.get(notification_id) |
|
150 | no = Notification.get(notification_id) | |
151 |
|
151 | |||
152 |
owner = a |
|
152 | owner = any(un.user.user_id == c.rhodecode_user.user_id | |
153 | for un in no.notifications_to_users) |
|
153 | for un in no.notifications_to_users) | |
|
154 | ||||
154 | if no and (h.HasPermissionAny('hg.admin', 'repository.admin')() or owner): |
|
155 | if no and (h.HasPermissionAny('hg.admin', 'repository.admin')() or owner): | |
155 | unotification = NotificationModel()\ |
|
156 | unotification = NotificationModel()\ | |
156 | .get_user_notification(c.user.user_id, no) |
|
157 | .get_user_notification(c.user.user_id, no) | |
@@ -165,7 +166,7 b' class NotificationsController(BaseContro' | |||||
165 |
|
166 | |||
166 | return render('admin/notifications/show_notification.html') |
|
167 | return render('admin/notifications/show_notification.html') | |
167 |
|
168 | |||
168 | return redirect(url('notifications')) |
|
169 | return abort(403) | |
169 |
|
170 | |||
170 | def edit(self, notification_id, format='html'): |
|
171 | def edit(self, notification_id, format='html'): | |
171 | """GET /_admin/notifications/id/edit: Form to edit an existing item""" |
|
172 | """GET /_admin/notifications/id/edit: Form to edit an existing item""" |
@@ -345,7 +345,7 b' class ReposController(BaseRepoController' | |||||
345 | @HasRepoPermissionAllDecorator('repository.admin') |
|
345 | @HasRepoPermissionAllDecorator('repository.admin') | |
346 | def delete_perm_users_group(self, repo_name): |
|
346 | def delete_perm_users_group(self, repo_name): | |
347 | """ |
|
347 | """ | |
348 |
DELETE an existing repository permission user |
|
348 | DELETE an existing repository permission user group | |
349 |
|
349 | |||
350 | :param repo_name: |
|
350 | :param repo_name: | |
351 | """ |
|
351 | """ | |
@@ -358,7 +358,7 b' class ReposController(BaseRepoController' | |||||
358 | except Exception: |
|
358 | except Exception: | |
359 | log.error(traceback.format_exc()) |
|
359 | log.error(traceback.format_exc()) | |
360 | h.flash(_('An error occurred during deletion of repository' |
|
360 | h.flash(_('An error occurred during deletion of repository' | |
361 |
' user |
|
361 | ' user groups'), | |
362 | category='error') |
|
362 | category='error') | |
363 | raise HTTPInternalServerError() |
|
363 | raise HTTPInternalServerError() | |
364 |
|
364 |
@@ -3,7 +3,7 b'' | |||||
3 | rhodecode.controllers.admin.repos_groups |
|
3 | rhodecode.controllers.admin.repos_groups | |
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
5 |
|
5 | |||
6 |
Repositor |
|
6 | Repository groups controller for RhodeCode | |
7 |
|
7 | |||
8 | :created_on: Mar 23, 2010 |
|
8 | :created_on: Mar 23, 2010 | |
9 | :author: marcink |
|
9 | :author: marcink | |
@@ -282,7 +282,7 b' class ReposGroupsController(BaseControll' | |||||
282 | @HasReposGroupPermissionAnyDecorator('group.admin') |
|
282 | @HasReposGroupPermissionAnyDecorator('group.admin') | |
283 | def delete_repos_group_user_perm(self, group_name): |
|
283 | def delete_repos_group_user_perm(self, group_name): | |
284 | """ |
|
284 | """ | |
285 |
DELETE an existing repositor |
|
285 | DELETE an existing repository group permission user | |
286 |
|
286 | |||
287 | :param group_name: |
|
287 | :param group_name: | |
288 | """ |
|
288 | """ | |
@@ -307,7 +307,7 b' class ReposGroupsController(BaseControll' | |||||
307 | @HasReposGroupPermissionAnyDecorator('group.admin') |
|
307 | @HasReposGroupPermissionAnyDecorator('group.admin') | |
308 | def delete_repos_group_users_group_perm(self, group_name): |
|
308 | def delete_repos_group_users_group_perm(self, group_name): | |
309 | """ |
|
309 | """ | |
310 |
DELETE an existing repositor |
|
310 | DELETE an existing repository group permission user group | |
311 |
|
311 | |||
312 | :param group_name: |
|
312 | :param group_name: | |
313 | """ |
|
313 | """ | |
@@ -322,7 +322,7 b' class ReposGroupsController(BaseControll' | |||||
322 | except Exception: |
|
322 | except Exception: | |
323 | log.error(traceback.format_exc()) |
|
323 | log.error(traceback.format_exc()) | |
324 | h.flash(_('An error occurred during deletion of group' |
|
324 | h.flash(_('An error occurred during deletion of group' | |
325 |
' user |
|
325 | ' user groups'), | |
326 | category='error') |
|
326 | category='error') | |
327 | raise HTTPInternalServerError() |
|
327 | raise HTTPInternalServerError() | |
328 |
|
328 |
@@ -474,18 +474,23 b' class SettingsController(BaseController)' | |||||
474 |
|
474 | |||
475 | @NotAnonymous() |
|
475 | @NotAnonymous() | |
476 | def my_account_my_pullrequests(self): |
|
476 | def my_account_my_pullrequests(self): | |
477 | c.my_pull_requests = PullRequest.query()\ |
|
477 | c.show_closed = request.GET.get('pr_show_closed') | |
|
478 | ||||
|
479 | def _filter(pr): | |||
|
480 | s = sorted(pr, key=lambda o: o.created_on, reverse=True) | |||
|
481 | if not c.show_closed: | |||
|
482 | s = filter(lambda p: p.status != PullRequest.STATUS_CLOSED, s) | |||
|
483 | return s | |||
|
484 | ||||
|
485 | c.my_pull_requests = _filter(PullRequest.query()\ | |||
478 | .filter(PullRequest.user_id == |
|
486 | .filter(PullRequest.user_id == | |
479 | self.rhodecode_user.user_id)\ |
|
487 | self.rhodecode_user.user_id)\ | |
480 |
. |
|
488 | .all()) | |
481 | .all() |
|
|||
482 |
|
489 | |||
483 |
c.participate_in_pull_requests = |
|
490 | c.participate_in_pull_requests = _filter([ | |
484 |
|
|
491 | x.pull_request for x in PullRequestReviewers.query()\ | |
485 |
|
|
492 | .filter(PullRequestReviewers.user_id == | |
486 |
|
|
493 | self.rhodecode_user.user_id).all()]) | |
487 | .all()], |
|
|||
488 | key=lambda o: o.created_on, reverse=True) |
|
|||
489 |
|
494 | |||
490 | return render('admin/users/user_edit_my_account_pullrequests.html') |
|
495 | return render('admin/users/user_edit_my_account_pullrequests.html') | |
491 |
|
496 |
@@ -3,7 +3,7 b'' | |||||
3 | rhodecode.controllers.admin.users_groups |
|
3 | rhodecode.controllers.admin.users_groups | |
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
5 |
|
5 | |||
6 |
User |
|
6 | User Groups crud controller for pylons | |
7 |
|
7 | |||
8 | :created_on: Jan 25, 2011 |
|
8 | :created_on: Jan 25, 2011 | |
9 | :author: marcink |
|
9 | :author: marcink | |
@@ -33,16 +33,16 b' from pylons.controllers.util import abor' | |||||
33 | from pylons.i18n.translation import _ |
|
33 | from pylons.i18n.translation import _ | |
34 |
|
34 | |||
35 | from rhodecode.lib import helpers as h |
|
35 | from rhodecode.lib import helpers as h | |
36 |
from rhodecode.lib.exceptions import User |
|
36 | from rhodecode.lib.exceptions import UserGroupsAssignedException | |
37 | from rhodecode.lib.utils2 import safe_unicode, str2bool |
|
37 | from rhodecode.lib.utils2 import safe_unicode, str2bool | |
38 | from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator |
|
38 | from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator | |
39 | from rhodecode.lib.base import BaseController, render |
|
39 | from rhodecode.lib.base import BaseController, render | |
40 |
|
40 | |||
41 |
from rhodecode.model.users_group import User |
|
41 | from rhodecode.model.users_group import UserGroupModel | |
42 |
|
42 | |||
43 |
from rhodecode.model.db import User, User |
|
43 | from rhodecode.model.db import User, UserGroup, UserGroupToPerm,\ | |
44 |
User |
|
44 | UserGroupRepoToPerm, UserGroupRepoGroupToPerm | |
45 |
from rhodecode.model.forms import User |
|
45 | from rhodecode.model.forms import UserGroupForm | |
46 | from rhodecode.model.meta import Session |
|
46 | from rhodecode.model.meta import Session | |
47 | from rhodecode.lib.utils import action_logger |
|
47 | from rhodecode.lib.utils import action_logger | |
48 | from sqlalchemy.orm import joinedload |
|
48 | from sqlalchemy.orm import joinedload | |
@@ -67,23 +67,23 b' class UsersGroupsController(BaseControll' | |||||
67 | def index(self, format='html'): |
|
67 | def index(self, format='html'): | |
68 | """GET /users_groups: All items in the collection""" |
|
68 | """GET /users_groups: All items in the collection""" | |
69 | # url('users_groups') |
|
69 | # url('users_groups') | |
70 |
c.users_groups_list = User |
|
70 | c.users_groups_list = UserGroup().query().all() | |
71 | return render('admin/users_groups/users_groups.html') |
|
71 | return render('admin/users_groups/users_groups.html') | |
72 |
|
72 | |||
73 | def create(self): |
|
73 | def create(self): | |
74 | """POST /users_groups: Create a new item""" |
|
74 | """POST /users_groups: Create a new item""" | |
75 | # url('users_groups') |
|
75 | # url('users_groups') | |
76 |
|
76 | |||
77 |
users_group_form = User |
|
77 | users_group_form = UserGroupForm()() | |
78 | try: |
|
78 | try: | |
79 | form_result = users_group_form.to_python(dict(request.POST)) |
|
79 | form_result = users_group_form.to_python(dict(request.POST)) | |
80 |
User |
|
80 | UserGroupModel().create(name=form_result['users_group_name'], | |
81 | active=form_result['users_group_active']) |
|
81 | active=form_result['users_group_active']) | |
82 | gr = form_result['users_group_name'] |
|
82 | gr = form_result['users_group_name'] | |
83 | action_logger(self.rhodecode_user, |
|
83 | action_logger(self.rhodecode_user, | |
84 | 'admin_created_users_group:%s' % gr, |
|
84 | 'admin_created_users_group:%s' % gr, | |
85 | None, self.ip_addr, self.sa) |
|
85 | None, self.ip_addr, self.sa) | |
86 |
h.flash(_('created user |
|
86 | h.flash(_('created user group %s') % gr, category='success') | |
87 | Session().commit() |
|
87 | Session().commit() | |
88 | except formencode.Invalid, errors: |
|
88 | except formencode.Invalid, errors: | |
89 | return htmlfill.render( |
|
89 | return htmlfill.render( | |
@@ -94,7 +94,7 b' class UsersGroupsController(BaseControll' | |||||
94 | encoding="UTF-8") |
|
94 | encoding="UTF-8") | |
95 | except Exception: |
|
95 | except Exception: | |
96 | log.error(traceback.format_exc()) |
|
96 | log.error(traceback.format_exc()) | |
97 |
h.flash(_('error occurred during creation of user |
|
97 | h.flash(_('error occurred during creation of user group %s') \ | |
98 | % request.POST.get('users_group_name'), category='error') |
|
98 | % request.POST.get('users_group_name'), category='error') | |
99 |
|
99 | |||
100 | return redirect(url('users_groups')) |
|
100 | return redirect(url('users_groups')) | |
@@ -110,20 +110,20 b' class UsersGroupsController(BaseControll' | |||||
110 | 'repositories_groups': {} |
|
110 | 'repositories_groups': {} | |
111 | } |
|
111 | } | |
112 |
|
112 | |||
113 |
ugroup_repo_perms = User |
|
113 | ugroup_repo_perms = UserGroupRepoToPerm.query()\ | |
114 |
.options(joinedload(User |
|
114 | .options(joinedload(UserGroupRepoToPerm.permission))\ | |
115 |
.options(joinedload(User |
|
115 | .options(joinedload(UserGroupRepoToPerm.repository))\ | |
116 |
.filter(User |
|
116 | .filter(UserGroupRepoToPerm.users_group_id == id)\ | |
117 | .all() |
|
117 | .all() | |
118 |
|
118 | |||
119 | for gr in ugroup_repo_perms: |
|
119 | for gr in ugroup_repo_perms: | |
120 | c.users_group.permissions['repositories'][gr.repository.repo_name] \ |
|
120 | c.users_group.permissions['repositories'][gr.repository.repo_name] \ | |
121 | = gr.permission.permission_name |
|
121 | = gr.permission.permission_name | |
122 |
|
122 | |||
123 |
ugroup_group_perms = User |
|
123 | ugroup_group_perms = UserGroupRepoGroupToPerm.query()\ | |
124 |
.options(joinedload(User |
|
124 | .options(joinedload(UserGroupRepoGroupToPerm.permission))\ | |
125 |
.options(joinedload(User |
|
125 | .options(joinedload(UserGroupRepoGroupToPerm.group))\ | |
126 |
.filter(User |
|
126 | .filter(UserGroupRepoGroupToPerm.users_group_id == id)\ | |
127 | .all() |
|
127 | .all() | |
128 |
|
128 | |||
129 | for gr in ugroup_group_perms: |
|
129 | for gr in ugroup_group_perms: | |
@@ -145,26 +145,26 b' class UsersGroupsController(BaseControll' | |||||
145 | # method='put') |
|
145 | # method='put') | |
146 | # url('users_group', id=ID) |
|
146 | # url('users_group', id=ID) | |
147 |
|
147 | |||
148 |
c.users_group = User |
|
148 | c.users_group = UserGroup.get_or_404(id) | |
149 | self._load_data(id) |
|
149 | self._load_data(id) | |
150 |
|
150 | |||
151 | available_members = [safe_unicode(x[0]) for x in c.available_members] |
|
151 | available_members = [safe_unicode(x[0]) for x in c.available_members] | |
152 |
|
152 | |||
153 |
users_group_form = User |
|
153 | users_group_form = UserGroupForm(edit=True, | |
154 | old_data=c.users_group.get_dict(), |
|
154 | old_data=c.users_group.get_dict(), | |
155 | available_members=available_members)() |
|
155 | available_members=available_members)() | |
156 |
|
156 | |||
157 | try: |
|
157 | try: | |
158 | form_result = users_group_form.to_python(request.POST) |
|
158 | form_result = users_group_form.to_python(request.POST) | |
159 |
User |
|
159 | UserGroupModel().update(c.users_group, form_result) | |
160 | gr = form_result['users_group_name'] |
|
160 | gr = form_result['users_group_name'] | |
161 | action_logger(self.rhodecode_user, |
|
161 | action_logger(self.rhodecode_user, | |
162 | 'admin_updated_users_group:%s' % gr, |
|
162 | 'admin_updated_users_group:%s' % gr, | |
163 | None, self.ip_addr, self.sa) |
|
163 | None, self.ip_addr, self.sa) | |
164 |
h.flash(_('updated user |
|
164 | h.flash(_('updated user group %s') % gr, category='success') | |
165 | Session().commit() |
|
165 | Session().commit() | |
166 | except formencode.Invalid, errors: |
|
166 | except formencode.Invalid, errors: | |
167 |
ug_model = User |
|
167 | ug_model = UserGroupModel() | |
168 | defaults = errors.value |
|
168 | defaults = errors.value | |
169 | e = errors.error_dict or {} |
|
169 | e = errors.error_dict or {} | |
170 | defaults.update({ |
|
170 | defaults.update({ | |
@@ -183,7 +183,7 b' class UsersGroupsController(BaseControll' | |||||
183 | encoding="UTF-8") |
|
183 | encoding="UTF-8") | |
184 | except Exception: |
|
184 | except Exception: | |
185 | log.error(traceback.format_exc()) |
|
185 | log.error(traceback.format_exc()) | |
186 |
h.flash(_('error occurred during update of user |
|
186 | h.flash(_('error occurred during update of user group %s') \ | |
187 | % request.POST.get('users_group_name'), category='error') |
|
187 | % request.POST.get('users_group_name'), category='error') | |
188 |
|
188 | |||
189 | return redirect(url('edit_users_group', id=id)) |
|
189 | return redirect(url('edit_users_group', id=id)) | |
@@ -196,16 +196,16 b' class UsersGroupsController(BaseControll' | |||||
196 | # h.form(url('users_group', id=ID), |
|
196 | # h.form(url('users_group', id=ID), | |
197 | # method='delete') |
|
197 | # method='delete') | |
198 | # url('users_group', id=ID) |
|
198 | # url('users_group', id=ID) | |
199 |
usr_gr = User |
|
199 | usr_gr = UserGroup.get_or_404(id) | |
200 | try: |
|
200 | try: | |
201 |
User |
|
201 | UserGroupModel().delete(usr_gr) | |
202 | Session().commit() |
|
202 | Session().commit() | |
203 |
h.flash(_('successfully deleted user |
|
203 | h.flash(_('successfully deleted user group'), category='success') | |
204 |
except User |
|
204 | except UserGroupsAssignedException, e: | |
205 | h.flash(e, category='error') |
|
205 | h.flash(e, category='error') | |
206 | except Exception: |
|
206 | except Exception: | |
207 | log.error(traceback.format_exc()) |
|
207 | log.error(traceback.format_exc()) | |
208 |
h.flash(_('An error occurred during deletion of user |
|
208 | h.flash(_('An error occurred during deletion of user group'), | |
209 | category='error') |
|
209 | category='error') | |
210 | return redirect(url('users_groups')) |
|
210 | return redirect(url('users_groups')) | |
211 |
|
211 | |||
@@ -217,10 +217,10 b' class UsersGroupsController(BaseControll' | |||||
217 | """GET /users_groups/id/edit: Form to edit an existing item""" |
|
217 | """GET /users_groups/id/edit: Form to edit an existing item""" | |
218 | # url('edit_users_group', id=ID) |
|
218 | # url('edit_users_group', id=ID) | |
219 |
|
219 | |||
220 |
c.users_group = User |
|
220 | c.users_group = UserGroup.get_or_404(id) | |
221 | self._load_data(id) |
|
221 | self._load_data(id) | |
222 |
|
222 | |||
223 |
ug_model = User |
|
223 | ug_model = UserGroupModel() | |
224 | defaults = c.users_group.get_dict() |
|
224 | defaults = c.users_group.get_dict() | |
225 | defaults.update({ |
|
225 | defaults.update({ | |
226 | 'create_repo_perm': ug_model.has_perm(c.users_group, |
|
226 | 'create_repo_perm': ug_model.has_perm(c.users_group, | |
@@ -240,37 +240,37 b' class UsersGroupsController(BaseControll' | |||||
240 | """PUT /users_perm/id: Update an existing item""" |
|
240 | """PUT /users_perm/id: Update an existing item""" | |
241 | # url('users_group_perm', id=ID, method='put') |
|
241 | # url('users_group_perm', id=ID, method='put') | |
242 |
|
242 | |||
243 |
users_group = User |
|
243 | users_group = UserGroup.get_or_404(id) | |
244 | grant_create_perm = str2bool(request.POST.get('create_repo_perm')) |
|
244 | grant_create_perm = str2bool(request.POST.get('create_repo_perm')) | |
245 | grant_fork_perm = str2bool(request.POST.get('fork_repo_perm')) |
|
245 | grant_fork_perm = str2bool(request.POST.get('fork_repo_perm')) | |
246 | inherit_perms = str2bool(request.POST.get('inherit_default_permissions')) |
|
246 | inherit_perms = str2bool(request.POST.get('inherit_default_permissions')) | |
247 |
|
247 | |||
248 |
user |
|
248 | usergroup_model = UserGroupModel() | |
249 |
|
249 | |||
250 | try: |
|
250 | try: | |
251 | users_group.inherit_default_permissions = inherit_perms |
|
251 | users_group.inherit_default_permissions = inherit_perms | |
252 | Session().add(users_group) |
|
252 | Session().add(users_group) | |
253 |
|
253 | |||
254 | if grant_create_perm: |
|
254 | if grant_create_perm: | |
255 |
user |
|
255 | usergroup_model.revoke_perm(id, 'hg.create.none') | |
256 |
user |
|
256 | usergroup_model.grant_perm(id, 'hg.create.repository') | |
257 |
h.flash(_("Granted 'repository create' permission to user |
|
257 | h.flash(_("Granted 'repository create' permission to user group"), | |
258 | category='success') |
|
258 | category='success') | |
259 | else: |
|
259 | else: | |
260 |
user |
|
260 | usergroup_model.revoke_perm(id, 'hg.create.repository') | |
261 |
user |
|
261 | usergroup_model.grant_perm(id, 'hg.create.none') | |
262 |
h.flash(_("Revoked 'repository create' permission to user |
|
262 | h.flash(_("Revoked 'repository create' permission to user group"), | |
263 | category='success') |
|
263 | category='success') | |
264 |
|
264 | |||
265 | if grant_fork_perm: |
|
265 | if grant_fork_perm: | |
266 |
user |
|
266 | usergroup_model.revoke_perm(id, 'hg.fork.none') | |
267 |
user |
|
267 | usergroup_model.grant_perm(id, 'hg.fork.repository') | |
268 |
h.flash(_("Granted 'repository fork' permission to user |
|
268 | h.flash(_("Granted 'repository fork' permission to user group"), | |
269 | category='success') |
|
269 | category='success') | |
270 | else: |
|
270 | else: | |
271 |
user |
|
271 | usergroup_model.revoke_perm(id, 'hg.fork.repository') | |
272 |
user |
|
272 | usergroup_model.grant_perm(id, 'hg.fork.none') | |
273 |
h.flash(_("Revoked 'repository fork' permission to user |
|
273 | h.flash(_("Revoked 'repository fork' permission to user group"), | |
274 | category='success') |
|
274 | category='success') | |
275 |
|
275 | |||
276 | Session().commit() |
|
276 | Session().commit() |
@@ -34,11 +34,12 b' from rhodecode.lib.auth import PasswordG' | |||||
34 | HasPermissionAllDecorator, HasPermissionAnyDecorator, \ |
|
34 | HasPermissionAllDecorator, HasPermissionAnyDecorator, \ | |
35 | HasPermissionAnyApi, HasRepoPermissionAnyApi |
|
35 | HasPermissionAnyApi, HasRepoPermissionAnyApi | |
36 | from rhodecode.lib.utils import map_groups, repo2db_mapper |
|
36 | from rhodecode.lib.utils import map_groups, repo2db_mapper | |
|
37 | from rhodecode.lib.utils2 import str2bool | |||
37 | from rhodecode.model.meta import Session |
|
38 | from rhodecode.model.meta import Session | |
38 | from rhodecode.model.scm import ScmModel |
|
39 | from rhodecode.model.scm import ScmModel | |
39 | from rhodecode.model.repo import RepoModel |
|
40 | from rhodecode.model.repo import RepoModel | |
40 | from rhodecode.model.user import UserModel |
|
41 | from rhodecode.model.user import UserModel | |
41 |
from rhodecode.model.users_group import User |
|
42 | from rhodecode.model.users_group import UserGroupModel | |
42 | from rhodecode.model.permission import PermissionModel |
|
43 | from rhodecode.model.permission import PermissionModel | |
43 | from rhodecode.model.db import Repository, RhodeCodeSetting, UserIpMap |
|
44 | from rhodecode.model.db import Repository, RhodeCodeSetting, UserIpMap | |
44 |
|
45 | |||
@@ -121,13 +122,13 b' def get_repo_or_error(repoid):' | |||||
121 |
|
122 | |||
122 | def get_users_group_or_error(usersgroupid): |
|
123 | def get_users_group_or_error(usersgroupid): | |
123 | """ |
|
124 | """ | |
124 |
Get user |
|
125 | Get user group by id or name or return JsonRPCError if not found | |
125 |
|
126 | |||
126 | :param userid: |
|
127 | :param userid: | |
127 | """ |
|
128 | """ | |
128 |
users_group = User |
|
129 | users_group = UserGroupModel().get_group(usersgroupid) | |
129 | if users_group is None: |
|
130 | if users_group is None: | |
130 |
raise JSONRPCError('user |
|
131 | raise JSONRPCError('user group `%s` does not exist' % usersgroupid) | |
131 | return users_group |
|
132 | return users_group | |
132 |
|
133 | |||
133 |
|
134 | |||
@@ -257,7 +258,7 b' class ApiController(JSONRPCController):' | |||||
257 | if isinstance(userid, Optional): |
|
258 | if isinstance(userid, Optional): | |
258 | userid = apiuser.user_id |
|
259 | userid = apiuser.user_id | |
259 | user = get_user_or_error(userid) |
|
260 | user = get_user_or_error(userid) | |
260 | locked = bool(locked) |
|
261 | locked = str2bool(locked) | |
261 | try: |
|
262 | try: | |
262 | if locked: |
|
263 | if locked: | |
263 | Repository.lock(repo, user.user_id) |
|
264 | Repository.lock(repo, user.user_id) | |
@@ -449,7 +450,7 b' class ApiController(JSONRPCController):' | |||||
449 | @HasPermissionAllDecorator('hg.admin') |
|
450 | @HasPermissionAllDecorator('hg.admin') | |
450 | def get_users_group(self, apiuser, usersgroupid): |
|
451 | def get_users_group(self, apiuser, usersgroupid): | |
451 | """" |
|
452 | """" | |
452 |
Get user |
|
453 | Get user group by name or id | |
453 |
|
454 | |||
454 | :param apiuser: |
|
455 | :param apiuser: | |
455 | :param usersgroupid: |
|
456 | :param usersgroupid: | |
@@ -468,13 +469,13 b' class ApiController(JSONRPCController):' | |||||
468 | @HasPermissionAllDecorator('hg.admin') |
|
469 | @HasPermissionAllDecorator('hg.admin') | |
469 | def get_users_groups(self, apiuser): |
|
470 | def get_users_groups(self, apiuser): | |
470 | """" |
|
471 | """" | |
471 |
Get all user |
|
472 | Get all user groups | |
472 |
|
473 | |||
473 | :param apiuser: |
|
474 | :param apiuser: | |
474 | """ |
|
475 | """ | |
475 |
|
476 | |||
476 | result = [] |
|
477 | result = [] | |
477 |
for users_group in User |
|
478 | for users_group in UserGroupModel().get_all(): | |
478 | result.append(users_group.get_api_data()) |
|
479 | result.append(users_group.get_api_data()) | |
479 | return result |
|
480 | return result | |
480 |
|
481 | |||
@@ -488,15 +489,15 b' class ApiController(JSONRPCController):' | |||||
488 | :param active: |
|
489 | :param active: | |
489 | """ |
|
490 | """ | |
490 |
|
491 | |||
491 |
if User |
|
492 | if UserGroupModel().get_by_name(group_name): | |
492 |
raise JSONRPCError("user |
|
493 | raise JSONRPCError("user group `%s` already exist" % group_name) | |
493 |
|
494 | |||
494 | try: |
|
495 | try: | |
495 | active = Optional.extract(active) |
|
496 | active = Optional.extract(active) | |
496 |
ug = User |
|
497 | ug = UserGroupModel().create(name=group_name, active=active) | |
497 | Session().commit() |
|
498 | Session().commit() | |
498 | return dict( |
|
499 | return dict( | |
499 |
msg='created new user |
|
500 | msg='created new user group `%s`' % group_name, | |
500 | users_group=ug.get_api_data() |
|
501 | users_group=ug.get_api_data() | |
501 | ) |
|
502 | ) | |
502 | except Exception: |
|
503 | except Exception: | |
@@ -506,7 +507,7 b' class ApiController(JSONRPCController):' | |||||
506 | @HasPermissionAllDecorator('hg.admin') |
|
507 | @HasPermissionAllDecorator('hg.admin') | |
507 | def add_user_to_users_group(self, apiuser, usersgroupid, userid): |
|
508 | def add_user_to_users_group(self, apiuser, usersgroupid, userid): | |
508 | """" |
|
509 | """" | |
509 |
Add a user to a user |
|
510 | Add a user to a user group | |
510 |
|
511 | |||
511 | :param apiuser: |
|
512 | :param apiuser: | |
512 | :param usersgroupid: |
|
513 | :param usersgroupid: | |
@@ -516,9 +517,9 b' class ApiController(JSONRPCController):' | |||||
516 | users_group = get_users_group_or_error(usersgroupid) |
|
517 | users_group = get_users_group_or_error(usersgroupid) | |
517 |
|
518 | |||
518 | try: |
|
519 | try: | |
519 |
ugm = User |
|
520 | ugm = UserGroupModel().add_user_to_group(users_group, user) | |
520 | success = True if ugm != True else False |
|
521 | success = True if ugm != True else False | |
521 |
msg = 'added member `%s` to user |
|
522 | msg = 'added member `%s` to user group `%s`' % ( | |
522 | user.username, users_group.users_group_name |
|
523 | user.username, users_group.users_group_name | |
523 | ) |
|
524 | ) | |
524 | msg = msg if success else 'User is already in that group' |
|
525 | msg = msg if success else 'User is already in that group' | |
@@ -531,7 +532,7 b' class ApiController(JSONRPCController):' | |||||
531 | except Exception: |
|
532 | except Exception: | |
532 | log.error(traceback.format_exc()) |
|
533 | log.error(traceback.format_exc()) | |
533 | raise JSONRPCError( |
|
534 | raise JSONRPCError( | |
534 |
'failed to add member to user |
|
535 | 'failed to add member to user group `%s`' % ( | |
535 | users_group.users_group_name |
|
536 | users_group.users_group_name | |
536 | ) |
|
537 | ) | |
537 | ) |
|
538 | ) | |
@@ -549,9 +550,9 b' class ApiController(JSONRPCController):' | |||||
549 | users_group = get_users_group_or_error(usersgroupid) |
|
550 | users_group = get_users_group_or_error(usersgroupid) | |
550 |
|
551 | |||
551 | try: |
|
552 | try: | |
552 |
success = User |
|
553 | success = UserGroupModel().remove_user_from_group(users_group, | |
553 | user) |
|
554 | user) | |
554 |
msg = 'removed member `%s` from user |
|
555 | msg = 'removed member `%s` from user group `%s`' % ( | |
555 | user.username, users_group.users_group_name |
|
556 | user.username, users_group.users_group_name | |
556 | ) |
|
557 | ) | |
557 | msg = msg if success else "User wasn't in group" |
|
558 | msg = msg if success else "User wasn't in group" | |
@@ -560,7 +561,7 b' class ApiController(JSONRPCController):' | |||||
560 | except Exception: |
|
561 | except Exception: | |
561 | log.error(traceback.format_exc()) |
|
562 | log.error(traceback.format_exc()) | |
562 | raise JSONRPCError( |
|
563 | raise JSONRPCError( | |
563 |
'failed to remove member from user |
|
564 | 'failed to remove member from user group `%s`' % ( | |
564 | users_group.users_group_name |
|
565 | users_group.users_group_name | |
565 | ) |
|
566 | ) | |
566 | ) |
|
567 | ) | |
@@ -890,7 +891,7 b' class ApiController(JSONRPCController):' | |||||
890 | def grant_users_group_permission(self, apiuser, repoid, usersgroupid, |
|
891 | def grant_users_group_permission(self, apiuser, repoid, usersgroupid, | |
891 | perm): |
|
892 | perm): | |
892 | """ |
|
893 | """ | |
893 |
Grant permission for user |
|
894 | Grant permission for user group on given repository, or update | |
894 | existing one if found |
|
895 | existing one if found | |
895 |
|
896 | |||
896 | :param apiuser: |
|
897 | :param apiuser: | |
@@ -909,7 +910,7 b' class ApiController(JSONRPCController):' | |||||
909 |
|
910 | |||
910 | Session().commit() |
|
911 | Session().commit() | |
911 | return dict( |
|
912 | return dict( | |
912 |
msg='Granted perm: `%s` for user |
|
913 | msg='Granted perm: `%s` for user group: `%s` in ' | |
913 | 'repo: `%s`' % ( |
|
914 | 'repo: `%s`' % ( | |
914 | perm.permission_name, users_group.users_group_name, |
|
915 | perm.permission_name, users_group.users_group_name, | |
915 | repo.repo_name |
|
916 | repo.repo_name | |
@@ -919,7 +920,7 b' class ApiController(JSONRPCController):' | |||||
919 | except Exception: |
|
920 | except Exception: | |
920 | log.error(traceback.format_exc()) |
|
921 | log.error(traceback.format_exc()) | |
921 | raise JSONRPCError( |
|
922 | raise JSONRPCError( | |
922 |
'failed to edit permission for user |
|
923 | 'failed to edit permission for user group: `%s` in ' | |
923 | 'repo: `%s`' % ( |
|
924 | 'repo: `%s`' % ( | |
924 | usersgroupid, repo.repo_name |
|
925 | usersgroupid, repo.repo_name | |
925 | ) |
|
926 | ) | |
@@ -928,7 +929,7 b' class ApiController(JSONRPCController):' | |||||
928 | @HasPermissionAllDecorator('hg.admin') |
|
929 | @HasPermissionAllDecorator('hg.admin') | |
929 | def revoke_users_group_permission(self, apiuser, repoid, usersgroupid): |
|
930 | def revoke_users_group_permission(self, apiuser, repoid, usersgroupid): | |
930 | """ |
|
931 | """ | |
931 |
Revoke permission for user |
|
932 | Revoke permission for user group on given repository | |
932 |
|
933 | |||
933 | :param apiuser: |
|
934 | :param apiuser: | |
934 | :param repoid: |
|
935 | :param repoid: | |
@@ -943,7 +944,7 b' class ApiController(JSONRPCController):' | |||||
943 |
|
944 | |||
944 | Session().commit() |
|
945 | Session().commit() | |
945 | return dict( |
|
946 | return dict( | |
946 |
msg='Revoked perm for user |
|
947 | msg='Revoked perm for user group: `%s` in repo: `%s`' % ( | |
947 | users_group.users_group_name, repo.repo_name |
|
948 | users_group.users_group_name, repo.repo_name | |
948 | ), |
|
949 | ), | |
949 | success=True |
|
950 | success=True | |
@@ -951,7 +952,7 b' class ApiController(JSONRPCController):' | |||||
951 | except Exception: |
|
952 | except Exception: | |
952 | log.error(traceback.format_exc()) |
|
953 | log.error(traceback.format_exc()) | |
953 | raise JSONRPCError( |
|
954 | raise JSONRPCError( | |
954 |
'failed to edit permission for user |
|
955 | 'failed to edit permission for user group: `%s` in ' | |
955 | 'repo: `%s`' % ( |
|
956 | 'repo: `%s`' % ( | |
956 | users_group.users_group_name, repo.repo_name |
|
957 | users_group.users_group_name, repo.repo_name | |
957 | ) |
|
958 | ) |
@@ -329,7 +329,7 b' class ChangesetController(BaseRepoContro' | |||||
329 | text = text or (_('Status change -> %s') |
|
329 | text = text or (_('Status change -> %s') | |
330 | % ChangesetStatus.get_status_lbl(status)) |
|
330 | % ChangesetStatus.get_status_lbl(status)) | |
331 |
|
331 | |||
332 | comm = ChangesetCommentsModel().create( |
|
332 | c.co = comm = ChangesetCommentsModel().create( | |
333 | text=text, |
|
333 | text=text, | |
334 | repo=c.rhodecode_db_repo.repo_id, |
|
334 | repo=c.rhodecode_db_repo.repo_id, | |
335 | user=c.rhodecode_user.user_id, |
|
335 | user=c.rhodecode_user.user_id, | |
@@ -371,12 +371,11 b' class ChangesetController(BaseRepoContro' | |||||
371 | if not request.environ.get('HTTP_X_PARTIAL_XHR'): |
|
371 | if not request.environ.get('HTTP_X_PARTIAL_XHR'): | |
372 | return redirect(h.url('changeset_home', repo_name=repo_name, |
|
372 | return redirect(h.url('changeset_home', repo_name=repo_name, | |
373 | revision=revision)) |
|
373 | revision=revision)) | |
374 |
|
374 | #only ajax below | ||
375 | data = { |
|
375 | data = { | |
376 | 'target_id': h.safeid(h.safe_unicode(request.POST.get('f_path'))), |
|
376 | 'target_id': h.safeid(h.safe_unicode(request.POST.get('f_path'))), | |
377 | } |
|
377 | } | |
378 | if comm: |
|
378 | if comm: | |
379 | c.co = comm |
|
|||
380 | data.update(comm.get_dict()) |
|
379 | data.update(comm.get_dict()) | |
381 | data.update({'rendered_text': |
|
380 | data.update({'rendered_text': | |
382 | render('changeset/changeset_comment_block.html')}) |
|
381 | render('changeset/changeset_comment_block.html')}) |
@@ -83,23 +83,28 b' class CompareController(BaseRepoControll' | |||||
83 | raise HTTPBadRequest() |
|
83 | raise HTTPBadRequest() | |
84 |
|
84 | |||
85 | def index(self, org_ref_type, org_ref, other_ref_type, other_ref): |
|
85 | def index(self, org_ref_type, org_ref, other_ref_type, other_ref): | |
86 |
|
86 | # org_ref will be evaluated in org_repo | ||
87 | org_repo = c.rhodecode_db_repo.repo_name |
|
87 | org_repo = c.rhodecode_db_repo.repo_name | |
88 | org_ref = (org_ref_type, org_ref) |
|
88 | org_ref = (org_ref_type, org_ref) | |
|
89 | # other_ref will be evaluated in other_repo | |||
89 | other_ref = (other_ref_type, other_ref) |
|
90 | other_ref = (other_ref_type, other_ref) | |
90 | other_repo = request.GET.get('other_repo', org_repo) |
|
91 | other_repo = request.GET.get('other_repo', org_repo) | |
91 | c.fulldiff = fulldiff = request.GET.get('fulldiff') |
|
92 | # fulldiff disables cut_off_limit | |
|
93 | c.fulldiff = request.GET.get('fulldiff') | |||
|
94 | # only consider this range of changesets | |||
92 | rev_start = request.GET.get('rev_start') |
|
95 | rev_start = request.GET.get('rev_start') | |
93 | rev_end = request.GET.get('rev_end') |
|
96 | rev_end = request.GET.get('rev_end') | |
94 |
|
97 | # partial uses compare_cs.html template directly | ||
95 | c.swap_url = h.url('compare_url', as_form=request.GET.get('as_form'), |
|
98 | partial = request.environ.get('HTTP_X_PARTIAL_XHR') | |
|
99 | # as_form puts hidden input field with changeset revisions | |||
|
100 | c.as_form = partial and request.GET.get('as_form') | |||
|
101 | # swap url for compare_diff page - never partial and never as_form | |||
|
102 | c.swap_url = h.url('compare_url', | |||
96 | repo_name=other_repo, |
|
103 | repo_name=other_repo, | |
97 | org_ref_type=other_ref[0], org_ref=other_ref[1], |
|
104 | org_ref_type=other_ref[0], org_ref=other_ref[1], | |
98 | other_repo=org_repo, |
|
105 | other_repo=org_repo, | |
99 | other_ref_type=org_ref[0], other_ref=org_ref[1]) |
|
106 | other_ref_type=org_ref[0], other_ref=org_ref[1]) | |
100 |
|
107 | |||
101 | partial = request.environ.get('HTTP_X_PARTIAL_XHR') |
|
|||
102 |
|
||||
103 | org_repo = Repository.get_by_repo_name(org_repo) |
|
108 | org_repo = Repository.get_by_repo_name(org_repo) | |
104 | other_repo = Repository.get_by_repo_name(other_repo) |
|
109 | other_repo = Repository.get_by_repo_name(other_repo) | |
105 |
|
110 | |||
@@ -148,8 +153,6 b' class CompareController(BaseRepoControll' | |||||
148 |
|
153 | |||
149 | c.statuses = c.rhodecode_db_repo.statuses([x.raw_id for x in |
|
154 | c.statuses = c.rhodecode_db_repo.statuses([x.raw_id for x in | |
150 | c.cs_ranges]) |
|
155 | c.cs_ranges]) | |
151 | # defines that we need hidden inputs with changesets |
|
|||
152 | c.as_form = request.GET.get('as_form', False) |
|
|||
153 | if partial: |
|
156 | if partial: | |
154 | return render('compare/compare_cs.html') |
|
157 | return render('compare/compare_cs.html') | |
155 |
|
158 | |||
@@ -163,7 +166,7 b' class CompareController(BaseRepoControll' | |||||
163 | org_ref = ('rev', ancestor) |
|
166 | org_ref = ('rev', ancestor) | |
164 | org_repo = other_repo |
|
167 | org_repo = other_repo | |
165 |
|
168 | |||
166 | diff_limit = self.cut_off_limit if not fulldiff else None |
|
169 | diff_limit = self.cut_off_limit if not c.fulldiff else None | |
167 |
|
170 | |||
168 | _diff = diffs.differ(org_repo, org_ref, other_repo, other_ref) |
|
171 | _diff = diffs.differ(org_repo, org_ref, other_repo, other_ref) | |
169 |
|
172 |
@@ -486,6 +486,8 b' class FilesController(BaseRepoController' | |||||
486 | c.changeset_1 = c.rhodecode_repo.get_changeset(diff1) |
|
486 | c.changeset_1 = c.rhodecode_repo.get_changeset(diff1) | |
487 | try: |
|
487 | try: | |
488 | node1 = c.changeset_1.get_node(f_path) |
|
488 | node1 = c.changeset_1.get_node(f_path) | |
|
489 | if node1.is_dir(): | |||
|
490 | raise NodeError('%s path is a %s not a file' % (node1, type(node1))) | |||
489 | except NodeDoesNotExistError: |
|
491 | except NodeDoesNotExistError: | |
490 | c.changeset_1 = EmptyChangeset(cs=diff1, |
|
492 | c.changeset_1 = EmptyChangeset(cs=diff1, | |
491 | revision=c.changeset_1.revision, |
|
493 | revision=c.changeset_1.revision, | |
@@ -499,6 +501,7 b' class FilesController(BaseRepoController' | |||||
499 | c.changeset_2 = c.rhodecode_repo.get_changeset(diff2) |
|
501 | c.changeset_2 = c.rhodecode_repo.get_changeset(diff2) | |
500 | try: |
|
502 | try: | |
501 | node2 = c.changeset_2.get_node(f_path) |
|
503 | node2 = c.changeset_2.get_node(f_path) | |
|
504 | raise NodeError('%s path is a %s not a file' % (node2, type(node2))) | |||
502 | except NodeDoesNotExistError: |
|
505 | except NodeDoesNotExistError: | |
503 | c.changeset_2 = EmptyChangeset(cs=diff2, |
|
506 | c.changeset_2 = EmptyChangeset(cs=diff2, | |
504 | revision=c.changeset_2.revision, |
|
507 | revision=c.changeset_2.revision, |
@@ -81,7 +81,7 b' class HomeController(BaseController):' | |||||
81 | def branch_tag_switcher(self, repo_name): |
|
81 | def branch_tag_switcher(self, repo_name): | |
82 | if request.is_xhr: |
|
82 | if request.is_xhr: | |
83 | c.rhodecode_db_repo = Repository.get_by_repo_name(c.repo_name) |
|
83 | c.rhodecode_db_repo = Repository.get_by_repo_name(c.repo_name) | |
84 |
|
|
84 | if c.rhodecode_db_repo: | |
85 | return render('/switch_to_list.html') |
|
85 | c.rhodecode_repo = c.rhodecode_db_repo.scm_instance | |
86 | else: |
|
86 | return render('/switch_to_list.html') | |
87 |
|
|
87 | raise HTTPBadRequest() |
@@ -67,29 +67,33 b' class PullrequestsController(BaseRepoCon' | |||||
67 | c.users_array = repo_model.get_users_js() |
|
67 | c.users_array = repo_model.get_users_js() | |
68 | c.users_groups_array = repo_model.get_users_groups_js() |
|
68 | c.users_groups_array = repo_model.get_users_groups_js() | |
69 |
|
69 | |||
70 | def _get_repo_refs(self, repo): |
|
70 | def _get_repo_refs(self, repo, rev=None): | |
71 | hist_l = [] |
|
71 | """return a structure with repo's interesting changesets, suitable for | |
72 |
|
72 | the selectors in pullrequest.html""" | ||
73 |
branches |
|
73 | branches = [('branch:%s:%s' % (k, v), k) | |
74 |
|
|
74 | for k, v in repo.branches.iteritems()] | |
75 |
bookmarks |
|
75 | bookmarks = [('book:%s:%s' % (k, v), k) | |
76 |
|
|
76 | for k, v in repo.bookmarks.iteritems()] | |
77 |
tags |
|
77 | tags = [('tag:%s:%s' % (k, v), k) | |
78 |
|
|
78 | for k, v in repo.tags.iteritems() | |
79 |
|
|
79 | if k != 'tip'] | |
80 |
|
80 | |||
81 | tip = repo.tags['tip'] |
|
81 | tip = repo.tags['tip'] | |
82 | tipref = 'tag:tip:%s' % tip |
|
|||
83 | colontip = ':' + tip |
|
82 | colontip = ':' + tip | |
84 |
tips = [x[1] for x in branches |
|
83 | tips = [x[1] for x in branches + bookmarks + tags | |
85 | if x[0].endswith(colontip)] |
|
84 | if x[0].endswith(colontip)] | |
86 | tags_group[0].append((tipref, 'tip (%s)' % ', '.join(tips))) |
|
85 | selected = 'tag:tip:%s' % tip | |
|
86 | special = [(selected, 'tip (%s)' % ', '.join(tips))] | |||
87 |
|
87 | |||
88 | hist_l.append(bookmarks_group) |
|
88 | if rev: | |
89 | hist_l.append(branches_group) |
|
89 | selected = 'rev:%s:%s' % (rev, rev) | |
90 | hist_l.append(tags_group) |
|
90 | special.append((selected, rev)) | |
91 |
|
91 | |||
92 | return hist_l, tipref |
|
92 | return [(special, _("Special")), | |
|
93 | (bookmarks, _("Bookmarks")), | |||
|
94 | (branches, _("Branches")), | |||
|
95 | (tags, _("Tags")), | |||
|
96 | ], selected | |||
93 |
|
97 | |||
94 | def _get_is_allowed_change_status(self, pull_request): |
|
98 | def _get_is_allowed_change_status(self, pull_request): | |
95 | owner = self.rhodecode_user.user_id == pull_request.user_id |
|
99 | owner = self.rhodecode_user.user_id == pull_request.user_id | |
@@ -291,8 +295,6 b' class PullrequestsController(BaseRepoCon' | |||||
291 | else EmptyChangeset(), 'raw_id')) |
|
295 | else EmptyChangeset(), 'raw_id')) | |
292 |
|
296 | |||
293 | c.statuses = org_repo.statuses([x.raw_id for x in c.cs_ranges]) |
|
297 | c.statuses = org_repo.statuses([x.raw_id for x in c.cs_ranges]) | |
294 | # defines that we need hidden inputs with changesets |
|
|||
295 | c.as_form = request.GET.get('as_form', False) |
|
|||
296 |
|
298 | |||
297 | c.org_ref = org_ref[1] |
|
299 | c.org_ref = org_ref[1] | |
298 | c.org_ref_type = org_ref[0] |
|
300 | c.org_ref_type = org_ref[0] | |
@@ -391,6 +393,7 b' class PullrequestsController(BaseRepoCon' | |||||
391 | ) |
|
393 | ) | |
392 | c.changeset_statuses = ChangesetStatus.STATUSES |
|
394 | c.changeset_statuses = ChangesetStatus.STATUSES | |
393 |
|
395 | |||
|
396 | c.as_form = False | |||
394 | return render('/pullrequests/pullrequest_show.html') |
|
397 | return render('/pullrequests/pullrequest_show.html') | |
395 |
|
398 | |||
396 | @NotAnonymous() |
|
399 | @NotAnonymous() | |
@@ -403,11 +406,15 b' class PullrequestsController(BaseRepoCon' | |||||
403 | status = request.POST.get('changeset_status') |
|
406 | status = request.POST.get('changeset_status') | |
404 | change_status = request.POST.get('change_changeset_status') |
|
407 | change_status = request.POST.get('change_changeset_status') | |
405 | text = request.POST.get('text') |
|
408 | text = request.POST.get('text') | |
|
409 | close_pr = request.POST.get('save_close') | |||
406 |
|
410 | |||
407 | allowed_to_change_status = self._get_is_allowed_change_status(pull_request) |
|
411 | allowed_to_change_status = self._get_is_allowed_change_status(pull_request) | |
408 | if status and change_status and allowed_to_change_status: |
|
412 | if status and change_status and allowed_to_change_status: | |
409 |
|
|
413 | _def = (_('status change -> %s') | |
410 | % ChangesetStatus.get_status_lbl(status)) |
|
414 | % ChangesetStatus.get_status_lbl(status)) | |
|
415 | if close_pr: | |||
|
416 | _def = _('Closing with') + ' ' + _def | |||
|
417 | text = text or _def | |||
411 | comm = ChangesetCommentsModel().create( |
|
418 | comm = ChangesetCommentsModel().create( | |
412 | text=text, |
|
419 | text=text, | |
413 | repo=c.rhodecode_db_repo.repo_id, |
|
420 | repo=c.rhodecode_db_repo.repo_id, | |
@@ -416,7 +423,9 b' class PullrequestsController(BaseRepoCon' | |||||
416 | f_path=request.POST.get('f_path'), |
|
423 | f_path=request.POST.get('f_path'), | |
417 | line_no=request.POST.get('line'), |
|
424 | line_no=request.POST.get('line'), | |
418 | status_change=(ChangesetStatus.get_status_lbl(status) |
|
425 | status_change=(ChangesetStatus.get_status_lbl(status) | |
419 | if status and change_status and allowed_to_change_status else None) |
|
426 | if status and change_status | |
|
427 | and allowed_to_change_status else None), | |||
|
428 | closing_pr=close_pr | |||
420 | ) |
|
429 | ) | |
421 |
|
430 | |||
422 | action_logger(self.rhodecode_user, |
|
431 | action_logger(self.rhodecode_user, | |
@@ -434,7 +443,7 b' class PullrequestsController(BaseRepoCon' | |||||
434 | pull_request=pull_request_id |
|
443 | pull_request=pull_request_id | |
435 | ) |
|
444 | ) | |
436 |
|
445 | |||
437 |
if |
|
446 | if close_pr: | |
438 | if status in ['rejected', 'approved']: |
|
447 | if status in ['rejected', 'approved']: | |
439 | PullRequestModel().close_pull_request(pull_request_id) |
|
448 | PullRequestModel().close_pull_request(pull_request_id) | |
440 | action_logger(self.rhodecode_user, |
|
449 | action_logger(self.rhodecode_user, |
@@ -411,7 +411,7 b' class AuthUser(object):' | |||||
411 | @property |
|
411 | @property | |
412 | def groups_admin(self): |
|
412 | def groups_admin(self): | |
413 | """ |
|
413 | """ | |
414 |
Returns list of repositor |
|
414 | Returns list of repository groups you're an admin of | |
415 | """ |
|
415 | """ | |
416 | return [x[0] for x in self.permissions['repositories_groups'].iteritems() |
|
416 | return [x[0] for x in self.permissions['repositories_groups'].iteritems() | |
417 | if x[1] == 'group.admin'] |
|
417 | if x[1] == 'group.admin'] |
@@ -68,6 +68,8 b' def run_task(task, *args, **kwargs):' | |||||
68 | except socket.error, e: |
|
68 | except socket.error, e: | |
69 | if isinstance(e, IOError) and e.errno == 111: |
|
69 | if isinstance(e, IOError) and e.errno == 111: | |
70 | log.debug('Unable to connect to celeryd. Sync execution') |
|
70 | log.debug('Unable to connect to celeryd. Sync execution') | |
|
71 | global CELERY_ON | |||
|
72 | CELERY_ON = False | |||
71 | else: |
|
73 | else: | |
72 | log.error(traceback.format_exc()) |
|
74 | log.error(traceback.format_exc()) | |
73 | except KeyError, e: |
|
75 | except KeyError, e: |
@@ -251,76 +251,10 b' def get_commits_stats(repo_name, ts_min_' | |||||
251 | log.info('LockHeld') |
|
251 | log.info('LockHeld') | |
252 | return 'Task with key %s already running' % lockkey |
|
252 | return 'Task with key %s already running' % lockkey | |
253 |
|
253 | |||
254 | @task(ignore_result=True) |
|
|||
255 | @dbsession |
|
|||
256 | def send_password_link(user_email): |
|
|||
257 | from rhodecode.model.notification import EmailNotificationModel |
|
|||
258 |
|
||||
259 | log = get_logger(send_password_link) |
|
|||
260 | DBS = get_session() |
|
|||
261 |
|
||||
262 | try: |
|
|||
263 | user = User.get_by_email(user_email) |
|
|||
264 | if user: |
|
|||
265 | log.debug('password reset user found %s' % user) |
|
|||
266 | link = url('reset_password_confirmation', key=user.api_key, |
|
|||
267 | qualified=True) |
|
|||
268 | reg_type = EmailNotificationModel.TYPE_PASSWORD_RESET |
|
|||
269 | body = EmailNotificationModel().get_email_tmpl(reg_type, |
|
|||
270 | **{'user':user.short_contact, |
|
|||
271 | 'reset_url':link}) |
|
|||
272 | log.debug('sending email') |
|
|||
273 | run_task(send_email, user_email, |
|
|||
274 | _("password reset link"), body) |
|
|||
275 | log.info('send new password mail to %s' % user_email) |
|
|||
276 | else: |
|
|||
277 | log.debug("password reset email %s not found" % user_email) |
|
|||
278 | except: |
|
|||
279 | log.error(traceback.format_exc()) |
|
|||
280 | return False |
|
|||
281 |
|
||||
282 | return True |
|
|||
283 |
|
254 | |||
284 | @task(ignore_result=True) |
|
255 | @task(ignore_result=True) | |
285 | @dbsession |
|
256 | @dbsession | |
286 | def reset_user_password(user_email): |
|
257 | def send_email(recipients, subject, body='', html_body=''): | |
287 | from rhodecode.lib import auth |
|
|||
288 |
|
||||
289 | log = get_logger(reset_user_password) |
|
|||
290 | DBS = get_session() |
|
|||
291 |
|
||||
292 | try: |
|
|||
293 | try: |
|
|||
294 | user = User.get_by_email(user_email) |
|
|||
295 | new_passwd = auth.PasswordGenerator().gen_password(8, |
|
|||
296 | auth.PasswordGenerator.ALPHABETS_BIG_SMALL) |
|
|||
297 | if user: |
|
|||
298 | user.password = auth.get_crypt_password(new_passwd) |
|
|||
299 | user.api_key = auth.generate_api_key(user.username) |
|
|||
300 | DBS.add(user) |
|
|||
301 | DBS.commit() |
|
|||
302 | log.info('change password for %s' % user_email) |
|
|||
303 | if new_passwd is None: |
|
|||
304 | raise Exception('unable to generate new password') |
|
|||
305 | except: |
|
|||
306 | log.error(traceback.format_exc()) |
|
|||
307 | DBS.rollback() |
|
|||
308 |
|
||||
309 | run_task(send_email, user_email, |
|
|||
310 | 'Your new password', |
|
|||
311 | 'Your new RhodeCode password:%s' % (new_passwd)) |
|
|||
312 | log.info('send new password mail to %s' % user_email) |
|
|||
313 |
|
||||
314 | except: |
|
|||
315 | log.error('Failed to update user password') |
|
|||
316 | log.error(traceback.format_exc()) |
|
|||
317 |
|
||||
318 | return True |
|
|||
319 |
|
||||
320 |
|
||||
321 | @task(ignore_result=True) |
|
|||
322 | @dbsession |
|
|||
323 | def send_email(recipients, subject, body, html_body=''): |
|
|||
324 | """ |
|
258 | """ | |
325 | Sends an email with defined parameters from the .ini files. |
|
259 | Sends an email with defined parameters from the .ini files. | |
326 |
|
260 | |||
@@ -348,7 +282,7 b' def send_email(recipients, subject, body' | |||||
348 | mail_port = email_config.get('smtp_port') |
|
282 | mail_port = email_config.get('smtp_port') | |
349 | tls = str2bool(email_config.get('smtp_use_tls')) |
|
283 | tls = str2bool(email_config.get('smtp_use_tls')) | |
350 | ssl = str2bool(email_config.get('smtp_use_ssl')) |
|
284 | ssl = str2bool(email_config.get('smtp_use_ssl')) | |
351 | debug = str2bool(config.get('debug')) |
|
285 | debug = str2bool(email_config.get('debug')) | |
352 | smtp_auth = email_config.get('smtp_auth') |
|
286 | smtp_auth = email_config.get('smtp_auth') | |
353 |
|
287 | |||
354 | if not mail_server: |
|
288 | if not mail_server: |
@@ -41,7 +41,7 b' from rhodecode.lib.vcs.utils.lazy import' | |||||
41 |
|
41 | |||
42 | from rhodecode.lib.utils2 import str2bool, safe_str, get_changeset_safe, \ |
|
42 | from rhodecode.lib.utils2 import str2bool, safe_str, get_changeset_safe, \ | |
43 | generate_api_key, safe_unicode |
|
43 | generate_api_key, safe_unicode | |
44 |
from rhodecode.lib.exceptions import User |
|
44 | from rhodecode.lib.exceptions import UserGroupsAssignedException | |
45 | from rhodecode.lib.compat import json |
|
45 | from rhodecode.lib.compat import json | |
46 |
|
46 | |||
47 | from rhodecode.model.meta import Base, Session |
|
47 | from rhodecode.model.meta import Base, Session | |
@@ -282,7 +282,7 b' class User(Base, BaseModel):' | |||||
282 | user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') |
|
282 | user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') | |
283 | repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') |
|
283 | repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') | |
284 |
|
284 | |||
285 |
group_member = relationship('User |
|
285 | group_member = relationship('UserGroupMember', cascade='all') | |
286 |
|
286 | |||
287 | @property |
|
287 | @property | |
288 | def full_contact(self): |
|
288 | def full_contact(self): | |
@@ -361,7 +361,7 b' class UserLog(Base, BaseModel):' | |||||
361 | repository = relationship('Repository') |
|
361 | repository = relationship('Repository') | |
362 |
|
362 | |||
363 |
|
363 | |||
364 |
class User |
|
364 | class UserGroup(Base, BaseModel): | |
365 | __tablename__ = 'users_groups' |
|
365 | __tablename__ = 'users_groups' | |
366 | __table_args__ = {'extend_existing':True} |
|
366 | __table_args__ = {'extend_existing':True} | |
367 |
|
367 | |||
@@ -369,7 +369,7 b' class UsersGroup(Base, BaseModel):' | |||||
369 | users_group_name = Column("users_group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None) |
|
369 | users_group_name = Column("users_group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None) | |
370 | users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) |
|
370 | users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) | |
371 |
|
371 | |||
372 |
members = relationship('User |
|
372 | members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") | |
373 |
|
373 | |||
374 | def __repr__(self): |
|
374 | def __repr__(self): | |
375 | return '<userGroup(%s)>' % (self.users_group_name) |
|
375 | return '<userGroup(%s)>' % (self.users_group_name) | |
@@ -425,7 +425,7 b' class UsersGroup(Base, BaseModel):' | |||||
425 | if v: |
|
425 | if v: | |
426 | v = [v] if isinstance(v, basestring) else v |
|
426 | v = [v] if isinstance(v, basestring) else v | |
427 | for u_id in set(v): |
|
427 | for u_id in set(v): | |
428 |
member = User |
|
428 | member = UserGroupMember(users_group_id, u_id) | |
429 | members_list.append(member) |
|
429 | members_list.append(member) | |
430 | setattr(users_group, 'members', members_list) |
|
430 | setattr(users_group, 'members', members_list) | |
431 | setattr(users_group, k, v) |
|
431 | setattr(users_group, k, v) | |
@@ -442,12 +442,12 b' class UsersGroup(Base, BaseModel):' | |||||
442 | try: |
|
442 | try: | |
443 |
|
443 | |||
444 | # check if this group is not assigned to repo |
|
444 | # check if this group is not assigned to repo | |
445 |
assigned_groups = User |
|
445 | assigned_groups = UserGroupRepoToPerm.query()\ | |
446 |
.filter(User |
|
446 | .filter(UserGroupRepoToPerm.users_group_id == | |
447 | users_group_id).all() |
|
447 | users_group_id).all() | |
448 |
|
448 | |||
449 | if assigned_groups: |
|
449 | if assigned_groups: | |
450 |
raise User |
|
450 | raise UserGroupsAssignedException('RepoGroup assigned to %s' % | |
451 | assigned_groups) |
|
451 | assigned_groups) | |
452 |
|
452 | |||
453 | users_group = cls.get(users_group_id, cache=False) |
|
453 | users_group = cls.get(users_group_id, cache=False) | |
@@ -458,7 +458,7 b' class UsersGroup(Base, BaseModel):' | |||||
458 | Session.rollback() |
|
458 | Session.rollback() | |
459 | raise |
|
459 | raise | |
460 |
|
460 | |||
461 |
class User |
|
461 | class UserGroupMember(Base, BaseModel): | |
462 | __tablename__ = 'users_groups_members' |
|
462 | __tablename__ = 'users_groups_members' | |
463 | __table_args__ = {'extend_existing':True} |
|
463 | __table_args__ = {'extend_existing':True} | |
464 |
|
464 | |||
@@ -467,7 +467,7 b' class UsersGroupMember(Base, BaseModel):' | |||||
467 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) |
|
467 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) | |
468 |
|
468 | |||
469 | user = relationship('User', lazy='joined') |
|
469 | user = relationship('User', lazy='joined') | |
470 |
users_group = relationship('User |
|
470 | users_group = relationship('UserGroup') | |
471 |
|
471 | |||
472 | def __init__(self, gr_id='', u_id=''): |
|
472 | def __init__(self, gr_id='', u_id=''): | |
473 | self.users_group_id = gr_id |
|
473 | self.users_group_id = gr_id | |
@@ -475,7 +475,7 b' class UsersGroupMember(Base, BaseModel):' | |||||
475 |
|
475 | |||
476 | @staticmethod |
|
476 | @staticmethod | |
477 | def add_user_to_group(group, user): |
|
477 | def add_user_to_group(group, user): | |
478 |
ugm = User |
|
478 | ugm = UserGroupMember() | |
479 | ugm.users_group = group |
|
479 | ugm.users_group = group | |
480 | ugm.user = user |
|
480 | ugm.user = user | |
481 | Session.add(ugm) |
|
481 | Session.add(ugm) | |
@@ -505,7 +505,7 b' class Repository(Base, BaseModel):' | |||||
505 | fork = relationship('Repository', remote_side=repo_id) |
|
505 | fork = relationship('Repository', remote_side=repo_id) | |
506 | group = relationship('RepoGroup') |
|
506 | group = relationship('RepoGroup') | |
507 | repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') |
|
507 | repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') | |
508 |
users_group_to_perm = relationship('User |
|
508 | users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') | |
509 | stats = relationship('Statistics', cascade='all', uselist=False) |
|
509 | stats = relationship('Statistics', cascade='all', uselist=False) | |
510 |
|
510 | |||
511 | followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all') |
|
511 | followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all') | |
@@ -909,7 +909,7 b' class UserToPerm(Base, BaseModel):' | |||||
909 | except: |
|
909 | except: | |
910 | Session.rollback() |
|
910 | Session.rollback() | |
911 |
|
911 | |||
912 |
class User |
|
912 | class UserGroupRepoToPerm(Base, BaseModel): | |
913 | __tablename__ = 'users_group_repo_to_perm' |
|
913 | __tablename__ = 'users_group_repo_to_perm' | |
914 | __table_args__ = (UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), {'extend_existing':True}) |
|
914 | __table_args__ = (UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), {'extend_existing':True}) | |
915 | users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) |
|
915 | users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) | |
@@ -917,21 +917,21 b' class UsersGroupRepoToPerm(Base, BaseMod' | |||||
917 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
917 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
918 | repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) |
|
918 | repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) | |
919 |
|
919 | |||
920 |
users_group = relationship('User |
|
920 | users_group = relationship('UserGroup') | |
921 | permission = relationship('Permission') |
|
921 | permission = relationship('Permission') | |
922 | repository = relationship('Repository') |
|
922 | repository = relationship('Repository') | |
923 |
|
923 | |||
924 | def __repr__(self): |
|
924 | def __repr__(self): | |
925 | return '<userGroup:%s => %s >' % (self.users_group, self.repository) |
|
925 | return '<userGroup:%s => %s >' % (self.users_group, self.repository) | |
926 |
|
926 | |||
927 |
class User |
|
927 | class UserGroupToPerm(Base, BaseModel): | |
928 | __tablename__ = 'users_group_to_perm' |
|
928 | __tablename__ = 'users_group_to_perm' | |
929 | __table_args__ = {'extend_existing':True} |
|
929 | __table_args__ = {'extend_existing':True} | |
930 | users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) |
|
930 | users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) | |
931 | users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) |
|
931 | users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) | |
932 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
932 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
933 |
|
933 | |||
934 |
users_group = relationship('User |
|
934 | users_group = relationship('UserGroup') | |
935 | permission = relationship('Permission') |
|
935 | permission = relationship('Permission') | |
936 |
|
936 | |||
937 |
|
937 |
@@ -305,7 +305,7 b' class User(Base, BaseModel):' | |||||
305 | repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') |
|
305 | repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') | |
306 | repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') |
|
306 | repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') | |
307 |
|
307 | |||
308 |
group_member = relationship('User |
|
308 | group_member = relationship('UserGroupMember', cascade='all') | |
309 |
|
309 | |||
310 | notifications = relationship('UserNotification', cascade='all') |
|
310 | notifications = relationship('UserNotification', cascade='all') | |
311 | # notifications assigned to this user |
|
311 | # notifications assigned to this user | |
@@ -423,7 +423,7 b' class UserLog(Base, BaseModel):' | |||||
423 | repository = relationship('Repository', cascade='') |
|
423 | repository = relationship('Repository', cascade='') | |
424 |
|
424 | |||
425 |
|
425 | |||
426 |
class User |
|
426 | class UserGroup(Base, BaseModel): | |
427 | __tablename__ = 'users_groups' |
|
427 | __tablename__ = 'users_groups' | |
428 | __table_args__ = ( |
|
428 | __table_args__ = ( | |
429 | {'extend_existing': True, 'mysql_engine':'InnoDB', |
|
429 | {'extend_existing': True, 'mysql_engine':'InnoDB', | |
@@ -434,9 +434,9 b' class UsersGroup(Base, BaseModel):' | |||||
434 | users_group_name = Column("users_group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None) |
|
434 | users_group_name = Column("users_group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None) | |
435 | users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) |
|
435 | users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) | |
436 |
|
436 | |||
437 |
members = relationship('User |
|
437 | members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") | |
438 |
users_group_to_perm = relationship('User |
|
438 | users_group_to_perm = relationship('UserGroupToPerm', cascade='all') | |
439 |
users_group_repo_to_perm = relationship('User |
|
439 | users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') | |
440 |
|
440 | |||
441 | def __unicode__(self): |
|
441 | def __unicode__(self): | |
442 | return u'<userGroup(%s)>' % (self.users_group_name) |
|
442 | return u'<userGroup(%s)>' % (self.users_group_name) | |
@@ -465,7 +465,7 b' class UsersGroup(Base, BaseModel):' | |||||
465 | return users_group.get(users_group_id) |
|
465 | return users_group.get(users_group_id) | |
466 |
|
466 | |||
467 |
|
467 | |||
468 |
class User |
|
468 | class UserGroupMember(Base, BaseModel): | |
469 | __tablename__ = 'users_groups_members' |
|
469 | __tablename__ = 'users_groups_members' | |
470 | __table_args__ = ( |
|
470 | __table_args__ = ( | |
471 | {'extend_existing': True, 'mysql_engine':'InnoDB', |
|
471 | {'extend_existing': True, 'mysql_engine':'InnoDB', | |
@@ -477,7 +477,7 b' class UsersGroupMember(Base, BaseModel):' | |||||
477 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) |
|
477 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) | |
478 |
|
478 | |||
479 | user = relationship('User', lazy='joined') |
|
479 | user = relationship('User', lazy='joined') | |
480 |
users_group = relationship('User |
|
480 | users_group = relationship('UserGroup') | |
481 |
|
481 | |||
482 | def __init__(self, gr_id='', u_id=''): |
|
482 | def __init__(self, gr_id='', u_id=''): | |
483 | self.users_group_id = gr_id |
|
483 | self.users_group_id = gr_id | |
@@ -510,7 +510,7 b' class Repository(Base, BaseModel):' | |||||
510 | fork = relationship('Repository', remote_side=repo_id) |
|
510 | fork = relationship('Repository', remote_side=repo_id) | |
511 | group = relationship('RepoGroup') |
|
511 | group = relationship('RepoGroup') | |
512 | repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') |
|
512 | repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') | |
513 |
users_group_to_perm = relationship('User |
|
513 | users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') | |
514 | stats = relationship('Statistics', cascade='all', uselist=False) |
|
514 | stats = relationship('Statistics', cascade='all', uselist=False) | |
515 |
|
515 | |||
516 | followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all') |
|
516 | followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all') | |
@@ -749,7 +749,7 b' class RepoGroup(Base, BaseModel):' | |||||
749 | group_description = Column("group_description", String(length=10000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) |
|
749 | group_description = Column("group_description", String(length=10000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) | |
750 |
|
750 | |||
751 | repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') |
|
751 | repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') | |
752 |
users_group_to_perm = relationship('User |
|
752 | users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') | |
753 |
|
753 | |||
754 | parent_group = relationship('RepoGroup', remote_side=group_id) |
|
754 | parent_group = relationship('RepoGroup', remote_side=group_id) | |
755 |
|
755 | |||
@@ -946,7 +946,7 b' class UserToPerm(Base, BaseModel):' | |||||
946 | permission = relationship('Permission', lazy='joined') |
|
946 | permission = relationship('Permission', lazy='joined') | |
947 |
|
947 | |||
948 |
|
948 | |||
949 |
class User |
|
949 | class UserGroupRepoToPerm(Base, BaseModel): | |
950 | __tablename__ = 'users_group_repo_to_perm' |
|
950 | __tablename__ = 'users_group_repo_to_perm' | |
951 | __table_args__ = ( |
|
951 | __table_args__ = ( | |
952 | UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), |
|
952 | UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), | |
@@ -958,7 +958,7 b' class UsersGroupRepoToPerm(Base, BaseMod' | |||||
958 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
958 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
959 | repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) |
|
959 | repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) | |
960 |
|
960 | |||
961 |
users_group = relationship('User |
|
961 | users_group = relationship('UserGroup') | |
962 | permission = relationship('Permission') |
|
962 | permission = relationship('Permission') | |
963 | repository = relationship('Repository') |
|
963 | repository = relationship('Repository') | |
964 |
|
964 | |||
@@ -975,7 +975,7 b' class UsersGroupRepoToPerm(Base, BaseMod' | |||||
975 | return u'<userGroup:%s => %s >' % (self.users_group, self.repository) |
|
975 | return u'<userGroup:%s => %s >' % (self.users_group, self.repository) | |
976 |
|
976 | |||
977 |
|
977 | |||
978 |
class User |
|
978 | class UserGroupToPerm(Base, BaseModel): | |
979 | __tablename__ = 'users_group_to_perm' |
|
979 | __tablename__ = 'users_group_to_perm' | |
980 | __table_args__ = ( |
|
980 | __table_args__ = ( | |
981 | UniqueConstraint('users_group_id', 'permission_id',), |
|
981 | UniqueConstraint('users_group_id', 'permission_id',), | |
@@ -986,7 +986,7 b' class UsersGroupToPerm(Base, BaseModel):' | |||||
986 | users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) |
|
986 | users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) | |
987 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
987 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
988 |
|
988 | |||
989 |
users_group = relationship('User |
|
989 | users_group = relationship('UserGroup') | |
990 | permission = relationship('Permission') |
|
990 | permission = relationship('Permission') | |
991 |
|
991 | |||
992 |
|
992 | |||
@@ -1008,7 +1008,7 b' class UserRepoGroupToPerm(Base, BaseMode' | |||||
1008 | permission = relationship('Permission') |
|
1008 | permission = relationship('Permission') | |
1009 |
|
1009 | |||
1010 |
|
1010 | |||
1011 |
class User |
|
1011 | class UserGroupRepoGroupToPerm(Base, BaseModel): | |
1012 | __tablename__ = 'users_group_repo_group_to_perm' |
|
1012 | __tablename__ = 'users_group_repo_group_to_perm' | |
1013 | __table_args__ = ( |
|
1013 | __table_args__ = ( | |
1014 | UniqueConstraint('users_group_id', 'group_id'), |
|
1014 | UniqueConstraint('users_group_id', 'group_id'), | |
@@ -1021,7 +1021,7 b' class UsersGroupRepoGroupToPerm(Base, Ba' | |||||
1021 | group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) |
|
1021 | group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) | |
1022 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
1022 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
1023 |
|
1023 | |||
1024 |
users_group = relationship('User |
|
1024 | users_group = relationship('UserGroup') | |
1025 | permission = relationship('Permission') |
|
1025 | permission = relationship('Permission') | |
1026 | group = relationship('RepoGroup') |
|
1026 | group = relationship('RepoGroup') | |
1027 |
|
1027 |
@@ -322,7 +322,7 b' class User(Base, BaseModel):' | |||||
322 | repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') |
|
322 | repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') | |
323 | repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') |
|
323 | repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') | |
324 |
|
324 | |||
325 |
group_member = relationship('User |
|
325 | group_member = relationship('UserGroupMember', cascade='all') | |
326 |
|
326 | |||
327 | notifications = relationship('UserNotification', cascade='all') |
|
327 | notifications = relationship('UserNotification', cascade='all') | |
328 | # notifications assigned to this user |
|
328 | # notifications assigned to this user | |
@@ -521,7 +521,7 b' class UserLog(Base, BaseModel):' | |||||
521 | repository = relationship('Repository', cascade='') |
|
521 | repository = relationship('Repository', cascade='') | |
522 |
|
522 | |||
523 |
|
523 | |||
524 |
class User |
|
524 | class UserGroup(Base, BaseModel): | |
525 | __tablename__ = 'users_groups' |
|
525 | __tablename__ = 'users_groups' | |
526 | __table_args__ = ( |
|
526 | __table_args__ = ( | |
527 | {'extend_existing': True, 'mysql_engine': 'InnoDB', |
|
527 | {'extend_existing': True, 'mysql_engine': 'InnoDB', | |
@@ -533,9 +533,9 b' class UsersGroup(Base, BaseModel):' | |||||
533 | users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) |
|
533 | users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) | |
534 | inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) |
|
534 | inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) | |
535 |
|
535 | |||
536 |
members = relationship('User |
|
536 | members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") | |
537 |
users_group_to_perm = relationship('User |
|
537 | users_group_to_perm = relationship('UserGroupToPerm', cascade='all') | |
538 |
users_group_repo_to_perm = relationship('User |
|
538 | users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') | |
539 |
|
539 | |||
540 | def __unicode__(self): |
|
540 | def __unicode__(self): | |
541 | return u'<userGroup(%s)>' % (self.users_group_name) |
|
541 | return u'<userGroup(%s)>' % (self.users_group_name) | |
@@ -575,7 +575,7 b' class UsersGroup(Base, BaseModel):' | |||||
575 | return data |
|
575 | return data | |
576 |
|
576 | |||
577 |
|
577 | |||
578 |
class User |
|
578 | class UserGroupMember(Base, BaseModel): | |
579 | __tablename__ = 'users_groups_members' |
|
579 | __tablename__ = 'users_groups_members' | |
580 | __table_args__ = ( |
|
580 | __table_args__ = ( | |
581 | {'extend_existing': True, 'mysql_engine': 'InnoDB', |
|
581 | {'extend_existing': True, 'mysql_engine': 'InnoDB', | |
@@ -587,7 +587,7 b' class UsersGroupMember(Base, BaseModel):' | |||||
587 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) |
|
587 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) | |
588 |
|
588 | |||
589 | user = relationship('User', lazy='joined') |
|
589 | user = relationship('User', lazy='joined') | |
590 |
users_group = relationship('User |
|
590 | users_group = relationship('UserGroup') | |
591 |
|
591 | |||
592 | def __init__(self, gr_id='', u_id=''): |
|
592 | def __init__(self, gr_id='', u_id=''): | |
593 | self.users_group_id = gr_id |
|
593 | self.users_group_id = gr_id | |
@@ -625,7 +625,7 b' class Repository(Base, BaseModel):' | |||||
625 | fork = relationship('Repository', remote_side=repo_id) |
|
625 | fork = relationship('Repository', remote_side=repo_id) | |
626 | group = relationship('RepoGroup') |
|
626 | group = relationship('RepoGroup') | |
627 | repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') |
|
627 | repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') | |
628 |
users_group_to_perm = relationship('User |
|
628 | users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') | |
629 | stats = relationship('Statistics', cascade='all', uselist=False) |
|
629 | stats = relationship('Statistics', cascade='all', uselist=False) | |
630 |
|
630 | |||
631 | followers = relationship('UserFollowing', |
|
631 | followers = relationship('UserFollowing', | |
@@ -1013,7 +1013,7 b' class RepoGroup(Base, BaseModel):' | |||||
1013 | enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) |
|
1013 | enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) | |
1014 |
|
1014 | |||
1015 | repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') |
|
1015 | repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') | |
1016 |
users_group_to_perm = relationship('User |
|
1016 | users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') | |
1017 |
|
1017 | |||
1018 | parent_group = relationship('RepoGroup', remote_side=group_id) |
|
1018 | parent_group = relationship('RepoGroup', remote_side=group_id) | |
1019 |
|
1019 | |||
@@ -1277,7 +1277,7 b' class UserToPerm(Base, BaseModel):' | |||||
1277 | permission = relationship('Permission', lazy='joined') |
|
1277 | permission = relationship('Permission', lazy='joined') | |
1278 |
|
1278 | |||
1279 |
|
1279 | |||
1280 |
class User |
|
1280 | class UserGroupRepoToPerm(Base, BaseModel): | |
1281 | __tablename__ = 'users_group_repo_to_perm' |
|
1281 | __tablename__ = 'users_group_repo_to_perm' | |
1282 | __table_args__ = ( |
|
1282 | __table_args__ = ( | |
1283 | UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), |
|
1283 | UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), | |
@@ -1289,7 +1289,7 b' class UsersGroupRepoToPerm(Base, BaseMod' | |||||
1289 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
1289 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
1290 | repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) |
|
1290 | repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) | |
1291 |
|
1291 | |||
1292 |
users_group = relationship('User |
|
1292 | users_group = relationship('UserGroup') | |
1293 | permission = relationship('Permission') |
|
1293 | permission = relationship('Permission') | |
1294 | repository = relationship('Repository') |
|
1294 | repository = relationship('Repository') | |
1295 |
|
1295 | |||
@@ -1306,7 +1306,7 b' class UsersGroupRepoToPerm(Base, BaseMod' | |||||
1306 | return u'<userGroup:%s => %s >' % (self.users_group, self.repository) |
|
1306 | return u'<userGroup:%s => %s >' % (self.users_group, self.repository) | |
1307 |
|
1307 | |||
1308 |
|
1308 | |||
1309 |
class User |
|
1309 | class UserGroupToPerm(Base, BaseModel): | |
1310 | __tablename__ = 'users_group_to_perm' |
|
1310 | __tablename__ = 'users_group_to_perm' | |
1311 | __table_args__ = ( |
|
1311 | __table_args__ = ( | |
1312 | UniqueConstraint('users_group_id', 'permission_id',), |
|
1312 | UniqueConstraint('users_group_id', 'permission_id',), | |
@@ -1317,7 +1317,7 b' class UsersGroupToPerm(Base, BaseModel):' | |||||
1317 | users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) |
|
1317 | users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) | |
1318 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
1318 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
1319 |
|
1319 | |||
1320 |
users_group = relationship('User |
|
1320 | users_group = relationship('UserGroup') | |
1321 | permission = relationship('Permission') |
|
1321 | permission = relationship('Permission') | |
1322 |
|
1322 | |||
1323 |
|
1323 | |||
@@ -1339,7 +1339,7 b' class UserRepoGroupToPerm(Base, BaseMode' | |||||
1339 | permission = relationship('Permission') |
|
1339 | permission = relationship('Permission') | |
1340 |
|
1340 | |||
1341 |
|
1341 | |||
1342 |
class User |
|
1342 | class UserGroupRepoGroupToPerm(Base, BaseModel): | |
1343 | __tablename__ = 'users_group_repo_group_to_perm' |
|
1343 | __tablename__ = 'users_group_repo_group_to_perm' | |
1344 | __table_args__ = ( |
|
1344 | __table_args__ = ( | |
1345 | UniqueConstraint('users_group_id', 'group_id'), |
|
1345 | UniqueConstraint('users_group_id', 'group_id'), | |
@@ -1352,7 +1352,7 b' class UsersGroupRepoGroupToPerm(Base, Ba' | |||||
1352 | group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) |
|
1352 | group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) | |
1353 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
1353 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
1354 |
|
1354 | |||
1355 |
users_group = relationship('User |
|
1355 | users_group = relationship('UserGroup') | |
1356 | permission = relationship('Permission') |
|
1356 | permission = relationship('Permission') | |
1357 | group = relationship('RepoGroup') |
|
1357 | group = relationship('RepoGroup') | |
1358 |
|
1358 |
@@ -341,7 +341,7 b' class User(Base, BaseModel):' | |||||
341 | repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') |
|
341 | repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') | |
342 | repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') |
|
342 | repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') | |
343 |
|
343 | |||
344 |
group_member = relationship('User |
|
344 | group_member = relationship('UserGroupMember', cascade='all') | |
345 |
|
345 | |||
346 | notifications = relationship('UserNotification', cascade='all') |
|
346 | notifications = relationship('UserNotification', cascade='all') | |
347 | # notifications assigned to this user |
|
347 | # notifications assigned to this user | |
@@ -541,7 +541,7 b' class UserLog(Base, BaseModel):' | |||||
541 | repository = relationship('Repository', cascade='') |
|
541 | repository = relationship('Repository', cascade='') | |
542 |
|
542 | |||
543 |
|
543 | |||
544 |
class User |
|
544 | class UserGroup(Base, BaseModel): | |
545 | __tablename__ = 'users_groups' |
|
545 | __tablename__ = 'users_groups' | |
546 | __table_args__ = ( |
|
546 | __table_args__ = ( | |
547 | {'extend_existing': True, 'mysql_engine': 'InnoDB', |
|
547 | {'extend_existing': True, 'mysql_engine': 'InnoDB', | |
@@ -553,9 +553,9 b' class UsersGroup(Base, BaseModel):' | |||||
553 | users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) |
|
553 | users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) | |
554 | inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) |
|
554 | inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) | |
555 |
|
555 | |||
556 |
members = relationship('User |
|
556 | members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") | |
557 |
users_group_to_perm = relationship('User |
|
557 | users_group_to_perm = relationship('UserGroupToPerm', cascade='all') | |
558 |
users_group_repo_to_perm = relationship('User |
|
558 | users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') | |
559 |
|
559 | |||
560 | def __unicode__(self): |
|
560 | def __unicode__(self): | |
561 | return u'<userGroup(%s)>' % (self.users_group_name) |
|
561 | return u'<userGroup(%s)>' % (self.users_group_name) | |
@@ -595,7 +595,7 b' class UsersGroup(Base, BaseModel):' | |||||
595 | return data |
|
595 | return data | |
596 |
|
596 | |||
597 |
|
597 | |||
598 |
class User |
|
598 | class UserGroupMember(Base, BaseModel): | |
599 | __tablename__ = 'users_groups_members' |
|
599 | __tablename__ = 'users_groups_members' | |
600 | __table_args__ = ( |
|
600 | __table_args__ = ( | |
601 | {'extend_existing': True, 'mysql_engine': 'InnoDB', |
|
601 | {'extend_existing': True, 'mysql_engine': 'InnoDB', | |
@@ -607,7 +607,7 b' class UsersGroupMember(Base, BaseModel):' | |||||
607 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) |
|
607 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) | |
608 |
|
608 | |||
609 | user = relationship('User', lazy='joined') |
|
609 | user = relationship('User', lazy='joined') | |
610 |
users_group = relationship('User |
|
610 | users_group = relationship('UserGroup') | |
611 |
|
611 | |||
612 | def __init__(self, gr_id='', u_id=''): |
|
612 | def __init__(self, gr_id='', u_id=''): | |
613 | self.users_group_id = gr_id |
|
613 | self.users_group_id = gr_id | |
@@ -645,7 +645,7 b' class Repository(Base, BaseModel):' | |||||
645 | fork = relationship('Repository', remote_side=repo_id) |
|
645 | fork = relationship('Repository', remote_side=repo_id) | |
646 | group = relationship('RepoGroup') |
|
646 | group = relationship('RepoGroup') | |
647 | repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') |
|
647 | repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') | |
648 |
users_group_to_perm = relationship('User |
|
648 | users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') | |
649 | stats = relationship('Statistics', cascade='all', uselist=False) |
|
649 | stats = relationship('Statistics', cascade='all', uselist=False) | |
650 |
|
650 | |||
651 | followers = relationship('UserFollowing', |
|
651 | followers = relationship('UserFollowing', | |
@@ -1033,7 +1033,7 b' class RepoGroup(Base, BaseModel):' | |||||
1033 | enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) |
|
1033 | enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) | |
1034 |
|
1034 | |||
1035 | repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') |
|
1035 | repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') | |
1036 |
users_group_to_perm = relationship('User |
|
1036 | users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') | |
1037 |
|
1037 | |||
1038 | parent_group = relationship('RepoGroup', remote_side=group_id) |
|
1038 | parent_group = relationship('RepoGroup', remote_side=group_id) | |
1039 |
|
1039 | |||
@@ -1297,7 +1297,7 b' class UserToPerm(Base, BaseModel):' | |||||
1297 | permission = relationship('Permission', lazy='joined') |
|
1297 | permission = relationship('Permission', lazy='joined') | |
1298 |
|
1298 | |||
1299 |
|
1299 | |||
1300 |
class User |
|
1300 | class UserGroupRepoToPerm(Base, BaseModel): | |
1301 | __tablename__ = 'users_group_repo_to_perm' |
|
1301 | __tablename__ = 'users_group_repo_to_perm' | |
1302 | __table_args__ = ( |
|
1302 | __table_args__ = ( | |
1303 | UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), |
|
1303 | UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), | |
@@ -1309,7 +1309,7 b' class UsersGroupRepoToPerm(Base, BaseMod' | |||||
1309 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
1309 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
1310 | repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) |
|
1310 | repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) | |
1311 |
|
1311 | |||
1312 |
users_group = relationship('User |
|
1312 | users_group = relationship('UserGroup') | |
1313 | permission = relationship('Permission') |
|
1313 | permission = relationship('Permission') | |
1314 | repository = relationship('Repository') |
|
1314 | repository = relationship('Repository') | |
1315 |
|
1315 | |||
@@ -1326,7 +1326,7 b' class UsersGroupRepoToPerm(Base, BaseMod' | |||||
1326 | return u'<userGroup:%s => %s >' % (self.users_group, self.repository) |
|
1326 | return u'<userGroup:%s => %s >' % (self.users_group, self.repository) | |
1327 |
|
1327 | |||
1328 |
|
1328 | |||
1329 |
class User |
|
1329 | class UserGroupToPerm(Base, BaseModel): | |
1330 | __tablename__ = 'users_group_to_perm' |
|
1330 | __tablename__ = 'users_group_to_perm' | |
1331 | __table_args__ = ( |
|
1331 | __table_args__ = ( | |
1332 | UniqueConstraint('users_group_id', 'permission_id',), |
|
1332 | UniqueConstraint('users_group_id', 'permission_id',), | |
@@ -1337,7 +1337,7 b' class UsersGroupToPerm(Base, BaseModel):' | |||||
1337 | users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) |
|
1337 | users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) | |
1338 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
1338 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
1339 |
|
1339 | |||
1340 |
users_group = relationship('User |
|
1340 | users_group = relationship('UserGroup') | |
1341 | permission = relationship('Permission') |
|
1341 | permission = relationship('Permission') | |
1342 |
|
1342 | |||
1343 |
|
1343 | |||
@@ -1359,7 +1359,7 b' class UserRepoGroupToPerm(Base, BaseMode' | |||||
1359 | permission = relationship('Permission') |
|
1359 | permission = relationship('Permission') | |
1360 |
|
1360 | |||
1361 |
|
1361 | |||
1362 |
class User |
|
1362 | class UserGroupRepoGroupToPerm(Base, BaseModel): | |
1363 | __tablename__ = 'users_group_repo_group_to_perm' |
|
1363 | __tablename__ = 'users_group_repo_group_to_perm' | |
1364 | __table_args__ = ( |
|
1364 | __table_args__ = ( | |
1365 | UniqueConstraint('users_group_id', 'group_id'), |
|
1365 | UniqueConstraint('users_group_id', 'group_id'), | |
@@ -1372,7 +1372,7 b' class UsersGroupRepoGroupToPerm(Base, Ba' | |||||
1372 | group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) |
|
1372 | group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) | |
1373 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
1373 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
1374 |
|
1374 | |||
1375 |
users_group = relationship('User |
|
1375 | users_group = relationship('UserGroup') | |
1376 | permission = relationship('Permission') |
|
1376 | permission = relationship('Permission') | |
1377 | group = relationship('RepoGroup') |
|
1377 | group = relationship('RepoGroup') | |
1378 |
|
1378 |
@@ -341,7 +341,7 b' class User(Base, BaseModel):' | |||||
341 | repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') |
|
341 | repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') | |
342 | repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') |
|
342 | repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') | |
343 |
|
343 | |||
344 |
group_member = relationship('User |
|
344 | group_member = relationship('UserGroupMember', cascade='all') | |
345 |
|
345 | |||
346 | notifications = relationship('UserNotification', cascade='all') |
|
346 | notifications = relationship('UserNotification', cascade='all') | |
347 | # notifications assigned to this user |
|
347 | # notifications assigned to this user | |
@@ -575,7 +575,7 b' class UserLog(Base, BaseModel):' | |||||
575 | repository = relationship('Repository', cascade='') |
|
575 | repository = relationship('Repository', cascade='') | |
576 |
|
576 | |||
577 |
|
577 | |||
578 |
class User |
|
578 | class UserGroup(Base, BaseModel): | |
579 | __tablename__ = 'users_groups' |
|
579 | __tablename__ = 'users_groups' | |
580 | __table_args__ = ( |
|
580 | __table_args__ = ( | |
581 | {'extend_existing': True, 'mysql_engine': 'InnoDB', |
|
581 | {'extend_existing': True, 'mysql_engine': 'InnoDB', | |
@@ -587,9 +587,9 b' class UsersGroup(Base, BaseModel):' | |||||
587 | users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) |
|
587 | users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) | |
588 | inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) |
|
588 | inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) | |
589 |
|
589 | |||
590 |
members = relationship('User |
|
590 | members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") | |
591 |
users_group_to_perm = relationship('User |
|
591 | users_group_to_perm = relationship('UserGroupToPerm', cascade='all') | |
592 |
users_group_repo_to_perm = relationship('User |
|
592 | users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') | |
593 |
|
593 | |||
594 | def __unicode__(self): |
|
594 | def __unicode__(self): | |
595 | return u'<userGroup(%s)>' % (self.users_group_name) |
|
595 | return u'<userGroup(%s)>' % (self.users_group_name) | |
@@ -629,7 +629,7 b' class UsersGroup(Base, BaseModel):' | |||||
629 | return data |
|
629 | return data | |
630 |
|
630 | |||
631 |
|
631 | |||
632 |
class User |
|
632 | class UserGroupMember(Base, BaseModel): | |
633 | __tablename__ = 'users_groups_members' |
|
633 | __tablename__ = 'users_groups_members' | |
634 | __table_args__ = ( |
|
634 | __table_args__ = ( | |
635 | {'extend_existing': True, 'mysql_engine': 'InnoDB', |
|
635 | {'extend_existing': True, 'mysql_engine': 'InnoDB', | |
@@ -641,7 +641,7 b' class UsersGroupMember(Base, BaseModel):' | |||||
641 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) |
|
641 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) | |
642 |
|
642 | |||
643 | user = relationship('User', lazy='joined') |
|
643 | user = relationship('User', lazy='joined') | |
644 |
users_group = relationship('User |
|
644 | users_group = relationship('UserGroup') | |
645 |
|
645 | |||
646 | def __init__(self, gr_id='', u_id=''): |
|
646 | def __init__(self, gr_id='', u_id=''): | |
647 | self.users_group_id = gr_id |
|
647 | self.users_group_id = gr_id | |
@@ -680,7 +680,7 b' class Repository(Base, BaseModel):' | |||||
680 | fork = relationship('Repository', remote_side=repo_id) |
|
680 | fork = relationship('Repository', remote_side=repo_id) | |
681 | group = relationship('RepoGroup') |
|
681 | group = relationship('RepoGroup') | |
682 | repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') |
|
682 | repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') | |
683 |
users_group_to_perm = relationship('User |
|
683 | users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') | |
684 | stats = relationship('Statistics', cascade='all', uselist=False) |
|
684 | stats = relationship('Statistics', cascade='all', uselist=False) | |
685 |
|
685 | |||
686 | followers = relationship('UserFollowing', |
|
686 | followers = relationship('UserFollowing', | |
@@ -1139,7 +1139,7 b' class RepoGroup(Base, BaseModel):' | |||||
1139 | enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) |
|
1139 | enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) | |
1140 |
|
1140 | |||
1141 | repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') |
|
1141 | repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') | |
1142 |
users_group_to_perm = relationship('User |
|
1142 | users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') | |
1143 |
|
1143 | |||
1144 | parent_group = relationship('RepoGroup', remote_side=group_id) |
|
1144 | parent_group = relationship('RepoGroup', remote_side=group_id) | |
1145 |
|
1145 | |||
@@ -1403,7 +1403,7 b' class UserToPerm(Base, BaseModel):' | |||||
1403 | permission = relationship('Permission', lazy='joined') |
|
1403 | permission = relationship('Permission', lazy='joined') | |
1404 |
|
1404 | |||
1405 |
|
1405 | |||
1406 |
class User |
|
1406 | class UserGroupRepoToPerm(Base, BaseModel): | |
1407 | __tablename__ = 'users_group_repo_to_perm' |
|
1407 | __tablename__ = 'users_group_repo_to_perm' | |
1408 | __table_args__ = ( |
|
1408 | __table_args__ = ( | |
1409 | UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), |
|
1409 | UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), | |
@@ -1415,7 +1415,7 b' class UsersGroupRepoToPerm(Base, BaseMod' | |||||
1415 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
1415 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
1416 | repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) |
|
1416 | repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) | |
1417 |
|
1417 | |||
1418 |
users_group = relationship('User |
|
1418 | users_group = relationship('UserGroup') | |
1419 | permission = relationship('Permission') |
|
1419 | permission = relationship('Permission') | |
1420 | repository = relationship('Repository') |
|
1420 | repository = relationship('Repository') | |
1421 |
|
1421 | |||
@@ -1432,7 +1432,7 b' class UsersGroupRepoToPerm(Base, BaseMod' | |||||
1432 | return u'<userGroup:%s => %s >' % (self.users_group, self.repository) |
|
1432 | return u'<userGroup:%s => %s >' % (self.users_group, self.repository) | |
1433 |
|
1433 | |||
1434 |
|
1434 | |||
1435 |
class User |
|
1435 | class UserGroupToPerm(Base, BaseModel): | |
1436 | __tablename__ = 'users_group_to_perm' |
|
1436 | __tablename__ = 'users_group_to_perm' | |
1437 | __table_args__ = ( |
|
1437 | __table_args__ = ( | |
1438 | UniqueConstraint('users_group_id', 'permission_id',), |
|
1438 | UniqueConstraint('users_group_id', 'permission_id',), | |
@@ -1443,7 +1443,7 b' class UsersGroupToPerm(Base, BaseModel):' | |||||
1443 | users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) |
|
1443 | users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) | |
1444 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
1444 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
1445 |
|
1445 | |||
1446 |
users_group = relationship('User |
|
1446 | users_group = relationship('UserGroup') | |
1447 | permission = relationship('Permission') |
|
1447 | permission = relationship('Permission') | |
1448 |
|
1448 | |||
1449 |
|
1449 | |||
@@ -1465,7 +1465,7 b' class UserRepoGroupToPerm(Base, BaseMode' | |||||
1465 | permission = relationship('Permission') |
|
1465 | permission = relationship('Permission') | |
1466 |
|
1466 | |||
1467 |
|
1467 | |||
1468 |
class User |
|
1468 | class UserGroupRepoGroupToPerm(Base, BaseModel): | |
1469 | __tablename__ = 'users_group_repo_group_to_perm' |
|
1469 | __tablename__ = 'users_group_repo_group_to_perm' | |
1470 | __table_args__ = ( |
|
1470 | __table_args__ = ( | |
1471 | UniqueConstraint('users_group_id', 'group_id'), |
|
1471 | UniqueConstraint('users_group_id', 'group_id'), | |
@@ -1478,7 +1478,7 b' class UsersGroupRepoGroupToPerm(Base, Ba' | |||||
1478 | group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) |
|
1478 | group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) | |
1479 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
1479 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
1480 |
|
1480 | |||
1481 |
users_group = relationship('User |
|
1481 | users_group = relationship('UserGroup') | |
1482 | permission = relationship('Permission') |
|
1482 | permission = relationship('Permission') | |
1483 | group = relationship('RepoGroup') |
|
1483 | group = relationship('RepoGroup') | |
1484 |
|
1484 |
@@ -34,26 +34,26 b' def upgrade(migrate_engine):' | |||||
34 | #========================================================================== |
|
34 | #========================================================================== | |
35 | # Add table `users_groups` |
|
35 | # Add table `users_groups` | |
36 | #========================================================================== |
|
36 | #========================================================================== | |
37 |
from rhodecode.lib.dbmigrate.schema.db_1_2_0 import User |
|
37 | from rhodecode.lib.dbmigrate.schema.db_1_2_0 import UserGroup | |
38 |
User |
|
38 | UserGroup().__table__.create() | |
39 |
|
39 | |||
40 | #========================================================================== |
|
40 | #========================================================================== | |
41 | # Add table `users_groups_members` |
|
41 | # Add table `users_groups_members` | |
42 | #========================================================================== |
|
42 | #========================================================================== | |
43 |
from rhodecode.lib.dbmigrate.schema.db_1_2_0 import User |
|
43 | from rhodecode.lib.dbmigrate.schema.db_1_2_0 import UserGroupMember | |
44 |
User |
|
44 | UserGroupMember().__table__.create() | |
45 |
|
45 | |||
46 | #========================================================================== |
|
46 | #========================================================================== | |
47 | # Add table `users_group_repo_to_perm` |
|
47 | # Add table `users_group_repo_to_perm` | |
48 | #========================================================================== |
|
48 | #========================================================================== | |
49 |
from rhodecode.lib.dbmigrate.schema.db_1_2_0 import User |
|
49 | from rhodecode.lib.dbmigrate.schema.db_1_2_0 import UserGroupRepoToPerm | |
50 |
User |
|
50 | UserGroupRepoToPerm().__table__.create() | |
51 |
|
51 | |||
52 | #========================================================================== |
|
52 | #========================================================================== | |
53 | # Add table `users_group_to_perm` |
|
53 | # Add table `users_group_to_perm` | |
54 | #========================================================================== |
|
54 | #========================================================================== | |
55 |
from rhodecode.lib.dbmigrate.schema.db_1_2_0 import User |
|
55 | from rhodecode.lib.dbmigrate.schema.db_1_2_0 import UserGroupToPerm | |
56 |
User |
|
56 | UserGroupToPerm().__table__.create() | |
57 |
|
57 | |||
58 | #========================================================================== |
|
58 | #========================================================================== | |
59 | # Upgrade of `users` table |
|
59 | # Upgrade of `users` table |
@@ -21,8 +21,8 b' def upgrade(migrate_engine):' | |||||
21 | #========================================================================== |
|
21 | #========================================================================== | |
22 | # Add table `users_group_repo_group_to_perm` |
|
22 | # Add table `users_group_repo_group_to_perm` | |
23 | #========================================================================== |
|
23 | #========================================================================== | |
24 |
from rhodecode.lib.dbmigrate.schema.db_1_3_0 import User |
|
24 | from rhodecode.lib.dbmigrate.schema.db_1_3_0 import UserGroupRepoGroupToPerm | |
25 |
User |
|
25 | UserGroupRepoGroupToPerm().__table__.create() | |
26 |
|
26 | |||
27 | #========================================================================== |
|
27 | #========================================================================== | |
28 | # Add table `changeset_comments` |
|
28 | # Add table `changeset_comments` | |
@@ -45,8 +45,8 b' def upgrade(migrate_engine):' | |||||
45 | #========================================================================== |
|
45 | #========================================================================== | |
46 | # Add unique to table `users_group_to_perm` |
|
46 | # Add unique to table `users_group_to_perm` | |
47 | #========================================================================== |
|
47 | #========================================================================== | |
48 |
from rhodecode.lib.dbmigrate.schema.db_1_3_0 import User |
|
48 | from rhodecode.lib.dbmigrate.schema.db_1_3_0 import UserGroupToPerm | |
49 |
tbl = User |
|
49 | tbl = UserGroupToPerm().__table__ | |
50 | cons = UniqueConstraint('users_group_id', 'permission_id', table=tbl) |
|
50 | cons = UniqueConstraint('users_group_id', 'permission_id', table=tbl) | |
51 | cons.create() |
|
51 | cons.create() | |
52 |
|
52 |
@@ -74,8 +74,8 b' def upgrade(migrate_engine):' | |||||
74 | #========================================================================== |
|
74 | #========================================================================== | |
75 | # USERS GROUP TABLE |
|
75 | # USERS GROUP TABLE | |
76 | #========================================================================== |
|
76 | #========================================================================== | |
77 |
from rhodecode.lib.dbmigrate.schema.db_1_3_0 import User |
|
77 | from rhodecode.lib.dbmigrate.schema.db_1_3_0 import UserGroup | |
78 |
tbl = User |
|
78 | tbl = UserGroup.__table__ | |
79 | # add inherit_default_permission column |
|
79 | # add inherit_default_permission column | |
80 | gr_inherit_default_permissions = Column( |
|
80 | gr_inherit_default_permissions = Column( | |
81 | "users_group_inherit_default_permissions", |
|
81 | "users_group_inherit_default_permissions", |
@@ -50,7 +50,7 b' class UserOwnsReposException(Exception):' | |||||
50 | pass |
|
50 | pass | |
51 |
|
51 | |||
52 |
|
52 | |||
53 |
class User |
|
53 | class UserGroupsAssignedException(Exception): | |
54 | pass |
|
54 | pass | |
55 |
|
55 | |||
56 |
|
56 |
@@ -684,9 +684,9 b' def action_parser(user_log, feed=False, ' | |||||
684 | get_user_name, 'user_add.png'), |
|
684 | get_user_name, 'user_add.png'), | |
685 | 'admin_updated_user': (_('[updated] user'), |
|
685 | 'admin_updated_user': (_('[updated] user'), | |
686 | get_user_name, 'user_edit.png'), |
|
686 | get_user_name, 'user_edit.png'), | |
687 |
'admin_created_users_group': (_('[created] user |
|
687 | 'admin_created_users_group': (_('[created] user group'), | |
688 | get_users_group, 'group_add.png'), |
|
688 | get_users_group, 'group_add.png'), | |
689 |
'admin_updated_users_group': (_('[updated] user |
|
689 | 'admin_updated_users_group': (_('[updated] user group'), | |
690 | get_users_group, 'group_edit.png'), |
|
690 | get_users_group, 'group_edit.png'), | |
691 | 'user_commented_revision': (_('[commented] on revision in repository'), |
|
691 | 'user_commented_revision': (_('[commented] on revision in repository'), | |
692 | get_cs_links, 'comment_add.png'), |
|
692 | get_cs_links, 'comment_add.png'), | |
@@ -977,7 +977,7 b' def fancy_file_stats(stats):' | |||||
977 | return literal('<div style="width:%spx">%s%s</div>' % (width, d_a, d_d)) |
|
977 | return literal('<div style="width:%spx">%s%s</div>' % (width, d_a, d_d)) | |
978 |
|
978 | |||
979 |
|
979 | |||
980 | def urlify_text(text_): |
|
980 | def urlify_text(text_, safe=True): | |
981 | """ |
|
981 | """ | |
982 | Extrac urls from text and make html links out of them |
|
982 | Extrac urls from text and make html links out of them | |
983 |
|
983 | |||
@@ -990,8 +990,10 b' def urlify_text(text_):' | |||||
990 | def url_func(match_obj): |
|
990 | def url_func(match_obj): | |
991 | url_full = match_obj.groups()[0] |
|
991 | url_full = match_obj.groups()[0] | |
992 | return '<a href="%(url)s">%(url)s</a>' % ({'url': url_full}) |
|
992 | return '<a href="%(url)s">%(url)s</a>' % ({'url': url_full}) | |
993 |
|
993 | _newtext = url_pat.sub(url_func, text_) | ||
994 | return literal(url_pat.sub(url_func, text_)) |
|
994 | if safe: | |
|
995 | return literal(_newtext) | |||
|
996 | return _newtext | |||
995 |
|
997 | |||
996 |
|
998 | |||
997 | def urlify_changesets(text_, repository): |
|
999 | def urlify_changesets(text_, repository): | |
@@ -1002,21 +1004,16 b' def urlify_changesets(text_, repository)' | |||||
1002 | :param repository: repo name to build the URL with |
|
1004 | :param repository: repo name to build the URL with | |
1003 | """ |
|
1005 | """ | |
1004 | from pylons import url # doh, we need to re-import url to mock it later |
|
1006 | from pylons import url # doh, we need to re-import url to mock it later | |
1005 |
URL_PAT = re.compile(r'( |
|
1007 | URL_PAT = re.compile(r'(^|\s)([0-9a-fA-F]{12,40})($|\s)') | |
1006 |
|
1008 | |||
1007 | def url_func(match_obj): |
|
1009 | def url_func(match_obj): | |
1008 |
rev = match_obj.groups()[ |
|
1010 | rev = match_obj.groups()[1] | |
1009 | pref = '' |
|
1011 | pref = match_obj.groups()[0] | |
1010 | suf = '' |
|
1012 | suf = match_obj.groups()[2] | |
1011 | if match_obj.group().startswith(' '): |
|
1013 | ||
1012 | pref = ' ' |
|
|||
1013 | if match_obj.group().endswith(' '): |
|
|||
1014 | suf = ' ' |
|
|||
1015 | tmpl = ( |
|
1014 | tmpl = ( | |
1016 | '%(pref)s<a class="%(cls)s" href="%(url)s">' |
|
1015 | '%(pref)s<a class="%(cls)s" href="%(url)s">' | |
1017 | '%(rev)s' |
|
1016 | '%(rev)s</a>%(suf)s' | |
1018 | '</a>' |
|
|||
1019 | '%(suf)s' |
|
|||
1020 | ) |
|
1017 | ) | |
1021 | return tmpl % { |
|
1018 | return tmpl % { | |
1022 | 'pref': pref, |
|
1019 | 'pref': pref, | |
@@ -1062,7 +1059,7 b' def urlify_commit(text_, repository=None' | |||||
1062 | newtext = urlify_changesets(escaper(text_), repository) |
|
1059 | newtext = urlify_changesets(escaper(text_), repository) | |
1063 |
|
1060 | |||
1064 | # extract http/https links and make them real urls |
|
1061 | # extract http/https links and make them real urls | |
1065 | newtext = urlify_text(newtext) |
|
1062 | newtext = urlify_text(newtext, safe=False) | |
1066 |
|
1063 | |||
1067 | try: |
|
1064 | try: | |
1068 | from rhodecode import CONFIG |
|
1065 | from rhodecode import CONFIG |
@@ -1,17 +1,20 b'' | |||||
1 |
# unionrepo.py - repository class for viewing union of repositor |
|
1 | # unionrepo.py - repository class for viewing union of repository changesets | |
2 | # |
|
2 | # | |
3 |
# Derived from |
|
3 | # Derived from bundlerepo.py | |
4 | # Copyright 2006, 2007 Benoit Boissinot <bboissin@gmail.com> |
|
4 | # Copyright 2006, 2007 Benoit Boissinot <bboissin@gmail.com> | |
5 | # Copyright 2013 Unity Technologies, Mads Kiilerich <madski@unity3d.com> |
|
5 | # Copyright 2013 Unity Technologies, Mads Kiilerich <madski@unity3d.com> | |
6 | # |
|
6 | # | |
7 | # This software may be used and distributed according to the terms of the |
|
7 | # This software may be used and distributed according to the terms of the | |
8 | # GNU General Public License version 2 or any later version. |
|
8 | # GNU General Public License version 2 or any later version. | |
9 |
|
9 | |||
10 |
"""Repository class for in-memory pull of one local repository to another |
|
10 | """Repository class for "in-memory pull" of one local repository to another, | |
|
11 | allowing operations like diff and log with revsets. | |||
11 | """ |
|
12 | """ | |
12 |
|
13 | |||
|
14 | import os | |||
13 | from mercurial.node import nullid |
|
15 | from mercurial.node import nullid | |
14 |
from mercurial import |
|
16 | from mercurial.i18n import _ | |
|
17 | from mercurial import util, mdiff, cmdutil, scmutil | |||
15 | from mercurial import localrepo, changelog, manifest, filelog, revlog |
|
18 | from mercurial import localrepo, changelog, manifest, filelog, revlog | |
16 |
|
19 | |||
17 | class unionrevlog(revlog.revlog): |
|
20 | class unionrevlog(revlog.revlog): | |
@@ -20,15 +23,14 b' class unionrevlog(revlog.revlog):' | |||||
20 | # To retrieve a revision, we just need to know the node id so we can |
|
23 | # To retrieve a revision, we just need to know the node id so we can | |
21 | # look it up in revlog2. |
|
24 | # look it up in revlog2. | |
22 | # |
|
25 | # | |
23 | # basemap is indexed with revisions coming from the second revlog. |
|
|||
24 | # |
|
|||
25 | # To differentiate a rev in the second revlog from a rev in the revlog, |
|
26 | # To differentiate a rev in the second revlog from a rev in the revlog, | |
26 |
# we check revision against |
|
27 | # we check revision against repotiprev. | |
|
28 | opener = scmutil.readonlyvfs(opener) | |||
27 | revlog.revlog.__init__(self, opener, indexfile) |
|
29 | revlog.revlog.__init__(self, opener, indexfile) | |
28 | self.revlog2 = revlog2 |
|
30 | self.revlog2 = revlog2 | |
29 |
|
31 | |||
30 | self.basemap = {} # mapping rev that is in revlog2 to ... nothing |
|
|||
31 | n = len(self) |
|
32 | n = len(self) | |
|
33 | self.repotiprev = n - 1 | |||
32 | self.bundlerevs = set() # used by 'bundle()' revset expression |
|
34 | self.bundlerevs = set() # used by 'bundle()' revset expression | |
33 | for rev2 in self.revlog2: |
|
35 | for rev2 in self.revlog2: | |
34 | rev = self.revlog2.index[rev2] |
|
36 | rev = self.revlog2.index[rev2] | |
@@ -42,7 +44,7 b' class unionrevlog(revlog.revlog):' | |||||
42 | link = linkmapper(linkrev) |
|
44 | link = linkmapper(linkrev) | |
43 |
|
45 | |||
44 | if node in self.nodemap: |
|
46 | if node in self.nodemap: | |
45 |
# this happens for |
|
47 | # this happens for the common revlog revisions | |
46 | self.bundlerevs.add(self.nodemap[node]) |
|
48 | self.bundlerevs.add(self.nodemap[node]) | |
47 | continue |
|
49 | continue | |
48 |
|
50 | |||
@@ -51,24 +53,23 b' class unionrevlog(revlog.revlog):' | |||||
51 |
|
53 | |||
52 | e = (None, None, None, None, |
|
54 | e = (None, None, None, None, | |
53 | link, self.rev(p1node), self.rev(p2node), node) |
|
55 | link, self.rev(p1node), self.rev(p2node), node) | |
54 | self.basemap[n] = None |
|
|||
55 | self.index.insert(-1, e) |
|
56 | self.index.insert(-1, e) | |
56 | self.nodemap[node] = n |
|
57 | self.nodemap[node] = n | |
57 | self.bundlerevs.add(n) |
|
58 | self.bundlerevs.add(n) | |
58 | n += 1 |
|
59 | n += 1 | |
59 |
|
60 | |||
60 | def _chunk(self, rev): |
|
61 | def _chunk(self, rev): | |
61 |
if rev |
|
62 | if rev <= self.repotiprev: | |
62 | return revlog.revlog._chunk(self, rev) |
|
63 | return revlog.revlog._chunk(self, rev) | |
63 | return self.revlog2._chunk(self.node(rev)) |
|
64 | return self.revlog2._chunk(self.node(rev)) | |
64 |
|
65 | |||
65 | def revdiff(self, rev1, rev2): |
|
66 | def revdiff(self, rev1, rev2): | |
66 | """return or calculate a delta between two revisions""" |
|
67 | """return or calculate a delta between two revisions""" | |
67 |
if rev1 |
|
68 | if rev1 > self.repotiprev and rev2 > self.repotiprev: | |
68 | return self.revlog2.revdiff( |
|
69 | return self.revlog2.revdiff( | |
69 | self.revlog2.rev(self.node(rev1)), |
|
70 | self.revlog2.rev(self.node(rev1)), | |
70 | self.revlog2.rev(self.node(rev2))) |
|
71 | self.revlog2.rev(self.node(rev2))) | |
71 |
elif rev1 |
|
72 | elif rev1 <= self.repotiprev and rev2 <= self.repotiprev: | |
72 | return revlog.revlog.revdiff(self, rev1, rev2) |
|
73 | return revlog.revlog.revdiff(self, rev1, rev2) | |
73 |
|
74 | |||
74 | return mdiff.textdiff(self.revision(self.node(rev1)), |
|
75 | return mdiff.textdiff(self.revision(self.node(rev1)), | |
@@ -88,7 +89,7 b' class unionrevlog(revlog.revlog):' | |||||
88 | if node == nullid: |
|
89 | if node == nullid: | |
89 | return "" |
|
90 | return "" | |
90 |
|
91 | |||
91 |
if rev |
|
92 | if rev > self.repotiprev: | |
92 | text = self.revlog2.revision(node) |
|
93 | text = self.revlog2.revision(node) | |
93 | self._cache = (node, rev, text) |
|
94 | self._cache = (node, rev, text) | |
94 | else: |
|
95 | else: | |
@@ -144,7 +145,7 b' class unionrepository(localrepo.localrep' | |||||
144 | util.expandpath(path2)) |
|
145 | util.expandpath(path2)) | |
145 | self.repo2 = localrepo.localrepository(ui, path2) |
|
146 | self.repo2 = localrepo.localrepository(ui, path2) | |
146 |
|
147 | |||
147 |
@ |
|
148 | @localrepo.unfilteredpropertycache | |
148 | def changelog(self): |
|
149 | def changelog(self): | |
149 | return unionchangelog(self.sopener, self.repo2.sopener) |
|
150 | return unionchangelog(self.sopener, self.repo2.sopener) | |
150 |
|
151 | |||
@@ -153,7 +154,7 b' class unionrepository(localrepo.localrep' | |||||
153 | node = self.repo2.changelog.node(rev2) |
|
154 | node = self.repo2.changelog.node(rev2) | |
154 | return self.changelog.rev(node) |
|
155 | return self.changelog.rev(node) | |
155 |
|
156 | |||
156 |
@ |
|
157 | @localrepo.unfilteredpropertycache | |
157 | def manifest(self): |
|
158 | def manifest(self): | |
158 | return unionmanifest(self.sopener, self.repo2.sopener, |
|
159 | return unionmanifest(self.sopener, self.repo2.sopener, | |
159 | self._clrev) |
|
160 | self._clrev) | |
@@ -174,8 +175,34 b' class unionrepository(localrepo.localrep' | |||||
174 | def peer(self): |
|
175 | def peer(self): | |
175 | return unionpeer(self) |
|
176 | return unionpeer(self) | |
176 |
|
177 | |||
|
178 | def getcwd(self): | |||
|
179 | return os.getcwd() # always outside the repo | |||
|
180 | ||||
177 | def instance(ui, path, create): |
|
181 | def instance(ui, path, create): | |
178 | u = util.url(path) |
|
182 | if create: | |
179 | assert u.scheme == 'union' |
|
183 | raise util.Abort(_('cannot create new union repository')) | |
180 | repopath, repopath2 = u.path.split("+", 1) |
|
184 | parentpath = ui.config("bundle", "mainreporoot", "") | |
|
185 | if not parentpath: | |||
|
186 | # try to find the correct path to the working directory repo | |||
|
187 | parentpath = cmdutil.findrepo(os.getcwd()) | |||
|
188 | if parentpath is None: | |||
|
189 | parentpath = '' | |||
|
190 | if parentpath: | |||
|
191 | # Try to make the full path relative so we get a nice, short URL. | |||
|
192 | # In particular, we don't want temp dir names in test outputs. | |||
|
193 | cwd = os.getcwd() | |||
|
194 | if parentpath == cwd: | |||
|
195 | parentpath = '' | |||
|
196 | else: | |||
|
197 | cwd = os.path.join(cwd,'') | |||
|
198 | if parentpath.startswith(cwd): | |||
|
199 | parentpath = parentpath[len(cwd):] | |||
|
200 | if path.startswith('union:'): | |||
|
201 | s = path.split(":", 1)[1].split("+", 1) | |||
|
202 | if len(s) == 1: | |||
|
203 | repopath, repopath2 = parentpath, s[0] | |||
|
204 | else: | |||
|
205 | repopath, repopath2 = s | |||
|
206 | else: | |||
|
207 | repopath, repopath2 = parentpath, path | |||
181 | return unionrepository(ui, repopath, repopath2) |
|
208 | return unionrepository(ui, repopath, repopath2) |
@@ -2,71 +2,71 b' import os' | |||||
2 |
|
2 | |||
3 |
|
3 | |||
4 | class LockFile(object): |
|
4 | class LockFile(object): | |
5 |
|
|
5 | """Provides methods to obtain, check for, and release a file based lock which | |
6 |
|
|
6 | should be used to handle concurrent access to the same file. | |
7 |
|
7 | |||
8 |
|
|
8 | As we are a utility class to be derived from, we only use protected methods. | |
9 |
|
9 | |||
10 |
|
|
10 | Locks will automatically be released on destruction""" | |
11 |
|
|
11 | __slots__ = ("_file_path", "_owns_lock") | |
12 |
|
12 | |||
13 |
|
|
13 | def __init__(self, file_path): | |
14 |
|
|
14 | self._file_path = file_path | |
15 |
|
|
15 | self._owns_lock = False | |
16 |
|
16 | |||
17 |
|
|
17 | def __del__(self): | |
18 |
|
|
18 | self._release_lock() | |
19 |
|
19 | |||
20 |
|
|
20 | def _lock_file_path(self): | |
21 |
|
|
21 | """:return: Path to lockfile""" | |
22 |
|
|
22 | return "%s.lock" % (self._file_path) | |
23 |
|
23 | |||
24 |
|
|
24 | def _has_lock(self): | |
25 |
|
|
25 | """:return: True if we have a lock and if the lockfile still exists | |
26 |
|
|
26 | :raise AssertionError: if our lock-file does not exist""" | |
27 |
|
|
27 | if not self._owns_lock: | |
28 |
|
|
28 | return False | |
29 |
|
29 | |||
30 |
|
|
30 | return True | |
31 |
|
31 | |||
32 |
|
|
32 | def _obtain_lock_or_raise(self): | |
33 |
|
|
33 | """Create a lock file as flag for other instances, mark our instance as lock-holder | |
34 |
|
34 | |||
35 |
|
|
35 | :raise IOError: if a lock was already present or a lock file could not be written""" | |
36 |
|
|
36 | if self._has_lock(): | |
37 | return |
|
37 | return | |
38 |
|
|
38 | lock_file = self._lock_file_path() | |
39 |
|
|
39 | if os.path.isfile(lock_file): | |
40 |
|
|
40 | raise IOError("Lock for file %r did already exist, delete %r in case the lock is illegal" % (self._file_path, lock_file)) | |
41 |
|
41 | |||
42 | try: |
|
42 | try: | |
43 |
|
|
43 | fd = os.open(lock_file, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0) | |
44 |
|
|
44 | os.close(fd) | |
45 |
|
|
45 | except OSError,e: | |
46 |
|
|
46 | raise IOError(str(e)) | |
47 |
|
47 | |||
48 |
|
|
48 | self._owns_lock = True | |
49 |
|
49 | |||
50 |
|
|
50 | def _obtain_lock(self): | |
51 |
|
|
51 | """The default implementation will raise if a lock cannot be obtained. | |
52 |
|
|
52 | Subclasses may override this method to provide a different implementation""" | |
53 |
|
|
53 | return self._obtain_lock_or_raise() | |
54 |
|
54 | |||
55 |
|
|
55 | def _release_lock(self): | |
56 |
|
|
56 | """Release our lock if we have one""" | |
57 |
|
|
57 | if not self._has_lock(): | |
58 | return |
|
58 | return | |
59 |
|
59 | |||
60 |
|
|
60 | # if someone removed our file beforhand, lets just flag this issue | |
61 |
|
|
61 | # instead of failing, to make it more usable. | |
62 |
|
|
62 | lfp = self._lock_file_path() | |
63 | try: |
|
63 | try: | |
64 |
|
|
64 | # on bloody windows, the file needs write permissions to be removable. | |
65 | # Why ... |
|
65 | # Why ... | |
66 |
|
|
66 | if os.name == 'nt': | |
67 |
|
|
67 | os.chmod(lfp, 0777) | |
68 |
|
|
68 | # END handle win32 | |
69 |
|
|
69 | os.remove(lfp) | |
70 |
|
|
70 | except OSError: | |
71 | pass |
|
71 | pass | |
72 |
|
|
72 | self._owns_lock = False |
@@ -35,6 +35,7 b' from rhodecode.model import BaseModel' | |||||
35 | from rhodecode.model.db import ChangesetComment, User, Repository, \ |
|
35 | from rhodecode.model.db import ChangesetComment, User, Repository, \ | |
36 | Notification, PullRequest |
|
36 | Notification, PullRequest | |
37 | from rhodecode.model.notification import NotificationModel |
|
37 | from rhodecode.model.notification import NotificationModel | |
|
38 | from rhodecode.model.meta import Session | |||
38 |
|
39 | |||
39 | log = logging.getLogger(__name__) |
|
40 | log = logging.getLogger(__name__) | |
40 |
|
41 | |||
@@ -57,8 +58,103 b' class ChangesetCommentsModel(BaseModel):' | |||||
57 | user_objects.append(user_obj) |
|
58 | user_objects.append(user_obj) | |
58 | return user_objects |
|
59 | return user_objects | |
59 |
|
60 | |||
|
61 | def _get_notification_data(self, repo, comment, user, comment_text, | |||
|
62 | line_no=None, revision=None, pull_request=None, | |||
|
63 | status_change=None, closing_pr=False): | |||
|
64 | """ | |||
|
65 | Get notification data | |||
|
66 | ||||
|
67 | :param comment_text: | |||
|
68 | :param line: | |||
|
69 | :returns: tuple (subj,body,recipients,notification_type,email_kwargs) | |||
|
70 | """ | |||
|
71 | # make notification | |||
|
72 | body = comment_text # text of the comment | |||
|
73 | line = '' | |||
|
74 | if line_no: | |||
|
75 | line = _('on line %s') % line_no | |||
|
76 | ||||
|
77 | #changeset | |||
|
78 | if revision: | |||
|
79 | notification_type = Notification.TYPE_CHANGESET_COMMENT | |||
|
80 | cs = repo.scm_instance.get_changeset(revision) | |||
|
81 | desc = "%s" % (cs.short_id) | |||
|
82 | ||||
|
83 | _url = h.url('changeset_home', | |||
|
84 | repo_name=repo.repo_name, | |||
|
85 | revision=revision, | |||
|
86 | anchor='comment-%s' % comment.comment_id, | |||
|
87 | qualified=True, | |||
|
88 | ) | |||
|
89 | subj = safe_unicode( | |||
|
90 | h.link_to('Re changeset: %(desc)s %(line)s' % \ | |||
|
91 | {'desc': desc, 'line': line}, | |||
|
92 | _url) | |||
|
93 | ) | |||
|
94 | email_subject = 'User %s commented on changeset %s' % \ | |||
|
95 | (user.username, h.short_id(revision)) | |||
|
96 | # get the current participants of this changeset | |||
|
97 | recipients = ChangesetComment.get_users(revision=revision) | |||
|
98 | # add changeset author if it's in rhodecode system | |||
|
99 | cs_author = User.get_from_cs_author(cs.author) | |||
|
100 | if not cs_author: | |||
|
101 | #use repo owner if we cannot extract the author correctly | |||
|
102 | cs_author = repo.user | |||
|
103 | recipients += [cs_author] | |||
|
104 | email_kwargs = { | |||
|
105 | 'status_change': status_change, | |||
|
106 | 'cs_comment_user': h.person(user.email), | |||
|
107 | 'cs_target_repo': h.url('summary_home', repo_name=repo.repo_name, | |||
|
108 | qualified=True), | |||
|
109 | 'cs_comment_url': _url, | |||
|
110 | 'raw_id': revision, | |||
|
111 | 'message': cs.message | |||
|
112 | } | |||
|
113 | #pull request | |||
|
114 | elif pull_request: | |||
|
115 | notification_type = Notification.TYPE_PULL_REQUEST_COMMENT | |||
|
116 | desc = comment.pull_request.title | |||
|
117 | _url = h.url('pullrequest_show', | |||
|
118 | repo_name=pull_request.other_repo.repo_name, | |||
|
119 | pull_request_id=pull_request.pull_request_id, | |||
|
120 | anchor='comment-%s' % comment.comment_id, | |||
|
121 | qualified=True, | |||
|
122 | ) | |||
|
123 | subj = safe_unicode( | |||
|
124 | h.link_to('Re pull request #%(pr_id)s: %(desc)s %(line)s' % \ | |||
|
125 | {'desc': desc, | |||
|
126 | 'pr_id': comment.pull_request.pull_request_id, | |||
|
127 | 'line': line}, | |||
|
128 | _url) | |||
|
129 | ) | |||
|
130 | email_subject = 'User %s commented on pull request #%s' % \ | |||
|
131 | (user.username, comment.pull_request.pull_request_id) | |||
|
132 | # get the current participants of this pull request | |||
|
133 | recipients = ChangesetComment.get_users(pull_request_id= | |||
|
134 | pull_request.pull_request_id) | |||
|
135 | # add pull request author | |||
|
136 | recipients += [pull_request.author] | |||
|
137 | ||||
|
138 | # add the reviewers to notification | |||
|
139 | recipients += [x.user for x in pull_request.reviewers] | |||
|
140 | ||||
|
141 | #set some variables for email notification | |||
|
142 | email_kwargs = { | |||
|
143 | 'pr_id': pull_request.pull_request_id, | |||
|
144 | 'status_change': status_change, | |||
|
145 | 'closing_pr': closing_pr, | |||
|
146 | 'pr_comment_url': _url, | |||
|
147 | 'pr_comment_user': h.person(user.email), | |||
|
148 | 'pr_target_repo': h.url('summary_home', | |||
|
149 | repo_name=pull_request.other_repo.repo_name, | |||
|
150 | qualified=True) | |||
|
151 | } | |||
|
152 | ||||
|
153 | return subj, body, recipients, notification_type, email_kwargs, email_subject | |||
|
154 | ||||
60 | def create(self, text, repo, user, revision=None, pull_request=None, |
|
155 | def create(self, text, repo, user, revision=None, pull_request=None, | |
61 |
f_path=None, line_no=None, status_change=None, |
|
156 | f_path=None, line_no=None, status_change=None, closing_pr=False, | |
|
157 | send_email=True): | |||
62 | """ |
|
158 | """ | |
63 | Creates new comment for changeset or pull request. |
|
159 | Creates new comment for changeset or pull request. | |
64 | IF status_change is not none this comment is associated with a |
|
160 | IF status_change is not none this comment is associated with a | |
@@ -72,9 +168,11 b' class ChangesetCommentsModel(BaseModel):' | |||||
72 | :param f_path: |
|
168 | :param f_path: | |
73 | :param line_no: |
|
169 | :param line_no: | |
74 | :param status_change: |
|
170 | :param status_change: | |
|
171 | :param closing_pr: | |||
75 | :param send_email: |
|
172 | :param send_email: | |
76 | """ |
|
173 | """ | |
77 | if not text: |
|
174 | if not text: | |
|
175 | log.warning('Missing text for comment, skipping...') | |||
78 | return |
|
176 | return | |
79 |
|
177 | |||
80 | repo = self._get_repo(repo) |
|
178 | repo = self._get_repo(repo) | |
@@ -87,8 +185,6 b' class ChangesetCommentsModel(BaseModel):' | |||||
87 | comment.line_no = line_no |
|
185 | comment.line_no = line_no | |
88 |
|
186 | |||
89 | if revision: |
|
187 | if revision: | |
90 | cs = repo.scm_instance.get_changeset(revision) |
|
|||
91 | desc = "%s - %s" % (cs.short_id, h.shorter(cs.message, 256)) |
|
|||
92 | comment.revision = revision |
|
188 | comment.revision = revision | |
93 | elif pull_request: |
|
189 | elif pull_request: | |
94 | pull_request = self.__get_pull_request(pull_request) |
|
190 | pull_request = self.__get_pull_request(pull_request) | |
@@ -96,82 +192,24 b' class ChangesetCommentsModel(BaseModel):' | |||||
96 | else: |
|
192 | else: | |
97 | raise Exception('Please specify revision or pull_request_id') |
|
193 | raise Exception('Please specify revision or pull_request_id') | |
98 |
|
194 | |||
99 |
|
|
195 | Session().add(comment) | |
100 |
|
|
196 | Session().flush() | |
101 |
|
||||
102 | # make notification |
|
|||
103 | line = '' |
|
|||
104 | body = text |
|
|||
105 |
|
||||
106 | #changeset |
|
|||
107 | if revision: |
|
|||
108 | if line_no: |
|
|||
109 | line = _('on line %s') % line_no |
|
|||
110 | subj = safe_unicode( |
|
|||
111 | h.link_to('Re commit: %(desc)s %(line)s' % \ |
|
|||
112 | {'desc': desc, 'line': line}, |
|
|||
113 | h.url('changeset_home', repo_name=repo.repo_name, |
|
|||
114 | revision=revision, |
|
|||
115 | anchor='comment-%s' % comment.comment_id, |
|
|||
116 | qualified=True, |
|
|||
117 | ) |
|
|||
118 | ) |
|
|||
119 | ) |
|
|||
120 | notification_type = Notification.TYPE_CHANGESET_COMMENT |
|
|||
121 | # get the current participants of this changeset |
|
|||
122 | recipients = ChangesetComment.get_users(revision=revision) |
|
|||
123 | # add changeset author if it's in rhodecode system |
|
|||
124 | cs_author = User.get_from_cs_author(cs.author) |
|
|||
125 | if not cs_author: |
|
|||
126 | #use repo owner if we cannot extract the author correctly |
|
|||
127 | cs_author = repo.user |
|
|||
128 | recipients += [cs_author] |
|
|||
129 | email_kwargs = { |
|
|||
130 | 'status_change': status_change, |
|
|||
131 | } |
|
|||
132 | #pull request |
|
|||
133 | elif pull_request: |
|
|||
134 | _url = h.url('pullrequest_show', |
|
|||
135 | repo_name=pull_request.other_repo.repo_name, |
|
|||
136 | pull_request_id=pull_request.pull_request_id, |
|
|||
137 | anchor='comment-%s' % comment.comment_id, |
|
|||
138 | qualified=True, |
|
|||
139 | ) |
|
|||
140 | subj = safe_unicode( |
|
|||
141 | h.link_to('Re pull request #%(pr_id)s: %(desc)s %(line)s' % \ |
|
|||
142 | {'desc': comment.pull_request.title, |
|
|||
143 | 'pr_id': comment.pull_request.pull_request_id, |
|
|||
144 | 'line': line}, |
|
|||
145 | _url) |
|
|||
146 | ) |
|
|||
147 |
|
||||
148 | notification_type = Notification.TYPE_PULL_REQUEST_COMMENT |
|
|||
149 | # get the current participants of this pull request |
|
|||
150 | recipients = ChangesetComment.get_users(pull_request_id= |
|
|||
151 | pull_request.pull_request_id) |
|
|||
152 | # add pull request author |
|
|||
153 | recipients += [pull_request.author] |
|
|||
154 |
|
||||
155 | # add the reviewers to notification |
|
|||
156 | recipients += [x.user for x in pull_request.reviewers] |
|
|||
157 |
|
||||
158 | #set some variables for email notification |
|
|||
159 | email_kwargs = { |
|
|||
160 | 'pr_id': pull_request.pull_request_id, |
|
|||
161 | 'status_change': status_change, |
|
|||
162 | 'pr_comment_url': _url, |
|
|||
163 | 'pr_comment_user': h.person(user.email), |
|
|||
164 | 'pr_target_repo': h.url('summary_home', |
|
|||
165 | repo_name=pull_request.other_repo.repo_name, |
|
|||
166 | qualified=True) |
|
|||
167 | } |
|
|||
168 |
|
197 | |||
169 | if send_email: |
|
198 | if send_email: | |
|
199 | (subj, body, recipients, notification_type, | |||
|
200 | email_kwargs, email_subject) = self._get_notification_data( | |||
|
201 | repo, comment, user, | |||
|
202 | comment_text=text, | |||
|
203 | line_no=line_no, | |||
|
204 | revision=revision, | |||
|
205 | pull_request=pull_request, | |||
|
206 | status_change=status_change, | |||
|
207 | closing_pr=closing_pr) | |||
170 | # create notification objects, and emails |
|
208 | # create notification objects, and emails | |
171 | NotificationModel().create( |
|
209 | NotificationModel().create( | |
172 | created_by=user, subject=subj, body=body, |
|
210 | created_by=user, subject=subj, body=body, | |
173 | recipients=recipients, type_=notification_type, |
|
211 | recipients=recipients, type_=notification_type, | |
174 | email_kwargs=email_kwargs |
|
212 | email_kwargs=email_kwargs, email_subject=email_subject | |
175 | ) |
|
213 | ) | |
176 |
|
214 | |||
177 | mention_recipients = set(self._extract_mentions(body))\ |
|
215 | mention_recipients = set(self._extract_mentions(body))\ | |
@@ -195,7 +233,7 b' class ChangesetCommentsModel(BaseModel):' | |||||
195 | :param comment_id: |
|
233 | :param comment_id: | |
196 | """ |
|
234 | """ | |
197 | comment = self.__get_changeset_comment(comment) |
|
235 | comment = self.__get_changeset_comment(comment) | |
198 |
|
|
236 | Session().delete(comment) | |
199 |
|
237 | |||
200 | return comment |
|
238 | return comment | |
201 |
|
239 | |||
@@ -204,11 +242,8 b' class ChangesetCommentsModel(BaseModel):' | |||||
204 | Get's main comments based on revision or pull_request_id |
|
242 | Get's main comments based on revision or pull_request_id | |
205 |
|
243 | |||
206 | :param repo_id: |
|
244 | :param repo_id: | |
207 | :type repo_id: |
|
|||
208 | :param revision: |
|
245 | :param revision: | |
209 | :type revision: |
|
|||
210 | :param pull_request: |
|
246 | :param pull_request: | |
211 | :type pull_request: |
|
|||
212 | """ |
|
247 | """ | |
213 |
|
248 | |||
214 | q = ChangesetComment.query()\ |
|
249 | q = ChangesetComment.query()\ | |
@@ -226,7 +261,7 b' class ChangesetCommentsModel(BaseModel):' | |||||
226 | return q.all() |
|
261 | return q.all() | |
227 |
|
262 | |||
228 | def get_inline_comments(self, repo_id, revision=None, pull_request=None): |
|
263 | def get_inline_comments(self, repo_id, revision=None, pull_request=None): | |
229 |
q = |
|
264 | q = Session().query(ChangesetComment)\ | |
230 | .filter(ChangesetComment.repo_id == repo_id)\ |
|
265 | .filter(ChangesetComment.repo_id == repo_id)\ | |
231 | .filter(ChangesetComment.line_no != None)\ |
|
266 | .filter(ChangesetComment.line_no != None)\ | |
232 | .filter(ChangesetComment.f_path != None)\ |
|
267 | .filter(ChangesetComment.f_path != None)\ |
@@ -44,6 +44,7 b' from rhodecode.lib.vcs import get_backen' | |||||
44 | from rhodecode.lib.vcs.utils.helpers import get_scm |
|
44 | from rhodecode.lib.vcs.utils.helpers import get_scm | |
45 | from rhodecode.lib.vcs.exceptions import VCSError |
|
45 | from rhodecode.lib.vcs.exceptions import VCSError | |
46 | from rhodecode.lib.vcs.utils.lazy import LazyProperty |
|
46 | from rhodecode.lib.vcs.utils.lazy import LazyProperty | |
|
47 | from rhodecode.lib.vcs.backends.base import EmptyChangeset | |||
47 |
|
48 | |||
48 | from rhodecode.lib.utils2 import str2bool, safe_str, get_changeset_safe, \ |
|
49 | from rhodecode.lib.utils2 import str2bool, safe_str, get_changeset_safe, \ | |
49 | safe_unicode, remove_suffix, remove_prefix |
|
50 | safe_unicode, remove_suffix, remove_prefix | |
@@ -341,7 +342,7 b' class User(Base, BaseModel):' | |||||
341 | repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') |
|
342 | repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') | |
342 | repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') |
|
343 | repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') | |
343 |
|
344 | |||
344 |
group_member = relationship('User |
|
345 | group_member = relationship('UserGroupMember', cascade='all') | |
345 |
|
346 | |||
346 | notifications = relationship('UserNotification', cascade='all') |
|
347 | notifications = relationship('UserNotification', cascade='all') | |
347 | # notifications assigned to this user |
|
348 | # notifications assigned to this user | |
@@ -604,7 +605,7 b' class UserLog(Base, BaseModel):' | |||||
604 | repository = relationship('Repository', cascade='') |
|
605 | repository = relationship('Repository', cascade='') | |
605 |
|
606 | |||
606 |
|
607 | |||
607 |
class User |
|
608 | class UserGroup(Base, BaseModel): | |
608 | __tablename__ = 'users_groups' |
|
609 | __tablename__ = 'users_groups' | |
609 | __table_args__ = ( |
|
610 | __table_args__ = ( | |
610 | {'extend_existing': True, 'mysql_engine': 'InnoDB', |
|
611 | {'extend_existing': True, 'mysql_engine': 'InnoDB', | |
@@ -616,9 +617,9 b' class UsersGroup(Base, BaseModel):' | |||||
616 | users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) |
|
617 | users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) | |
617 | inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) |
|
618 | inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) | |
618 |
|
619 | |||
619 |
members = relationship('User |
|
620 | members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") | |
620 |
users_group_to_perm = relationship('User |
|
621 | users_group_to_perm = relationship('UserGroupToPerm', cascade='all') | |
621 |
users_group_repo_to_perm = relationship('User |
|
622 | users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') | |
622 |
|
623 | |||
623 | def __unicode__(self): |
|
624 | def __unicode__(self): | |
624 | return u'<userGroup(%s)>' % (self.users_group_name) |
|
625 | return u'<userGroup(%s)>' % (self.users_group_name) | |
@@ -658,7 +659,7 b' class UsersGroup(Base, BaseModel):' | |||||
658 | return data |
|
659 | return data | |
659 |
|
660 | |||
660 |
|
661 | |||
661 |
class User |
|
662 | class UserGroupMember(Base, BaseModel): | |
662 | __tablename__ = 'users_groups_members' |
|
663 | __tablename__ = 'users_groups_members' | |
663 | __table_args__ = ( |
|
664 | __table_args__ = ( | |
664 | {'extend_existing': True, 'mysql_engine': 'InnoDB', |
|
665 | {'extend_existing': True, 'mysql_engine': 'InnoDB', | |
@@ -670,7 +671,7 b' class UsersGroupMember(Base, BaseModel):' | |||||
670 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) |
|
671 | user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) | |
671 |
|
672 | |||
672 | user = relationship('User', lazy='joined') |
|
673 | user = relationship('User', lazy='joined') | |
673 |
users_group = relationship('User |
|
674 | users_group = relationship('UserGroup') | |
674 |
|
675 | |||
675 | def __init__(self, gr_id='', u_id=''): |
|
676 | def __init__(self, gr_id='', u_id=''): | |
676 | self.users_group_id = gr_id |
|
677 | self.users_group_id = gr_id | |
@@ -747,7 +748,7 b' class Repository(Base, BaseModel):' | |||||
747 | fork = relationship('Repository', remote_side=repo_id) |
|
748 | fork = relationship('Repository', remote_side=repo_id) | |
748 | group = relationship('RepoGroup') |
|
749 | group = relationship('RepoGroup') | |
749 | repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') |
|
750 | repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') | |
750 |
users_group_to_perm = relationship('User |
|
751 | users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') | |
751 | stats = relationship('Statistics', cascade='all', uselist=False) |
|
752 | stats = relationship('Statistics', cascade='all', uselist=False) | |
752 |
|
753 | |||
753 | followers = relationship('UserFollowing', |
|
754 | followers = relationship('UserFollowing', | |
@@ -1053,15 +1054,18 b' class Repository(Base, BaseModel):' | |||||
1053 | """ |
|
1054 | """ | |
1054 | from rhodecode.lib.vcs.backends.base import BaseChangeset |
|
1055 | from rhodecode.lib.vcs.backends.base import BaseChangeset | |
1055 | if cs_cache is None: |
|
1056 | if cs_cache is None: | |
1056 |
cs_cache = |
|
1057 | cs_cache = EmptyChangeset() | |
|
1058 | # use no-cache version here | |||
|
1059 | scm_repo = self.scm_instance_no_cache | |||
|
1060 | if scm_repo: | |||
|
1061 | cs_cache = scm_repo.get_changeset() | |||
|
1062 | ||||
1057 | if isinstance(cs_cache, BaseChangeset): |
|
1063 | if isinstance(cs_cache, BaseChangeset): | |
1058 | cs_cache = cs_cache.__json__() |
|
1064 | cs_cache = cs_cache.__json__() | |
1059 |
|
1065 | |||
1060 | if (cs_cache != self.changeset_cache |
|
1066 | if (cs_cache != self.changeset_cache or not self.changeset_cache): | |
1061 | or not self.last_change |
|
|||
1062 | or not self.changeset_cache): |
|
|||
1063 | _default = datetime.datetime.fromtimestamp(0) |
|
1067 | _default = datetime.datetime.fromtimestamp(0) | |
1064 |
last_change = cs_cache.get('date') or |
|
1068 | last_change = cs_cache.get('date') or _default | |
1065 | log.debug('updated repo %s with new cs cache %s' % (self, cs_cache)) |
|
1069 | log.debug('updated repo %s with new cs cache %s' % (self, cs_cache)) | |
1066 | self.updated_on = last_change |
|
1070 | self.updated_on = last_change | |
1067 | self.changeset_cache = cs_cache |
|
1071 | self.changeset_cache = cs_cache | |
@@ -1188,7 +1192,8 b' class Repository(Base, BaseModel):' | |||||
1188 | repo_full_path = self.repo_full_path |
|
1192 | repo_full_path = self.repo_full_path | |
1189 | try: |
|
1193 | try: | |
1190 | alias = get_scm(repo_full_path)[0] |
|
1194 | alias = get_scm(repo_full_path)[0] | |
1191 |
log.debug('Creating instance of %s repository' |
|
1195 | log.debug('Creating instance of %s repository from %s' | |
|
1196 | % (alias, repo_full_path)) | |||
1192 | backend = get_backend(alias) |
|
1197 | backend = get_backend(alias) | |
1193 | except VCSError: |
|
1198 | except VCSError: | |
1194 | log.error(traceback.format_exc()) |
|
1199 | log.error(traceback.format_exc()) | |
@@ -1227,7 +1232,7 b' class RepoGroup(Base, BaseModel):' | |||||
1227 | enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) |
|
1232 | enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) | |
1228 |
|
1233 | |||
1229 | repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') |
|
1234 | repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') | |
1230 |
users_group_to_perm = relationship('User |
|
1235 | users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') | |
1231 |
|
1236 | |||
1232 | parent_group = relationship('RepoGroup', remote_side=group_id) |
|
1237 | parent_group = relationship('RepoGroup', remote_side=group_id) | |
1233 |
|
1238 | |||
@@ -1378,10 +1383,10 b' class Permission(Base, BaseModel):' | |||||
1378 | ('repository.write', _('Repository write access')), |
|
1383 | ('repository.write', _('Repository write access')), | |
1379 | ('repository.admin', _('Repository admin access')), |
|
1384 | ('repository.admin', _('Repository admin access')), | |
1380 |
|
1385 | |||
1381 |
('group.none', _('Repositor |
|
1386 | ('group.none', _('Repository group no access')), | |
1382 |
('group.read', _('Repositor |
|
1387 | ('group.read', _('Repository group read access')), | |
1383 |
('group.write', _('Repositor |
|
1388 | ('group.write', _('Repository group write access')), | |
1384 |
('group.admin', _('Repositor |
|
1389 | ('group.admin', _('Repository group admin access')), | |
1385 |
|
1390 | |||
1386 | ('hg.admin', _('RhodeCode Administrator')), |
|
1391 | ('hg.admin', _('RhodeCode Administrator')), | |
1387 | ('hg.create.none', _('Repository creation disabled')), |
|
1392 | ('hg.create.none', _('Repository creation disabled')), | |
@@ -1490,7 +1495,7 b' class UserToPerm(Base, BaseModel):' | |||||
1490 | permission = relationship('Permission', lazy='joined') |
|
1495 | permission = relationship('Permission', lazy='joined') | |
1491 |
|
1496 | |||
1492 |
|
1497 | |||
1493 |
class User |
|
1498 | class UserGroupRepoToPerm(Base, BaseModel): | |
1494 | __tablename__ = 'users_group_repo_to_perm' |
|
1499 | __tablename__ = 'users_group_repo_to_perm' | |
1495 | __table_args__ = ( |
|
1500 | __table_args__ = ( | |
1496 | UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), |
|
1501 | UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), | |
@@ -1502,7 +1507,7 b' class UsersGroupRepoToPerm(Base, BaseMod' | |||||
1502 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
1507 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
1503 | repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) |
|
1508 | repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) | |
1504 |
|
1509 | |||
1505 |
users_group = relationship('User |
|
1510 | users_group = relationship('UserGroup') | |
1506 | permission = relationship('Permission') |
|
1511 | permission = relationship('Permission') | |
1507 | repository = relationship('Repository') |
|
1512 | repository = relationship('Repository') | |
1508 |
|
1513 | |||
@@ -1519,7 +1524,7 b' class UsersGroupRepoToPerm(Base, BaseMod' | |||||
1519 | return u'<userGroup:%s => %s >' % (self.users_group, self.repository) |
|
1524 | return u'<userGroup:%s => %s >' % (self.users_group, self.repository) | |
1520 |
|
1525 | |||
1521 |
|
1526 | |||
1522 |
class User |
|
1527 | class UserGroupToPerm(Base, BaseModel): | |
1523 | __tablename__ = 'users_group_to_perm' |
|
1528 | __tablename__ = 'users_group_to_perm' | |
1524 | __table_args__ = ( |
|
1529 | __table_args__ = ( | |
1525 | UniqueConstraint('users_group_id', 'permission_id',), |
|
1530 | UniqueConstraint('users_group_id', 'permission_id',), | |
@@ -1530,7 +1535,7 b' class UsersGroupToPerm(Base, BaseModel):' | |||||
1530 | users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) |
|
1535 | users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) | |
1531 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
1536 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
1532 |
|
1537 | |||
1533 |
users_group = relationship('User |
|
1538 | users_group = relationship('UserGroup') | |
1534 | permission = relationship('Permission') |
|
1539 | permission = relationship('Permission') | |
1535 |
|
1540 | |||
1536 |
|
1541 | |||
@@ -1552,7 +1557,7 b' class UserRepoGroupToPerm(Base, BaseMode' | |||||
1552 | permission = relationship('Permission') |
|
1557 | permission = relationship('Permission') | |
1553 |
|
1558 | |||
1554 |
|
1559 | |||
1555 |
class User |
|
1560 | class UserGroupRepoGroupToPerm(Base, BaseModel): | |
1556 | __tablename__ = 'users_group_repo_group_to_perm' |
|
1561 | __tablename__ = 'users_group_repo_group_to_perm' | |
1557 | __table_args__ = ( |
|
1562 | __table_args__ = ( | |
1558 | UniqueConstraint('users_group_id', 'group_id'), |
|
1563 | UniqueConstraint('users_group_id', 'group_id'), | |
@@ -1565,7 +1570,7 b' class UsersGroupRepoGroupToPerm(Base, Ba' | |||||
1565 | group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) |
|
1570 | group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) | |
1566 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) |
|
1571 | permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |
1567 |
|
1572 | |||
1568 |
users_group = relationship('User |
|
1573 | users_group = relationship('UserGroup') | |
1569 | permission = relationship('Permission') |
|
1574 | permission = relationship('Permission') | |
1570 | group = relationship('RepoGroup') |
|
1575 | group = relationship('RepoGroup') | |
1571 |
|
1576 |
@@ -94,14 +94,14 b' def UserForm(edit=False, old_data={}):' | |||||
94 | return _UserForm |
|
94 | return _UserForm | |
95 |
|
95 | |||
96 |
|
96 | |||
97 |
def User |
|
97 | def UserGroupForm(edit=False, old_data={}, available_members=[]): | |
98 |
class _User |
|
98 | class _UserGroupForm(formencode.Schema): | |
99 | allow_extra_fields = True |
|
99 | allow_extra_fields = True | |
100 | filter_extra_fields = True |
|
100 | filter_extra_fields = True | |
101 |
|
101 | |||
102 | users_group_name = All( |
|
102 | users_group_name = All( | |
103 | v.UnicodeString(strip=True, min=1, not_empty=True), |
|
103 | v.UnicodeString(strip=True, min=1, not_empty=True), | |
104 |
v.ValidUser |
|
104 | v.ValidUserGroup(edit, old_data) | |
105 | ) |
|
105 | ) | |
106 |
|
106 | |||
107 | users_group_active = v.StringBoolean(if_missing=False) |
|
107 | users_group_active = v.StringBoolean(if_missing=False) | |
@@ -112,7 +112,7 b' def UsersGroupForm(edit=False, old_data=' | |||||
112 | if_missing=None, not_empty=False |
|
112 | if_missing=None, not_empty=False | |
113 | ) |
|
113 | ) | |
114 |
|
114 | |||
115 |
return _User |
|
115 | return _UserGroupForm | |
116 |
|
116 | |||
117 |
|
117 | |||
118 | def ReposGroupForm(edit=False, old_data={}, available_groups=[], |
|
118 | def ReposGroupForm(edit=False, old_data={}, available_groups=[], |
@@ -28,12 +28,14 b' import os' | |||||
28 | import logging |
|
28 | import logging | |
29 | import traceback |
|
29 | import traceback | |
30 |
|
30 | |||
|
31 | from pylons import tmpl_context as c | |||
31 | from pylons.i18n.translation import _ |
|
32 | from pylons.i18n.translation import _ | |
32 |
|
33 | |||
33 | import rhodecode |
|
34 | import rhodecode | |
34 | from rhodecode.lib import helpers as h |
|
35 | from rhodecode.lib import helpers as h | |
35 | from rhodecode.model import BaseModel |
|
36 | from rhodecode.model import BaseModel | |
36 | from rhodecode.model.db import Notification, User, UserNotification |
|
37 | from rhodecode.model.db import Notification, User, UserNotification | |
|
38 | from rhodecode.model.meta import Session | |||
37 |
|
39 | |||
38 | log = logging.getLogger(__name__) |
|
40 | log = logging.getLogger(__name__) | |
39 |
|
41 | |||
@@ -54,7 +56,7 b' class NotificationModel(BaseModel):' | |||||
54 |
|
56 | |||
55 | def create(self, created_by, subject, body, recipients=None, |
|
57 | def create(self, created_by, subject, body, recipients=None, | |
56 | type_=Notification.TYPE_MESSAGE, with_email=True, |
|
58 | type_=Notification.TYPE_MESSAGE, with_email=True, | |
57 | email_kwargs={}): |
|
59 | email_kwargs={}, email_subject=None): | |
58 | """ |
|
60 | """ | |
59 |
|
61 | |||
60 | Creates notification of given type |
|
62 | Creates notification of given type | |
@@ -68,6 +70,7 b' class NotificationModel(BaseModel):' | |||||
68 | :param type_: type of notification |
|
70 | :param type_: type of notification | |
69 | :param with_email: send email with this notification |
|
71 | :param with_email: send email with this notification | |
70 | :param email_kwargs: additional dict to pass as args to email template |
|
72 | :param email_kwargs: additional dict to pass as args to email template | |
|
73 | :param email_subject: use given subject as email subject | |||
71 | """ |
|
74 | """ | |
72 | from rhodecode.lib.celerylib import tasks, run_task |
|
75 | from rhodecode.lib.celerylib import tasks, run_task | |
73 |
|
76 | |||
@@ -105,9 +108,11 b' class NotificationModel(BaseModel):' | |||||
105 |
|
108 | |||
106 | # send email with notification to all other participants |
|
109 | # send email with notification to all other participants | |
107 | for rec in rec_objs: |
|
110 | for rec in rec_objs: | |
108 | email_subject = NotificationModel().make_description(notif, False) |
|
111 | if not email_subject: | |
|
112 | email_subject = NotificationModel()\ | |||
|
113 | .make_description(notif, show_age=False) | |||
109 | type_ = type_ |
|
114 | type_ = type_ | |
110 | email_body = body |
|
115 | email_body = None # we set body to none, we just send HTML emails | |
111 | ## this is passed into template |
|
116 | ## this is passed into template | |
112 | kwargs = {'subject': subject, 'body': h.rst_w_mentions(body)} |
|
117 | kwargs = {'subject': subject, 'body': h.rst_w_mentions(body)} | |
113 | kwargs.update(email_kwargs) |
|
118 | kwargs.update(email_kwargs) | |
@@ -130,7 +135,7 b' class NotificationModel(BaseModel):' | |||||
130 | .filter(UserNotification.notification |
|
135 | .filter(UserNotification.notification | |
131 | == notification)\ |
|
136 | == notification)\ | |
132 | .one() |
|
137 | .one() | |
133 |
|
|
138 | Session().delete(obj) | |
134 | return True |
|
139 | return True | |
135 | except Exception: |
|
140 | except Exception: | |
136 | log.error(traceback.format_exc()) |
|
141 | log.error(traceback.format_exc()) | |
@@ -141,7 +146,6 b' class NotificationModel(BaseModel):' | |||||
141 | Get mentions for given user, filter them if filter dict is given |
|
146 | Get mentions for given user, filter them if filter dict is given | |
142 |
|
147 | |||
143 | :param user: |
|
148 | :param user: | |
144 | :type user: |
|
|||
145 | :param filter: |
|
149 | :param filter: | |
146 | """ |
|
150 | """ | |
147 | user = self._get_user(user) |
|
151 | user = self._get_user(user) | |
@@ -167,7 +171,7 b' class NotificationModel(BaseModel):' | |||||
167 | == notification)\ |
|
171 | == notification)\ | |
168 | .one() |
|
172 | .one() | |
169 | obj.read = True |
|
173 | obj.read = True | |
170 |
|
|
174 | Session().add(obj) | |
171 | return True |
|
175 | return True | |
172 | except Exception: |
|
176 | except Exception: | |
173 | log.error(traceback.format_exc()) |
|
177 | log.error(traceback.format_exc()) | |
@@ -187,7 +191,7 b' class NotificationModel(BaseModel):' | |||||
187 | # update on joined tables :( |
|
191 | # update on joined tables :( | |
188 | for obj in q.all(): |
|
192 | for obj in q.all(): | |
189 | obj.read = True |
|
193 | obj.read = True | |
190 |
|
|
194 | Session().add(obj) | |
191 |
|
195 | |||
192 | def get_unread_cnt_for_user(self, user): |
|
196 | def get_unread_cnt_for_user(self, user): | |
193 | user = self._get_user(user) |
|
197 | user = self._get_user(user) | |
@@ -217,7 +221,7 b' class NotificationModel(BaseModel):' | |||||
217 | #alias |
|
221 | #alias | |
218 | _n = notification |
|
222 | _n = notification | |
219 | _map = { |
|
223 | _map = { | |
220 |
_n.TYPE_CHANGESET_COMMENT: _('commented on c |
|
224 | _n.TYPE_CHANGESET_COMMENT: _('commented on changeset at %(when)s'), | |
221 | _n.TYPE_MESSAGE: _('sent message at %(when)s'), |
|
225 | _n.TYPE_MESSAGE: _('sent message at %(when)s'), | |
222 | _n.TYPE_MENTION: _('mentioned you at %(when)s'), |
|
226 | _n.TYPE_MENTION: _('mentioned you at %(when)s'), | |
223 | _n.TYPE_REGISTRATION: _('registered in RhodeCode at %(when)s'), |
|
227 | _n.TYPE_REGISTRATION: _('registered in RhodeCode at %(when)s'), | |
@@ -272,7 +276,8 b' class EmailNotificationModel(BaseModel):' | |||||
272 | email_template = self._tmpl_lookup.get_template(base) |
|
276 | email_template = self._tmpl_lookup.get_template(base) | |
273 | # translator and helpers inject |
|
277 | # translator and helpers inject | |
274 | _kwargs = {'_': _, |
|
278 | _kwargs = {'_': _, | |
275 |
'h': h |
|
279 | 'h': h, | |
|
280 | 'c': c} | |||
276 | _kwargs.update(kwargs) |
|
281 | _kwargs.update(kwargs) | |
277 | log.debug('rendering tmpl %s with kwargs %s' % (base, _kwargs)) |
|
282 | log.debug('rendering tmpl %s with kwargs %s' % (base, _kwargs)) | |
278 | return email_template.render(**_kwargs) |
|
283 | return email_template.render(**_kwargs) |
@@ -75,13 +75,13 b' class PullRequestModel(BaseModel):' | |||||
75 | new.title = title |
|
75 | new.title = title | |
76 | new.description = description |
|
76 | new.description = description | |
77 | new.author = created_by_user |
|
77 | new.author = created_by_user | |
78 |
|
|
78 | Session().add(new) | |
79 | Session().flush() |
|
79 | Session().flush() | |
80 | #members |
|
80 | #members | |
81 | for member in set(reviewers): |
|
81 | for member in set(reviewers): | |
82 | _usr = self._get_user(member) |
|
82 | _usr = self._get_user(member) | |
83 | reviewer = PullRequestReviewers(_usr, new) |
|
83 | reviewer = PullRequestReviewers(_usr, new) | |
84 |
|
|
84 | Session().add(reviewer) | |
85 |
|
85 | |||
86 | #reset state to under-review |
|
86 | #reset state to under-review | |
87 | ChangesetStatusModel().set_status( |
|
87 | ChangesetStatusModel().set_status( | |
@@ -90,7 +90,8 b' class PullRequestModel(BaseModel):' | |||||
90 | user=created_by_user, |
|
90 | user=created_by_user, | |
91 | pull_request=new |
|
91 | pull_request=new | |
92 | ) |
|
92 | ) | |
93 |
|
93 | revision_data = [(x.raw_id, x.message) | ||
|
94 | for x in map(org_repo.get_changeset, revisions)] | |||
94 | #notification to reviewers |
|
95 | #notification to reviewers | |
95 | notif = NotificationModel() |
|
96 | notif = NotificationModel() | |
96 |
|
97 | |||
@@ -114,7 +115,7 b' class PullRequestModel(BaseModel):' | |||||
114 | 'pr_repo_url': h.url('summary_home', repo_name=other_repo.repo_name, |
|
115 | 'pr_repo_url': h.url('summary_home', repo_name=other_repo.repo_name, | |
115 | qualified=True,), |
|
116 | qualified=True,), | |
116 | 'pr_url': pr_url, |
|
117 | 'pr_url': pr_url, | |
117 |
'pr_revisions': revision |
|
118 | 'pr_revisions': revision_data | |
118 | } |
|
119 | } | |
119 |
|
120 | |||
120 | notif.create(created_by=created_by_user, subject=subject, body=body, |
|
121 | notif.create(created_by=created_by_user, subject=subject, body=body, | |
@@ -140,7 +141,7 b' class PullRequestModel(BaseModel):' | |||||
140 | for uid in to_add: |
|
141 | for uid in to_add: | |
141 | _usr = self._get_user(uid) |
|
142 | _usr = self._get_user(uid) | |
142 | reviewer = PullRequestReviewers(_usr, pull_request) |
|
143 | reviewer = PullRequestReviewers(_usr, pull_request) | |
143 |
|
|
144 | Session().add(reviewer) | |
144 |
|
145 | |||
145 | for uid in to_remove: |
|
146 | for uid in to_remove: | |
146 | reviewer = PullRequestReviewers.query()\ |
|
147 | reviewer = PullRequestReviewers.query()\ | |
@@ -148,7 +149,7 b' class PullRequestModel(BaseModel):' | |||||
148 | PullRequestReviewers.pull_request==pull_request)\ |
|
149 | PullRequestReviewers.pull_request==pull_request)\ | |
149 | .scalar() |
|
150 | .scalar() | |
150 | if reviewer: |
|
151 | if reviewer: | |
151 |
|
|
152 | Session().delete(reviewer) | |
152 |
|
153 | |||
153 | def delete(self, pull_request): |
|
154 | def delete(self, pull_request): | |
154 | pull_request = self.__get_pull_request(pull_request) |
|
155 | pull_request = self.__get_pull_request(pull_request) | |
@@ -158,7 +159,7 b' class PullRequestModel(BaseModel):' | |||||
158 | pull_request = self.__get_pull_request(pull_request) |
|
159 | pull_request = self.__get_pull_request(pull_request) | |
159 | pull_request.status = PullRequest.STATUS_CLOSED |
|
160 | pull_request.status = PullRequest.STATUS_CLOSED | |
160 | pull_request.updated_on = datetime.datetime.now() |
|
161 | pull_request.updated_on = datetime.datetime.now() | |
161 |
|
|
162 | Session().add(pull_request) | |
162 |
|
163 | |||
163 | def _get_changesets(self, alias, org_repo, org_ref, other_repo, other_ref): |
|
164 | def _get_changesets(self, alias, org_repo, org_ref, other_repo, other_ref): | |
164 | """ |
|
165 | """ | |
@@ -248,11 +249,7 b' class PullRequestModel(BaseModel):' | |||||
248 | if len(other_ref) != 2 or not isinstance(org_ref, (list, tuple)): |
|
249 | if len(other_ref) != 2 or not isinstance(org_ref, (list, tuple)): | |
249 | raise Exception('other_ref must be a two element list/tuple') |
|
250 | raise Exception('other_ref must be a two element list/tuple') | |
250 |
|
251 | |||
251 | org_repo_scm = org_repo.scm_instance |
|
252 | cs_ranges, ancestor = self._get_changesets(org_repo.scm_instance.alias, | |
252 | other_repo_scm = other_repo.scm_instance |
|
253 | org_repo.scm_instance, org_ref, | |
253 |
|
254 | other_repo.scm_instance, other_ref) | ||
254 | alias = org_repo.scm_instance.alias |
|
|||
255 | cs_ranges, ancestor = self._get_changesets(alias, |
|
|||
256 | org_repo_scm, org_ref, |
|
|||
257 | other_repo_scm, other_ref) |
|
|||
258 | return cs_ranges, ancestor |
|
255 | return cs_ranges, ancestor |
@@ -38,7 +38,7 b' from rhodecode.lib.hooks import log_crea' | |||||
38 |
|
38 | |||
39 | from rhodecode.model import BaseModel |
|
39 | from rhodecode.model import BaseModel | |
40 | from rhodecode.model.db import Repository, UserRepoToPerm, User, Permission, \ |
|
40 | from rhodecode.model.db import Repository, UserRepoToPerm, User, Permission, \ | |
41 |
Statistics, User |
|
41 | Statistics, UserGroup, UserGroupRepoToPerm, RhodeCodeUi, RepoGroup,\ | |
42 | RhodeCodeSetting, RepositoryField |
|
42 | RhodeCodeSetting, RepositoryField | |
43 | from rhodecode.lib import helpers as h |
|
43 | from rhodecode.lib import helpers as h | |
44 | from rhodecode.lib.auth import HasRepoPermissionAny |
|
44 | from rhodecode.lib.auth import HasRepoPermissionAny | |
@@ -54,8 +54,8 b' class RepoModel(BaseModel):' | |||||
54 | URL_SEPARATOR = Repository.url_sep() |
|
54 | URL_SEPARATOR = Repository.url_sep() | |
55 |
|
55 | |||
56 | def __get_users_group(self, users_group): |
|
56 | def __get_users_group(self, users_group): | |
57 |
return self._get_instance(User |
|
57 | return self._get_instance(UserGroup, users_group, | |
58 |
callback=User |
|
58 | callback=UserGroup.get_by_group_name) | |
59 |
|
59 | |||
60 | def _get_repos_group(self, repos_group): |
|
60 | def _get_repos_group(self, repos_group): | |
61 | return self._get_instance(RepoGroup, repos_group, |
|
61 | return self._get_instance(RepoGroup, repos_group, | |
@@ -120,8 +120,8 b' class RepoModel(BaseModel):' | |||||
120 | ) |
|
120 | ) | |
121 |
|
121 | |||
122 | def get_users_groups_js(self): |
|
122 | def get_users_groups_js(self): | |
123 |
users_groups = self.sa.query(User |
|
123 | users_groups = self.sa.query(UserGroup)\ | |
124 |
.filter(User |
|
124 | .filter(UserGroup.users_group_active == True).all() | |
125 |
|
125 | |||
126 | return json.dumps([ |
|
126 | return json.dumps([ | |
127 | { |
|
127 | { | |
@@ -149,11 +149,7 b' class RepoModel(BaseModel):' | |||||
149 | if not repositories: |
|
149 | if not repositories: | |
150 | repositories = Repository.getAll() |
|
150 | repositories = Repository.getAll() | |
151 | for repo in repositories: |
|
151 | for repo in repositories: | |
152 |
|
|
152 | repo.update_changeset_cache() | |
153 | last_cs = EmptyChangeset() |
|
|||
154 | if scm_repo: |
|
|||
155 | last_cs = scm_repo.get_changeset() |
|
|||
156 | repo.update_changeset_cache(last_cs) |
|
|||
157 |
|
153 | |||
158 | def get_repos_as_dict(self, repos_list=None, admin=False, perm_check=True, |
|
154 | def get_repos_as_dict(self, repos_list=None, admin=False, perm_check=True, | |
159 | super_user_actions=False): |
|
155 | super_user_actions=False): | |
@@ -415,15 +411,15 b' class RepoModel(BaseModel):' | |||||
415 | repo = fork_of |
|
411 | repo = fork_of | |
416 | user_perms = UserRepoToPerm.query()\ |
|
412 | user_perms = UserRepoToPerm.query()\ | |
417 | .filter(UserRepoToPerm.repository == repo).all() |
|
413 | .filter(UserRepoToPerm.repository == repo).all() | |
418 |
group_perms = User |
|
414 | group_perms = UserGroupRepoToPerm.query()\ | |
419 |
.filter(User |
|
415 | .filter(UserGroupRepoToPerm.repository == repo).all() | |
420 |
|
416 | |||
421 | for perm in user_perms: |
|
417 | for perm in user_perms: | |
422 | UserRepoToPerm.create(perm.user, new_repo, |
|
418 | UserRepoToPerm.create(perm.user, new_repo, | |
423 | perm.permission) |
|
419 | perm.permission) | |
424 |
|
420 | |||
425 | for perm in group_perms: |
|
421 | for perm in group_perms: | |
426 |
User |
|
422 | UserGroupRepoToPerm.create(perm.users_group, new_repo, | |
427 | perm.permission) |
|
423 | perm.permission) | |
428 | else: |
|
424 | else: | |
429 | _create_default_perms() |
|
425 | _create_default_perms() | |
@@ -549,12 +545,12 b' class RepoModel(BaseModel):' | |||||
549 |
|
545 | |||
550 | def grant_users_group_permission(self, repo, group_name, perm): |
|
546 | def grant_users_group_permission(self, repo, group_name, perm): | |
551 | """ |
|
547 | """ | |
552 |
Grant permission for user |
|
548 | Grant permission for user group on given repository, or update | |
553 | existing one if found |
|
549 | existing one if found | |
554 |
|
550 | |||
555 | :param repo: Instance of Repository, repository_id, or repository name |
|
551 | :param repo: Instance of Repository, repository_id, or repository name | |
556 | :param group_name: Instance of UserGroup, users_group_id, |
|
552 | :param group_name: Instance of UserGroup, users_group_id, | |
557 |
or user |
|
553 | or user group name | |
558 | :param perm: Instance of Permission, or permission_name |
|
554 | :param perm: Instance of Permission, or permission_name | |
559 | """ |
|
555 | """ | |
560 | repo = self._get_repo(repo) |
|
556 | repo = self._get_repo(repo) | |
@@ -562,14 +558,14 b' class RepoModel(BaseModel):' | |||||
562 | permission = self._get_perm(perm) |
|
558 | permission = self._get_perm(perm) | |
563 |
|
559 | |||
564 | # check if we have that permission already |
|
560 | # check if we have that permission already | |
565 |
obj = self.sa.query(User |
|
561 | obj = self.sa.query(UserGroupRepoToPerm)\ | |
566 |
.filter(User |
|
562 | .filter(UserGroupRepoToPerm.users_group == group_name)\ | |
567 |
.filter(User |
|
563 | .filter(UserGroupRepoToPerm.repository == repo)\ | |
568 | .scalar() |
|
564 | .scalar() | |
569 |
|
565 | |||
570 | if obj is None: |
|
566 | if obj is None: | |
571 | # create new |
|
567 | # create new | |
572 |
obj = User |
|
568 | obj = UserGroupRepoToPerm() | |
573 |
|
569 | |||
574 | obj.repository = repo |
|
570 | obj.repository = repo | |
575 | obj.users_group = group_name |
|
571 | obj.users_group = group_name | |
@@ -579,18 +575,18 b' class RepoModel(BaseModel):' | |||||
579 |
|
575 | |||
580 | def revoke_users_group_permission(self, repo, group_name): |
|
576 | def revoke_users_group_permission(self, repo, group_name): | |
581 | """ |
|
577 | """ | |
582 |
Revoke permission for user |
|
578 | Revoke permission for user group on given repository | |
583 |
|
579 | |||
584 | :param repo: Instance of Repository, repository_id, or repository name |
|
580 | :param repo: Instance of Repository, repository_id, or repository name | |
585 | :param group_name: Instance of UserGroup, users_group_id, |
|
581 | :param group_name: Instance of UserGroup, users_group_id, | |
586 |
or user |
|
582 | or user group name | |
587 | """ |
|
583 | """ | |
588 | repo = self._get_repo(repo) |
|
584 | repo = self._get_repo(repo) | |
589 | group_name = self.__get_users_group(group_name) |
|
585 | group_name = self.__get_users_group(group_name) | |
590 |
|
586 | |||
591 |
obj = self.sa.query(User |
|
587 | obj = self.sa.query(UserGroupRepoToPerm)\ | |
592 |
.filter(User |
|
588 | .filter(UserGroupRepoToPerm.repository == repo)\ | |
593 |
.filter(User |
|
589 | .filter(UserGroupRepoToPerm.users_group == group_name)\ | |
594 | .scalar() |
|
590 | .scalar() | |
595 | if obj: |
|
591 | if obj: | |
596 | self.sa.delete(obj) |
|
592 | self.sa.delete(obj) |
@@ -26,7 +26,7 b'' | |||||
26 |
|
26 | |||
27 | import logging |
|
27 | import logging | |
28 | from rhodecode.model import BaseModel |
|
28 | from rhodecode.model import BaseModel | |
29 |
from rhodecode.model.db import UserRepoToPerm, User |
|
29 | from rhodecode.model.db import UserRepoToPerm, UserGroupRepoToPerm, \ | |
30 | Permission |
|
30 | Permission | |
31 |
|
31 | |||
32 | log = logging.getLogger(__name__) |
|
32 | log = logging.getLogger(__name__) | |
@@ -64,9 +64,9 b' class RepositoryPermissionModel(BaseMode' | |||||
64 | self.sa.delete(current) |
|
64 | self.sa.delete(current) | |
65 |
|
65 | |||
66 | def get_users_group_permission(self, repository, users_group): |
|
66 | def get_users_group_permission(self, repository, users_group): | |
67 |
return User |
|
67 | return UserGroupRepoToPerm.query() \ | |
68 |
.filter(User |
|
68 | .filter(UserGroupRepoToPerm.users_group == users_group) \ | |
69 |
.filter(User |
|
69 | .filter(UserGroupRepoToPerm.repository == repository) \ | |
70 | .scalar() |
|
70 | .scalar() | |
71 |
|
71 | |||
72 | def update_users_group_permission(self, repository, users_group, |
|
72 | def update_users_group_permission(self, repository, users_group, | |
@@ -77,7 +77,7 b' class RepositoryPermissionModel(BaseMode' | |||||
77 | if not current.permission is permission: |
|
77 | if not current.permission is permission: | |
78 | current.permission = permission |
|
78 | current.permission = permission | |
79 | else: |
|
79 | else: | |
80 |
p = User |
|
80 | p = UserGroupRepoToPerm() | |
81 | p.users_group = users_group |
|
81 | p.users_group = users_group | |
82 | p.repository = repository |
|
82 | p.repository = repository | |
83 | p.permission = permission |
|
83 | p.permission = permission |
@@ -3,7 +3,7 b'' | |||||
3 | rhodecode.model.user_group |
|
3 | rhodecode.model.user_group | |
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
5 |
|
5 | |||
6 |
|
|
6 | repo group model for RhodeCode | |
7 |
|
7 | |||
8 | :created_on: Jan 25, 2011 |
|
8 | :created_on: Jan 25, 2011 | |
9 | :author: marcink |
|
9 | :author: marcink | |
@@ -33,7 +33,7 b' from rhodecode.lib.utils2 import LazyPro' | |||||
33 |
|
33 | |||
34 | from rhodecode.model import BaseModel |
|
34 | from rhodecode.model import BaseModel | |
35 | from rhodecode.model.db import RepoGroup, RhodeCodeUi, UserRepoGroupToPerm, \ |
|
35 | from rhodecode.model.db import RepoGroup, RhodeCodeUi, UserRepoGroupToPerm, \ | |
36 |
User, Permission, User |
|
36 | User, Permission, UserGroupRepoGroupToPerm, UserGroup, Repository | |
37 |
|
37 | |||
38 | log = logging.getLogger(__name__) |
|
38 | log = logging.getLogger(__name__) | |
39 |
|
39 | |||
@@ -43,8 +43,8 b' class ReposGroupModel(BaseModel):' | |||||
43 | cls = RepoGroup |
|
43 | cls = RepoGroup | |
44 |
|
44 | |||
45 | def __get_users_group(self, users_group): |
|
45 | def __get_users_group(self, users_group): | |
46 |
return self._get_instance(User |
|
46 | return self._get_instance(UserGroup, users_group, | |
47 |
callback=User |
|
47 | callback=UserGroup.get_by_group_name) | |
48 |
|
48 | |||
49 | def _get_repos_group(self, repos_group): |
|
49 | def _get_repos_group(self, repos_group): | |
50 | return self._get_instance(RepoGroup, repos_group, |
|
50 | return self._get_instance(RepoGroup, repos_group, | |
@@ -79,7 +79,7 b' class ReposGroupModel(BaseModel):' | |||||
79 |
|
79 | |||
80 | def __create_group(self, group_name): |
|
80 | def __create_group(self, group_name): | |
81 | """ |
|
81 | """ | |
82 |
makes repositor |
|
82 | makes repository group on filesystem | |
83 |
|
83 | |||
84 | :param repo_name: |
|
84 | :param repo_name: | |
85 | :param parent_id: |
|
85 | :param parent_id: | |
@@ -218,7 +218,7 b' class ReposGroupModel(BaseModel):' | |||||
218 | if member_type == 'user': |
|
218 | if member_type == 'user': | |
219 | # this updates also current one if found |
|
219 | # this updates also current one if found | |
220 | _set_perm_user(obj, user=member, perm=perm) |
|
220 | _set_perm_user(obj, user=member, perm=perm) | |
221 |
## set for user |
|
221 | ## set for user group | |
222 | else: |
|
222 | else: | |
223 | _set_perm_group(obj, users_group=member, perm=perm) |
|
223 | _set_perm_group(obj, users_group=member, perm=perm) | |
224 | # set new permissions |
|
224 | # set new permissions | |
@@ -289,11 +289,11 b' class ReposGroupModel(BaseModel):' | |||||
289 | def delete_permission(self, repos_group, obj, obj_type, recursive): |
|
289 | def delete_permission(self, repos_group, obj, obj_type, recursive): | |
290 | """ |
|
290 | """ | |
291 | Revokes permission for repos_group for given obj(user or users_group), |
|
291 | Revokes permission for repos_group for given obj(user or users_group), | |
292 |
obj_type can be user or user |
|
292 | obj_type can be user or user group | |
293 |
|
293 | |||
294 | :param repos_group: |
|
294 | :param repos_group: | |
295 |
:param obj: user or user |
|
295 | :param obj: user or user group id | |
296 |
:param obj_type: user or user |
|
296 | :param obj_type: user or user group type | |
297 | :param recursive: recurse to all children of group |
|
297 | :param recursive: recurse to all children of group | |
298 | """ |
|
298 | """ | |
299 | from rhodecode.model.repo import RepoModel |
|
299 | from rhodecode.model.repo import RepoModel | |
@@ -327,7 +327,7 b' class ReposGroupModel(BaseModel):' | |||||
327 |
|
327 | |||
328 | def grant_user_permission(self, repos_group, user, perm): |
|
328 | def grant_user_permission(self, repos_group, user, perm): | |
329 | """ |
|
329 | """ | |
330 |
Grant permission for user on given repositor |
|
330 | Grant permission for user on given repository group, or update | |
331 | existing one if found |
|
331 | existing one if found | |
332 |
|
332 | |||
333 | :param repos_group: Instance of ReposGroup, repositories_group_id, |
|
333 | :param repos_group: Instance of ReposGroup, repositories_group_id, | |
@@ -356,7 +356,7 b' class ReposGroupModel(BaseModel):' | |||||
356 |
|
356 | |||
357 | def revoke_user_permission(self, repos_group, user): |
|
357 | def revoke_user_permission(self, repos_group, user): | |
358 | """ |
|
358 | """ | |
359 |
Revoke permission for user on given repositor |
|
359 | Revoke permission for user on given repository group | |
360 |
|
360 | |||
361 | :param repos_group: Instance of ReposGroup, repositories_group_id, |
|
361 | :param repos_group: Instance of ReposGroup, repositories_group_id, | |
362 | or repositories_group name |
|
362 | or repositories_group name | |
@@ -376,13 +376,13 b' class ReposGroupModel(BaseModel):' | |||||
376 |
|
376 | |||
377 | def grant_users_group_permission(self, repos_group, group_name, perm): |
|
377 | def grant_users_group_permission(self, repos_group, group_name, perm): | |
378 | """ |
|
378 | """ | |
379 |
Grant permission for user |
|
379 | Grant permission for user group on given repository group, or update | |
380 | existing one if found |
|
380 | existing one if found | |
381 |
|
381 | |||
382 | :param repos_group: Instance of ReposGroup, repositories_group_id, |
|
382 | :param repos_group: Instance of ReposGroup, repositories_group_id, | |
383 | or repositories_group name |
|
383 | or repositories_group name | |
384 | :param group_name: Instance of UserGroup, users_group_id, |
|
384 | :param group_name: Instance of UserGroup, users_group_id, | |
385 |
or user |
|
385 | or user group name | |
386 | :param perm: Instance of Permission, or permission_name |
|
386 | :param perm: Instance of Permission, or permission_name | |
387 | """ |
|
387 | """ | |
388 | repos_group = self._get_repos_group(repos_group) |
|
388 | repos_group = self._get_repos_group(repos_group) | |
@@ -390,14 +390,14 b' class ReposGroupModel(BaseModel):' | |||||
390 | permission = self._get_perm(perm) |
|
390 | permission = self._get_perm(perm) | |
391 |
|
391 | |||
392 | # check if we have that permission already |
|
392 | # check if we have that permission already | |
393 |
obj = self.sa.query(User |
|
393 | obj = self.sa.query(UserGroupRepoGroupToPerm)\ | |
394 |
.filter(User |
|
394 | .filter(UserGroupRepoGroupToPerm.group == repos_group)\ | |
395 |
.filter(User |
|
395 | .filter(UserGroupRepoGroupToPerm.users_group == group_name)\ | |
396 | .scalar() |
|
396 | .scalar() | |
397 |
|
397 | |||
398 | if obj is None: |
|
398 | if obj is None: | |
399 | # create new |
|
399 | # create new | |
400 |
obj = User |
|
400 | obj = UserGroupRepoGroupToPerm() | |
401 |
|
401 | |||
402 | obj.group = repos_group |
|
402 | obj.group = repos_group | |
403 | obj.users_group = group_name |
|
403 | obj.users_group = group_name | |
@@ -407,19 +407,19 b' class ReposGroupModel(BaseModel):' | |||||
407 |
|
407 | |||
408 | def revoke_users_group_permission(self, repos_group, group_name): |
|
408 | def revoke_users_group_permission(self, repos_group, group_name): | |
409 | """ |
|
409 | """ | |
410 |
Revoke permission for user |
|
410 | Revoke permission for user group on given repository group | |
411 |
|
411 | |||
412 | :param repos_group: Instance of ReposGroup, repositories_group_id, |
|
412 | :param repos_group: Instance of ReposGroup, repositories_group_id, | |
413 | or repositories_group name |
|
413 | or repositories_group name | |
414 | :param group_name: Instance of UserGroup, users_group_id, |
|
414 | :param group_name: Instance of UserGroup, users_group_id, | |
415 |
or user |
|
415 | or user group name | |
416 | """ |
|
416 | """ | |
417 | repos_group = self._get_repos_group(repos_group) |
|
417 | repos_group = self._get_repos_group(repos_group) | |
418 | group_name = self.__get_users_group(group_name) |
|
418 | group_name = self.__get_users_group(group_name) | |
419 |
|
419 | |||
420 |
obj = self.sa.query(User |
|
420 | obj = self.sa.query(UserGroupRepoGroupToPerm)\ | |
421 |
.filter(User |
|
421 | .filter(UserGroupRepoGroupToPerm.group == repos_group)\ | |
422 |
.filter(User |
|
422 | .filter(UserGroupRepoGroupToPerm.users_group == group_name)\ | |
423 | .scalar() |
|
423 | .scalar() | |
424 | if obj: |
|
424 | if obj: | |
425 | self.sa.delete(obj) |
|
425 | self.sa.delete(obj) |
@@ -291,9 +291,7 b' class ScmModel(BaseModel):' | |||||
291 | if all_groups is None: |
|
291 | if all_groups is None: | |
292 | all_groups = RepoGroup.query()\ |
|
292 | all_groups = RepoGroup.query()\ | |
293 | .filter(RepoGroup.group_parent_id == None).all() |
|
293 | .filter(RepoGroup.group_parent_id == None).all() | |
294 |
|
|
294 | return [x for x in GroupList(all_groups)] | |
295 |
|
||||
296 | return group_iter |
|
|||
297 |
|
295 | |||
298 | def mark_for_invalidation(self, repo_name): |
|
296 | def mark_for_invalidation(self, repo_name): | |
299 | """ |
|
297 | """ |
@@ -37,11 +37,12 b' from rhodecode.lib.utils2 import safe_un' | |||||
37 | from rhodecode.lib.caching_query import FromCache |
|
37 | from rhodecode.lib.caching_query import FromCache | |
38 | from rhodecode.model import BaseModel |
|
38 | from rhodecode.model import BaseModel | |
39 | from rhodecode.model.db import User, UserRepoToPerm, Repository, Permission, \ |
|
39 | from rhodecode.model.db import User, UserRepoToPerm, Repository, Permission, \ | |
40 |
UserToPerm, User |
|
40 | UserToPerm, UserGroupRepoToPerm, UserGroupToPerm, UserGroupMember, \ | |
41 |
Notification, RepoGroup, UserRepoGroupToPerm, User |
|
41 | Notification, RepoGroup, UserRepoGroupToPerm, UserGroupRepoGroupToPerm, \ | |
42 | UserEmailMap, UserIpMap |
|
42 | UserEmailMap, UserIpMap | |
43 | from rhodecode.lib.exceptions import DefaultUserException, \ |
|
43 | from rhodecode.lib.exceptions import DefaultUserException, \ | |
44 | UserOwnsReposException |
|
44 | UserOwnsReposException | |
|
45 | from rhodecode.model.meta import Session | |||
45 |
|
46 | |||
46 |
|
47 | |||
47 | log = logging.getLogger(__name__) |
|
48 | log = logging.getLogger(__name__) | |
@@ -316,11 +317,61 b' class UserModel(BaseModel):' | |||||
316 |
|
317 | |||
317 | def reset_password_link(self, data): |
|
318 | def reset_password_link(self, data): | |
318 | from rhodecode.lib.celerylib import tasks, run_task |
|
319 | from rhodecode.lib.celerylib import tasks, run_task | |
319 | run_task(tasks.send_password_link, data['email']) |
|
320 | from rhodecode.model.notification import EmailNotificationModel | |
|
321 | user_email = data['email'] | |||
|
322 | try: | |||
|
323 | user = User.get_by_email(user_email) | |||
|
324 | if user: | |||
|
325 | log.debug('password reset user found %s' % user) | |||
|
326 | link = url('reset_password_confirmation', key=user.api_key, | |||
|
327 | qualified=True) | |||
|
328 | reg_type = EmailNotificationModel.TYPE_PASSWORD_RESET | |||
|
329 | body = EmailNotificationModel().get_email_tmpl(reg_type, | |||
|
330 | **{'user': user.short_contact, | |||
|
331 | 'reset_url': link}) | |||
|
332 | log.debug('sending email') | |||
|
333 | run_task(tasks.send_email, user_email, | |||
|
334 | _("password reset link"), body, body) | |||
|
335 | log.info('send new password mail to %s' % user_email) | |||
|
336 | else: | |||
|
337 | log.debug("password reset email %s not found" % user_email) | |||
|
338 | except: | |||
|
339 | log.error(traceback.format_exc()) | |||
|
340 | return False | |||
|
341 | ||||
|
342 | return True | |||
320 |
|
343 | |||
321 | def reset_password(self, data): |
|
344 | def reset_password(self, data): | |
322 | from rhodecode.lib.celerylib import tasks, run_task |
|
345 | from rhodecode.lib.celerylib import tasks, run_task | |
323 | run_task(tasks.reset_user_password, data['email']) |
|
346 | from rhodecode.lib import auth | |
|
347 | user_email = data['email'] | |||
|
348 | try: | |||
|
349 | try: | |||
|
350 | user = User.get_by_email(user_email) | |||
|
351 | new_passwd = auth.PasswordGenerator().gen_password(8, | |||
|
352 | auth.PasswordGenerator.ALPHABETS_BIG_SMALL) | |||
|
353 | if user: | |||
|
354 | user.password = auth.get_crypt_password(new_passwd) | |||
|
355 | user.api_key = auth.generate_api_key(user.username) | |||
|
356 | Session().add(user) | |||
|
357 | Session().commit() | |||
|
358 | log.info('change password for %s' % user_email) | |||
|
359 | if new_passwd is None: | |||
|
360 | raise Exception('unable to generate new password') | |||
|
361 | except: | |||
|
362 | log.error(traceback.format_exc()) | |||
|
363 | Session().rollback() | |||
|
364 | ||||
|
365 | run_task(tasks.send_email, user_email, | |||
|
366 | _('Your new password'), | |||
|
367 | _('Your new RhodeCode password:%s') % (new_passwd)) | |||
|
368 | log.info('send new password mail to %s' % user_email) | |||
|
369 | ||||
|
370 | except: | |||
|
371 | log.error('Failed to update user password') | |||
|
372 | log.error(traceback.format_exc()) | |||
|
373 | ||||
|
374 | return True | |||
324 |
|
375 | |||
325 | def fill_data(self, auth_user, user_id=None, api_key=None): |
|
376 | def fill_data(self, auth_user, user_id=None, api_key=None): | |
326 | """ |
|
377 | """ | |
@@ -413,7 +464,7 b' class UserModel(BaseModel):' | |||||
413 | p = 'repository.admin' |
|
464 | p = 'repository.admin' | |
414 | user.permissions[RK][r_k] = p |
|
465 | user.permissions[RK][r_k] = p | |
415 |
|
466 | |||
416 |
# repositor |
|
467 | # repository groups | |
417 | for perm in default_repo_groups_perms: |
|
468 | for perm in default_repo_groups_perms: | |
418 | rg_k = perm.UserRepoGroupToPerm.group.group_name |
|
469 | rg_k = perm.UserRepoGroupToPerm.group.group_name | |
419 | p = 'group.admin' |
|
470 | p = 'group.admin' | |
@@ -446,7 +497,7 b' class UserModel(BaseModel):' | |||||
446 |
|
497 | |||
447 | user.permissions[RK][r_k] = p |
|
498 | user.permissions[RK][r_k] = p | |
448 |
|
499 | |||
449 |
# defaults for repositor |
|
500 | # defaults for repository groups taken from default user permission | |
450 | # on given group |
|
501 | # on given group | |
451 | for perm in default_repo_groups_perms: |
|
502 | for perm in default_repo_groups_perms: | |
452 | rg_k = perm.UserRepoGroupToPerm.group.group_name |
|
503 | rg_k = perm.UserRepoGroupToPerm.group.group_name | |
@@ -461,13 +512,13 b' class UserModel(BaseModel):' | |||||
461 | 'hg.create.none', 'hg.create.repository']) |
|
512 | 'hg.create.none', 'hg.create.repository']) | |
462 |
|
513 | |||
463 | # USER GROUPS comes first |
|
514 | # USER GROUPS comes first | |
464 |
# user |
|
515 | # user group global permissions | |
465 |
user_perms_from_users_groups = self.sa.query(User |
|
516 | user_perms_from_users_groups = self.sa.query(UserGroupToPerm)\ | |
466 |
.options(joinedload(User |
|
517 | .options(joinedload(UserGroupToPerm.permission))\ | |
467 |
.join((User |
|
518 | .join((UserGroupMember, UserGroupToPerm.users_group_id == | |
468 |
User |
|
519 | UserGroupMember.users_group_id))\ | |
469 |
.filter(User |
|
520 | .filter(UserGroupMember.user_id == uid)\ | |
470 |
.order_by(User |
|
521 | .order_by(UserGroupToPerm.users_group_id)\ | |
471 | .all() |
|
522 | .all() | |
472 | #need to group here by groups since user can be in more than one group |
|
523 | #need to group here by groups since user can be in more than one group | |
473 | _grouped = [[x, list(y)] for x, y in |
|
524 | _grouped = [[x, list(y)] for x, y in | |
@@ -508,21 +559,21 b' class UserModel(BaseModel):' | |||||
508 | # permission should be selected based on selected method |
|
559 | # permission should be selected based on selected method | |
509 | #====================================================================== |
|
560 | #====================================================================== | |
510 |
|
561 | |||
511 |
# user |
|
562 | # user group for repositories permissions | |
512 | user_repo_perms_from_users_groups = \ |
|
563 | user_repo_perms_from_users_groups = \ | |
513 |
self.sa.query(User |
|
564 | self.sa.query(UserGroupRepoToPerm, Permission, Repository,)\ | |
514 |
.join((Repository, User |
|
565 | .join((Repository, UserGroupRepoToPerm.repository_id == | |
515 | Repository.repo_id))\ |
|
566 | Repository.repo_id))\ | |
516 |
.join((Permission, User |
|
567 | .join((Permission, UserGroupRepoToPerm.permission_id == | |
517 | Permission.permission_id))\ |
|
568 | Permission.permission_id))\ | |
518 |
.join((User |
|
569 | .join((UserGroupMember, UserGroupRepoToPerm.users_group_id == | |
519 |
User |
|
570 | UserGroupMember.users_group_id))\ | |
520 |
.filter(User |
|
571 | .filter(UserGroupMember.user_id == uid)\ | |
521 | .all() |
|
572 | .all() | |
522 |
|
573 | |||
523 | multiple_counter = collections.defaultdict(int) |
|
574 | multiple_counter = collections.defaultdict(int) | |
524 | for perm in user_repo_perms_from_users_groups: |
|
575 | for perm in user_repo_perms_from_users_groups: | |
525 |
r_k = perm.User |
|
576 | r_k = perm.UserGroupRepoToPerm.repository.repo_name | |
526 | multiple_counter[r_k] += 1 |
|
577 | multiple_counter[r_k] += 1 | |
527 | p = perm.Permission.permission_name |
|
578 | p = perm.Permission.permission_name | |
528 | cur_perm = user.permissions[RK][r_k] |
|
579 | cur_perm = user.permissions[RK][r_k] | |
@@ -559,27 +610,27 b' class UserModel(BaseModel):' | |||||
559 | user.permissions[RK][r_k] = p |
|
610 | user.permissions[RK][r_k] = p | |
560 |
|
611 | |||
561 | #====================================================================== |
|
612 | #====================================================================== | |
562 |
# !! PERMISSIONS FOR REPOSITOR |
|
613 | # !! PERMISSIONS FOR REPOSITORY GROUPS !! | |
563 | #====================================================================== |
|
614 | #====================================================================== | |
564 | #====================================================================== |
|
615 | #====================================================================== | |
565 | # check if user is part of user groups for this repository groups and |
|
616 | # check if user is part of user groups for this repository groups and | |
566 | # fill in his permission from it. _choose_perm decides of which |
|
617 | # fill in his permission from it. _choose_perm decides of which | |
567 | # permission should be selected based on selected method |
|
618 | # permission should be selected based on selected method | |
568 | #====================================================================== |
|
619 | #====================================================================== | |
569 |
# user |
|
620 | # user group for repo groups permissions | |
570 | user_repo_group_perms_from_users_groups = \ |
|
621 | user_repo_group_perms_from_users_groups = \ | |
571 |
self.sa.query(User |
|
622 | self.sa.query(UserGroupRepoGroupToPerm, Permission, RepoGroup)\ | |
572 |
.join((RepoGroup, User |
|
623 | .join((RepoGroup, UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id))\ | |
573 |
.join((Permission, User |
|
624 | .join((Permission, UserGroupRepoGroupToPerm.permission_id | |
574 | == Permission.permission_id))\ |
|
625 | == Permission.permission_id))\ | |
575 |
.join((User |
|
626 | .join((UserGroupMember, UserGroupRepoGroupToPerm.users_group_id | |
576 |
== User |
|
627 | == UserGroupMember.users_group_id))\ | |
577 |
.filter(User |
|
628 | .filter(UserGroupMember.user_id == uid)\ | |
578 | .all() |
|
629 | .all() | |
579 |
|
630 | |||
580 | multiple_counter = collections.defaultdict(int) |
|
631 | multiple_counter = collections.defaultdict(int) | |
581 | for perm in user_repo_group_perms_from_users_groups: |
|
632 | for perm in user_repo_group_perms_from_users_groups: | |
582 |
g_k = perm.User |
|
633 | g_k = perm.UserGroupRepoGroupToPerm.group.group_name | |
583 | multiple_counter[g_k] += 1 |
|
634 | multiple_counter[g_k] += 1 | |
584 | p = perm.Permission.permission_name |
|
635 | p = perm.Permission.permission_name | |
585 | cur_perm = user.permissions[GK][g_k] |
|
636 | cur_perm = user.permissions[GK][g_k] |
@@ -3,7 +3,7 b'' | |||||
3 | rhodecode.model.users_group |
|
3 | rhodecode.model.users_group | |
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
5 |
|
5 | |||
6 |
user |
|
6 | user group model for RhodeCode | |
7 |
|
7 | |||
8 | :created_on: Oct 1, 2011 |
|
8 | :created_on: Oct 1, 2011 | |
9 | :author: nvinot |
|
9 | :author: nvinot | |
@@ -28,33 +28,33 b' import logging' | |||||
28 | import traceback |
|
28 | import traceback | |
29 |
|
29 | |||
30 | from rhodecode.model import BaseModel |
|
30 | from rhodecode.model import BaseModel | |
31 |
from rhodecode.model.db import User |
|
31 | from rhodecode.model.db import UserGroupMember, UserGroup,\ | |
32 |
User |
|
32 | UserGroupRepoToPerm, Permission, UserGroupToPerm, User | |
33 |
from rhodecode.lib.exceptions import User |
|
33 | from rhodecode.lib.exceptions import UserGroupsAssignedException | |
34 |
|
34 | |||
35 | log = logging.getLogger(__name__) |
|
35 | log = logging.getLogger(__name__) | |
36 |
|
36 | |||
37 |
|
37 | |||
38 |
class User |
|
38 | class UserGroupModel(BaseModel): | |
39 |
|
39 | |||
40 |
cls = User |
|
40 | cls = UserGroup | |
41 |
|
41 | |||
42 | def __get_users_group(self, users_group): |
|
42 | def __get_users_group(self, users_group): | |
43 |
return self._get_instance(User |
|
43 | return self._get_instance(UserGroup, users_group, | |
44 |
callback=User |
|
44 | callback=UserGroup.get_by_group_name) | |
45 |
|
45 | |||
46 | def get(self, users_group_id, cache=False): |
|
46 | def get(self, users_group_id, cache=False): | |
47 |
return User |
|
47 | return UserGroup.get(users_group_id) | |
48 |
|
48 | |||
49 | def get_group(self, users_group): |
|
49 | def get_group(self, users_group): | |
50 | return self.__get_users_group(users_group) |
|
50 | return self.__get_users_group(users_group) | |
51 |
|
51 | |||
52 | def get_by_name(self, name, cache=False, case_insensitive=False): |
|
52 | def get_by_name(self, name, cache=False, case_insensitive=False): | |
53 |
return User |
|
53 | return UserGroup.get_by_group_name(name, cache, case_insensitive) | |
54 |
|
54 | |||
55 | def create(self, name, active=True): |
|
55 | def create(self, name, active=True): | |
56 | try: |
|
56 | try: | |
57 |
new = User |
|
57 | new = UserGroup() | |
58 | new.users_group_name = name |
|
58 | new.users_group_name = name | |
59 | new.users_group_active = active |
|
59 | new.users_group_active = active | |
60 | self.sa.add(new) |
|
60 | self.sa.add(new) | |
@@ -76,7 +76,7 b' class UsersGroupModel(BaseModel):' | |||||
76 | if v: |
|
76 | if v: | |
77 | v = [v] if isinstance(v, basestring) else v |
|
77 | v = [v] if isinstance(v, basestring) else v | |
78 | for u_id in set(v): |
|
78 | for u_id in set(v): | |
79 |
member = User |
|
79 | member = UserGroupMember(users_group.users_group_id, u_id) | |
80 | members_list.append(member) |
|
80 | members_list.append(member) | |
81 | setattr(users_group, 'members', members_list) |
|
81 | setattr(users_group, 'members', members_list) | |
82 | setattr(users_group, k, v) |
|
82 | setattr(users_group, k, v) | |
@@ -99,11 +99,11 b' class UsersGroupModel(BaseModel):' | |||||
99 | users_group = self.__get_users_group(users_group) |
|
99 | users_group = self.__get_users_group(users_group) | |
100 |
|
100 | |||
101 | # check if this group is not assigned to repo |
|
101 | # check if this group is not assigned to repo | |
102 |
assigned_groups = User |
|
102 | assigned_groups = UserGroupRepoToPerm.query()\ | |
103 |
.filter(User |
|
103 | .filter(UserGroupRepoToPerm.users_group == users_group).all() | |
104 |
|
104 | |||
105 | if assigned_groups and force is False: |
|
105 | if assigned_groups and force is False: | |
106 |
raise User |
|
106 | raise UserGroupsAssignedException('RepoGroup assigned to %s' % | |
107 | assigned_groups) |
|
107 | assigned_groups) | |
108 |
|
108 | |||
109 | self.sa.delete(users_group) |
|
109 | self.sa.delete(users_group) | |
@@ -121,7 +121,7 b' class UsersGroupModel(BaseModel):' | |||||
121 | return True |
|
121 | return True | |
122 |
|
122 | |||
123 | try: |
|
123 | try: | |
124 |
users_group_member = User |
|
124 | users_group_member = UserGroupMember() | |
125 | users_group_member.user = user |
|
125 | users_group_member.user = user | |
126 | users_group_member.users_group = users_group |
|
126 | users_group_member.users_group = users_group | |
127 |
|
127 | |||
@@ -160,23 +160,23 b' class UsersGroupModel(BaseModel):' | |||||
160 | users_group = self.__get_users_group(users_group) |
|
160 | users_group = self.__get_users_group(users_group) | |
161 | perm = self._get_perm(perm) |
|
161 | perm = self._get_perm(perm) | |
162 |
|
162 | |||
163 |
return User |
|
163 | return UserGroupToPerm.query()\ | |
164 |
.filter(User |
|
164 | .filter(UserGroupToPerm.users_group == users_group)\ | |
165 |
.filter(User |
|
165 | .filter(UserGroupToPerm.permission == perm).scalar() is not None | |
166 |
|
166 | |||
167 | def grant_perm(self, users_group, perm): |
|
167 | def grant_perm(self, users_group, perm): | |
168 | users_group = self.__get_users_group(users_group) |
|
168 | users_group = self.__get_users_group(users_group) | |
169 | perm = self._get_perm(perm) |
|
169 | perm = self._get_perm(perm) | |
170 |
|
170 | |||
171 | # if this permission is already granted skip it |
|
171 | # if this permission is already granted skip it | |
172 |
_perm = User |
|
172 | _perm = UserGroupToPerm.query()\ | |
173 |
.filter(User |
|
173 | .filter(UserGroupToPerm.users_group == users_group)\ | |
174 |
.filter(User |
|
174 | .filter(UserGroupToPerm.permission == perm)\ | |
175 | .scalar() |
|
175 | .scalar() | |
176 | if _perm: |
|
176 | if _perm: | |
177 | return |
|
177 | return | |
178 |
|
178 | |||
179 |
new = User |
|
179 | new = UserGroupToPerm() | |
180 | new.users_group = users_group |
|
180 | new.users_group = users_group | |
181 | new.permission = perm |
|
181 | new.permission = perm | |
182 | self.sa.add(new) |
|
182 | self.sa.add(new) | |
@@ -185,8 +185,8 b' class UsersGroupModel(BaseModel):' | |||||
185 | users_group = self.__get_users_group(users_group) |
|
185 | users_group = self.__get_users_group(users_group) | |
186 | perm = self._get_perm(perm) |
|
186 | perm = self._get_perm(perm) | |
187 |
|
187 | |||
188 |
obj = User |
|
188 | obj = UserGroupToPerm.query()\ | |
189 |
.filter(User |
|
189 | .filter(UserGroupToPerm.users_group == users_group)\ | |
190 |
.filter(User |
|
190 | .filter(UserGroupToPerm.permission == perm).scalar() | |
191 | if obj: |
|
191 | if obj: | |
192 | self.sa.delete(obj) |
|
192 | self.sa.delete(obj) |
@@ -16,7 +16,7 b' from formencode.validators import (' | |||||
16 | from rhodecode.lib.compat import OrderedSet |
|
16 | from rhodecode.lib.compat import OrderedSet | |
17 | from rhodecode.lib import ipaddr |
|
17 | from rhodecode.lib import ipaddr | |
18 | from rhodecode.lib.utils import repo_name_slug |
|
18 | from rhodecode.lib.utils import repo_name_slug | |
19 |
from rhodecode.model.db import RepoGroup, Repository, User |
|
19 | from rhodecode.model.db import RepoGroup, Repository, UserGroup, User,\ | |
20 | ChangesetStatus |
|
20 | ChangesetStatus | |
21 | from rhodecode.lib.exceptions import LdapImportError |
|
21 | from rhodecode.lib.exceptions import LdapImportError | |
22 | from rhodecode.config.routing import ADMIN_PREFIX |
|
22 | from rhodecode.config.routing import ADMIN_PREFIX | |
@@ -129,13 +129,13 b' def ValidRepoUser():' | |||||
129 | return _validator |
|
129 | return _validator | |
130 |
|
130 | |||
131 |
|
131 | |||
132 |
def ValidUser |
|
132 | def ValidUserGroup(edit=False, old_data={}): | |
133 | class _validator(formencode.validators.FancyValidator): |
|
133 | class _validator(formencode.validators.FancyValidator): | |
134 | messages = { |
|
134 | messages = { | |
135 |
'invalid_group': _(u'Invalid user |
|
135 | 'invalid_group': _(u'Invalid user group name'), | |
136 |
'group_exist': _(u'User |
|
136 | 'group_exist': _(u'User group "%(usergroup)s" already exists'), | |
137 |
'invalid_user |
|
137 | 'invalid_usergroup_name': | |
138 |
_(u'user |
|
138 | _(u'user group name may only contain alphanumeric ' | |
139 | 'characters underscores, periods or dashes and must begin ' |
|
139 | 'characters underscores, periods or dashes and must begin ' | |
140 | 'with alphanumeric character') |
|
140 | 'with alphanumeric character') | |
141 | } |
|
141 | } | |
@@ -150,19 +150,19 b' def ValidUsersGroup(edit=False, old_data' | |||||
150 | old_ugname = None |
|
150 | old_ugname = None | |
151 | if edit: |
|
151 | if edit: | |
152 | old_id = old_data.get('users_group_id') |
|
152 | old_id = old_data.get('users_group_id') | |
153 |
old_ugname = User |
|
153 | old_ugname = UserGroup.get(old_id).users_group_name | |
154 |
|
154 | |||
155 | if old_ugname != value or not edit: |
|
155 | if old_ugname != value or not edit: | |
156 |
is_existing_group = User |
|
156 | is_existing_group = UserGroup.get_by_group_name(value, | |
157 | case_insensitive=True) |
|
157 | case_insensitive=True) | |
158 | if is_existing_group: |
|
158 | if is_existing_group: | |
159 |
msg = M(self, 'group_exist', state, user |
|
159 | msg = M(self, 'group_exist', state, usergroup=value) | |
160 | raise formencode.Invalid(msg, value, state, |
|
160 | raise formencode.Invalid(msg, value, state, | |
161 | error_dict=dict(users_group_name=msg) |
|
161 | error_dict=dict(users_group_name=msg) | |
162 | ) |
|
162 | ) | |
163 |
|
163 | |||
164 | if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+$', value) is None: |
|
164 | if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+$', value) is None: | |
165 |
msg = M(self, 'invalid_user |
|
165 | msg = M(self, 'invalid_usergroup_name', state) | |
166 | raise formencode.Invalid(msg, value, state, |
|
166 | raise formencode.Invalid(msg, value, state, | |
167 | error_dict=dict(users_group_name=msg) |
|
167 | error_dict=dict(users_group_name=msg) | |
168 | ) |
|
168 | ) | |
@@ -317,7 +317,7 b' def ValidRepoName(edit=False, old_data={' | |||||
317 | _(u'Repository named %(repo)s already exists'), |
|
317 | _(u'Repository named %(repo)s already exists'), | |
318 | 'repository_in_group_exists': _(u'Repository "%(repo)s" already ' |
|
318 | 'repository_in_group_exists': _(u'Repository "%(repo)s" already ' | |
319 | 'exists in group "%(group)s"'), |
|
319 | 'exists in group "%(group)s"'), | |
320 |
'same_group_exists': _(u'Repositor |
|
320 | 'same_group_exists': _(u'Repository group with name "%(repo)s" ' | |
321 | 'already exists') |
|
321 | 'already exists') | |
322 | } |
|
322 | } | |
323 |
|
323 | |||
@@ -547,7 +547,7 b" def ValidPerms(type_='repo'):" | |||||
547 | class _validator(formencode.validators.FancyValidator): |
|
547 | class _validator(formencode.validators.FancyValidator): | |
548 | messages = { |
|
548 | messages = { | |
549 | 'perm_new_member_name': |
|
549 | 'perm_new_member_name': | |
550 |
_(u'This username or user |
|
550 | _(u'This username or user group name is not valid') | |
551 | } |
|
551 | } | |
552 |
|
552 | |||
553 | def to_python(self, value, state): |
|
553 | def to_python(self, value, state): | |
@@ -604,9 +604,9 b" def ValidPerms(type_='repo'):" | |||||
604 | .filter(User.active == True)\ |
|
604 | .filter(User.active == True)\ | |
605 | .filter(User.username == k).one() |
|
605 | .filter(User.username == k).one() | |
606 | if t is 'users_group': |
|
606 | if t is 'users_group': | |
607 |
self.user_db = User |
|
607 | self.user_db = UserGroup.query()\ | |
608 |
.filter(User |
|
608 | .filter(UserGroup.users_group_active == True)\ | |
609 |
.filter(User |
|
609 | .filter(UserGroup.users_group_name == k).one() | |
610 |
|
610 | |||
611 | except Exception: |
|
611 | except Exception: | |
612 | log.exception('Updated permission failed') |
|
612 | log.exception('Updated permission failed') |
@@ -160,56 +160,48 b' div.options a {' | |||||
160 | .top-left-rounded-corner { |
|
160 | .top-left-rounded-corner { | |
161 | -webkit-border-top-left-radius: 8px; |
|
161 | -webkit-border-top-left-radius: 8px; | |
162 | -khtml-border-radius-topleft: 8px; |
|
162 | -khtml-border-radius-topleft: 8px; | |
163 | -moz-border-radius-topleft: 8px; |
|
|||
164 | border-top-left-radius: 8px; |
|
163 | border-top-left-radius: 8px; | |
165 | } |
|
164 | } | |
166 |
|
165 | |||
167 | .top-right-rounded-corner { |
|
166 | .top-right-rounded-corner { | |
168 | -webkit-border-top-right-radius: 8px; |
|
167 | -webkit-border-top-right-radius: 8px; | |
169 | -khtml-border-radius-topright: 8px; |
|
168 | -khtml-border-radius-topright: 8px; | |
170 | -moz-border-radius-topright: 8px; |
|
|||
171 | border-top-right-radius: 8px; |
|
169 | border-top-right-radius: 8px; | |
172 | } |
|
170 | } | |
173 |
|
171 | |||
174 | .bottom-left-rounded-corner { |
|
172 | .bottom-left-rounded-corner { | |
175 | -webkit-border-bottom-left-radius: 8px; |
|
173 | -webkit-border-bottom-left-radius: 8px; | |
176 | -khtml-border-radius-bottomleft: 8px; |
|
174 | -khtml-border-radius-bottomleft: 8px; | |
177 | -moz-border-radius-bottomleft: 8px; |
|
|||
178 | border-bottom-left-radius: 8px; |
|
175 | border-bottom-left-radius: 8px; | |
179 | } |
|
176 | } | |
180 |
|
177 | |||
181 | .bottom-right-rounded-corner { |
|
178 | .bottom-right-rounded-corner { | |
182 | -webkit-border-bottom-right-radius: 8px; |
|
179 | -webkit-border-bottom-right-radius: 8px; | |
183 | -khtml-border-radius-bottomright: 8px; |
|
180 | -khtml-border-radius-bottomright: 8px; | |
184 | -moz-border-radius-bottomright: 8px; |
|
|||
185 | border-bottom-right-radius: 8px; |
|
181 | border-bottom-right-radius: 8px; | |
186 | } |
|
182 | } | |
187 |
|
183 | |||
188 | .top-left-rounded-corner-mid { |
|
184 | .top-left-rounded-corner-mid { | |
189 | -webkit-border-top-left-radius: 4px; |
|
185 | -webkit-border-top-left-radius: 4px; | |
190 | -khtml-border-radius-topleft: 4px; |
|
186 | -khtml-border-radius-topleft: 4px; | |
191 | -moz-border-radius-topleft: 4px; |
|
|||
192 | border-top-left-radius: 4px; |
|
187 | border-top-left-radius: 4px; | |
193 | } |
|
188 | } | |
194 |
|
189 | |||
195 | .top-right-rounded-corner-mid { |
|
190 | .top-right-rounded-corner-mid { | |
196 | -webkit-border-top-right-radius: 4px; |
|
191 | -webkit-border-top-right-radius: 4px; | |
197 | -khtml-border-radius-topright: 4px; |
|
192 | -khtml-border-radius-topright: 4px; | |
198 | -moz-border-radius-topright: 4px; |
|
|||
199 | border-top-right-radius: 4px; |
|
193 | border-top-right-radius: 4px; | |
200 | } |
|
194 | } | |
201 |
|
195 | |||
202 | .bottom-left-rounded-corner-mid { |
|
196 | .bottom-left-rounded-corner-mid { | |
203 | -webkit-border-bottom-left-radius: 4px; |
|
197 | -webkit-border-bottom-left-radius: 4px; | |
204 | -khtml-border-radius-bottomleft: 4px; |
|
198 | -khtml-border-radius-bottomleft: 4px; | |
205 | -moz-border-radius-bottomleft: 4px; |
|
|||
206 | border-bottom-left-radius: 4px; |
|
199 | border-bottom-left-radius: 4px; | |
207 | } |
|
200 | } | |
208 |
|
201 | |||
209 | .bottom-right-rounded-corner-mid { |
|
202 | .bottom-right-rounded-corner-mid { | |
210 | -webkit-border-bottom-right-radius: 4px; |
|
203 | -webkit-border-bottom-right-radius: 4px; | |
211 | -khtml-border-radius-bottomright: 4px; |
|
204 | -khtml-border-radius-bottomright: 4px; | |
212 | -moz-border-radius-bottomright: 4px; |
|
|||
213 | border-bottom-right-radius: 4px; |
|
205 | border-bottom-right-radius: 4px; | |
214 | } |
|
206 | } | |
215 |
|
207 | |||
@@ -244,12 +236,10 b' div:hover > a.permalink {' | |||||
244 |
|
236 | |||
245 | #header { |
|
237 | #header { | |
246 | } |
|
238 | } | |
247 |
|
||||
248 | #header ul#logged-user { |
|
239 | #header ul#logged-user { | |
249 | margin-bottom: 5px !important; |
|
240 | margin-bottom: 5px !important; | |
250 | -webkit-border-radius: 0px 0px 8px 8px; |
|
241 | -webkit-border-radius: 0px 0px 8px 8px; | |
251 | -khtml-border-radius: 0px 0px 8px 8px; |
|
242 | -khtml-border-radius: 0px 0px 8px 8px; | |
252 | -moz-border-radius: 0px 0px 8px 8px; |
|
|||
253 | border-radius: 0px 0px 8px 8px; |
|
243 | border-radius: 0px 0px 8px 8px; | |
254 | height: 37px; |
|
244 | height: 37px; | |
255 | background-color: #003B76; |
|
245 | background-color: #003B76; | |
@@ -260,7 +250,7 b' div:hover > a.permalink {' | |||||
260 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) ); |
|
250 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) ); | |
261 | background-image: -webkit-linear-gradient(top, #003b76, #00376e); |
|
251 | background-image: -webkit-linear-gradient(top, #003b76, #00376e); | |
262 | background-image: -o-linear-gradient(top, #003b76, #00376e); |
|
252 | background-image: -o-linear-gradient(top, #003b76, #00376e); | |
263 |
background-image: linear-gradient(to |
|
253 | background-image: linear-gradient(to bottom, #003b76, #00376e); | |
264 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',endColorstr='#00376e', GradientType=0 ); |
|
254 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',endColorstr='#00376e', GradientType=0 ); | |
265 | box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6); |
|
255 | box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6); | |
266 | } |
|
256 | } | |
@@ -314,19 +304,18 b' div:hover > a.permalink {' | |||||
314 | background-color: #003B76; |
|
304 | background-color: #003B76; | |
315 | opacity: 0.01; |
|
305 | opacity: 0.01; | |
316 | cursor: pointer; |
|
306 | cursor: pointer; | |
317 |
min-height: 10px; |
|
307 | min-height: 10px; | |
318 | width: 100% !important; |
|
308 | width: 100% !important; | |
319 | -webkit-border-radius: 0px 0px 4px 4px; |
|
309 | -webkit-border-radius: 0px 0px 4px 4px; | |
320 | -khtml-border-radius: 0px 0px 4px 4px; |
|
310 | -khtml-border-radius: 0px 0px 4px 4px; | |
321 | -moz-border-radius: 0px 0px 4px 4px; |
|
|||
322 | border-radius: 0px 0px 4px 4px; |
|
311 | border-radius: 0px 0px 4px 4px; | |
323 | } |
|
312 | } | |
324 |
|
313 | |||
325 | #header-dd:hover{ |
|
314 | #header-dd:hover{ | |
326 |
|
|
315 | opacity: 0.2; | |
327 | -webkit-transition: opacity 0.5s ease-in-out; |
|
316 | -webkit-transition: opacity 0.5s ease-in-out; | |
328 | -moz-transition: opacity 0.5s ease-in-out; |
|
317 | -moz-transition: opacity 0.5s ease-in-out; | |
329 |
transition: opacity 0.5s ease-in-out; |
|
318 | transition: opacity 0.5s ease-in-out; | |
330 | } |
|
319 | } | |
331 |
|
320 | |||
332 | #header #header-inner { |
|
321 | #header #header-inner { | |
@@ -341,7 +330,7 b' div:hover > a.permalink {' | |||||
341 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76),color-stop(100%, #00376e) ); |
|
330 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76),color-stop(100%, #00376e) ); | |
342 | background-image: -webkit-linear-gradient(top, #003b76, #00376e); |
|
331 | background-image: -webkit-linear-gradient(top, #003b76, #00376e); | |
343 | background-image: -o-linear-gradient(top, #003b76, #00376e); |
|
332 | background-image: -o-linear-gradient(top, #003b76, #00376e); | |
344 |
background-image: linear-gradient(to |
|
333 | background-image: linear-gradient(to bottom, #003b76, #00376e); | |
345 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',endColorstr='#00376e', GradientType=0 ); |
|
334 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',endColorstr='#00376e', GradientType=0 ); | |
346 | margin: 0; |
|
335 | margin: 0; | |
347 | padding: 0; |
|
336 | padding: 0; | |
@@ -349,17 +338,15 b' div:hover > a.permalink {' | |||||
349 | box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6); |
|
338 | box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6); | |
350 | -webkit-border-radius: 0px 0px 4px 4px; |
|
339 | -webkit-border-radius: 0px 0px 4px 4px; | |
351 | -khtml-border-radius: 0px 0px 4px 4px; |
|
340 | -khtml-border-radius: 0px 0px 4px 4px; | |
352 | -moz-border-radius: 0px 0px 4px 4px; |
|
|||
353 | border-radius: 0px 0px 4px 4px; |
|
341 | border-radius: 0px 0px 4px 4px; | |
354 | } |
|
342 | } | |
355 | #header #header-inner.hover { |
|
343 | #header #header-inner.hover { | |
356 | width: 100% !important; |
|
344 | width: 100% !important; | |
357 | -webkit-border-radius: 0px 0px 0px 0px; |
|
345 | -webkit-border-radius: 0px 0px 0px 0px; | |
358 | -khtml-border-radius: 0px 0px 0px 0px; |
|
346 | -khtml-border-radius: 0px 0px 0px 0px; | |
359 | -moz-border-radius: 0px 0px 0px 0px; |
|
|||
360 | border-radius: 0px 0px 0px 0px; |
|
347 | border-radius: 0px 0px 0px 0px; | |
361 | position: fixed !important; |
|
348 | position: fixed !important; | |
362 |
z-index: 10000; |
|
349 | z-index: 10000; | |
363 | } |
|
350 | } | |
364 |
|
351 | |||
365 | .ie7 #header #header-inner.hover, |
|
352 | .ie7 #header #header-inner.hover, | |
@@ -439,7 +426,6 b' div:hover > a.permalink {' | |||||
439 | padding: 0; |
|
426 | padding: 0; | |
440 | -webkit-border-radius: 4px 4px 4px 4px; |
|
427 | -webkit-border-radius: 4px 4px 4px 4px; | |
441 | -khtml-border-radius: 4px 4px 4px 4px; |
|
428 | -khtml-border-radius: 4px 4px 4px 4px; | |
442 | -moz-border-radius: 4px 4px 4px 4px; |
|
|||
443 | border-radius: 4px 4px 4px 4px; |
|
429 | border-radius: 4px 4px 4px 4px; | |
444 | } |
|
430 | } | |
445 |
|
431 | |||
@@ -1096,7 +1082,6 b' tbody .yui-dt-editable { cursor: pointer' | |||||
1096 | padding: 0 0 10px; |
|
1082 | padding: 0 0 10px; | |
1097 | -webkit-border-radius: 4px 4px 4px 4px; |
|
1083 | -webkit-border-radius: 4px 4px 4px 4px; | |
1098 | -khtml-border-radius: 4px 4px 4px 4px; |
|
1084 | -khtml-border-radius: 4px 4px 4px 4px; | |
1099 | -moz-border-radius: 4px 4px 4px 4px; |
|
|||
1100 | border-radius: 4px 4px 4px 4px; |
|
1085 | border-radius: 4px 4px 4px 4px; | |
1101 | box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6); |
|
1086 | box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6); | |
1102 | } |
|
1087 | } | |
@@ -1126,7 +1111,7 b' tbody .yui-dt-editable { cursor: pointer' | |||||
1126 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) ); |
|
1111 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) ); | |
1127 | background-image: -webkit-linear-gradient(top, #003b76, #00376e); |
|
1112 | background-image: -webkit-linear-gradient(top, #003b76, #00376e); | |
1128 | background-image: -o-linear-gradient(top, #003b76, #00376e); |
|
1113 | background-image: -o-linear-gradient(top, #003b76, #00376e); | |
1129 |
background-image: linear-gradient(to |
|
1114 | background-image: linear-gradient(to bottom, #003b76, #00376e); | |
1130 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76', endColorstr='#00376e', GradientType=0 ); |
|
1115 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76', endColorstr='#00376e', GradientType=0 ); | |
1131 | margin: 0 0 20px; |
|
1116 | margin: 0 0 20px; | |
1132 | padding: 0; |
|
1117 | padding: 0; | |
@@ -1267,7 +1252,7 b' tbody .yui-dt-editable { cursor: pointer' | |||||
1267 | background:-moz-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1)); |
|
1252 | background:-moz-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1)); | |
1268 | background:-o-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1)); |
|
1253 | background:-o-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1)); | |
1269 | background:-ms-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1)); |
|
1254 | background:-ms-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1)); | |
1270 |
background:linear-gradient(to |
|
1255 | background:linear-gradient(to bottom,rgba(255,255,255,0),rgba(64,96,128,0.1)); | |
1271 |
|
1256 | |||
1272 | display: none; |
|
1257 | display: none; | |
1273 | } |
|
1258 | } | |
@@ -1623,7 +1608,6 b' div.form div.fields div.field div.button' | |||||
1623 | padding: 0; |
|
1608 | padding: 0; | |
1624 | border: 1px solid #eee; |
|
1609 | border: 1px solid #eee; | |
1625 | -webkit-border-radius: 4px; |
|
1610 | -webkit-border-radius: 4px; | |
1626 | -moz-border-radius: 4px; |
|
|||
1627 | border-radius: 4px; |
|
1611 | border-radius: 4px; | |
1628 | } |
|
1612 | } | |
1629 |
|
1613 | |||
@@ -1949,7 +1933,6 b' div.form div.fields div.field div.button' | |||||
1949 | margin-right: 1px; |
|
1933 | margin-right: 1px; | |
1950 | -webkit-border-radius: 4px 4px 4px 4px; |
|
1934 | -webkit-border-radius: 4px 4px 4px 4px; | |
1951 | -khtml-border-radius: 4px 4px 4px 4px; |
|
1935 | -khtml-border-radius: 4px 4px 4px 4px; | |
1952 | -moz-border-radius: 4px 4px 4px 4px; |
|
|||
1953 | border-radius: 4px 4px 4px 4px; |
|
1936 | border-radius: 4px 4px 4px 4px; | |
1954 |
|
1937 | |||
1955 | border: solid 1px #9CF; |
|
1938 | border: solid 1px #9CF; | |
@@ -2027,12 +2010,11 b' a.metatag[tag="license"]:hover {' | |||||
2027 | background-image : -webkit-gradient( linear, left top, left bottom, color-stop( 0%, #003b76), color-stop( 100%, #00376e)); |
|
2010 | background-image : -webkit-gradient( linear, left top, left bottom, color-stop( 0%, #003b76), color-stop( 100%, #00376e)); | |
2028 | background-image : -webkit-linear-gradient( top, #003b76, #00376e)); |
|
2011 | background-image : -webkit-linear-gradient( top, #003b76, #00376e)); | |
2029 | background-image : -o-linear-gradient( top, #003b76, #00376e)); |
|
2012 | background-image : -o-linear-gradient( top, #003b76, #00376e)); | |
2030 |
background-image : linear-gradient( |
|
2013 | background-image : linear-gradient(to bottom, #003b76, #00376e); | |
2031 | filter :progid : DXImageTransform.Microsoft.gradient ( startColorstr = '#003b76', endColorstr = '#00376e', GradientType = 0); |
|
2014 | filter :progid : DXImageTransform.Microsoft.gradient ( startColorstr = '#003b76', endColorstr = '#00376e', GradientType = 0); | |
2032 | box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6); |
|
2015 | box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6); | |
2033 | -webkit-border-radius: 4px 4px 4px 4px; |
|
2016 | -webkit-border-radius: 4px 4px 4px 4px; | |
2034 | -khtml-border-radius: 4px 4px 4px 4px; |
|
2017 | -khtml-border-radius: 4px 4px 4px 4px; | |
2035 | -moz-border-radius: 4px 4px 4px 4px; |
|
|||
2036 | border-radius: 4px 4px 4px 4px; |
|
2018 | border-radius: 4px 4px 4px 4px; | |
2037 | } |
|
2019 | } | |
2038 |
|
2020 | |||
@@ -2063,7 +2045,7 b' a.metatag[tag="license"]:hover {' | |||||
2063 | background-image : -webkit-gradient( linear, left top, left bottom, color-stop( 0%, #003b76), color-stop( 100%, #00376e)); |
|
2045 | background-image : -webkit-gradient( linear, left top, left bottom, color-stop( 0%, #003b76), color-stop( 100%, #00376e)); | |
2064 | background-image : -webkit-linear-gradient( top, #003b76, #00376e)); |
|
2046 | background-image : -webkit-linear-gradient( top, #003b76, #00376e)); | |
2065 | background-image : -o-linear-gradient( top, #003b76, #00376e)); |
|
2047 | background-image : -o-linear-gradient( top, #003b76, #00376e)); | |
2066 |
background-image : linear-gradient( |
|
2048 | background-image : linear-gradient(to bottom, #003b76, #00376e); | |
2067 | filter : progid : DXImageTransform.Microsoft.gradient ( startColorstr = '#003b76', endColorstr = '#00376e', GradientType = 0); |
|
2049 | filter : progid : DXImageTransform.Microsoft.gradient ( startColorstr = '#003b76', endColorstr = '#00376e', GradientType = 0); | |
2068 | margin: 0 auto; |
|
2050 | margin: 0 auto; | |
2069 | padding: 0; |
|
2051 | padding: 0; | |
@@ -2147,13 +2129,12 b' a.metatag[tag="license"]:hover {' | |||||
2147 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) ); |
|
2129 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) ); | |
2148 | background-image: -webkit-linear-gradient(top, #003b76, #00376e); |
|
2130 | background-image: -webkit-linear-gradient(top, #003b76, #00376e); | |
2149 | background-image: -o-linear-gradient(top, #003b76, #00376e); |
|
2131 | background-image: -o-linear-gradient(top, #003b76, #00376e); | |
2150 |
background-image: linear-gradient(to |
|
2132 | background-image: linear-gradient(to bottom, #003b76, #00376e); | |
2151 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76', endColorstr='#00376e', GradientType=0 ); |
|
2133 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76', endColorstr='#00376e', GradientType=0 ); | |
2152 |
|
2134 | |||
2153 | z-index: 999; |
|
2135 | z-index: 999; | |
2154 | -webkit-border-radius: 0px 0px 4px 4px; |
|
2136 | -webkit-border-radius: 0px 0px 4px 4px; | |
2155 | -khtml-border-radius: 0px 0px 4px 4px; |
|
2137 | -khtml-border-radius: 0px 0px 4px 4px; | |
2156 | -moz-border-radius: 0px 0px 4px 4px; |
|
|||
2157 | border-radius: 0px 0px 4px 4px; |
|
2138 | border-radius: 0px 0px 4px 4px; | |
2158 | box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6); |
|
2139 | box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6); | |
2159 | } |
|
2140 | } | |
@@ -2213,7 +2194,7 b' a.metatag[tag="license"]:hover {' | |||||
2213 | #quick_login .unread a { |
|
2194 | #quick_login .unread a { | |
2214 | color: #FFFFFF; |
|
2195 | color: #FFFFFF; | |
2215 | display: block; |
|
2196 | display: block; | |
2216 |
padding: 2px; |
|
2197 | padding: 2px; | |
2217 | } |
|
2198 | } | |
2218 | #quick_login .notifications a:hover, |
|
2199 | #quick_login .notifications a:hover, | |
2219 | #quick_login .unread a:hover { |
|
2200 | #quick_login .unread a:hover { | |
@@ -2304,7 +2285,7 b' a.metatag[tag="license"]:hover {' | |||||
2304 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) ); |
|
2285 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) ); | |
2305 | background-image: -webkit-linear-gradient(top, #003b76, #00376e); |
|
2286 | background-image: -webkit-linear-gradient(top, #003b76, #00376e); | |
2306 | background-image: -o-linear-gradient(top, #003b76, #00376e); |
|
2287 | background-image: -o-linear-gradient(top, #003b76, #00376e); | |
2307 |
background-image: linear-gradient(to |
|
2288 | background-image: linear-gradient(to bottom, #003b76, #00376e); | |
2308 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76', |
|
2289 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76', | |
2309 | endColorstr='#00376e', GradientType=0 ); |
|
2290 | endColorstr='#00376e', GradientType=0 ); | |
2310 | margin: 0 auto; |
|
2291 | margin: 0 auto; | |
@@ -2780,7 +2761,6 b' h3.files_location {' | |||||
2780 | color: #444444; |
|
2761 | color: #444444; | |
2781 | background: #FEA; |
|
2762 | background: #FEA; | |
2782 | -webkit-border-radius: 0px 0px 0px 6px; |
|
2763 | -webkit-border-radius: 0px 0px 0px 6px; | |
2783 | -moz-border-radius: 0px 0px 0px 6px; |
|
|||
2784 | border-radius: 0px 0px 0px 6px; |
|
2764 | border-radius: 0px 0px 0px 6px; | |
2785 | padding: 1px; |
|
2765 | padding: 1px; | |
2786 | } |
|
2766 | } | |
@@ -2815,7 +2795,6 b' h3.files_location {' | |||||
2815 | text-transform: uppercase; |
|
2795 | text-transform: uppercase; | |
2816 | white-space: nowrap; |
|
2796 | white-space: nowrap; | |
2817 | -webkit-border-radius: 3px; |
|
2797 | -webkit-border-radius: 3px; | |
2818 | -moz-border-radius: 3px; |
|
|||
2819 | border-radius: 3px; |
|
2798 | border-radius: 3px; | |
2820 | margin-right: 2px; |
|
2799 | margin-right: 2px; | |
2821 | } |
|
2800 | } | |
@@ -2841,7 +2820,6 b' h3.files_location {' | |||||
2841 | color: #ffffff; |
|
2820 | color: #ffffff; | |
2842 | white-space: nowrap; |
|
2821 | white-space: nowrap; | |
2843 | -webkit-border-radius: 3px; |
|
2822 | -webkit-border-radius: 3px; | |
2844 | -moz-border-radius: 3px; |
|
|||
2845 | border-radius: 3px; |
|
2823 | border-radius: 3px; | |
2846 | } |
|
2824 | } | |
2847 | .right .logtags .branchtag a:hover, .logtags .branchtag a { |
|
2825 | .right .logtags .branchtag a:hover, .logtags .branchtag a { | |
@@ -2859,7 +2837,6 b' h3.files_location {' | |||||
2859 | color: #ffffff; |
|
2837 | color: #ffffff; | |
2860 | white-space: nowrap; |
|
2838 | white-space: nowrap; | |
2861 | -webkit-border-radius: 3px; |
|
2839 | -webkit-border-radius: 3px; | |
2862 | -moz-border-radius: 3px; |
|
|||
2863 | border-radius: 3px; |
|
2840 | border-radius: 3px; | |
2864 | } |
|
2841 | } | |
2865 | .right .logtags .tagtag a:hover, .logtags .tagtag a { |
|
2842 | .right .logtags .tagtag a:hover, .logtags .tagtag a { | |
@@ -2878,7 +2855,6 b' h3.files_location {' | |||||
2878 | text-transform: uppercase; |
|
2855 | text-transform: uppercase; | |
2879 | white-space: nowrap; |
|
2856 | white-space: nowrap; | |
2880 | -webkit-border-radius: 3px; |
|
2857 | -webkit-border-radius: 3px; | |
2881 | -moz-border-radius: 3px; |
|
|||
2882 | border-radius: 3px; |
|
2858 | border-radius: 3px; | |
2883 | } |
|
2859 | } | |
2884 | .right .logbooks .bookbook, .logbooks .bookbook a, .right .logtags .bookbook, .logtags .bookbook a { |
|
2860 | .right .logbooks .bookbook, .logbooks .bookbook a, .right .logtags .bookbook, .logtags .bookbook a { | |
@@ -2896,7 +2872,6 b' div.browserblock {' | |||||
2896 | line-height: 125%; |
|
2872 | line-height: 125%; | |
2897 | padding: 0; |
|
2873 | padding: 0; | |
2898 | -webkit-border-radius: 6px 6px 0px 0px; |
|
2874 | -webkit-border-radius: 6px 6px 0px 0px; | |
2899 | -moz-border-radius: 6px 6px 0px 0px; |
|
|||
2900 | border-radius: 6px 6px 0px 0px; |
|
2875 | border-radius: 6px 6px 0px 0px; | |
2901 | } |
|
2876 | } | |
2902 |
|
2877 | |||
@@ -3109,16 +3084,14 b' table.code-browser .submodule-dir {' | |||||
3109 | border: 2px solid #003367; |
|
3084 | border: 2px solid #003367; | |
3110 | font: 100% sans-serif; |
|
3085 | font: 100% sans-serif; | |
3111 | width: auto; |
|
3086 | width: auto; | |
3112 |
opacity: 1 |
|
3087 | opacity: 1; | |
3113 | padding: 8px; |
|
3088 | padding: 8px; | |
3114 |
|
3089 | |||
3115 | white-space: pre-wrap; |
|
3090 | white-space: pre-wrap; | |
3116 | -webkit-border-radius: 8px 8px 8px 8px; |
|
3091 | -webkit-border-radius: 8px 8px 8px 8px; | |
3117 | -khtml-border-radius: 8px 8px 8px 8px; |
|
3092 | -khtml-border-radius: 8px 8px 8px 8px; | |
3118 | -moz-border-radius: 8px 8px 8px 8px; |
|
|||
3119 | border-radius: 8px 8px 8px 8px; |
|
3093 | border-radius: 8px 8px 8px 8px; | |
3120 | box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6); |
|
3094 | box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6); | |
3121 | -moz-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6); |
|
|||
3122 | -webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6); |
|
3095 | -webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6); | |
3123 | } |
|
3096 | } | |
3124 |
|
3097 | |||
@@ -3130,12 +3103,11 b' table.code-browser .submodule-dir {' | |||||
3130 | border: 2px solid #003367; |
|
3103 | border: 2px solid #003367; | |
3131 | font: 100% sans-serif; |
|
3104 | font: 100% sans-serif; | |
3132 | width: auto; |
|
3105 | width: auto; | |
3133 |
opacity: 1 |
|
3106 | opacity: 1; | |
3134 | padding: 8px; |
|
3107 | padding: 8px; | |
3135 | white-space: pre-wrap; |
|
3108 | white-space: pre-wrap; | |
3136 | -webkit-border-radius: 8px 8px 8px 8px; |
|
3109 | -webkit-border-radius: 8px 8px 8px 8px; | |
3137 | -khtml-border-radius: 8px 8px 8px 8px; |
|
3110 | -khtml-border-radius: 8px 8px 8px 8px; | |
3138 | -moz-border-radius: 8px 8px 8px 8px; |
|
|||
3139 | border-radius: 8px 8px 8px 8px; |
|
3111 | border-radius: 8px 8px 8px 8px; | |
3140 | box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6); |
|
3112 | box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6); | |
3141 | } |
|
3113 | } | |
@@ -3182,7 +3154,6 b' table.code-browser .submodule-dir {' | |||||
3182 | position: absolute; |
|
3154 | position: absolute; | |
3183 | width: 100%; |
|
3155 | width: 100%; | |
3184 | background: #000; |
|
3156 | background: #000; | |
3185 | -moz-opacity: 0.1px; |
|
|||
3186 | opacity: .10; |
|
3157 | opacity: .10; | |
3187 | filter: alpha(opacity = 10); |
|
3158 | filter: alpha(opacity = 10); | |
3188 | z-index: 9049; |
|
3159 | z-index: 9049; | |
@@ -3428,7 +3399,7 b' table.code-browser .submodule-dir {' | |||||
3428 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35) ); |
|
3399 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35) ); | |
3429 | background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); |
|
3400 | background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); | |
3430 | background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); |
|
3401 | background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); | |
3431 |
background-image: linear-gradient(to |
|
3402 | background-image: linear-gradient(to bottom, #ee5f5b, #c43c35); | |
3432 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b',endColorstr='#c43c35', GradientType=0 ); |
|
3403 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b',endColorstr='#c43c35', GradientType=0 ); | |
3433 | border-color: #c43c35 #c43c35 #882a25; |
|
3404 | border-color: #c43c35 #c43c35 #882a25; | |
3434 | } |
|
3405 | } | |
@@ -3443,7 +3414,7 b' table.code-browser .submodule-dir {' | |||||
3443 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fceec1), color-stop(100%, #eedc94) ); |
|
3414 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fceec1), color-stop(100%, #eedc94) ); | |
3444 | background-image: -webkit-linear-gradient(top, #fceec1, #eedc94); |
|
3415 | background-image: -webkit-linear-gradient(top, #fceec1, #eedc94); | |
3445 | background-image: -o-linear-gradient(top, #fceec1, #eedc94); |
|
3416 | background-image: -o-linear-gradient(top, #fceec1, #eedc94); | |
3446 |
background-image: linear-gradient(to |
|
3417 | background-image: linear-gradient(to bottom, #fceec1, #eedc94); | |
3447 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fceec1', endColorstr='#eedc94', GradientType=0 ); |
|
3418 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fceec1', endColorstr='#eedc94', GradientType=0 ); | |
3448 | border-color: #eedc94 #eedc94 #e4c652; |
|
3419 | border-color: #eedc94 #eedc94 #e4c652; | |
3449 | } |
|
3420 | } | |
@@ -3457,7 +3428,7 b' table.code-browser .submodule-dir {' | |||||
3457 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957) ); |
|
3428 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957) ); | |
3458 | background-image: -webkit-linear-gradient(top, #62c462, #57a957); |
|
3429 | background-image: -webkit-linear-gradient(top, #62c462, #57a957); | |
3459 | background-image: -o-linear-gradient(top, #62c462, #57a957); |
|
3430 | background-image: -o-linear-gradient(top, #62c462, #57a957); | |
3460 |
background-image: linear-gradient(to |
|
3431 | background-image: linear-gradient(to bottom, #62c462, #57a957); | |
3461 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0 ); |
|
3432 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0 ); | |
3462 | border-color: #57a957 #57a957 #3d773d; |
|
3433 | border-color: #57a957 #57a957 #3d773d; | |
3463 | } |
|
3434 | } | |
@@ -3471,7 +3442,7 b' table.code-browser .submodule-dir {' | |||||
3471 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9) ); |
|
3442 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9) ); | |
3472 | background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); |
|
3443 | background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); | |
3473 | background-image: -o-linear-gradient(top, #5bc0de, #339bb9); |
|
3444 | background-image: -o-linear-gradient(top, #5bc0de, #339bb9); | |
3474 |
background-image: linear-gradient(to |
|
3445 | background-image: linear-gradient(to bottom, #5bc0de, #339bb9); | |
3475 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0 ); |
|
3446 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0 ); | |
3476 | border-color: #339bb9 #339bb9 #22697d; |
|
3447 | border-color: #339bb9 #339bb9 #22697d; | |
3477 | } |
|
3448 | } | |
@@ -3492,10 +3463,8 b' table.code-browser .submodule-dir {' | |||||
3492 | border-width: 1px; |
|
3463 | border-width: 1px; | |
3493 | border-style: solid; |
|
3464 | border-style: solid; | |
3494 | -webkit-border-radius: 4px; |
|
3465 | -webkit-border-radius: 4px; | |
3495 | -moz-border-radius: 4px; |
|
|||
3496 | border-radius: 4px; |
|
3466 | border-radius: 4px; | |
3497 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); |
|
3467 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); | |
3498 | -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); |
|
|||
3499 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); |
|
3468 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); | |
3500 | } |
|
3469 | } | |
3501 |
|
3470 | |||
@@ -3524,7 +3493,7 b' table#permissions_manage {' | |||||
3524 |
|
3493 | |||
3525 | table#permissions_manage span.private_repo_msg { |
|
3494 | table#permissions_manage span.private_repo_msg { | |
3526 | font-size: 0.8em; |
|
3495 | font-size: 0.8em; | |
3527 |
opacity: 0.6 |
|
3496 | opacity: 0.6; | |
3528 | } |
|
3497 | } | |
3529 |
|
3498 | |||
3530 | table#permissions_manage td.private_repo_msg { |
|
3499 | table#permissions_manage td.private_repo_msg { | |
@@ -3543,14 +3512,12 b' div.gravatar {' | |||||
3543 | line-height:0; |
|
3512 | line-height:0; | |
3544 | -webkit-border-radius: 3px; |
|
3513 | -webkit-border-radius: 3px; | |
3545 | -khtml-border-radius: 3px; |
|
3514 | -khtml-border-radius: 3px; | |
3546 | -moz-border-radius: 3px; |
|
|||
3547 | border-radius: 3px; |
|
3515 | border-radius: 3px; | |
3548 | } |
|
3516 | } | |
3549 |
|
3517 | |||
3550 | div.gravatar img { |
|
3518 | div.gravatar img { | |
3551 | -webkit-border-radius: 2px; |
|
3519 | -webkit-border-radius: 2px; | |
3552 | -khtml-border-radius: 2px; |
|
3520 | -khtml-border-radius: 2px; | |
3553 | -moz-border-radius: 2px; |
|
|||
3554 | border-radius: 2px; |
|
3521 | border-radius: 2px; | |
3555 | } |
|
3522 | } | |
3556 |
|
3523 | |||
@@ -3586,7 +3553,7 b' div.gravatar img {' | |||||
3586 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4),color-stop(100%, #DADADA) ); |
|
3553 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4),color-stop(100%, #DADADA) ); | |
3587 | background-image: -webkit-linear-gradient(top, #F4F4F4, #DADADA) ); |
|
3554 | background-image: -webkit-linear-gradient(top, #F4F4F4, #DADADA) ); | |
3588 | background-image: -o-linear-gradient(top, #F4F4F4, #DADADA) ); |
|
3555 | background-image: -o-linear-gradient(top, #F4F4F4, #DADADA) ); | |
3589 |
background-image: linear-gradient(to |
|
3556 | background-image: linear-gradient(to bottom, #F4F4F4, #DADADA); | |
3590 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#F4F4F4', endColorstr='#DADADA', GradientType=0); |
|
3557 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#F4F4F4', endColorstr='#DADADA', GradientType=0); | |
3591 |
|
3558 | |||
3592 | border-top: 1px solid #DDD; |
|
3559 | border-top: 1px solid #DDD; | |
@@ -3598,7 +3565,6 b' div.gravatar img {' | |||||
3598 | margin: 0px 3px 3px 0px; |
|
3565 | margin: 0px 3px 3px 0px; | |
3599 | -webkit-border-radius: 4px 4px 4px 4px !important; |
|
3566 | -webkit-border-radius: 4px 4px 4px 4px !important; | |
3600 | -khtml-border-radius: 4px 4px 4px 4px !important; |
|
3567 | -khtml-border-radius: 4px 4px 4px 4px !important; | |
3601 | -moz-border-radius: 4px 4px 4px 4px !important; |
|
|||
3602 | border-radius: 4px 4px 4px 4px !important; |
|
3568 | border-radius: 4px 4px 4px 4px !important; | |
3603 | cursor: pointer !important; |
|
3569 | cursor: pointer !important; | |
3604 | padding: 3px 3px 3px 3px; |
|
3570 | padding: 3px 3px 3px 3px; | |
@@ -3623,7 +3589,6 b' div.gravatar img {' | |||||
3623 | margin: 0px 0px 3px -4px; |
|
3589 | margin: 0px 0px 3px -4px; | |
3624 | -webkit-border-radius: 0px 4px 4px 0px !important; |
|
3590 | -webkit-border-radius: 0px 4px 4px 0px !important; | |
3625 | -khtml-border-radius: 0px 4px 4px 0px !important; |
|
3591 | -khtml-border-radius: 0px 4px 4px 0px !important; | |
3626 | -moz-border-radius: 0px 4px 4px 0px !important; |
|
|||
3627 | border-radius: 0px 4px 4px 0px !important; |
|
3592 | border-radius: 0px 4px 4px 0px !important; | |
3628 | width: 100px; |
|
3593 | width: 100px; | |
3629 | text-align: center; |
|
3594 | text-align: center; | |
@@ -3642,7 +3607,7 b' div.gravatar img {' | |||||
3642 | } |
|
3607 | } | |
3643 |
|
3608 | |||
3644 | .ui-btn.disabled:hover { |
|
3609 | .ui-btn.disabled:hover { | |
3645 |
background-position: |
|
3610 | background-position: 0; | |
3646 | color: #999; |
|
3611 | color: #999; | |
3647 | text-decoration: none; |
|
3612 | text-decoration: none; | |
3648 | box-shadow: none !important; |
|
3613 | box-shadow: none !important; | |
@@ -3658,7 +3623,7 b' div.gravatar img {' | |||||
3658 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35)); |
|
3623 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35)); | |
3659 | background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); |
|
3624 | background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); | |
3660 | background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); |
|
3625 | background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); | |
3661 |
background-image: linear-gradient(to |
|
3626 | background-image: linear-gradient(to bottom, #ee5f5b, #c43c35); | |
3662 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0); |
|
3627 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0); | |
3663 | border-color: #c43c35 #c43c35 #882a25; |
|
3628 | border-color: #c43c35 #c43c35 #882a25; | |
3664 | border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); |
|
3629 | border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); | |
@@ -3675,7 +3640,7 b' div.gravatar img {' | |||||
3675 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9)); |
|
3640 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9)); | |
3676 | background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); |
|
3641 | background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); | |
3677 | background-image: -o-linear-gradient(top, #5bc0de, #339bb9); |
|
3642 | background-image: -o-linear-gradient(top, #5bc0de, #339bb9); | |
3678 |
background-image: linear-gradient(to |
|
3643 | background-image: linear-gradient(to bottom, #5bc0de, #339bb9); | |
3679 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0); |
|
3644 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0); | |
3680 | border-color: #339bb9 #339bb9 #22697d; |
|
3645 | border-color: #339bb9 #339bb9 #22697d; | |
3681 | border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); |
|
3646 | border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); | |
@@ -3690,7 +3655,7 b' div.gravatar img {' | |||||
3690 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957)); |
|
3655 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957)); | |
3691 | background-image: -webkit-linear-gradient(top, #62c462, #57a957); |
|
3656 | background-image: -webkit-linear-gradient(top, #62c462, #57a957); | |
3692 | background-image: -o-linear-gradient(top, #62c462, #57a957); |
|
3657 | background-image: -o-linear-gradient(top, #62c462, #57a957); | |
3693 |
background-image: linear-gradient(to |
|
3658 | background-image: linear-gradient(to bottom, #62c462, #57a957); | |
3694 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0); |
|
3659 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0); | |
3695 | border-color: #57a957 #57a957 #3d773d; |
|
3660 | border-color: #57a957 #57a957 #3d773d; | |
3696 | border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); |
|
3661 | border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); | |
@@ -3864,7 +3829,6 b' input.ui-button {' | |||||
3864 | padding: 6px 12px; |
|
3829 | padding: 6px 12px; | |
3865 | -webkit-border-radius: 4px 4px 4px 4px; |
|
3830 | -webkit-border-radius: 4px 4px 4px 4px; | |
3866 | -khtml-border-radius: 4px 4px 4px 4px; |
|
3831 | -khtml-border-radius: 4px 4px 4px 4px; | |
3867 | -moz-border-radius: 4px 4px 4px 4px; |
|
|||
3868 | border-radius: 4px 4px 4px 4px; |
|
3832 | border-radius: 4px 4px 4px 4px; | |
3869 | box-shadow: 0 1px 0 #ececec; |
|
3833 | box-shadow: 0 1px 0 #ececec; | |
3870 | cursor: pointer; |
|
3834 | cursor: pointer; | |
@@ -3996,6 +3960,10 b' div.form div.fields div.field div.highli' | |||||
3996 | padding: 0; |
|
3960 | padding: 0; | |
3997 | } |
|
3961 | } | |
3998 |
|
3962 | |||
|
3963 | #login div.form div.fields div.field div.input input.large { | |||
|
3964 | width: 250px; | |||
|
3965 | } | |||
|
3966 | ||||
3999 | #login div.form div.fields div.field div.checkbox, #register div.form div.fields div.field div.checkbox { |
|
3967 | #login div.form div.fields div.field div.checkbox, #register div.form div.fields div.field div.checkbox { | |
4000 | margin: 0 0 0 184px; |
|
3968 | margin: 0 0 0 184px; | |
4001 | padding: 0; |
|
3969 | padding: 0; | |
@@ -4038,7 +4006,6 b' div#legend_container table td, div#legen' | |||||
4038 | .q_filter_box { |
|
4006 | .q_filter_box { | |
4039 | -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset; |
|
4007 | -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset; | |
4040 | -webkit-border-radius: 4px; |
|
4008 | -webkit-border-radius: 4px; | |
4041 | -moz-border-radius: 4px; |
|
|||
4042 | border-radius: 4px; |
|
4009 | border-radius: 4px; | |
4043 | border: 0 none; |
|
4010 | border: 0 none; | |
4044 | color: #AAAAAA; |
|
4011 | color: #AAAAAA; | |
@@ -4188,7 +4155,6 b' div.readme .readme_box pre {' | |||||
4188 | overflow: auto; |
|
4155 | overflow: auto; | |
4189 | -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset; |
|
4156 | -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset; | |
4190 | -webkit-border-radius: 3px; |
|
4157 | -webkit-border-radius: 3px; | |
4191 | -moz-border-radius: 3px; |
|
|||
4192 | border-radius: 3px; |
|
4158 | border-radius: 3px; | |
4193 | } |
|
4159 | } | |
4194 |
|
4160 | |||
@@ -4290,7 +4256,6 b' div.rst-block pre {' | |||||
4290 | overflow: auto; |
|
4256 | overflow: auto; | |
4291 | -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset; |
|
4257 | -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset; | |
4292 | -webkit-border-radius: 3px; |
|
4258 | -webkit-border-radius: 3px; | |
4293 | -moz-border-radius: 3px; |
|
|||
4294 | border-radius: 3px; |
|
4259 | border-radius: 3px; | |
4295 | } |
|
4260 | } | |
4296 |
|
4261 | |||
@@ -4304,7 +4269,6 b' div.rst-block pre {' | |||||
4304 | border: 1px solid #ddd; |
|
4269 | border: 1px solid #ddd; | |
4305 | margin-top: 10px; |
|
4270 | margin-top: 10px; | |
4306 | -webkit-border-radius: 4px; |
|
4271 | -webkit-border-radius: 4px; | |
4307 | -moz-border-radius: 4px; |
|
|||
4308 | border-radius: 4px; |
|
4272 | border-radius: 4px; | |
4309 | } |
|
4273 | } | |
4310 |
|
4274 | |||
@@ -4354,7 +4318,6 b' div.rst-block pre {' | |||||
4354 | .comment-form .clearfix { |
|
4318 | .comment-form .clearfix { | |
4355 | background: #EEE; |
|
4319 | background: #EEE; | |
4356 | -webkit-border-radius: 4px; |
|
4320 | -webkit-border-radius: 4px; | |
4357 | -moz-border-radius: 4px; |
|
|||
4358 | border-radius: 4px; |
|
4321 | border-radius: 4px; | |
4359 | padding: 10px; |
|
4322 | padding: 10px; | |
4360 | } |
|
4323 | } | |
@@ -4440,7 +4403,6 b' form.comment-form {' | |||||
4440 | .comment-inline-form .clearfix { |
|
4403 | .comment-inline-form .clearfix { | |
4441 | background: #EEE; |
|
4404 | background: #EEE; | |
4442 | -webkit-border-radius: 4px; |
|
4405 | -webkit-border-radius: 4px; | |
4443 | -moz-border-radius: 4px; |
|
|||
4444 | border-radius: 4px; |
|
4406 | border-radius: 4px; | |
4445 | padding: 5px; |
|
4407 | padding: 5px; | |
4446 | } |
|
4408 | } | |
@@ -4517,7 +4479,6 b' form.comment-inline-form {' | |||||
4517 | .inline-comments .comment { |
|
4479 | .inline-comments .comment { | |
4518 | border: 1px solid #ddd; |
|
4480 | border: 1px solid #ddd; | |
4519 | -webkit-border-radius: 4px; |
|
4481 | -webkit-border-radius: 4px; | |
4520 | -moz-border-radius: 4px; |
|
|||
4521 | border-radius: 4px; |
|
4482 | border-radius: 4px; | |
4522 | margin: 3px 3px 5px 5px; |
|
4483 | margin: 3px 3px 5px 5px; | |
4523 | background-color: #FAFAFA; |
|
4484 | background-color: #FAFAFA; | |
@@ -4584,7 +4545,6 b' form.comment-inline-form {' | |||||
4584 | background-color: #DEDEDE !important; |
|
4545 | background-color: #DEDEDE !important; | |
4585 | border-radius: 4px !important; |
|
4546 | border-radius: 4px !important; | |
4586 | -webkit-border-radius: 4px !important; |
|
4547 | -webkit-border-radius: 4px !important; | |
4587 | -moz-border-radius: 4px !important; |
|
|||
4588 | } |
|
4548 | } | |
4589 |
|
4549 | |||
4590 | .notification-header { |
|
4550 | .notification-header { | |
@@ -4609,7 +4569,6 b' form.comment-inline-form {' | |||||
4609 | .notification-table { |
|
4569 | .notification-table { | |
4610 | border: 1px solid #ccc; |
|
4570 | border: 1px solid #ccc; | |
4611 | -webkit-border-radius: 6px 6px 6px 6px; |
|
4571 | -webkit-border-radius: 6px 6px 6px 6px; | |
4612 | -moz-border-radius: 6px 6px 6px 6px; |
|
|||
4613 | border-radius: 6px 6px 6px 6px; |
|
4572 | border-radius: 6px 6px 6px 6px; | |
4614 | clear: both; |
|
4573 | clear: both; | |
4615 | margin: 0px 20px 0px 20px; |
|
4574 | margin: 0px 20px 0px 20px; | |
@@ -4660,7 +4619,6 b' PULL REQUESTS' | |||||
4660 | text-transform: uppercase; |
|
4619 | text-transform: uppercase; | |
4661 | white-space: nowrap; |
|
4620 | white-space: nowrap; | |
4662 | -webkit-border-radius: 3px; |
|
4621 | -webkit-border-radius: 3px; | |
4663 | -moz-border-radius: 3px; |
|
|||
4664 | border-radius: 3px; |
|
4622 | border-radius: 3px; | |
4665 | } |
|
4623 | } | |
4666 |
|
4624 | |||
@@ -4698,6 +4656,24 b' PULL REQUESTS' | |||||
4698 | /***************************************************************************** |
|
4656 | /***************************************************************************** | |
4699 | DIFFS CSS |
|
4657 | DIFFS CSS | |
4700 | ******************************************************************************/ |
|
4658 | ******************************************************************************/ | |
|
4659 | .diff-collapse{ | |||
|
4660 | text-align: center; | |||
|
4661 | margin-bottom: -15px; | |||
|
4662 | } | |||
|
4663 | .diff-collapse-button{ | |||
|
4664 | cursor: pointer; | |||
|
4665 | color: #666; | |||
|
4666 | font-size: 16px; | |||
|
4667 | } | |||
|
4668 | .diff-container { | |||
|
4669 | ||||
|
4670 | } | |||
|
4671 | ||||
|
4672 | .diff-container.hidden{ | |||
|
4673 | display: none; | |||
|
4674 | overflow: hidden; | |||
|
4675 | } | |||
|
4676 | ||||
4701 |
|
4677 | |||
4702 | div.diffblock { |
|
4678 | div.diffblock { | |
4703 | overflow: auto; |
|
4679 | overflow: auto; | |
@@ -4709,7 +4685,6 b' div.diffblock {' | |||||
4709 | /* new */ |
|
4685 | /* new */ | |
4710 | line-height: 125%; |
|
4686 | line-height: 125%; | |
4711 | -webkit-border-radius: 6px 6px 0px 0px; |
|
4687 | -webkit-border-radius: 6px 6px 0px 0px; | |
4712 | -moz-border-radius: 6px 6px 0px 0px; |
|
|||
4713 | border-radius: 6px 6px 0px 0px; |
|
4688 | border-radius: 6px 6px 0px 0px; | |
4714 | } |
|
4689 | } | |
4715 | div.diffblock.margined { |
|
4690 | div.diffblock.margined { | |
@@ -4787,12 +4762,13 b' div.diffblock pre.raw {' | |||||
4787 | table.code-difftable { |
|
4762 | table.code-difftable { | |
4788 | border-collapse: collapse; |
|
4763 | border-collapse: collapse; | |
4789 | width: 99%; |
|
4764 | width: 99%; | |
|
4765 | border-radius: 0px !important; | |||
4790 | } |
|
4766 | } | |
4791 | table.code-difftable td { |
|
4767 | table.code-difftable td { | |
4792 | padding: 0 !important; |
|
4768 | padding: 0 !important; | |
4793 | background: none !important; |
|
4769 | background: none !important; | |
4794 | border:0 !important; |
|
4770 | border:0 !important; | |
4795 |
vertical-align: |
|
4771 | vertical-align: baseline !important | |
4796 | } |
|
4772 | } | |
4797 | table.code-difftable .context { |
|
4773 | table.code-difftable .context { | |
4798 | background:none repeat scroll 0 0 #DDE7EF; |
|
4774 | background:none repeat scroll 0 0 #DDE7EF; | |
@@ -4887,3 +4863,8 b' table.code-difftable .code pre {' | |||||
4887 | div.comment:target>.comment-wrapp { |
|
4863 | div.comment:target>.comment-wrapp { | |
4888 | border: solid 2px #ee0 !important; |
|
4864 | border: solid 2px #ee0 !important; | |
4889 | } |
|
4865 | } | |
|
4866 | ||||
|
4867 | .lineno:target a { | |||
|
4868 | border: solid 2px #ee0 !important; | |||
|
4869 | margin: -2px; | |||
|
4870 | } |
@@ -302,12 +302,25 b' var pyroutes = (function() {' | |||||
302 | } |
|
302 | } | |
303 | if (matchlist.hasOwnProperty(route_name)) { |
|
303 | if (matchlist.hasOwnProperty(route_name)) { | |
304 | var route = matchlist[route_name]; |
|
304 | var route = matchlist[route_name]; | |
|
305 | // param substitution | |||
305 | for(var i=0; i < route[1].length; i++) { |
|
306 | for(var i=0; i < route[1].length; i++) { | |
306 |
|
307 | |||
307 | if (!params.hasOwnProperty(route[1][i])) |
|
308 | if (!params.hasOwnProperty(route[1][i])) | |
308 | throw new Error(route[1][i] + ' missing in "' + route_name + '" route generation'); |
|
309 | throw new Error(route[1][i] + ' missing in "' + route_name + '" route generation'); | |
309 | } |
|
310 | } | |
310 | result = sprintf(route[0], params); |
|
311 | result = sprintf(route[0], params); | |
|
312 | ||||
|
313 | var ret = []; | |||
|
314 | //extra params => GET | |||
|
315 | for(param in params){ | |||
|
316 | if (route[1].indexOf(param) == -1){ | |||
|
317 | ret.push(encodeURIComponent(param) + "=" + encodeURIComponent(params[param])); | |||
|
318 | } | |||
|
319 | } | |||
|
320 | var _parts = ret.join("&"); | |||
|
321 | if(_parts){ | |||
|
322 | result = result +'?'+ _parts | |||
|
323 | } | |||
311 | } |
|
324 | } | |
312 |
|
325 | |||
313 | return result; |
|
326 | return result; | |
@@ -1289,7 +1302,7 b' var MembersAutoComplete = function (divi' | |||||
1289 | return matches; |
|
1302 | return matches; | |
1290 | }; |
|
1303 | }; | |
1291 |
|
1304 | |||
1292 |
// Define a custom search function for the DataSource of user |
|
1305 | // Define a custom search function for the DataSource of userGroups | |
1293 | var matchGroups = function (sQuery) { |
|
1306 | var matchGroups = function (sQuery) { | |
1294 | // Case insensitive matching |
|
1307 | // Case insensitive matching | |
1295 | var query = sQuery.toLowerCase(); |
|
1308 | var query = sQuery.toLowerCase(); | |
@@ -1707,7 +1720,7 b' var PullRequestAutoComplete = function (' | |||||
1707 | return matches; |
|
1720 | return matches; | |
1708 | }; |
|
1721 | }; | |
1709 |
|
1722 | |||
1710 |
// Define a custom search function for the DataSource of user |
|
1723 | // Define a custom search function for the DataSource of userGroups | |
1711 | var matchGroups = function (sQuery) { |
|
1724 | var matchGroups = function (sQuery) { | |
1712 | // Case insensitive matching |
|
1725 | // Case insensitive matching | |
1713 | var query = sQuery.toLowerCase(); |
|
1726 | var query = sQuery.toLowerCase(); | |
@@ -2149,3 +2162,26 b' var MultiSelectWidget = function(selecte' | |||||
2149 | }); |
|
2162 | }); | |
2150 | } |
|
2163 | } | |
2151 | } |
|
2164 | } | |
|
2165 | ||||
|
2166 | ||||
|
2167 | // global hooks after DOM is loaded | |||
|
2168 | ||||
|
2169 | YUE.onDOMReady(function(){ | |||
|
2170 | YUE.on(YUQ('.diff-collapse-button'), 'click', function(e){ | |||
|
2171 | var button = e.currentTarget; | |||
|
2172 | var t = YUD.get(button).getAttribute('target'); | |||
|
2173 | console.log(t); | |||
|
2174 | if(YUD.hasClass(t, 'hidden')){ | |||
|
2175 | YUD.removeClass(t, 'hidden'); | |||
|
2176 | YUD.get(button).innerHTML = "↑ {0} ↑".format(_TM['collapse diff']); | |||
|
2177 | } | |||
|
2178 | else if(!YUD.hasClass(t, 'hidden')){ | |||
|
2179 | YUD.addClass(t, 'hidden'); | |||
|
2180 | YUD.get(button).innerHTML = "↓ {0} ↓".format(_TM['expand diff']); | |||
|
2181 | } | |||
|
2182 | }); | |||
|
2183 | ||||
|
2184 | ||||
|
2185 | ||||
|
2186 | }); | |||
|
2187 |
@@ -39,7 +39,12 b'' | |||||
39 | <span id="${c.notification.notification_id}" class="delete-notification delete_icon action"></span> |
|
39 | <span id="${c.notification.notification_id}" class="delete-notification delete_icon action"></span> | |
40 | </div> |
|
40 | </div> | |
41 | </div> |
|
41 | </div> | |
42 |
<div class="notification-body"> |
|
42 | <div class="notification-body"> | |
|
43 | <div class="notification-subject">${h.literal(c.notification.subject)}</div> | |||
|
44 | %if c.notification.body: | |||
|
45 | ${h.rst_w_mentions(c.notification.body)} | |||
|
46 | %endif | |||
|
47 | </div> | |||
43 | </div> |
|
48 | </div> | |
44 | </div> |
|
49 | </div> | |
45 | </div> |
|
50 | </div> |
@@ -59,7 +59,7 b'' | |||||
59 | ${h.checkbox('overwrite_default_group','true')} |
|
59 | ${h.checkbox('overwrite_default_group','true')} | |
60 | <label for="overwrite_default_group"> |
|
60 | <label for="overwrite_default_group"> | |
61 | <span class="tooltip" |
|
61 | <span class="tooltip" | |
62 |
title="${h.tooltip(_('All default permissions on each repository group will be reset to choosen permission, note that all custom default permission on repositor |
|
62 | title="${h.tooltip(_('All default permissions on each repository group will be reset to choosen permission, note that all custom default permission on repository groups will be lost'))}"> | |
63 | ${_('overwrite existing settings')}</span> </label> |
|
63 | ${_('overwrite existing settings')}</span> </label> | |
64 |
|
64 | |||
65 | </div> |
|
65 | </div> |
@@ -38,7 +38,7 b'' | |||||
38 | %endif |
|
38 | %endif | |
39 | %endfor |
|
39 | %endfor | |
40 |
|
40 | |||
41 |
## USER |
|
41 | ## USER GROUPS | |
42 | %for g2p in c.repo_info.users_group_to_perm: |
|
42 | %for g2p in c.repo_info.users_group_to_perm: | |
43 | <tr id="id${id(g2p.users_group.users_group_name)}"> |
|
43 | <tr id="id${id(g2p.users_group.users_group_name)}"> | |
44 | <td>${h.radio('g_perm_%s' % g2p.users_group.users_group_name,'repository.none')}</td> |
|
44 | <td>${h.radio('g_perm_%s' % g2p.users_group.users_group_name,'repository.none')}</td> | |
@@ -54,7 +54,7 b'' | |||||
54 | %endif |
|
54 | %endif | |
55 | </td> |
|
55 | </td> | |
56 | <td> |
|
56 | <td> | |
57 |
<span class="delete_icon action_button" onclick="ajaxActionUser |
|
57 | <span class="delete_icon action_button" onclick="ajaxActionUserGroup(${g2p.users_group.users_group_id},'${'id%s'%id(g2p.users_group.users_group_name)}')"> | |
58 | ${_('revoke')} |
|
58 | ${_('revoke')} | |
59 | </span> |
|
59 | </span> | |
60 | </td> |
|
60 | </td> | |
@@ -101,7 +101,7 b' function ajaxActionUser(user_id, field_i' | |||||
101 | var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData); |
|
101 | var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData); | |
102 | }; |
|
102 | }; | |
103 |
|
103 | |||
104 |
function ajaxActionUser |
|
104 | function ajaxActionUserGroup(users_group_id,field_id){ | |
105 | var sUrl = "${h.url('delete_repo_users_group',repo_name=c.repo_name)}"; |
|
105 | var sUrl = "${h.url('delete_repo_users_group',repo_name=c.repo_name)}"; | |
106 | var callback = { |
|
106 | var callback = { | |
107 | success:function(o){ |
|
107 | success:function(o){ | |
@@ -109,7 +109,7 b' function ajaxActionUsersGroup(users_grou' | |||||
109 | tr.parentNode.removeChild(tr); |
|
109 | tr.parentNode.removeChild(tr); | |
110 | }, |
|
110 | }, | |
111 | failure:function(o){ |
|
111 | failure:function(o){ | |
112 |
alert("${_('Failed to remove user |
|
112 | alert("${_('Failed to remove user group')}"); | |
113 | }, |
|
113 | }, | |
114 | }; |
|
114 | }; | |
115 | var postData = '_method=delete&users_group_id='+users_group_id; |
|
115 | var postData = '_method=delete&users_group_id='+users_group_id; |
@@ -40,7 +40,7 b'' | |||||
40 | </tr> |
|
40 | </tr> | |
41 | %endfor |
|
41 | %endfor | |
42 |
|
42 | |||
43 |
## USER |
|
43 | ## USER GROUPS | |
44 | %for g2p in c.repos_group.users_group_to_perm: |
|
44 | %for g2p in c.repos_group.users_group_to_perm: | |
45 | <tr id="id${id(g2p.users_group.users_group_name)}"> |
|
45 | <tr id="id${id(g2p.users_group.users_group_name)}"> | |
46 | <td>${h.radio('g_perm_%s' % g2p.users_group.users_group_name,'group.none')}</td> |
|
46 | <td>${h.radio('g_perm_%s' % g2p.users_group.users_group_name,'group.none')}</td> | |
@@ -51,7 +51,7 b'' | |||||
51 | <img class="perm-gravatar" src="${h.url('/images/icons/group.png')}"/>${g2p.users_group.users_group_name} |
|
51 | <img class="perm-gravatar" src="${h.url('/images/icons/group.png')}"/>${g2p.users_group.users_group_name} | |
52 | </td> |
|
52 | </td> | |
53 | <td> |
|
53 | <td> | |
54 |
<span class="delete_icon action_button" onclick="ajaxActionUser |
|
54 | <span class="delete_icon action_button" onclick="ajaxActionUserGroup(${g2p.users_group.users_group_id},'${'id%s'%id(g2p.users_group.users_group_name)}')"> | |
55 | ${_('revoke')} |
|
55 | ${_('revoke')} | |
56 | </span> |
|
56 | </span> | |
57 | </td> |
|
57 | </td> | |
@@ -105,7 +105,7 b' function ajaxActionUser(user_id, field_i' | |||||
105 | var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData); |
|
105 | var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData); | |
106 | }; |
|
106 | }; | |
107 |
|
107 | |||
108 |
function ajaxActionUser |
|
108 | function ajaxActionUserGroup(users_group_id,field_id){ | |
109 | var sUrl = "${h.url('delete_repos_group_users_group_perm',group_name=c.repos_group.group_name)}"; |
|
109 | var sUrl = "${h.url('delete_repos_group_users_group_perm',group_name=c.repos_group.group_name)}"; | |
110 | var callback = { |
|
110 | var callback = { | |
111 | success:function(o){ |
|
111 | success:function(o){ | |
@@ -113,7 +113,7 b' function ajaxActionUsersGroup(users_grou' | |||||
113 | tr.parentNode.removeChild(tr); |
|
113 | tr.parentNode.removeChild(tr); | |
114 | }, |
|
114 | }, | |
115 | failure:function(o){ |
|
115 | failure:function(o){ | |
116 |
alert("${_('Failed to remove user |
|
116 | alert("${_('Failed to remove user group')}"); | |
117 | }, |
|
117 | }, | |
118 | }; |
|
118 | }; | |
119 | var recursive = YUD.get('recursive').checked; |
|
119 | var recursive = YUD.get('recursive').checked; |
@@ -2,14 +2,14 b'' | |||||
2 | <%inherit file="/base/base.html"/> |
|
2 | <%inherit file="/base/base.html"/> | |
3 |
|
3 | |||
4 | <%def name="title()"> |
|
4 | <%def name="title()"> | |
5 |
${_('Repositor |
|
5 | ${_('Repository groups administration')} - ${c.rhodecode_name} | |
6 | </%def> |
|
6 | </%def> | |
7 |
|
7 | |||
8 |
|
8 | |||
9 | <%def name="breadcrumbs_links()"> |
|
9 | <%def name="breadcrumbs_links()"> | |
10 | ${h.link_to(_('Admin'),h.url('admin_home'))} |
|
10 | ${h.link_to(_('Admin'),h.url('admin_home'))} | |
11 | » |
|
11 | » | |
12 |
${_('repositor |
|
12 | ${_('repository groups')} | |
13 | </%def> |
|
13 | </%def> | |
14 | <%def name="page_nav()"> |
|
14 | <%def name="page_nav()"> | |
15 | ${self.menu('admin')} |
|
15 | ${self.menu('admin')} | |
@@ -48,7 +48,7 b'' | |||||
48 | <tr> |
|
48 | <tr> | |
49 | <td> |
|
49 | <td> | |
50 | <div style="white-space: nowrap"> |
|
50 | <div style="white-space: nowrap"> | |
51 |
<img class="icon" alt="${_('Repositor |
|
51 | <img class="icon" alt="${_('Repository group')}" src="${h.url('/images/icons/database_link.png')}"/> | |
52 | ${h.link_to(h.literal(' » '.join(map(h.safe_unicode,[g.name for g in gr.parents+[gr]]))), url('repos_group_home',group_name=gr.group_name))} |
|
52 | ${h.link_to(h.literal(' » '.join(map(h.safe_unicode,[g.name for g in gr.parents+[gr]]))), url('repos_group_home',group_name=gr.group_name))} | |
53 | </div> |
|
53 | </div> | |
54 | </td> |
|
54 | </td> | |
@@ -69,7 +69,7 b'' | |||||
69 |
|
69 | |||
70 | </table> |
|
70 | </table> | |
71 | % else: |
|
71 | % else: | |
72 |
${_('There are no repositor |
|
72 | ${_('There are no repository groups yet')} | |
73 | % endif |
|
73 | % endif | |
74 |
|
74 | |||
75 | </div> |
|
75 | </div> |
@@ -64,7 +64,7 b'' | |||||
64 | <div class="checkboxes"> |
|
64 | <div class="checkboxes"> | |
65 | <div class="checkbox"> |
|
65 | <div class="checkbox"> | |
66 | ${h.checkbox('full_index',True)} |
|
66 | ${h.checkbox('full_index',True)} | |
67 |
<label for="full_index">${_(' |
|
67 | <label for="full_index">${_('Build from scratch')}</label> | |
68 | </div> |
|
68 | </div> | |
69 | </div> |
|
69 | </div> | |
70 | </div> |
|
70 | </div> | |
@@ -85,7 +85,7 b'' | |||||
85 |
|
85 | |||
86 | <div class="field"> |
|
86 | <div class="field"> | |
87 | <div class="label"> |
|
87 | <div class="label"> | |
88 |
<label for="rhodecode_title">${_(' |
|
88 | <label for="rhodecode_title">${_('Site branding')}:</label> | |
89 | </div> |
|
89 | </div> | |
90 | <div class="input"> |
|
90 | <div class="input"> | |
91 | ${h.text('rhodecode_title',size=30)} |
|
91 | ${h.text('rhodecode_title',size=30)} | |
@@ -94,7 +94,7 b'' | |||||
94 |
|
94 | |||
95 | <div class="field"> |
|
95 | <div class="field"> | |
96 | <div class="label"> |
|
96 | <div class="label"> | |
97 |
<label for="rhodecode_realm">${_(' |
|
97 | <label for="rhodecode_realm">${_('HTTP authentication realm')}:</label> | |
98 | </div> |
|
98 | </div> | |
99 | <div class="input"> |
|
99 | <div class="input"> | |
100 | ${h.text('rhodecode_realm',size=30)} |
|
100 | ${h.text('rhodecode_realm',size=30)} | |
@@ -103,7 +103,7 b'' | |||||
103 |
|
103 | |||
104 | <div class="field"> |
|
104 | <div class="field"> | |
105 | <div class="label"> |
|
105 | <div class="label"> | |
106 | <label for="rhodecode_ga_code">${_('GA code')}:</label> |
|
106 | <label for="rhodecode_ga_code">${_('Google Analytics code')}:</label> | |
107 | </div> |
|
107 | </div> | |
108 | <div class="input"> |
|
108 | <div class="input"> | |
109 | ${h.text('rhodecode_ga_code',size=30)} |
|
109 | ${h.text('rhodecode_ga_code',size=30)} |
@@ -40,12 +40,12 b'' | |||||
40 | </div> |
|
40 | </div> | |
41 | <div class="field"> |
|
41 | <div class="field"> | |
42 | <div class="label"> |
|
42 | <div class="label"> | |
43 | <label>${_('API key')}</label> ${c.user.api_key} |
|
43 | <label>${_('API key')}:</label> ${c.user.api_key} | |
44 | </div> |
|
44 | </div> | |
45 | </div> |
|
45 | </div> | |
46 | <div class="field"> |
|
46 | <div class="field"> | |
47 | <div class="label"> |
|
47 | <div class="label"> | |
48 |
<label>${_(' |
|
48 | <label>${_('Current IP')}:</label> ${c.perm_user.ip_addr or "?"} | |
49 | </div> |
|
49 | </div> | |
50 | </div> |
|
50 | </div> | |
51 | <div class="fields"> |
|
51 | <div class="fields"> |
@@ -102,6 +102,7 b'' | |||||
102 | </div> |
|
102 | </div> | |
103 |
|
103 | |||
104 | <script type="text/javascript"> |
|
104 | <script type="text/javascript"> | |
|
105 | pyroutes.register('admin_settings_my_pullrequests', "${url('admin_settings_my_pullrequests')}", []); | |||
105 |
|
106 | |||
106 | var show_perms = function(e){ |
|
107 | var show_perms = function(e){ | |
107 | YUD.addClass('show_perms', 'current'); |
|
108 | YUD.addClass('show_perms', 'current'); | |
@@ -145,8 +146,15 b' var show_pullrequests = function(e){' | |||||
145 | YUD.setStyle('pullrequests_container','display',''); |
|
146 | YUD.setStyle('pullrequests_container','display',''); | |
146 | YUD.setStyle('q_filter','display','none'); |
|
147 | YUD.setStyle('q_filter','display','none'); | |
147 |
|
148 | |||
148 |
var url = |
|
149 | var url = pyroutes.url('admin_settings_my_pullrequests'); | |
149 | ypjax(url, 'pullrequests_container'); |
|
150 | if(YUD.get('show_closed') && YUD.get('show_closed').checked) { | |
|
151 | var url = pyroutes.url('admin_settings_my_pullrequests', {'pr_show_closed': '1'}); | |||
|
152 | } | |||
|
153 | ypjax(url, 'pullrequests_container', function(){ | |||
|
154 | YUE.on('show_closed','change',function (e) { | |||
|
155 | show_pullrequests(e); | |||
|
156 | }); | |||
|
157 | }); | |||
150 | } |
|
158 | } | |
151 | YUE.on('show_pullrequests','click',function(e){ |
|
159 | YUE.on('show_pullrequests','click',function(e){ | |
152 | show_pullrequests(e) |
|
160 | show_pullrequests(e) | |
@@ -270,6 +278,7 b' function table_renderer(data){' | |||||
270 | clearTimeout(filterTimeout); |
|
278 | clearTimeout(filterTimeout); | |
271 | filterTimeout = setTimeout(updateFilter,600); |
|
279 | filterTimeout = setTimeout(updateFilter,600); | |
272 | }); |
|
280 | }); | |
|
281 | ||||
273 | } |
|
282 | } | |
274 | </script> |
|
283 | </script> | |
275 | </%def> |
|
284 | </%def> |
@@ -1,4 +1,8 b'' | |||||
1 |
|
1 | %if c.show_closed: | ||
|
2 | ${h.checkbox('show_closed',checked="checked", label=_('Show closed pull requests'))} | |||
|
3 | %else: | |||
|
4 | ${h.checkbox('show_closed',label=_('Show closed pull requests'))} | |||
|
5 | %endif | |||
2 | <div class="pullrequests_section_head">${_('Opened by me')}</div> |
|
6 | <div class="pullrequests_section_head">${_('Opened by me')}</div> | |
3 | <ul> |
|
7 | <ul> | |
4 | %if c.my_pull_requests: |
|
8 | %if c.my_pull_requests: |
@@ -2,14 +2,14 b'' | |||||
2 | <%inherit file="/base/base.html"/> |
|
2 | <%inherit file="/base/base.html"/> | |
3 |
|
3 | |||
4 | <%def name="title()"> |
|
4 | <%def name="title()"> | |
5 |
${_('Add user |
|
5 | ${_('Add user group')} - ${c.rhodecode_name} | |
6 | </%def> |
|
6 | </%def> | |
7 | <%def name="breadcrumbs_links()"> |
|
7 | <%def name="breadcrumbs_links()"> | |
8 | ${h.link_to(_('Admin'),h.url('admin_home'))} |
|
8 | ${h.link_to(_('Admin'),h.url('admin_home'))} | |
9 | » |
|
9 | » | |
10 |
${h.link_to(_('User |
|
10 | ${h.link_to(_('User groups'),h.url('users_groups'))} | |
11 | » |
|
11 | » | |
12 |
${_('add new user |
|
12 | ${_('add new user group')} | |
13 | </%def> |
|
13 | </%def> | |
14 |
|
14 | |||
15 | <%def name="page_nav()"> |
|
15 | <%def name="page_nav()"> |
@@ -2,13 +2,13 b'' | |||||
2 | <%inherit file="/base/base.html"/> |
|
2 | <%inherit file="/base/base.html"/> | |
3 |
|
3 | |||
4 | <%def name="title()"> |
|
4 | <%def name="title()"> | |
5 |
${_('Edit user |
|
5 | ${_('Edit user group')} ${c.users_group.users_group_name} - ${c.rhodecode_name} | |
6 | </%def> |
|
6 | </%def> | |
7 |
|
7 | |||
8 | <%def name="breadcrumbs_links()"> |
|
8 | <%def name="breadcrumbs_links()"> | |
9 | ${h.link_to(_('Admin'),h.url('admin_home'))} |
|
9 | ${h.link_to(_('Admin'),h.url('admin_home'))} | |
10 | » |
|
10 | » | |
11 |
${h.link_to(_('User |
|
11 | ${h.link_to(_('UserGroups'),h.url('users_groups'))} | |
12 | » |
|
12 | » | |
13 | ${_('edit')} "${c.users_group.users_group_name}" |
|
13 | ${_('edit')} "${c.users_group.users_group_name}" | |
14 | </%def> |
|
14 | </%def> |
@@ -2,13 +2,13 b'' | |||||
2 | <%inherit file="/base/base.html"/> |
|
2 | <%inherit file="/base/base.html"/> | |
3 |
|
3 | |||
4 | <%def name="title()"> |
|
4 | <%def name="title()"> | |
5 |
${_('User |
|
5 | ${_('User groups administration')} - ${c.rhodecode_name} | |
6 | </%def> |
|
6 | </%def> | |
7 |
|
7 | |||
8 | <%def name="breadcrumbs_links()"> |
|
8 | <%def name="breadcrumbs_links()"> | |
9 | ${h.link_to(_('Admin'),h.url('admin_home'))} |
|
9 | ${h.link_to(_('Admin'),h.url('admin_home'))} | |
10 | » |
|
10 | » | |
11 |
${_('user |
|
11 | ${_('user groups')} | |
12 | </%def> |
|
12 | </%def> | |
13 |
|
13 | |||
14 | <%def name="page_nav()"> |
|
14 | <%def name="page_nav()"> | |
@@ -44,7 +44,7 b'' | |||||
44 | <td> |
|
44 | <td> | |
45 | ${h.form(url('users_group', id=u_group.users_group_id),method='delete')} |
|
45 | ${h.form(url('users_group', id=u_group.users_group_id),method='delete')} | |
46 | ${h.submit('remove_',_('delete'),id="remove_group_%s" % u_group.users_group_id, |
|
46 | ${h.submit('remove_',_('delete'),id="remove_group_%s" % u_group.users_group_id, | |
47 |
class_="delete_icon action_button",onclick="return confirm('"+_('Confirm to delete this user |
|
47 | class_="delete_icon action_button",onclick="return confirm('"+_('Confirm to delete this user group: %s') % u_group.users_group_name+"');")} | |
48 | ${h.end_form()} |
|
48 | ${h.end_form()} | |
49 | </td> |
|
49 | </td> | |
50 | </tr> |
|
50 | </tr> |
@@ -71,9 +71,9 b'' | |||||
71 | <ul class="admin_menu"> |
|
71 | <ul class="admin_menu"> | |
72 | <li>${h.link_to(_('admin journal'),h.url('admin_home'),class_='journal')}</li> |
|
72 | <li>${h.link_to(_('admin journal'),h.url('admin_home'),class_='journal')}</li> | |
73 | <li>${h.link_to(_('repositories'),h.url('repos'),class_='repos')}</li> |
|
73 | <li>${h.link_to(_('repositories'),h.url('repos'),class_='repos')}</li> | |
74 |
<li>${h.link_to(_('repositor |
|
74 | <li>${h.link_to(_('repository groups'),h.url('repos_groups'),class_='repos_groups')}</li> | |
75 | <li>${h.link_to(_('users'),h.url('users'),class_='users')}</li> |
|
75 | <li>${h.link_to(_('users'),h.url('users'),class_='users')}</li> | |
76 |
<li>${h.link_to(_('user |
|
76 | <li>${h.link_to(_('user groups'),h.url('users_groups'),class_='groups')}</li> | |
77 | <li>${h.link_to(_('permissions'),h.url('edit_permission',id='default'),class_='permissions')}</li> |
|
77 | <li>${h.link_to(_('permissions'),h.url('edit_permission',id='default'),class_='permissions')}</li> | |
78 | <li>${h.link_to(_('ldap'),h.url('ldap_home'),class_='ldap')}</li> |
|
78 | <li>${h.link_to(_('ldap'),h.url('ldap_home'),class_='ldap')}</li> | |
79 | <li>${h.link_to(_('defaults'),h.url('defaults'),class_='defaults')}</li> |
|
79 | <li>${h.link_to(_('defaults'),h.url('defaults'),class_='defaults')}</li> | |
@@ -233,7 +233,7 b'' | |||||
233 | <label for="username">${_('Username')}:</label> |
|
233 | <label for="username">${_('Username')}:</label> | |
234 | </div> |
|
234 | </div> | |
235 | <div class="input"> |
|
235 | <div class="input"> | |
236 |
${h.text('username',class_='focus' |
|
236 | ${h.text('username',class_='focus')} | |
237 | </div> |
|
237 | </div> | |
238 |
|
238 | |||
239 | </div> |
|
239 | </div> | |
@@ -242,7 +242,7 b'' | |||||
242 | <label for="password">${_('Password')}:</label> |
|
242 | <label for="password">${_('Password')}:</label> | |
243 | </div> |
|
243 | </div> | |
244 | <div class="input"> |
|
244 | <div class="input"> | |
245 |
${h.password('password',class_='focus' |
|
245 | ${h.password('password',class_='focus')} | |
246 | </div> |
|
246 | </div> | |
247 |
|
247 | |||
248 | </div> |
|
248 | </div> |
@@ -52,7 +52,10 b'' | |||||
52 | 'Open new pull request': "${_('Open new pull request')}", |
|
52 | 'Open new pull request': "${_('Open new pull request')}", | |
53 | 'Open new pull request for selected changesets': "${_('Open new pull request for selected changesets')}", |
|
53 | 'Open new pull request for selected changesets': "${_('Open new pull request for selected changesets')}", | |
54 | 'Show selected changes __S -> __E': "${_('Show selected changes __S -> __E')}", |
|
54 | 'Show selected changes __S -> __E': "${_('Show selected changes __S -> __E')}", | |
|
55 | 'Show selected change __S': "${_('Show selected change __S')}", | |||
55 | 'Selection link': "${_('Selection link')}", |
|
56 | 'Selection link': "${_('Selection link')}", | |
|
57 | 'collapse diff': "${_('collapse diff')}", | |||
|
58 | 'expand diff': "${_('expand diff')}", | |||
56 | }; |
|
59 | }; | |
57 | var _TM = TRANSLATION_MAP; |
|
60 | var _TM = TRANSLATION_MAP; | |
58 |
|
61 |
@@ -27,7 +27,7 b'' | |||||
27 | </div> |
|
27 | </div> | |
28 | <!-- end box / title --> |
|
28 | <!-- end box / title --> | |
29 | %if c.repo_branches: |
|
29 | %if c.repo_branches: | |
30 |
<div class="info_box" id="compare_branches" style="clear: both;padding: 10px 19px; |
|
30 | <div class="info_box" id="compare_branches" style="clear: both;padding: 10px 19px;text-align: right;"><a href="#" class="ui-btn small">${_('Compare branches')}</a></div> | |
31 | %endif |
|
31 | %endif | |
32 | <div class="table"> |
|
32 | <div class="table"> | |
33 | <%include file='branches_data.html'/> |
|
33 | <%include file='branches_data.html'/> |
@@ -33,15 +33,15 b'' | |||||
33 | <canvas id="graph_canvas"></canvas> |
|
33 | <canvas id="graph_canvas"></canvas> | |
34 | </div> |
|
34 | </div> | |
35 | <div id="graph_content"> |
|
35 | <div id="graph_content"> | |
36 |
<div class="info_box" style="clear: both;padding: 10px 6px; |
|
36 | <div class="info_box" style="clear: both;padding: 10px 6px;text-align: right;"> | |
37 | <a href="#" class="ui-btn small" id="rev_range_container" style="display:none"></a> |
|
37 | <a href="#" class="ui-btn small" id="rev_range_container" style="display:none"></a> | |
38 | <a href="#" class="ui-btn small" id="rev_range_clear" style="display:none">${_('Clear selection')}</a> |
|
38 | <a href="#" class="ui-btn small" id="rev_range_clear" style="display:none">${_('Clear selection')}</a> | |
39 |
|
39 | |||
40 | %if c.rhodecode_db_repo.fork: |
|
40 | %if c.rhodecode_db_repo.fork: | |
41 |
<a title="${_(' |
|
41 | <a title="${_('Compare fork with %s' % c.rhodecode_db_repo.fork.repo_name)}" href="${h.url('compare_url',repo_name=c.rhodecode_db_repo.fork.repo_name,org_ref_type='branch',org_ref='default',other_repo=c.repo_name,other_ref_type='branch',other_ref=request.GET.get('branch') or 'default')}" class="ui-btn small">${_('Compare fork with parent')}</a> | |
42 | %endif |
|
42 | %endif | |
43 | %if h.is_hg(c.rhodecode_repo): |
|
43 | %if h.is_hg(c.rhodecode_repo): | |
44 |
<a id="open_new_pr" href="${h.url('pullrequest_ |
|
44 | <a id="open_new_pr" href="${h.url('pullrequest_form',repo_name=c.repo_name)}" class="ui-btn small">${_('Open new pull request')}</a> | |
45 | %endif |
|
45 | %endif | |
46 | </div> |
|
46 | </div> | |
47 | <div class="container_header"> |
|
47 | <div class="container_header"> | |
@@ -72,7 +72,7 b'' | |||||
72 | </div> |
|
72 | </div> | |
73 | <div class="mid"> |
|
73 | <div class="mid"> | |
74 | <div class="message">${h.urlify_commit(cs.message, c.repo_name,h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}</div> |
|
74 | <div class="message">${h.urlify_commit(cs.message, c.repo_name,h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}</div> | |
75 |
<div class="expand"><span class="expandtext">↓ ${_(' |
|
75 | <div class="expand"><span class="expandtext">↓ ${_('Show more')} ↓</span></div> | |
76 | </div> |
|
76 | </div> | |
77 | <div class="right"> |
|
77 | <div class="right"> | |
78 | <div class="changes"> |
|
78 | <div class="changes"> | |
@@ -163,7 +163,6 b'' | |||||
163 | if(checked_checkboxes.length>0){ |
|
163 | if(checked_checkboxes.length>0){ | |
164 | // modify open pull request to show we have selected cs |
|
164 | // modify open pull request to show we have selected cs | |
165 | YUD.get('open_new_pr').innerHTML = _TM['Open new pull request for selected changesets']; |
|
165 | YUD.get('open_new_pr').innerHTML = _TM['Open new pull request for selected changesets']; | |
166 |
|
||||
167 | }else{ |
|
166 | }else{ | |
168 | YUD.get('open_new_pr').innerHTML = _TM['Open new pull request']; |
|
167 | YUD.get('open_new_pr').innerHTML = _TM['Open new pull request']; | |
169 | } |
|
168 | } | |
@@ -172,32 +171,13 b'' | |||||
172 | if(checked_checkboxes.length>0){ |
|
171 | if(checked_checkboxes.length>0){ | |
173 | var rev_end = checked_checkboxes[0].name; |
|
172 | var rev_end = checked_checkboxes[0].name; | |
174 | var rev_start = checked_checkboxes[checked_checkboxes.length-1].name; |
|
173 | var rev_start = checked_checkboxes[checked_checkboxes.length-1].name; | |
175 |
|
||||
176 | // now select all checkboxes in the middle. |
|
|||
177 | var checked = false; |
|
|||
178 | for (var i=0; i<checkboxes.length; i++){ |
|
|||
179 | var cb = checkboxes[i]; |
|
|||
180 | var rev = cb.name; |
|
|||
181 |
|
||||
182 | if (rev == rev_end){ |
|
|||
183 | checked = true; |
|
|||
184 | } |
|
|||
185 | if (checked){ |
|
|||
186 | cb.checked = true; |
|
|||
187 | } |
|
|||
188 | else{ |
|
|||
189 | cb.checked = false; |
|
|||
190 | } |
|
|||
191 | if (rev == rev_start){ |
|
|||
192 | checked = false; |
|
|||
193 | } |
|
|||
194 |
|
||||
195 | } |
|
|||
196 |
|
||||
197 | var url = url_tmpl.replace('__REVRANGE__', |
|
174 | var url = url_tmpl.replace('__REVRANGE__', | |
198 | rev_start+'...'+rev_end); |
|
175 | rev_start+'...'+rev_end); | |
199 |
|
176 | |||
200 |
var link = |
|
177 | var link = (rev_start == rev_end) | |
|
178 | ? _TM['Show selected change __S'] | |||
|
179 | : _TM['Show selected changes __S -> __E']; | |||
|
180 | ||||
201 | link = link.replace('__S',rev_start.substr(0,6)); |
|
181 | link = link.replace('__S',rev_start.substr(0,6)); | |
202 | link = link.replace('__E',rev_end.substr(0,6)); |
|
182 | link = link.replace('__E',rev_end.substr(0,6)); | |
203 | YUD.get('rev_range_container').href = url; |
|
183 | YUD.get('rev_range_container').href = url; |
@@ -4,7 +4,10 b'' | |||||
4 | ## ${diff_block.diff_block(change)} |
|
4 | ## ${diff_block.diff_block(change)} | |
5 | ## |
|
5 | ## | |
6 | <%def name="diff_block(change)"> |
|
6 | <%def name="diff_block(change)"> | |
7 |
|
7 | <div class="diff-collapse"> | ||
|
8 | <span target="${'diff-container-%s' % (id(change))}" class="diff-collapse-button">↑ ${_('collapse diff')} ↑</span> | |||
|
9 | </div> | |||
|
10 | <div class="diff-container" id="${'diff-container-%s' % (id(change))}"> | |||
8 | %for FID,(cs1, cs2, change, path, diff, stats) in change.iteritems(): |
|
11 | %for FID,(cs1, cs2, change, path, diff, stats) in change.iteritems(): | |
9 | ##%if op !='removed': |
|
12 | ##%if op !='removed': | |
10 | <div id="${FID}_target" style="clear:both;margin-top:25px"></div> |
|
13 | <div id="${FID}_target" style="clear:both;margin-top:25px"></div> | |
@@ -37,7 +40,7 b'' | |||||
37 | </div> |
|
40 | </div> | |
38 | ##%endif |
|
41 | ##%endif | |
39 | %endfor |
|
42 | %endfor | |
40 |
|
43 | </div> | ||
41 | </%def> |
|
44 | </%def> | |
42 |
|
45 | |||
43 | <%def name="diff_block_simple(change)"> |
|
46 | <%def name="diff_block_simple(change)"> | |
@@ -49,8 +52,8 b'' | |||||
49 | <div class="changeset_header"> |
|
52 | <div class="changeset_header"> | |
50 | <div class="changeset_file"> |
|
53 | <div class="changeset_file"> | |
51 | ${h.safe_unicode(filenode_path)} | |
|
54 | ${h.safe_unicode(filenode_path)} | | |
52 | <a class="spantag" href="${h.url('files_home', repo_name=c.repo_name, f_path=filenode_path, revision=c.org_ref)}">${c.org_ref_type}@${c.org_ref}</a> -> |
|
55 | <a class="spantag" href="${h.url('files_home', repo_name=c.repo_name, f_path=filenode_path, revision=c.org_ref)}" title="${_('show file at latest version in this repo')}">${c.org_ref_type}@${h.short_id(c.org_ref) if c.org_ref_type=='rev' else c.org_ref}</a> -> | |
53 | <a class="spantag" href="${h.url('files_home', repo_name=c.repo_name, f_path=filenode_path, revision=c.other_ref)}">${c.other_ref_type}@${c.other_ref}</a> |
|
56 | <a class="spantag" href="${h.url('files_home', repo_name=c.repo_name, f_path=filenode_path, revision=c.other_ref)}" title="${_('show file at initial version in this repo')}">${c.other_ref_type}@${h.short_id(c.other_ref) if c.other_ref_type=='rev' else c.other_ref}</a> | |
54 | </div> |
|
57 | </div> | |
55 | </div> |
|
58 | </div> | |
56 | </div> |
|
59 | </div> |
@@ -1,12 +1,17 b'' | |||||
1 | ## -*- coding: utf-8 -*- |
|
1 | ## -*- coding: utf-8 -*- | |
2 | <%inherit file="main.html"/> |
|
2 | <%inherit file="main.html"/> | |
3 |
|
3 | ##message from user goes here | ||
4 | <h4>${subject}</h4> |
|
4 | <p> | |
5 |
|
5 | ${cs_comment_user}: <br/> | ||
6 | ${body} |
|
6 | ${body} | |
|
7 | </p> | |||
|
8 | %if status_change: | |||
|
9 | <span>${_('New status')} -> ${status_change}</span> | |||
|
10 | %endif | |||
|
11 | <div>${_('View this comment here')}: ${cs_comment_url}</div> | |||
7 |
|
12 | |||
8 | % if status_change is not None: |
|
13 | <pre> | |
9 | <div> |
|
14 | ${_('Repo')}: ${cs_target_repo} | |
10 | ${_('New status')} -> ${status_change} |
|
15 | ${_('Changeset')}: ${h.short_id(raw_id)} | |
11 | </div> |
|
16 | ${_('desc')}: ${h.shorter(message, 256)} | |
12 | % endif |
|
17 | </pre> |
@@ -1,12 +1,11 b'' | |||||
1 | ## -*- coding: utf-8 -*- |
|
1 | ## -*- coding: utf-8 -*- | |
2 | <%inherit file="main.html"/> |
|
2 | <%inherit file="main.html"/> | |
3 |
|
3 | |||
4 |
${_('Hello |
|
4 | <h4>${_('Hello %s') % user}</h4> | |
5 |
|
5 | <div>${_('We received a request to create a new password for your account.')}</div> | ||
6 | ${_('We received a request to create a new password for your account.')} |
|
6 | <div>${_('You can generate it by clicking following URL')}:</div> | |
7 |
|
7 | <pre> | ||
8 | ${_('You can generate it by clicking following URL')}: |
|
|||
9 |
|
||||
10 | ${reset_url} |
|
8 | ${reset_url} | |
11 |
|
9 | </pre> | ||
12 | ${_("If you didn't request new password please ignore this email.")} |
|
10 | <br/> | |
|
11 | ${_("If you did not request new password please ignore this email.")} |
@@ -10,8 +10,10 b'' | |||||
10 | </p> |
|
10 | </p> | |
11 |
|
11 | |||
12 | <div>${_('revisions for reviewing')}</div> |
|
12 | <div>${_('revisions for reviewing')}</div> | |
13 | <ul> |
|
13 | <pre> | |
14 | %for r in pr_revisions: |
|
14 | %for r,r_msg in pr_revisions: | |
15 | <li>${r}</li> |
|
15 | ${h.short_id(r)}: | |
|
16 | ${h.shorter(r_msg, 256)} | |||
|
17 | ||||
16 | %endfor |
|
18 | %endfor | |
17 | </ul> |
|
19 | </pre> |
@@ -1,13 +1,18 b'' | |||||
1 | ## -*- coding: utf-8 -*- |
|
1 | ## -*- coding: utf-8 -*- | |
2 | <%inherit file="main.html"/> |
|
2 | <%inherit file="main.html"/> | |
3 |
|
3 | ${_('Pull request #%s for repository %s') % (pr_id, pr_target_repo) |n} | ||
4 | ${_('User %s commented on pull request #%s for repository %s') % ('<b>%s</b>' % pr_comment_user, pr_id, pr_target_repo) |n} |
|
4 | ##message from user goes here | |
|
5 | <p> | |||
|
6 | ${pr_comment_user}: <br/> | |||
|
7 | ${body} | |||
|
8 | </p> | |||
5 | <div>${_('View this comment here')}: ${pr_comment_url}</div> |
|
9 | <div>${_('View this comment here')}: ${pr_comment_url}</div> | |
6 |
|
10 | |||
7 | <p> |
|
|||
8 | ${body} |
|
|||
9 |
|
||||
10 | %if status_change: |
|
11 | %if status_change: | |
11 | <span>${_('New status')} -> ${status_change}</span> |
|
12 | %if closing_pr: | |
|
13 | <span>${_('Closing pull request with status')} -> ${status_change}</span> | |||
|
14 | %else: | |||
|
15 | <span>${_('New status')} -> ${status_change}</span> | |||
|
16 | %endif | |||
12 | %endif |
|
17 | %endif | |
13 | </p> |
|
18 | </p> |
@@ -86,8 +86,11 b' YUE.onDOMReady(function(){' | |||||
86 | h_lines.push(parseInt(highlight_ranges[pos])); |
|
86 | h_lines.push(parseInt(highlight_ranges[pos])); | |
87 | } |
|
87 | } | |
88 | } |
|
88 | } | |
89 |
|
|
89 | highlight_lines(h_lines); | |
90 |
|
90 | var _first_line= YUD.get('L'+h_lines[0]); | ||
|
91 | if(_first_line){ | |||
|
92 | _first_line.scrollIntoView() | |||
|
93 | } | |||
91 | } |
|
94 | } | |
92 |
|
95 | |||
93 | // select code link event |
|
96 | // select code link event |
@@ -48,7 +48,7 b'' | |||||
48 | <tr> |
|
48 | <tr> | |
49 | <td> |
|
49 | <td> | |
50 | <div style="white-space: nowrap"> |
|
50 | <div style="white-space: nowrap"> | |
51 |
<img class="icon" alt="${_('Repositor |
|
51 | <img class="icon" alt="${_('Repository group')}" src="${h.url('/images/icons/database_link.png')}"/> | |
52 | ${h.link_to(gr.name,url('repos_group_home',group_name=gr.group_name))} |
|
52 | ${h.link_to(gr.name,url('repos_group_home',group_name=gr.group_name))} | |
53 | </div> |
|
53 | </div> | |
54 | </td> |
|
54 | </td> |
@@ -31,7 +31,7 b'' | |||||
31 | <label for="username">${_('Username')}:</label> |
|
31 | <label for="username">${_('Username')}:</label> | |
32 | </div> |
|
32 | </div> | |
33 | <div class="input"> |
|
33 | <div class="input"> | |
34 |
${h.text('username',class_='focus |
|
34 | ${h.text('username',class_='focus large')} | |
35 | </div> |
|
35 | </div> | |
36 |
|
36 | |||
37 | </div> |
|
37 | </div> | |
@@ -40,7 +40,7 b'' | |||||
40 | <label for="password">${_('Password')}:</label> |
|
40 | <label for="password">${_('Password')}:</label> | |
41 | </div> |
|
41 | </div> | |
42 | <div class="input"> |
|
42 | <div class="input"> | |
43 |
${h.password('password',class_='focus |
|
43 | ${h.password('password',class_='focus large')} | |
44 | </div> |
|
44 | </div> | |
45 |
|
45 | |||
46 | </div> |
|
46 | </div> |
@@ -30,7 +30,7 b'' | |||||
30 | <span style="font-size: 20px"> |
|
30 | <span style="font-size: 20px"> | |
31 | ${h.select('org_repo','',c.org_repos,class_='refs')}:${h.select('org_ref',c.default_org_ref,c.org_refs,class_='refs')} |
|
31 | ${h.select('org_repo','',c.org_repos,class_='refs')}:${h.select('org_ref',c.default_org_ref,c.org_refs,class_='refs')} | |
32 | </span> |
|
32 | </span> | |
33 |
<div style="padding:5px 3px 3px |
|
33 | <div style="padding:5px 3px 3px 20px;">${c.rhodecode_db_repo.description}</div> | |
34 | </div> |
|
34 | </div> | |
35 | <div style="clear:both;padding-top: 10px"></div> |
|
35 | <div style="clear:both;padding-top: 10px"></div> | |
36 | </div> |
|
36 | </div> | |
@@ -44,7 +44,7 b'' | |||||
44 | <span style="font-size: 20px"> |
|
44 | <span style="font-size: 20px"> | |
45 | ${h.select('other_repo',c.default_other_repo,c.other_repos,class_='refs')}:${h.select('other_ref',c.default_other_ref,c.default_other_refs,class_='refs')} |
|
45 | ${h.select('other_repo',c.default_other_repo,c.other_repos,class_='refs')}:${h.select('other_ref',c.default_other_ref,c.default_other_refs,class_='refs')} | |
46 | </span> |
|
46 | </span> | |
47 |
<div id="other_repo_desc" style="padding:5px 3px 3px |
|
47 | <div id="other_repo_desc" style="padding:5px 3px 3px 20px;"></div> | |
48 | </div> |
|
48 | </div> | |
49 | <div style="clear:both;padding-top: 10px"></div> |
|
49 | <div style="clear:both;padding-top: 10px"></div> | |
50 | </div> |
|
50 | </div> | |
@@ -146,24 +146,25 b'' | |||||
146 |
|
146 | |||
147 | var select_refs = YUQ('#pull_request_form select.refs') |
|
147 | var select_refs = YUQ('#pull_request_form select.refs') | |
148 | var rev_data = { |
|
148 | var rev_data = { | |
149 |
|
|
149 | 'org_repo': org_repo, | |
150 |
|
|
150 | 'org_ref': org_ref[2], | |
151 |
|
|
151 | 'org_ref_type': 'rev', | |
152 |
|
|
152 | 'other_repo': other_repo, | |
153 |
'other_ref': other_ref[ |
|
153 | 'other_ref': other_ref[2], | |
154 |
'other_ref_type': |
|
154 | 'other_ref_type': 'rev', | |
155 | }; // gather the org/other ref and repo here |
|
155 | }; // gather the org/other ref and repo here | |
156 |
|
156 | |||
157 | for (k in rev_data){ |
|
157 | for (k in rev_data){ | |
158 |
|
|
158 | url = url.replace('__'+k+'__',rev_data[k]); | |
159 | } |
|
159 | } | |
160 |
|
160 | |||
|
161 | YUD.get('pull_request_overview').innerHTML = "${_('Loading ...')}"; | |||
|
162 | YUD.get('pull_request_overview_url').href = url; // shouldn't have as_form ... but ... | |||
|
163 | YUD.setStyle(YUD.get('pull_request_overview_url').parentElement,'display',''); | |||
161 | ypjax(url,'pull_request_overview', function(data){ |
|
164 | ypjax(url,'pull_request_overview', function(data){ | |
162 | var sel_box = YUQ('#pull_request_form #other_repo')[0]; |
|
165 | var sel_box = YUQ('#pull_request_form #other_repo')[0]; | |
163 | var repo_name = sel_box.options[sel_box.selectedIndex].value; |
|
166 | var repo_name = sel_box.options[sel_box.selectedIndex].value; | |
164 | var _data = other_repos_info[repo_name]; |
|
167 | var _data = other_repos_info[repo_name]; | |
165 | YUD.get('pull_request_overview_url').href = url; |
|
|||
166 | YUD.setStyle(YUD.get('pull_request_overview_url').parentElement,'display',''); |
|
|||
167 | YUD.get('other_repo_desc').innerHTML = other_repos_info[repo_name]['description']; |
|
168 | YUD.get('other_repo_desc').innerHTML = other_repos_info[repo_name]['description']; | |
168 | YUD.get('other_ref').innerHTML = other_repos_info[repo_name]['revs']; |
|
169 | YUD.get('other_ref').innerHTML = other_repos_info[repo_name]['revs']; | |
169 | // select back the revision that was just compared |
|
170 | // select back the revision that was just compared | |
@@ -171,8 +172,8 b'' | |||||
171 | // reset && add the reviewer based on selected repo |
|
172 | // reset && add the reviewer based on selected repo | |
172 | YUD.get('review_members').innerHTML = ''; |
|
173 | YUD.get('review_members').innerHTML = ''; | |
173 | addReviewMember(_data.user.user_id, _data.user.firstname, |
|
174 | addReviewMember(_data.user.user_id, _data.user.firstname, | |
174 |
|
|
175 | _data.user.lastname, _data.user.username, | |
175 |
|
|
176 | _data.user.gravatar_link); | |
176 | }) |
|
177 | }) | |
177 | } |
|
178 | } | |
178 |
|
179 |
@@ -7,7 +7,7 b'' | |||||
7 | <%def name="breadcrumbs_links()"> |
|
7 | <%def name="breadcrumbs_links()"> | |
8 | ${h.link_to(_(u'Home'),h.url('/'))} |
|
8 | ${h.link_to(_(u'Home'),h.url('/'))} | |
9 | » |
|
9 | » | |
10 | ${h.link_to(c.repo_name,h.url('changelog_home',repo_name=c.repo_name))} |
|
10 | ${h.repo_link(c.rhodecode_db_repo.groups_and_repo)} | |
11 | » |
|
11 | » | |
12 | ${_('Pull request #%s') % c.pull_request.pull_request_id} |
|
12 | ${_('Pull request #%s') % c.pull_request.pull_request_id} | |
13 | </%def> |
|
13 | </%def> | |
@@ -22,7 +22,12 b'' | |||||
22 | %if c.pull_request.is_closed(): |
|
22 | %if c.pull_request.is_closed(): | |
23 | <div style="padding:10px; font-size:22px;width:100%;text-align: center; color:#88D882">${_('Closed %s') % (h.age(c.pull_request.updated_on))} ${_('with status %s') % h.changeset_status_lbl(c.current_changeset_status)}</div> |
|
23 | <div style="padding:10px; font-size:22px;width:100%;text-align: center; color:#88D882">${_('Closed %s') % (h.age(c.pull_request.updated_on))} ${_('with status %s') % h.changeset_status_lbl(c.current_changeset_status)}</div> | |
24 | %endif |
|
24 | %endif | |
25 | <h3>${_('Title')}: ${c.pull_request.title}</h3> |
|
25 | <h3> | |
|
26 | %if c.pull_request.is_closed(): | |||
|
27 | <img src="${h.url('/images/icons/lock_go.png')}" title="${_('Closed')}"/> | |||
|
28 | %endif | |||
|
29 | <img src="${h.url('/images/icons/flag_status_%s.png' % str(c.pull_request.last_review_status))}" /> | |||
|
30 | ${_('Title')}: ${c.pull_request.title}</h3> | |||
26 |
|
31 | |||
27 | <div class="form"> |
|
32 | <div class="form"> | |
28 | <div id="summary" class="fields"> |
|
33 | <div id="summary" class="fields"> |
@@ -4,7 +4,7 b'' | |||||
4 | <ul> |
|
4 | <ul> | |
5 | %if c.rhodecode_repo.branches.values(): |
|
5 | %if c.rhodecode_repo.branches.values(): | |
6 | %for cnt,branch in enumerate(c.rhodecode_repo.branches.items()): |
|
6 | %for cnt,branch in enumerate(c.rhodecode_repo.branches.items()): | |
7 | <li><div><pre>${h.link_to('%s - %s' % (branch[0],h.short_id(branch[1])),h.url('files_home',repo_name=c.repo_name,revision=branch[0]))}</pre></div></li> |
|
7 | <li><div><pre>${h.link_to('%s - %s' % (branch[0],h.short_id(branch[1])),h.url('files_home',repo_name=c.repo_name,revision=(branch[0] if '/' not in branch[0] else branch[1]), at=branch[0]))}</pre></div></li> | |
8 | %endfor |
|
8 | %endfor | |
9 | %else: |
|
9 | %else: | |
10 | <li>${h.link_to(_('There are no branches yet'),'#')}</li> |
|
10 | <li>${h.link_to(_('There are no branches yet'),'#')}</li> | |
@@ -16,7 +16,7 b'' | |||||
16 | <ul> |
|
16 | <ul> | |
17 | %if c.rhodecode_repo.tags.values(): |
|
17 | %if c.rhodecode_repo.tags.values(): | |
18 | %for cnt,tag in enumerate(c.rhodecode_repo.tags.items()): |
|
18 | %for cnt,tag in enumerate(c.rhodecode_repo.tags.items()): | |
19 | <li><div><pre>${h.link_to('%s - %s' % (tag[0],h.short_id(tag[1])),h.url('files_home',repo_name=c.repo_name,revision=tag[0]))}</pre></div></li> |
|
19 | <li><div><pre>${h.link_to('%s - %s' % (tag[0],h.short_id(tag[1])),h.url('files_home',repo_name=c.repo_name,revision=(tag[0] if '/' not in tag[0] else tag[1]), at=tag[0]))}</pre></div></li> | |
20 | %endfor |
|
20 | %endfor | |
21 | %else: |
|
21 | %else: | |
22 | <li>${h.link_to(_('There are no tags yet'),'#')}</li> |
|
22 | <li>${h.link_to(_('There are no tags yet'),'#')}</li> | |
@@ -29,7 +29,7 b'' | |||||
29 | <ul> |
|
29 | <ul> | |
30 | %if c.rhodecode_repo.bookmarks.values(): |
|
30 | %if c.rhodecode_repo.bookmarks.values(): | |
31 | %for cnt,book in enumerate(c.rhodecode_repo.bookmarks.items()): |
|
31 | %for cnt,book in enumerate(c.rhodecode_repo.bookmarks.items()): | |
32 | <li><div><pre>${h.link_to('%s - %s' % (book[0],h.short_id(book[1])),h.url('files_home',repo_name=c.repo_name,revision=book[1]))}</pre></div></li> |
|
32 | <li><div><pre>${h.link_to('%s - %s' % (book[0],h.short_id(book[1])),h.url('files_home',repo_name=c.repo_name,revision=(book[0] if '/' not in book[0] else book[1]), at=book[0]))}</pre></div></li> | |
33 | %endfor |
|
33 | %endfor | |
34 | %else: |
|
34 | %else: | |
35 | <li>${h.link_to(_('There are no bookmarks yet'),'#')}</li> |
|
35 | <li>${h.link_to(_('There are no bookmarks yet'),'#')}</li> |
@@ -27,7 +27,7 b'' | |||||
27 | </div> |
|
27 | </div> | |
28 | <!-- end box / title --> |
|
28 | <!-- end box / title --> | |
29 | %if c.repo_tags: |
|
29 | %if c.repo_tags: | |
30 |
<div class="info_box" id="compare_tags" style="clear: both;padding: 10px 19px; |
|
30 | <div class="info_box" id="compare_tags" style="clear: both;padding: 10px 19px;text-align: right;"><a href="#" class="ui-btn small">${_('Compare tags')}</a></div> | |
31 | %endif |
|
31 | %endif | |
32 | <div class="table"> |
|
32 | <div class="table"> | |
33 | <%include file='tags_data.html'/> |
|
33 | <%include file='tags_data.html'/> |
@@ -6,7 +6,7 b' from rhodecode.tests import *' | |||||
6 | from rhodecode.lib.compat import json |
|
6 | from rhodecode.lib.compat import json | |
7 | from rhodecode.lib.auth import AuthUser |
|
7 | from rhodecode.lib.auth import AuthUser | |
8 | from rhodecode.model.user import UserModel |
|
8 | from rhodecode.model.user import UserModel | |
9 |
from rhodecode.model.users_group import User |
|
9 | from rhodecode.model.users_group import UserGroupModel | |
10 | from rhodecode.model.repo import RepoModel |
|
10 | from rhodecode.model.repo import RepoModel | |
11 | from rhodecode.model.meta import Session |
|
11 | from rhodecode.model.meta import Session | |
12 | from rhodecode.model.scm import ScmModel |
|
12 | from rhodecode.model.scm import ScmModel | |
@@ -43,19 +43,19 b' def api_call(test_obj, params):' | |||||
43 | return response |
|
43 | return response | |
44 |
|
44 | |||
45 |
|
45 | |||
46 |
TEST_USER |
|
46 | TEST_USER_GROUP = 'test_users_group' | |
47 |
|
47 | |||
48 |
|
48 | |||
49 |
def make_users_group(name=TEST_USER |
|
49 | def make_users_group(name=TEST_USER_GROUP): | |
50 |
gr = User |
|
50 | gr = UserGroupModel().create(name=name) | |
51 |
User |
|
51 | UserGroupModel().add_user_to_group(users_group=gr, | |
52 | user=TEST_USER_ADMIN_LOGIN) |
|
52 | user=TEST_USER_ADMIN_LOGIN) | |
53 | Session().commit() |
|
53 | Session().commit() | |
54 | return gr |
|
54 | return gr | |
55 |
|
55 | |||
56 |
|
56 | |||
57 |
def destroy_users_group(name=TEST_USER |
|
57 | def destroy_users_group(name=TEST_USER_GROUP): | |
58 |
User |
|
58 | UserGroupModel().delete(users_group=name, force=True) | |
59 | Session().commit() |
|
59 | Session().commit() | |
60 |
|
60 | |||
61 |
|
61 | |||
@@ -999,10 +999,10 b' class BaseTestApi(object):' | |||||
999 |
|
999 | |||
1000 | def test_api_get_users_group(self): |
|
1000 | def test_api_get_users_group(self): | |
1001 | id_, params = _build_data(self.apikey, 'get_users_group', |
|
1001 | id_, params = _build_data(self.apikey, 'get_users_group', | |
1002 |
usersgroupid=TEST_USER |
|
1002 | usersgroupid=TEST_USER_GROUP) | |
1003 | response = api_call(self, params) |
|
1003 | response = api_call(self, params) | |
1004 |
|
1004 | |||
1005 |
users_group = User |
|
1005 | users_group = UserGroupModel().get_group(TEST_USER_GROUP) | |
1006 | members = [] |
|
1006 | members = [] | |
1007 | for user in users_group.members: |
|
1007 | for user in users_group.members: | |
1008 | user = user.user |
|
1008 | user = user.user | |
@@ -1021,13 +1021,13 b' class BaseTestApi(object):' | |||||
1021 | response = api_call(self, params) |
|
1021 | response = api_call(self, params) | |
1022 |
|
1022 | |||
1023 | expected = [] |
|
1023 | expected = [] | |
1024 |
for gr_name in [TEST_USER |
|
1024 | for gr_name in [TEST_USER_GROUP, 'test_users_group2']: | |
1025 |
users_group = User |
|
1025 | users_group = UserGroupModel().get_group(gr_name) | |
1026 | ret = users_group.get_api_data() |
|
1026 | ret = users_group.get_api_data() | |
1027 | expected.append(ret) |
|
1027 | expected.append(ret) | |
1028 | self._compare_ok(id_, expected, given=response.body) |
|
1028 | self._compare_ok(id_, expected, given=response.body) | |
1029 |
|
1029 | |||
1030 |
User |
|
1030 | UserGroupModel().delete(users_group='test_users_group2') | |
1031 | Session().commit() |
|
1031 | Session().commit() | |
1032 |
|
1032 | |||
1033 | def test_api_create_users_group(self): |
|
1033 | def test_api_create_users_group(self): | |
@@ -1037,8 +1037,8 b' class BaseTestApi(object):' | |||||
1037 | response = api_call(self, params) |
|
1037 | response = api_call(self, params) | |
1038 |
|
1038 | |||
1039 | ret = { |
|
1039 | ret = { | |
1040 |
'msg': 'created new user |
|
1040 | 'msg': 'created new user group `%s`' % group_name, | |
1041 |
'users_group': jsonify(User |
|
1041 | 'users_group': jsonify(UserGroupModel()\ | |
1042 | .get_by_name(group_name)\ |
|
1042 | .get_by_name(group_name)\ | |
1043 | .get_api_data()) |
|
1043 | .get_api_data()) | |
1044 | } |
|
1044 | } | |
@@ -1049,13 +1049,13 b' class BaseTestApi(object):' | |||||
1049 |
|
1049 | |||
1050 | def test_api_get_users_group_that_exist(self): |
|
1050 | def test_api_get_users_group_that_exist(self): | |
1051 | id_, params = _build_data(self.apikey, 'create_users_group', |
|
1051 | id_, params = _build_data(self.apikey, 'create_users_group', | |
1052 |
group_name=TEST_USER |
|
1052 | group_name=TEST_USER_GROUP) | |
1053 | response = api_call(self, params) |
|
1053 | response = api_call(self, params) | |
1054 |
|
1054 | |||
1055 |
expected = "user |
|
1055 | expected = "user group `%s` already exist" % TEST_USER_GROUP | |
1056 | self._compare_error(id_, expected, given=response.body) |
|
1056 | self._compare_error(id_, expected, given=response.body) | |
1057 |
|
1057 | |||
1058 |
@mock.patch.object(User |
|
1058 | @mock.patch.object(UserGroupModel, 'create', crash) | |
1059 | def test_api_get_users_group_exception_occurred(self): |
|
1059 | def test_api_get_users_group_exception_occurred(self): | |
1060 | group_name = 'exception_happens' |
|
1060 | group_name = 'exception_happens' | |
1061 | id_, params = _build_data(self.apikey, 'create_users_group', |
|
1061 | id_, params = _build_data(self.apikey, 'create_users_group', | |
@@ -1067,7 +1067,7 b' class BaseTestApi(object):' | |||||
1067 |
|
1067 | |||
1068 | def test_api_add_user_to_users_group(self): |
|
1068 | def test_api_add_user_to_users_group(self): | |
1069 | gr_name = 'test_group' |
|
1069 | gr_name = 'test_group' | |
1070 |
User |
|
1070 | UserGroupModel().create(gr_name) | |
1071 | Session().commit() |
|
1071 | Session().commit() | |
1072 | id_, params = _build_data(self.apikey, 'add_user_to_users_group', |
|
1072 | id_, params = _build_data(self.apikey, 'add_user_to_users_group', | |
1073 | usersgroupid=gr_name, |
|
1073 | usersgroupid=gr_name, | |
@@ -1075,13 +1075,13 b' class BaseTestApi(object):' | |||||
1075 | response = api_call(self, params) |
|
1075 | response = api_call(self, params) | |
1076 |
|
1076 | |||
1077 | expected = { |
|
1077 | expected = { | |
1078 |
'msg': 'added member `%s` to user |
|
1078 | 'msg': 'added member `%s` to user group `%s`' % ( | |
1079 | TEST_USER_ADMIN_LOGIN, gr_name |
|
1079 | TEST_USER_ADMIN_LOGIN, gr_name | |
1080 | ), |
|
1080 | ), | |
1081 | 'success': True} |
|
1081 | 'success': True} | |
1082 | self._compare_ok(id_, expected, given=response.body) |
|
1082 | self._compare_ok(id_, expected, given=response.body) | |
1083 |
|
1083 | |||
1084 |
User |
|
1084 | UserGroupModel().delete(users_group=gr_name) | |
1085 | Session().commit() |
|
1085 | Session().commit() | |
1086 |
|
1086 | |||
1087 | def test_api_add_user_to_users_group_that_doesnt_exist(self): |
|
1087 | def test_api_add_user_to_users_group_that_doesnt_exist(self): | |
@@ -1090,29 +1090,29 b' class BaseTestApi(object):' | |||||
1090 | userid=TEST_USER_ADMIN_LOGIN) |
|
1090 | userid=TEST_USER_ADMIN_LOGIN) | |
1091 | response = api_call(self, params) |
|
1091 | response = api_call(self, params) | |
1092 |
|
1092 | |||
1093 |
expected = 'user |
|
1093 | expected = 'user group `%s` does not exist' % 'false-group' | |
1094 | self._compare_error(id_, expected, given=response.body) |
|
1094 | self._compare_error(id_, expected, given=response.body) | |
1095 |
|
1095 | |||
1096 |
@mock.patch.object(User |
|
1096 | @mock.patch.object(UserGroupModel, 'add_user_to_group', crash) | |
1097 | def test_api_add_user_to_users_group_exception_occurred(self): |
|
1097 | def test_api_add_user_to_users_group_exception_occurred(self): | |
1098 | gr_name = 'test_group' |
|
1098 | gr_name = 'test_group' | |
1099 |
User |
|
1099 | UserGroupModel().create(gr_name) | |
1100 | Session().commit() |
|
1100 | Session().commit() | |
1101 | id_, params = _build_data(self.apikey, 'add_user_to_users_group', |
|
1101 | id_, params = _build_data(self.apikey, 'add_user_to_users_group', | |
1102 | usersgroupid=gr_name, |
|
1102 | usersgroupid=gr_name, | |
1103 | userid=TEST_USER_ADMIN_LOGIN) |
|
1103 | userid=TEST_USER_ADMIN_LOGIN) | |
1104 | response = api_call(self, params) |
|
1104 | response = api_call(self, params) | |
1105 |
|
1105 | |||
1106 |
expected = 'failed to add member to user |
|
1106 | expected = 'failed to add member to user group `%s`' % gr_name | |
1107 | self._compare_error(id_, expected, given=response.body) |
|
1107 | self._compare_error(id_, expected, given=response.body) | |
1108 |
|
1108 | |||
1109 |
User |
|
1109 | UserGroupModel().delete(users_group=gr_name) | |
1110 | Session().commit() |
|
1110 | Session().commit() | |
1111 |
|
1111 | |||
1112 | def test_api_remove_user_from_users_group(self): |
|
1112 | def test_api_remove_user_from_users_group(self): | |
1113 | gr_name = 'test_group_3' |
|
1113 | gr_name = 'test_group_3' | |
1114 |
gr = User |
|
1114 | gr = UserGroupModel().create(gr_name) | |
1115 |
User |
|
1115 | UserGroupModel().add_user_to_group(gr, user=TEST_USER_ADMIN_LOGIN) | |
1116 | Session().commit() |
|
1116 | Session().commit() | |
1117 | id_, params = _build_data(self.apikey, 'remove_user_from_users_group', |
|
1117 | id_, params = _build_data(self.apikey, 'remove_user_from_users_group', | |
1118 | usersgroupid=gr_name, |
|
1118 | usersgroupid=gr_name, | |
@@ -1120,30 +1120,30 b' class BaseTestApi(object):' | |||||
1120 | response = api_call(self, params) |
|
1120 | response = api_call(self, params) | |
1121 |
|
1121 | |||
1122 | expected = { |
|
1122 | expected = { | |
1123 |
'msg': 'removed member `%s` from user |
|
1123 | 'msg': 'removed member `%s` from user group `%s`' % ( | |
1124 | TEST_USER_ADMIN_LOGIN, gr_name |
|
1124 | TEST_USER_ADMIN_LOGIN, gr_name | |
1125 | ), |
|
1125 | ), | |
1126 | 'success': True} |
|
1126 | 'success': True} | |
1127 | self._compare_ok(id_, expected, given=response.body) |
|
1127 | self._compare_ok(id_, expected, given=response.body) | |
1128 |
|
1128 | |||
1129 |
User |
|
1129 | UserGroupModel().delete(users_group=gr_name) | |
1130 | Session().commit() |
|
1130 | Session().commit() | |
1131 |
|
1131 | |||
1132 |
@mock.patch.object(User |
|
1132 | @mock.patch.object(UserGroupModel, 'remove_user_from_group', crash) | |
1133 | def test_api_remove_user_from_users_group_exception_occurred(self): |
|
1133 | def test_api_remove_user_from_users_group_exception_occurred(self): | |
1134 | gr_name = 'test_group_3' |
|
1134 | gr_name = 'test_group_3' | |
1135 |
gr = User |
|
1135 | gr = UserGroupModel().create(gr_name) | |
1136 |
User |
|
1136 | UserGroupModel().add_user_to_group(gr, user=TEST_USER_ADMIN_LOGIN) | |
1137 | Session().commit() |
|
1137 | Session().commit() | |
1138 | id_, params = _build_data(self.apikey, 'remove_user_from_users_group', |
|
1138 | id_, params = _build_data(self.apikey, 'remove_user_from_users_group', | |
1139 | usersgroupid=gr_name, |
|
1139 | usersgroupid=gr_name, | |
1140 | userid=TEST_USER_ADMIN_LOGIN) |
|
1140 | userid=TEST_USER_ADMIN_LOGIN) | |
1141 | response = api_call(self, params) |
|
1141 | response = api_call(self, params) | |
1142 |
|
1142 | |||
1143 |
expected = 'failed to remove member from user |
|
1143 | expected = 'failed to remove member from user group `%s`' % gr_name | |
1144 | self._compare_error(id_, expected, given=response.body) |
|
1144 | self._compare_error(id_, expected, given=response.body) | |
1145 |
|
1145 | |||
1146 |
User |
|
1146 | UserGroupModel().delete(users_group=gr_name) | |
1147 | Session().commit() |
|
1147 | Session().commit() | |
1148 |
|
1148 | |||
1149 | @parameterized.expand([('none', 'repository.none'), |
|
1149 | @parameterized.expand([('none', 'repository.none'), | |
@@ -1224,13 +1224,13 b' class BaseTestApi(object):' | |||||
1224 | def test_api_grant_users_group_permission(self, name, perm): |
|
1224 | def test_api_grant_users_group_permission(self, name, perm): | |
1225 | id_, params = _build_data(self.apikey, 'grant_users_group_permission', |
|
1225 | id_, params = _build_data(self.apikey, 'grant_users_group_permission', | |
1226 | repoid=self.REPO, |
|
1226 | repoid=self.REPO, | |
1227 |
usersgroupid=TEST_USER |
|
1227 | usersgroupid=TEST_USER_GROUP, | |
1228 | perm=perm) |
|
1228 | perm=perm) | |
1229 | response = api_call(self, params) |
|
1229 | response = api_call(self, params) | |
1230 |
|
1230 | |||
1231 | ret = { |
|
1231 | ret = { | |
1232 |
'msg': 'Granted perm: `%s` for user |
|
1232 | 'msg': 'Granted perm: `%s` for user group: `%s` in repo: `%s`' % ( | |
1233 |
perm, TEST_USER |
|
1233 | perm, TEST_USER_GROUP, self.REPO | |
1234 | ), |
|
1234 | ), | |
1235 | 'success': True |
|
1235 | 'success': True | |
1236 | } |
|
1236 | } | |
@@ -1241,7 +1241,7 b' class BaseTestApi(object):' | |||||
1241 | perm = 'haha.no.permission' |
|
1241 | perm = 'haha.no.permission' | |
1242 | id_, params = _build_data(self.apikey, 'grant_users_group_permission', |
|
1242 | id_, params = _build_data(self.apikey, 'grant_users_group_permission', | |
1243 | repoid=self.REPO, |
|
1243 | repoid=self.REPO, | |
1244 |
usersgroupid=TEST_USER |
|
1244 | usersgroupid=TEST_USER_GROUP, | |
1245 | perm=perm) |
|
1245 | perm=perm) | |
1246 | response = api_call(self, params) |
|
1246 | response = api_call(self, params) | |
1247 |
|
1247 | |||
@@ -1253,28 +1253,28 b' class BaseTestApi(object):' | |||||
1253 | perm = 'repository.read' |
|
1253 | perm = 'repository.read' | |
1254 | id_, params = _build_data(self.apikey, 'grant_users_group_permission', |
|
1254 | id_, params = _build_data(self.apikey, 'grant_users_group_permission', | |
1255 | repoid=self.REPO, |
|
1255 | repoid=self.REPO, | |
1256 |
usersgroupid=TEST_USER |
|
1256 | usersgroupid=TEST_USER_GROUP, | |
1257 | perm=perm) |
|
1257 | perm=perm) | |
1258 | response = api_call(self, params) |
|
1258 | response = api_call(self, params) | |
1259 |
|
1259 | |||
1260 |
expected = 'failed to edit permission for user |
|
1260 | expected = 'failed to edit permission for user group: `%s` in repo: `%s`' % ( | |
1261 |
TEST_USER |
|
1261 | TEST_USER_GROUP, self.REPO | |
1262 | ) |
|
1262 | ) | |
1263 | self._compare_error(id_, expected, given=response.body) |
|
1263 | self._compare_error(id_, expected, given=response.body) | |
1264 |
|
1264 | |||
1265 | def test_api_revoke_users_group_permission(self): |
|
1265 | def test_api_revoke_users_group_permission(self): | |
1266 | RepoModel().grant_users_group_permission(repo=self.REPO, |
|
1266 | RepoModel().grant_users_group_permission(repo=self.REPO, | |
1267 |
group_name=TEST_USER |
|
1267 | group_name=TEST_USER_GROUP, | |
1268 | perm='repository.read') |
|
1268 | perm='repository.read') | |
1269 | Session().commit() |
|
1269 | Session().commit() | |
1270 | id_, params = _build_data(self.apikey, 'revoke_users_group_permission', |
|
1270 | id_, params = _build_data(self.apikey, 'revoke_users_group_permission', | |
1271 | repoid=self.REPO, |
|
1271 | repoid=self.REPO, | |
1272 |
usersgroupid=TEST_USER |
|
1272 | usersgroupid=TEST_USER_GROUP,) | |
1273 | response = api_call(self, params) |
|
1273 | response = api_call(self, params) | |
1274 |
|
1274 | |||
1275 | expected = { |
|
1275 | expected = { | |
1276 |
'msg': 'Revoked perm for user |
|
1276 | 'msg': 'Revoked perm for user group: `%s` in repo: `%s`' % ( | |
1277 |
TEST_USER |
|
1277 | TEST_USER_GROUP, self.REPO | |
1278 | ), |
|
1278 | ), | |
1279 | 'success': True |
|
1279 | 'success': True | |
1280 | } |
|
1280 | } | |
@@ -1285,10 +1285,10 b' class BaseTestApi(object):' | |||||
1285 |
|
1285 | |||
1286 | id_, params = _build_data(self.apikey, 'revoke_users_group_permission', |
|
1286 | id_, params = _build_data(self.apikey, 'revoke_users_group_permission', | |
1287 | repoid=self.REPO, |
|
1287 | repoid=self.REPO, | |
1288 |
usersgroupid=TEST_USER |
|
1288 | usersgroupid=TEST_USER_GROUP,) | |
1289 | response = api_call(self, params) |
|
1289 | response = api_call(self, params) | |
1290 |
|
1290 | |||
1291 |
expected = 'failed to edit permission for user |
|
1291 | expected = 'failed to edit permission for user group: `%s` in repo: `%s`' % ( | |
1292 |
TEST_USER |
|
1292 | TEST_USER_GROUP, self.REPO | |
1293 | ) |
|
1293 | ) | |
1294 | self._compare_error(id_, expected, given=response.body) |
|
1294 | self._compare_error(id_, expected, given=response.body) |
@@ -1,7 +1,7 b'' | |||||
1 | from rhodecode.tests import * |
|
1 | from rhodecode.tests import * | |
2 |
from rhodecode.model.db import User |
|
2 | from rhodecode.model.db import UserGroup, UserGroupToPerm, Permission | |
3 |
|
3 | |||
4 |
TEST_USER |
|
4 | TEST_USER_GROUP = 'admins_test' | |
5 |
|
5 | |||
6 |
|
6 | |||
7 | class TestAdminUsersGroupsController(TestController): |
|
7 | class TestAdminUsersGroupsController(TestController): | |
@@ -15,14 +15,14 b' class TestAdminUsersGroupsController(Tes' | |||||
15 |
|
15 | |||
16 | def test_create(self): |
|
16 | def test_create(self): | |
17 | self.log_user() |
|
17 | self.log_user() | |
18 |
users_group_name = TEST_USER |
|
18 | users_group_name = TEST_USER_GROUP | |
19 | response = self.app.post(url('users_groups'), |
|
19 | response = self.app.post(url('users_groups'), | |
20 | {'users_group_name': users_group_name, |
|
20 | {'users_group_name': users_group_name, | |
21 | 'active':True}) |
|
21 | 'active':True}) | |
22 | response.follow() |
|
22 | response.follow() | |
23 |
|
23 | |||
24 | self.checkSessionFlash(response, |
|
24 | self.checkSessionFlash(response, | |
25 |
'created user |
|
25 | 'created user group %s' % TEST_USER_GROUP) | |
26 |
|
26 | |||
27 | def test_new(self): |
|
27 | def test_new(self): | |
28 | response = self.app.get(url('new_users_group')) |
|
28 | response = self.app.get(url('new_users_group')) | |
@@ -39,50 +39,50 b' class TestAdminUsersGroupsController(Tes' | |||||
39 |
|
39 | |||
40 | def test_delete(self): |
|
40 | def test_delete(self): | |
41 | self.log_user() |
|
41 | self.log_user() | |
42 |
users_group_name = TEST_USER |
|
42 | users_group_name = TEST_USER_GROUP + 'another' | |
43 | response = self.app.post(url('users_groups'), |
|
43 | response = self.app.post(url('users_groups'), | |
44 | {'users_group_name':users_group_name, |
|
44 | {'users_group_name':users_group_name, | |
45 | 'active':True}) |
|
45 | 'active':True}) | |
46 | response.follow() |
|
46 | response.follow() | |
47 |
|
47 | |||
48 | self.checkSessionFlash(response, |
|
48 | self.checkSessionFlash(response, | |
49 |
'created user |
|
49 | 'created user group %s' % users_group_name) | |
50 |
|
50 | |||
51 |
gr = self.Session.query(User |
|
51 | gr = self.Session.query(UserGroup)\ | |
52 |
.filter(User |
|
52 | .filter(UserGroup.users_group_name == | |
53 | users_group_name).one() |
|
53 | users_group_name).one() | |
54 |
|
54 | |||
55 | response = self.app.delete(url('users_group', id=gr.users_group_id)) |
|
55 | response = self.app.delete(url('users_group', id=gr.users_group_id)) | |
56 |
|
56 | |||
57 |
gr = self.Session.query(User |
|
57 | gr = self.Session.query(UserGroup)\ | |
58 |
.filter(User |
|
58 | .filter(UserGroup.users_group_name == | |
59 | users_group_name).scalar() |
|
59 | users_group_name).scalar() | |
60 |
|
60 | |||
61 | self.assertEqual(gr, None) |
|
61 | self.assertEqual(gr, None) | |
62 |
|
62 | |||
63 | def test_enable_repository_read_on_group(self): |
|
63 | def test_enable_repository_read_on_group(self): | |
64 | self.log_user() |
|
64 | self.log_user() | |
65 |
users_group_name = TEST_USER |
|
65 | users_group_name = TEST_USER_GROUP + 'another2' | |
66 | response = self.app.post(url('users_groups'), |
|
66 | response = self.app.post(url('users_groups'), | |
67 | {'users_group_name': users_group_name, |
|
67 | {'users_group_name': users_group_name, | |
68 | 'active': True}) |
|
68 | 'active': True}) | |
69 | response.follow() |
|
69 | response.follow() | |
70 |
|
70 | |||
71 |
ug = User |
|
71 | ug = UserGroup.get_by_group_name(users_group_name) | |
72 | self.checkSessionFlash(response, |
|
72 | self.checkSessionFlash(response, | |
73 |
'created user |
|
73 | 'created user group %s' % users_group_name) | |
74 | ## ENABLE REPO CREATE ON A GROUP |
|
74 | ## ENABLE REPO CREATE ON A GROUP | |
75 | response = self.app.put(url('users_group_perm', id=ug.users_group_id), |
|
75 | response = self.app.put(url('users_group_perm', id=ug.users_group_id), | |
76 | {'create_repo_perm': True}) |
|
76 | {'create_repo_perm': True}) | |
77 |
|
77 | |||
78 | response.follow() |
|
78 | response.follow() | |
79 |
ug = User |
|
79 | ug = UserGroup.get_by_group_name(users_group_name) | |
80 | p = Permission.get_by_key('hg.create.repository') |
|
80 | p = Permission.get_by_key('hg.create.repository') | |
81 | p2 = Permission.get_by_key('hg.fork.none') |
|
81 | p2 = Permission.get_by_key('hg.fork.none') | |
82 | # check if user has this perms, they should be here since |
|
82 | # check if user has this perms, they should be here since | |
83 | # defaults are on |
|
83 | # defaults are on | |
84 |
perms = User |
|
84 | perms = UserGroupToPerm.query()\ | |
85 |
.filter(User |
|
85 | .filter(UserGroupToPerm.users_group == ug).all() | |
86 |
|
86 | |||
87 | self.assertEqual( |
|
87 | self.assertEqual( | |
88 | [[x.users_group_id, x.permission_id, ] for x in perms], |
|
88 | [[x.users_group_id, x.permission_id, ] for x in perms], | |
@@ -95,13 +95,13 b' class TestAdminUsersGroupsController(Tes' | |||||
95 | {}) |
|
95 | {}) | |
96 |
|
96 | |||
97 | response.follow() |
|
97 | response.follow() | |
98 |
ug = User |
|
98 | ug = UserGroup.get_by_group_name(users_group_name) | |
99 | p = Permission.get_by_key('hg.create.none') |
|
99 | p = Permission.get_by_key('hg.create.none') | |
100 | p2 = Permission.get_by_key('hg.fork.none') |
|
100 | p2 = Permission.get_by_key('hg.fork.none') | |
101 | # check if user has this perms, they should be here since |
|
101 | # check if user has this perms, they should be here since | |
102 | # defaults are on |
|
102 | # defaults are on | |
103 |
perms = User |
|
103 | perms = UserGroupToPerm.query()\ | |
104 |
.filter(User |
|
104 | .filter(UserGroupToPerm.users_group == ug).all() | |
105 |
|
105 | |||
106 | self.assertEqual( |
|
106 | self.assertEqual( | |
107 | sorted([[x.users_group_id, x.permission_id, ] for x in perms]), |
|
107 | sorted([[x.users_group_id, x.permission_id, ] for x in perms]), | |
@@ -110,18 +110,18 b' class TestAdminUsersGroupsController(Tes' | |||||
110 | ) |
|
110 | ) | |
111 |
|
111 | |||
112 | # DELETE ! |
|
112 | # DELETE ! | |
113 |
ug = User |
|
113 | ug = UserGroup.get_by_group_name(users_group_name) | |
114 | ugid = ug.users_group_id |
|
114 | ugid = ug.users_group_id | |
115 | response = self.app.delete(url('users_group', id=ug.users_group_id)) |
|
115 | response = self.app.delete(url('users_group', id=ug.users_group_id)) | |
116 | response = response.follow() |
|
116 | response = response.follow() | |
117 |
gr = self.Session.query(User |
|
117 | gr = self.Session.query(UserGroup)\ | |
118 |
.filter(User |
|
118 | .filter(UserGroup.users_group_name == | |
119 | users_group_name).scalar() |
|
119 | users_group_name).scalar() | |
120 |
|
120 | |||
121 | self.assertEqual(gr, None) |
|
121 | self.assertEqual(gr, None) | |
122 | p = Permission.get_by_key('hg.create.repository') |
|
122 | p = Permission.get_by_key('hg.create.repository') | |
123 |
perms = User |
|
123 | perms = UserGroupToPerm.query()\ | |
124 |
.filter(User |
|
124 | .filter(UserGroupToPerm.users_group_id == ugid).all() | |
125 | perms = [[x.users_group_id, |
|
125 | perms = [[x.users_group_id, | |
126 | x.permission_id, ] for x in perms] |
|
126 | x.permission_id, ] for x in perms] | |
127 | self.assertEqual( |
|
127 | self.assertEqual( | |
@@ -131,27 +131,27 b' class TestAdminUsersGroupsController(Tes' | |||||
131 |
|
131 | |||
132 | def test_enable_repository_fork_on_group(self): |
|
132 | def test_enable_repository_fork_on_group(self): | |
133 | self.log_user() |
|
133 | self.log_user() | |
134 |
users_group_name = TEST_USER |
|
134 | users_group_name = TEST_USER_GROUP + 'another2' | |
135 | response = self.app.post(url('users_groups'), |
|
135 | response = self.app.post(url('users_groups'), | |
136 | {'users_group_name': users_group_name, |
|
136 | {'users_group_name': users_group_name, | |
137 | 'active': True}) |
|
137 | 'active': True}) | |
138 | response.follow() |
|
138 | response.follow() | |
139 |
|
139 | |||
140 |
ug = User |
|
140 | ug = UserGroup.get_by_group_name(users_group_name) | |
141 | self.checkSessionFlash(response, |
|
141 | self.checkSessionFlash(response, | |
142 |
'created user |
|
142 | 'created user group %s' % users_group_name) | |
143 | ## ENABLE REPO CREATE ON A GROUP |
|
143 | ## ENABLE REPO CREATE ON A GROUP | |
144 | response = self.app.put(url('users_group_perm', id=ug.users_group_id), |
|
144 | response = self.app.put(url('users_group_perm', id=ug.users_group_id), | |
145 | {'fork_repo_perm': True}) |
|
145 | {'fork_repo_perm': True}) | |
146 |
|
146 | |||
147 | response.follow() |
|
147 | response.follow() | |
148 |
ug = User |
|
148 | ug = UserGroup.get_by_group_name(users_group_name) | |
149 | p = Permission.get_by_key('hg.create.none') |
|
149 | p = Permission.get_by_key('hg.create.none') | |
150 | p2 = Permission.get_by_key('hg.fork.repository') |
|
150 | p2 = Permission.get_by_key('hg.fork.repository') | |
151 | # check if user has this perms, they should be here since |
|
151 | # check if user has this perms, they should be here since | |
152 | # defaults are on |
|
152 | # defaults are on | |
153 |
perms = User |
|
153 | perms = UserGroupToPerm.query()\ | |
154 |
.filter(User |
|
154 | .filter(UserGroupToPerm.users_group == ug).all() | |
155 |
|
155 | |||
156 | self.assertEqual( |
|
156 | self.assertEqual( | |
157 | [[x.users_group_id, x.permission_id, ] for x in perms], |
|
157 | [[x.users_group_id, x.permission_id, ] for x in perms], | |
@@ -164,13 +164,13 b' class TestAdminUsersGroupsController(Tes' | |||||
164 | {}) |
|
164 | {}) | |
165 |
|
165 | |||
166 | response.follow() |
|
166 | response.follow() | |
167 |
ug = User |
|
167 | ug = UserGroup.get_by_group_name(users_group_name) | |
168 | p = Permission.get_by_key('hg.create.none') |
|
168 | p = Permission.get_by_key('hg.create.none') | |
169 | p2 = Permission.get_by_key('hg.fork.none') |
|
169 | p2 = Permission.get_by_key('hg.fork.none') | |
170 | # check if user has this perms, they should be here since |
|
170 | # check if user has this perms, they should be here since | |
171 | # defaults are on |
|
171 | # defaults are on | |
172 |
perms = User |
|
172 | perms = UserGroupToPerm.query()\ | |
173 |
.filter(User |
|
173 | .filter(UserGroupToPerm.users_group == ug).all() | |
174 |
|
174 | |||
175 | self.assertEqual( |
|
175 | self.assertEqual( | |
176 | [[x.users_group_id, x.permission_id, ] for x in perms], |
|
176 | [[x.users_group_id, x.permission_id, ] for x in perms], | |
@@ -179,18 +179,18 b' class TestAdminUsersGroupsController(Tes' | |||||
179 | ) |
|
179 | ) | |
180 |
|
180 | |||
181 | # DELETE ! |
|
181 | # DELETE ! | |
182 |
ug = User |
|
182 | ug = UserGroup.get_by_group_name(users_group_name) | |
183 | ugid = ug.users_group_id |
|
183 | ugid = ug.users_group_id | |
184 | response = self.app.delete(url('users_group', id=ug.users_group_id)) |
|
184 | response = self.app.delete(url('users_group', id=ug.users_group_id)) | |
185 | response = response.follow() |
|
185 | response = response.follow() | |
186 |
gr = self.Session.query(User |
|
186 | gr = self.Session.query(UserGroup)\ | |
187 |
.filter(User |
|
187 | .filter(UserGroup.users_group_name == | |
188 | users_group_name).scalar() |
|
188 | users_group_name).scalar() | |
189 |
|
189 | |||
190 | self.assertEqual(gr, None) |
|
190 | self.assertEqual(gr, None) | |
191 | p = Permission.get_by_key('hg.fork.repository') |
|
191 | p = Permission.get_by_key('hg.fork.repository') | |
192 |
perms = User |
|
192 | perms = UserGroupToPerm.query()\ | |
193 |
.filter(User |
|
193 | .filter(UserGroupToPerm.users_group_id == ugid).all() | |
194 | perms = [[x.users_group_id, |
|
194 | perms = [[x.users_group_id, | |
195 | x.permission_id, ] for x in perms] |
|
195 | x.permission_id, ] for x in perms] | |
196 | self.assertEqual( |
|
196 | self.assertEqual( |
@@ -120,7 +120,7 b' class TestCompareController(TestControll' | |||||
120 | ## files |
|
120 | ## files | |
121 | response.mustcontain("""<a href="/%s/compare/branch@%s...branch@%s?other_repo=%s#C--826e8142e6ba">file1</a>""" % (repo1.repo_name, rev2, rev1, repo2.repo_name)) |
|
121 | response.mustcontain("""<a href="/%s/compare/branch@%s...branch@%s?other_repo=%s#C--826e8142e6ba">file1</a>""" % (repo1.repo_name, rev2, rev1, repo2.repo_name)) | |
122 | #swap |
|
122 | #swap | |
123 |
response.mustcontain("""<a href="/%s/compare/branch@%s...branch@%s? |
|
123 | response.mustcontain("""<a href="/%s/compare/branch@%s...branch@%s?other_repo=%s">[swap]</a>""" % (repo2.repo_name, rev1, rev2, repo1.repo_name)) | |
124 |
|
124 | |||
125 | def test_compare_forks_on_branch_extra_commits_origin_has_incomming_hg(self): |
|
125 | def test_compare_forks_on_branch_extra_commits_origin_has_incomming_hg(self): | |
126 | self.log_user() |
|
126 | self.log_user() | |
@@ -173,7 +173,7 b' class TestCompareController(TestControll' | |||||
173 | ## files |
|
173 | ## files | |
174 | response.mustcontain("""<a href="/%s/compare/branch@%s...branch@%s?other_repo=%s#C--826e8142e6ba">file1</a>""" % (repo1.repo_name, rev2, rev1, repo2.repo_name)) |
|
174 | response.mustcontain("""<a href="/%s/compare/branch@%s...branch@%s?other_repo=%s#C--826e8142e6ba">file1</a>""" % (repo1.repo_name, rev2, rev1, repo2.repo_name)) | |
175 | #swap |
|
175 | #swap | |
176 |
response.mustcontain("""<a href="/%s/compare/branch@%s...branch@%s? |
|
176 | response.mustcontain("""<a href="/%s/compare/branch@%s...branch@%s?other_repo=%s">[swap]</a>""" % (repo2.repo_name, rev1, rev2, repo1.repo_name)) | |
177 |
|
177 | |||
178 | def test_compare_cherry_pick_changesets_from_bottom(self): |
|
178 | def test_compare_cherry_pick_changesets_from_bottom(self): | |
179 |
|
179 |
@@ -6,7 +6,7 b' class TestReposGroupsController(TestCont' | |||||
6 | def test_index(self): |
|
6 | def test_index(self): | |
7 | self.log_user() |
|
7 | self.log_user() | |
8 | response = self.app.get(url('repos_groups')) |
|
8 | response = self.app.get(url('repos_groups')) | |
9 |
response.mustcontain('There are no repositor |
|
9 | response.mustcontain('There are no repository groups yet') | |
10 |
|
10 | |||
11 | # def test_index_as_xml(self): |
|
11 | # def test_index_as_xml(self): | |
12 | # response = self.app.get(url('formatted_repos_groups', format='xml')) |
|
12 | # response = self.app.get(url('formatted_repos_groups', format='xml')) |
@@ -4,11 +4,11 b' from rhodecode.tests import *' | |||||
4 | from rhodecode.tests.models.common import _make_group |
|
4 | from rhodecode.tests.models.common import _make_group | |
5 | from rhodecode.model.repos_group import ReposGroupModel |
|
5 | from rhodecode.model.repos_group import ReposGroupModel | |
6 | from rhodecode.model.repo import RepoModel |
|
6 | from rhodecode.model.repo import RepoModel | |
7 |
from rhodecode.model.db import RepoGroup, User, User |
|
7 | from rhodecode.model.db import RepoGroup, User, UserGroupRepoGroupToPerm | |
8 | from rhodecode.model.user import UserModel |
|
8 | from rhodecode.model.user import UserModel | |
9 |
|
9 | |||
10 | from rhodecode.model.meta import Session |
|
10 | from rhodecode.model.meta import Session | |
11 |
from rhodecode.model.users_group import User |
|
11 | from rhodecode.model.users_group import UserGroupModel | |
12 | from rhodecode.lib.auth import AuthUser |
|
12 | from rhodecode.lib.auth import AuthUser | |
13 | from rhodecode.tests.api.api_base import create_repo |
|
13 | from rhodecode.tests.api.api_base import create_repo | |
14 |
|
14 | |||
@@ -51,7 +51,7 b' class TestPermissions(unittest.TestCase)' | |||||
51 | ReposGroupModel().delete(self.g2.group_id) |
|
51 | ReposGroupModel().delete(self.g2.group_id) | |
52 |
|
52 | |||
53 | if hasattr(self, 'ug1'): |
|
53 | if hasattr(self, 'ug1'): | |
54 |
User |
|
54 | UserGroupModel().delete(self.ug1, force=True) | |
55 |
|
55 | |||
56 | Session().commit() |
|
56 | Session().commit() | |
57 |
|
57 | |||
@@ -124,10 +124,10 b' class TestPermissions(unittest.TestCase)' | |||||
124 |
|
124 | |||
125 | def test_propagated_permission_from_users_group_by_explicit_perms_exist(self): |
|
125 | def test_propagated_permission_from_users_group_by_explicit_perms_exist(self): | |
126 | # make group |
|
126 | # make group | |
127 |
self.ug1 = User |
|
127 | self.ug1 = UserGroupModel().create('G1') | |
128 | # add user to group |
|
128 | # add user to group | |
129 |
|
129 | |||
130 |
User |
|
130 | UserGroupModel().add_user_to_group(self.ug1, self.u1) | |
131 |
|
131 | |||
132 | # set permission to lower |
|
132 | # set permission to lower | |
133 | new_perm = 'repository.none' |
|
133 | new_perm = 'repository.none' | |
@@ -158,10 +158,10 b' class TestPermissions(unittest.TestCase)' | |||||
158 |
|
158 | |||
159 | def test_propagated_permission_from_users_group(self): |
|
159 | def test_propagated_permission_from_users_group(self): | |
160 | # make group |
|
160 | # make group | |
161 |
self.ug1 = User |
|
161 | self.ug1 = UserGroupModel().create('G1') | |
162 | # add user to group |
|
162 | # add user to group | |
163 |
|
163 | |||
164 |
User |
|
164 | UserGroupModel().add_user_to_group(self.ug1, self.u3) | |
165 |
|
165 | |||
166 | # grant perm for group this should override default permission from user |
|
166 | # grant perm for group this should override default permission from user | |
167 | new_perm_gr = 'repository.write' |
|
167 | new_perm_gr = 'repository.write' | |
@@ -183,9 +183,9 b' class TestPermissions(unittest.TestCase)' | |||||
183 |
|
183 | |||
184 | def test_propagated_permission_from_users_group_lower_weight(self): |
|
184 | def test_propagated_permission_from_users_group_lower_weight(self): | |
185 | # make group |
|
185 | # make group | |
186 |
self.ug1 = User |
|
186 | self.ug1 = UserGroupModel().create('G1') | |
187 | # add user to group |
|
187 | # add user to group | |
188 |
User |
|
188 | UserGroupModel().add_user_to_group(self.ug1, self.u1) | |
189 |
|
189 | |||
190 | # set permission to lower |
|
190 | # set permission to lower | |
191 | new_perm_h = 'repository.write' |
|
191 | new_perm_h = 'repository.write' | |
@@ -299,13 +299,13 b' class TestPermissions(unittest.TestCase)' | |||||
299 | user=self.anon, |
|
299 | user=self.anon, | |
300 | perm='group.none') |
|
300 | perm='group.none') | |
301 | # make group |
|
301 | # make group | |
302 |
self.ug1 = User |
|
302 | self.ug1 = UserGroupModel().create('G1') | |
303 | # add user to group |
|
303 | # add user to group | |
304 |
User |
|
304 | UserGroupModel().add_user_to_group(self.ug1, self.u1) | |
305 | Session().commit() |
|
305 | Session().commit() | |
306 |
|
306 | |||
307 | # check if user is in the group |
|
307 | # check if user is in the group | |
308 |
membrs = [x.user_id for x in User |
|
308 | membrs = [x.user_id for x in UserGroupModel().get(self.ug1.users_group_id).members] | |
309 | self.assertEqual(membrs, [self.u1.user_id]) |
|
309 | self.assertEqual(membrs, [self.u1.user_id]) | |
310 | # add some user to that group |
|
310 | # add some user to that group | |
311 |
|
311 | |||
@@ -324,9 +324,9 b' class TestPermissions(unittest.TestCase)' | |||||
324 | perm='group.read') |
|
324 | perm='group.read') | |
325 | Session().commit() |
|
325 | Session().commit() | |
326 | # check if the |
|
326 | # check if the | |
327 |
obj = Session().query(User |
|
327 | obj = Session().query(UserGroupRepoGroupToPerm)\ | |
328 |
.filter(User |
|
328 | .filter(UserGroupRepoGroupToPerm.group == self.g1)\ | |
329 |
.filter(User |
|
329 | .filter(UserGroupRepoGroupToPerm.users_group == self.ug1)\ | |
330 | .scalar() |
|
330 | .scalar() | |
331 | self.assertEqual(obj.permission.permission_name, 'group.read') |
|
331 | self.assertEqual(obj.permission.permission_name, 'group.read') | |
332 |
|
332 | |||
@@ -439,10 +439,10 b' class TestPermissions(unittest.TestCase)' | |||||
439 | u1_auth = AuthUser(user_id=self.u1.user_id) |
|
439 | u1_auth = AuthUser(user_id=self.u1.user_id) | |
440 | self.assertEqual(u1_auth.permissions['repositories']['myownrepo'], |
|
440 | self.assertEqual(u1_auth.permissions['repositories']['myownrepo'], | |
441 | 'repository.admin') |
|
441 | 'repository.admin') | |
442 |
#set his permission as user |
|
442 | #set his permission as user group, he should still be admin | |
443 |
self.ug1 = User |
|
443 | self.ug1 = UserGroupModel().create('G1') | |
444 | # add user to group |
|
444 | # add user to group | |
445 |
User |
|
445 | UserGroupModel().add_user_to_group(self.ug1, self.u1) | |
446 | RepoModel().grant_users_group_permission(repo, group_name=self.ug1, |
|
446 | RepoModel().grant_users_group_permission(repo, group_name=self.ug1, | |
447 | perm='repository.none') |
|
447 | perm='repository.none') | |
448 |
|
448 |
@@ -1,12 +1,12 b'' | |||||
1 | import unittest |
|
1 | import unittest | |
2 | from rhodecode.tests import * |
|
2 | from rhodecode.tests import * | |
3 |
|
3 | |||
4 |
from rhodecode.model.db import User, User |
|
4 | from rhodecode.model.db import User, UserGroup, UserGroupMember, UserEmailMap,\ | |
5 | Permission |
|
5 | Permission | |
6 | from rhodecode.model.user import UserModel |
|
6 | from rhodecode.model.user import UserModel | |
7 |
|
7 | |||
8 | from rhodecode.model.meta import Session |
|
8 | from rhodecode.model.meta import Session | |
9 |
from rhodecode.model.users_group import User |
|
9 | from rhodecode.model.users_group import UserGroupModel | |
10 |
|
10 | |||
11 |
|
11 | |||
12 | class TestUser(unittest.TestCase): |
|
12 | class TestUser(unittest.TestCase): | |
@@ -22,19 +22,19 b' class TestUser(unittest.TestCase):' | |||||
22 | Session().commit() |
|
22 | Session().commit() | |
23 | self.assertEqual(User.get_by_username(u'test_user'), usr) |
|
23 | self.assertEqual(User.get_by_username(u'test_user'), usr) | |
24 |
|
24 | |||
25 |
# make user |
|
25 | # make user group | |
26 |
users_group = User |
|
26 | users_group = UserGroupModel().create('some_example_group') | |
27 | Session().commit() |
|
27 | Session().commit() | |
28 |
|
28 | |||
29 |
User |
|
29 | UserGroupModel().add_user_to_group(users_group, usr) | |
30 | Session().commit() |
|
30 | Session().commit() | |
31 |
|
31 | |||
32 |
self.assertEqual(User |
|
32 | self.assertEqual(UserGroup.get(users_group.users_group_id), users_group) | |
33 |
self.assertEqual(User |
|
33 | self.assertEqual(UserGroupMember.query().count(), 1) | |
34 | UserModel().delete(usr.user_id) |
|
34 | UserModel().delete(usr.user_id) | |
35 | Session().commit() |
|
35 | Session().commit() | |
36 |
|
36 | |||
37 |
self.assertEqual(User |
|
37 | self.assertEqual(UserGroupMember.query().all(), []) | |
38 |
|
38 | |||
39 | def test_additonal_email_as_main(self): |
|
39 | def test_additonal_email_as_main(self): | |
40 | usr = UserModel().create_or_update(username=u'test_user', |
|
40 | usr = UserModel().create_or_update(username=u'test_user', |
@@ -10,7 +10,7 b' from rhodecode.model.meta import Session' | |||||
10 | from nose.tools import with_setup |
|
10 | from nose.tools import with_setup | |
11 | from rhodecode.tests.models.common import _create_project_tree, check_tree_perms, \ |
|
11 | from rhodecode.tests.models.common import _create_project_tree, check_tree_perms, \ | |
12 | _get_perms, _check_expected_count, expected_count, _destroy_project_tree |
|
12 | _get_perms, _check_expected_count, expected_count, _destroy_project_tree | |
13 |
from rhodecode.model.users_group import User |
|
13 | from rhodecode.model.users_group import UserGroupModel | |
14 | from rhodecode.model.repo import RepoModel |
|
14 | from rhodecode.model.repo import RepoModel | |
15 |
|
15 | |||
16 |
|
16 | |||
@@ -40,10 +40,10 b' def setup_module():' | |||||
40 | Session().commit() |
|
40 | Session().commit() | |
41 | test_u2_id = test_u2.user_id |
|
41 | test_u2_id = test_u2.user_id | |
42 |
|
42 | |||
43 |
gr1 = User |
|
43 | gr1 = UserGroupModel().create(name='perms_group_1') | |
44 | Session().commit() |
|
44 | Session().commit() | |
45 | test_u2_gr_id = gr1.users_group_id |
|
45 | test_u2_gr_id = gr1.users_group_id | |
46 |
User |
|
46 | UserGroupModel().add_user_to_group(gr1, user=test_u2_id) | |
47 | Session().commit() |
|
47 | Session().commit() | |
48 |
|
48 | |||
49 | _get_repo_perms = functools.partial(_get_perms, key='repositories', |
|
49 | _get_repo_perms = functools.partial(_get_perms, key='repositories', |
@@ -209,6 +209,21 b' class TestLibs(unittest.TestCase):' | |||||
209 | grav = gravatar_url(email_address=em, size=24) |
|
209 | grav = gravatar_url(email_address=em, size=24) | |
210 | assert grav == 'https://server.com/%s/%s' % (_md5(em), 24) |
|
210 | assert grav == 'https://server.com/%s/%s' % (_md5(em), 24) | |
211 |
|
211 | |||
|
212 | def _quick_url(self, text, tmpl="""<a class="revision-link" href="%s">%s</a>""", url_=None): | |||
|
213 | """ | |||
|
214 | Changes `some text url[foo]` => `some text <a href="/">foo</a> | |||
|
215 | ||||
|
216 | :param text: | |||
|
217 | """ | |||
|
218 | import re | |||
|
219 | #quickly change expected url[] into a link | |||
|
220 | URL_PAT = re.compile(r'(?:url\[)(.+?)(?:\])') | |||
|
221 | ||||
|
222 | def url_func(match_obj): | |||
|
223 | _url = match_obj.groups()[0] | |||
|
224 | return tmpl % (url_ or '/some-url', _url) | |||
|
225 | return URL_PAT.sub(url_func, text) | |||
|
226 | ||||
212 | @parameterized.expand([ |
|
227 | @parameterized.expand([ | |
213 | ("", |
|
228 | ("", | |
214 | ""), |
|
229 | ""), | |
@@ -228,27 +243,48 b' class TestLibs(unittest.TestCase):' | |||||
228 | "url[ffffffffffff] some text traalaa"), |
|
243 | "url[ffffffffffff] some text traalaa"), | |
229 | ("""Multi line |
|
244 | ("""Multi line | |
230 | 123123123123 |
|
245 | 123123123123 | |
231 |
some text 123123123123 |
|
246 | some text 123123123123 | |
|
247 | sometimes ! | |||
|
248 | """, | |||
232 | """Multi line |
|
249 | """Multi line | |
233 | url[123123123123] |
|
250 | url[123123123123] | |
234 |
some text url[123123123123] |
|
251 | some text url[123123123123] | |
|
252 | sometimes ! | |||
|
253 | """) | |||
235 | ]) |
|
254 | ]) | |
236 | def test_urlify_changesets(self, sample, expected): |
|
255 | def test_urlify_changesets(self, sample, expected): | |
237 | import re |
|
|||
238 |
|
||||
239 | def fake_url(self, *args, **kwargs): |
|
256 | def fake_url(self, *args, **kwargs): | |
240 | return '/some-url' |
|
257 | return '/some-url' | |
241 |
|
258 | |||
242 | #quickly change expected url[] into a link |
|
259 | expected = self._quick_url(expected) | |
243 | URL_PAT = re.compile(r'(?:url\[)(.+?)(?:\])') |
|
|||
244 |
|
||||
245 | def url_func(match_obj): |
|
|||
246 | _url = match_obj.groups()[0] |
|
|||
247 | tmpl = """<a class="revision-link" href="/some-url">%s</a>""" |
|
|||
248 | return tmpl % _url |
|
|||
249 |
|
||||
250 | expected = URL_PAT.sub(url_func, expected) |
|
|||
251 |
|
260 | |||
252 | with mock.patch('pylons.url', fake_url): |
|
261 | with mock.patch('pylons.url', fake_url): | |
253 | from rhodecode.lib.helpers import urlify_changesets |
|
262 | from rhodecode.lib.helpers import urlify_changesets | |
254 | self.assertEqual(urlify_changesets(sample, 'repo_name'), expected) |
|
263 | self.assertEqual(urlify_changesets(sample, 'repo_name'), expected) | |
|
264 | ||||
|
265 | @parameterized.expand([ | |||
|
266 | ("", | |||
|
267 | "", | |||
|
268 | ""), | |||
|
269 | ("https://svn.apache.org/repos", | |||
|
270 | "url[https://svn.apache.org/repos]", | |||
|
271 | "https://svn.apache.org/repos"), | |||
|
272 | ("http://svn.apache.org/repos", | |||
|
273 | "url[http://svn.apache.org/repos]", | |||
|
274 | "http://svn.apache.org/repos"), | |||
|
275 | ("from rev a also rev http://google.com", | |||
|
276 | "from rev a also rev url[http://google.com]", | |||
|
277 | "http://google.com"), | |||
|
278 | ("""Multi line | |||
|
279 | https://foo.bar.com | |||
|
280 | some text lalala""", | |||
|
281 | """Multi line | |||
|
282 | url[https://foo.bar.com] | |||
|
283 | some text lalala""", | |||
|
284 | "https://foo.bar.com") | |||
|
285 | ]) | |||
|
286 | def test_urlify_test(self, sample, expected, url_): | |||
|
287 | from rhodecode.lib.helpers import urlify_text | |||
|
288 | expected = self._quick_url(expected, | |||
|
289 | tmpl="""<a href="%s">%s</a>""", url_=url_) | |||
|
290 | self.assertEqual(urlify_text(sample), expected) |
@@ -5,7 +5,7 b' import formencode' | |||||
5 | from rhodecode.tests import * |
|
5 | from rhodecode.tests import * | |
6 |
|
6 | |||
7 | from rhodecode.model import validators as v |
|
7 | from rhodecode.model import validators as v | |
8 |
from rhodecode.model.users_group import User |
|
8 | from rhodecode.model.users_group import UserGroupModel | |
9 |
|
9 | |||
10 | from rhodecode.model.meta import Session |
|
10 | from rhodecode.model.meta import Session | |
11 | from rhodecode.model.repos_group import ReposGroupModel |
|
11 | from rhodecode.model.repos_group import ReposGroupModel | |
@@ -51,25 +51,25 b' class TestReposGroups(unittest.TestCase)' | |||||
51 | self.assertEqual(TEST_USER_ADMIN_LOGIN, |
|
51 | self.assertEqual(TEST_USER_ADMIN_LOGIN, | |
52 | validator.to_python(TEST_USER_ADMIN_LOGIN)) |
|
52 | validator.to_python(TEST_USER_ADMIN_LOGIN)) | |
53 |
|
53 | |||
54 |
def test_ValidUser |
|
54 | def test_ValidUserGroup(self): | |
55 |
validator = v.ValidUser |
|
55 | validator = v.ValidUserGroup() | |
56 | self.assertRaises(formencode.Invalid, validator.to_python, 'default') |
|
56 | self.assertRaises(formencode.Invalid, validator.to_python, 'default') | |
57 | self.assertRaises(formencode.Invalid, validator.to_python, '.,') |
|
57 | self.assertRaises(formencode.Invalid, validator.to_python, '.,') | |
58 |
|
58 | |||
59 |
gr = User |
|
59 | gr = UserGroupModel().create('test') | |
60 |
gr2 = User |
|
60 | gr2 = UserGroupModel().create('tes2') | |
61 | Session.commit() |
|
61 | Session.commit() | |
62 | self.assertRaises(formencode.Invalid, validator.to_python, 'test') |
|
62 | self.assertRaises(formencode.Invalid, validator.to_python, 'test') | |
63 | assert gr.users_group_id != None |
|
63 | assert gr.users_group_id != None | |
64 |
validator = v.ValidUser |
|
64 | validator = v.ValidUserGroup(edit=True, | |
65 | old_data={'users_group_id': |
|
65 | old_data={'users_group_id': | |
66 | gr2.users_group_id}) |
|
66 | gr2.users_group_id}) | |
67 |
|
67 | |||
68 | self.assertRaises(formencode.Invalid, validator.to_python, 'test') |
|
68 | self.assertRaises(formencode.Invalid, validator.to_python, 'test') | |
69 | self.assertRaises(formencode.Invalid, validator.to_python, 'TesT') |
|
69 | self.assertRaises(formencode.Invalid, validator.to_python, 'TesT') | |
70 | self.assertRaises(formencode.Invalid, validator.to_python, 'TEST') |
|
70 | self.assertRaises(formencode.Invalid, validator.to_python, 'TEST') | |
71 |
User |
|
71 | UserGroupModel().delete(gr) | |
72 |
User |
|
72 | UserGroupModel().delete(gr2) | |
73 | Session.commit() |
|
73 | Session.commit() | |
74 |
|
74 | |||
75 | def test_ValidReposGroup(self): |
|
75 | def test_ValidReposGroup(self): |
@@ -35,11 +35,12 b' is_windows = __platform__ in _get_meta_v' | |||||
35 | requirements = [ |
|
35 | requirements = [ | |
36 | "waitress==0.8.2", |
|
36 | "waitress==0.8.2", | |
37 | "webob==1.0.8", |
|
37 | "webob==1.0.8", | |
|
38 | "webtest==1.4.3", | |||
38 | "Pylons==1.0.0", |
|
39 | "Pylons==1.0.0", | |
39 | "Beaker==1.6.4", |
|
40 | "Beaker==1.6.4", | |
40 | "WebHelpers==1.3", |
|
41 | "WebHelpers==1.3", | |
41 | "formencode==1.2.4", |
|
42 | "formencode==1.2.4", | |
42 |
"SQLAlchemy==0.7. |
|
43 | "SQLAlchemy==0.7.10", | |
43 | "Mako==0.7.3", |
|
44 | "Mako==0.7.3", | |
44 | "pygments>=1.5", |
|
45 | "pygments>=1.5", | |
45 | "whoosh>=2.4.0,<2.5", |
|
46 | "whoosh>=2.4.0,<2.5", |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now