##// END OF EJS Templates
permissions: rename write+ to write or higher for more explicit meaning.
marcink -
r4462:91b375f2 stable
parent child Browse files
Show More
@@ -1,140 +1,140 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2020 RhodeCode GmbH
3 # Copyright (C) 2011-2020 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import logging
21 import logging
22
22
23 from pyramid.httpexceptions import HTTPFound
23 from pyramid.httpexceptions import HTTPFound
24 from pyramid.view import view_config
24 from pyramid.view import view_config
25
25
26 from rhodecode.apps._base import RepoAppView
26 from rhodecode.apps._base import RepoAppView
27 from rhodecode.lib import helpers as h
27 from rhodecode.lib import helpers as h
28 from rhodecode.lib import audit_logger
28 from rhodecode.lib import audit_logger
29 from rhodecode.lib.auth import (
29 from rhodecode.lib.auth import (
30 LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired)
30 LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired)
31 from rhodecode.lib.utils2 import str2bool
31 from rhodecode.lib.utils2 import str2bool
32 from rhodecode.model.db import User
32 from rhodecode.model.db import User
33 from rhodecode.model.forms import RepoPermsForm
33 from rhodecode.model.forms import RepoPermsForm
34 from rhodecode.model.meta import Session
34 from rhodecode.model.meta import Session
35 from rhodecode.model.permission import PermissionModel
35 from rhodecode.model.permission import PermissionModel
36 from rhodecode.model.repo import RepoModel
36 from rhodecode.model.repo import RepoModel
37
37
38 log = logging.getLogger(__name__)
38 log = logging.getLogger(__name__)
39
39
40
40
41 class RepoSettingsPermissionsView(RepoAppView):
41 class RepoSettingsPermissionsView(RepoAppView):
42
42
43 def load_default_context(self):
43 def load_default_context(self):
44 c = self._get_local_tmpl_context()
44 c = self._get_local_tmpl_context()
45 return c
45 return c
46
46
47 @LoginRequired()
47 @LoginRequired()
48 @HasRepoPermissionAnyDecorator('repository.admin')
48 @HasRepoPermissionAnyDecorator('repository.admin')
49 @view_config(
49 @view_config(
50 route_name='edit_repo_perms', request_method='GET',
50 route_name='edit_repo_perms', request_method='GET',
51 renderer='rhodecode:templates/admin/repos/repo_edit.mako')
51 renderer='rhodecode:templates/admin/repos/repo_edit.mako')
52 def edit_permissions(self):
52 def edit_permissions(self):
53 _ = self.request.translate
53 _ = self.request.translate
54 c = self.load_default_context()
54 c = self.load_default_context()
55 c.active = 'permissions'
55 c.active = 'permissions'
56 if self.request.GET.get('branch_permissions'):
56 if self.request.GET.get('branch_permissions'):
57 h.flash(_('Explicitly add user or user group with write+ '
57 h.flash(_('Explicitly add user or user group with write or higher '
58 'permission to modify their branch permissions.'),
58 'permission to modify their branch permissions.'),
59 category='notice')
59 category='notice')
60 return self._get_template_context(c)
60 return self._get_template_context(c)
61
61
62 @LoginRequired()
62 @LoginRequired()
63 @HasRepoPermissionAnyDecorator('repository.admin')
63 @HasRepoPermissionAnyDecorator('repository.admin')
64 @CSRFRequired()
64 @CSRFRequired()
65 @view_config(
65 @view_config(
66 route_name='edit_repo_perms', request_method='POST',
66 route_name='edit_repo_perms', request_method='POST',
67 renderer='rhodecode:templates/admin/repos/repo_edit.mako')
67 renderer='rhodecode:templates/admin/repos/repo_edit.mako')
68 def edit_permissions_update(self):
68 def edit_permissions_update(self):
69 _ = self.request.translate
69 _ = self.request.translate
70 c = self.load_default_context()
70 c = self.load_default_context()
71 c.active = 'permissions'
71 c.active = 'permissions'
72 data = self.request.POST
72 data = self.request.POST
73 # store private flag outside of HTML to verify if we can modify
73 # store private flag outside of HTML to verify if we can modify
74 # default user permissions, prevents submission of FAKE post data
74 # default user permissions, prevents submission of FAKE post data
75 # into the form for private repos
75 # into the form for private repos
76 data['repo_private'] = self.db_repo.private
76 data['repo_private'] = self.db_repo.private
77 form = RepoPermsForm(self.request.translate)().to_python(data)
77 form = RepoPermsForm(self.request.translate)().to_python(data)
78 changes = RepoModel().update_permissions(
78 changes = RepoModel().update_permissions(
79 self.db_repo_name, form['perm_additions'], form['perm_updates'],
79 self.db_repo_name, form['perm_additions'], form['perm_updates'],
80 form['perm_deletions'])
80 form['perm_deletions'])
81
81
82 action_data = {
82 action_data = {
83 'added': changes['added'],
83 'added': changes['added'],
84 'updated': changes['updated'],
84 'updated': changes['updated'],
85 'deleted': changes['deleted'],
85 'deleted': changes['deleted'],
86 }
86 }
87 audit_logger.store_web(
87 audit_logger.store_web(
88 'repo.edit.permissions', action_data=action_data,
88 'repo.edit.permissions', action_data=action_data,
89 user=self._rhodecode_user, repo=self.db_repo)
89 user=self._rhodecode_user, repo=self.db_repo)
90
90
91 Session().commit()
91 Session().commit()
92 h.flash(_('Repository access permissions updated'), category='success')
92 h.flash(_('Repository access permissions updated'), category='success')
93
93
94 affected_user_ids = None
94 affected_user_ids = None
95 if changes.get('default_user_changed', False):
95 if changes.get('default_user_changed', False):
96 # if we change the default user, we need to flush everyone permissions
96 # if we change the default user, we need to flush everyone permissions
97 affected_user_ids = User.get_all_user_ids()
97 affected_user_ids = User.get_all_user_ids()
98 PermissionModel().flush_user_permission_caches(
98 PermissionModel().flush_user_permission_caches(
99 changes, affected_user_ids=affected_user_ids)
99 changes, affected_user_ids=affected_user_ids)
100
100
101 raise HTTPFound(
101 raise HTTPFound(
102 h.route_path('edit_repo_perms', repo_name=self.db_repo_name))
102 h.route_path('edit_repo_perms', repo_name=self.db_repo_name))
103
103
104 @LoginRequired()
104 @LoginRequired()
105 @HasRepoPermissionAnyDecorator('repository.admin')
105 @HasRepoPermissionAnyDecorator('repository.admin')
106 @CSRFRequired()
106 @CSRFRequired()
107 @view_config(
107 @view_config(
108 route_name='edit_repo_perms_set_private', request_method='POST',
108 route_name='edit_repo_perms_set_private', request_method='POST',
109 renderer='json_ext')
109 renderer='json_ext')
110 def edit_permissions_set_private_repo(self):
110 def edit_permissions_set_private_repo(self):
111 _ = self.request.translate
111 _ = self.request.translate
112 self.load_default_context()
112 self.load_default_context()
113
113
114 private_flag = str2bool(self.request.POST.get('private'))
114 private_flag = str2bool(self.request.POST.get('private'))
115
115
116 try:
116 try:
117 repo = RepoModel().get(self.db_repo.repo_id)
117 repo = RepoModel().get(self.db_repo.repo_id)
118 repo.private = private_flag
118 repo.private = private_flag
119 Session().add(repo)
119 Session().add(repo)
120 RepoModel().grant_user_permission(
120 RepoModel().grant_user_permission(
121 repo=self.db_repo, user=User.DEFAULT_USER, perm='repository.none'
121 repo=self.db_repo, user=User.DEFAULT_USER, perm='repository.none'
122 )
122 )
123
123
124 Session().commit()
124 Session().commit()
125
125
126 h.flash(_('Repository `{}` private mode set successfully').format(self.db_repo_name),
126 h.flash(_('Repository `{}` private mode set successfully').format(self.db_repo_name),
127 category='success')
127 category='success')
128 # NOTE(dan): we change repo private mode we need to notify all USERS
128 # NOTE(dan): we change repo private mode we need to notify all USERS
129 affected_user_ids = User.get_all_user_ids()
129 affected_user_ids = User.get_all_user_ids()
130 PermissionModel().trigger_permission_flush(affected_user_ids)
130 PermissionModel().trigger_permission_flush(affected_user_ids)
131
131
132 except Exception:
132 except Exception:
133 log.exception("Exception during update of repository")
133 log.exception("Exception during update of repository")
134 h.flash(_('Error occurred during update of repository {}').format(
134 h.flash(_('Error occurred during update of repository {}').format(
135 self.db_repo_name), category='error')
135 self.db_repo_name), category='error')
136
136
137 return {
137 return {
138 'redirect_url': h.route_path('edit_repo_perms', repo_name=self.db_repo_name),
138 'redirect_url': h.route_path('edit_repo_perms', repo_name=self.db_repo_name),
139 'private': private_flag
139 'private': private_flag
140 }
140 }
@@ -1,162 +1,162 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2020 RhodeCode GmbH
3 # Copyright (C) 2016-2020 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import os
21 import os
22 import sys
22 import sys
23 import json
23 import json
24 import logging
24 import logging
25
25
26 from rhodecode.lib.hooks_daemon import prepare_callback_daemon
26 from rhodecode.lib.hooks_daemon import prepare_callback_daemon
27 from rhodecode.lib.vcs.conf import settings as vcs_settings
27 from rhodecode.lib.vcs.conf import settings as vcs_settings
28 from rhodecode.model.scm import ScmModel
28 from rhodecode.model.scm import ScmModel
29
29
30 log = logging.getLogger(__name__)
30 log = logging.getLogger(__name__)
31
31
32
32
33 class VcsServer(object):
33 class VcsServer(object):
34 _path = None # set executable path for hg/git/svn binary
34 _path = None # set executable path for hg/git/svn binary
35 backend = None # set in child classes
35 backend = None # set in child classes
36 tunnel = None # subprocess handling tunnel
36 tunnel = None # subprocess handling tunnel
37 write_perms = ['repository.admin', 'repository.write']
37 write_perms = ['repository.admin', 'repository.write']
38 read_perms = ['repository.read', 'repository.admin', 'repository.write']
38 read_perms = ['repository.read', 'repository.admin', 'repository.write']
39
39
40 def __init__(self, user, user_permissions, config, env):
40 def __init__(self, user, user_permissions, config, env):
41 self.user = user
41 self.user = user
42 self.user_permissions = user_permissions
42 self.user_permissions = user_permissions
43 self.config = config
43 self.config = config
44 self.env = env
44 self.env = env
45 self.stdin = sys.stdin
45 self.stdin = sys.stdin
46
46
47 self.repo_name = None
47 self.repo_name = None
48 self.repo_mode = None
48 self.repo_mode = None
49 self.store = ''
49 self.store = ''
50 self.ini_path = ''
50 self.ini_path = ''
51
51
52 def _invalidate_cache(self, repo_name):
52 def _invalidate_cache(self, repo_name):
53 """
53 """
54 Set's cache for this repository for invalidation on next access
54 Set's cache for this repository for invalidation on next access
55
55
56 :param repo_name: full repo name, also a cache key
56 :param repo_name: full repo name, also a cache key
57 """
57 """
58 ScmModel().mark_for_invalidation(repo_name)
58 ScmModel().mark_for_invalidation(repo_name)
59
59
60 def has_write_perm(self):
60 def has_write_perm(self):
61 permission = self.user_permissions.get(self.repo_name)
61 permission = self.user_permissions.get(self.repo_name)
62 if permission in ['repository.write', 'repository.admin']:
62 if permission in ['repository.write', 'repository.admin']:
63 return True
63 return True
64
64
65 return False
65 return False
66
66
67 def _check_permissions(self, action):
67 def _check_permissions(self, action):
68 permission = self.user_permissions.get(self.repo_name)
68 permission = self.user_permissions.get(self.repo_name)
69 log.debug('permission for %s on %s are: %s',
69 log.debug('permission for %s on %s are: %s',
70 self.user, self.repo_name, permission)
70 self.user, self.repo_name, permission)
71
71
72 if not permission:
72 if not permission:
73 log.error('user `%s` permissions to repo:%s are empty. Forbidding access.',
73 log.error('user `%s` permissions to repo:%s are empty. Forbidding access.',
74 self.user, self.repo_name)
74 self.user, self.repo_name)
75 return -2
75 return -2
76
76
77 if action == 'pull':
77 if action == 'pull':
78 if permission in self.read_perms:
78 if permission in self.read_perms:
79 log.info(
79 log.info(
80 'READ Permissions for User "%s" detected to repo "%s"!',
80 'READ Permissions for User "%s" detected to repo "%s"!',
81 self.user, self.repo_name)
81 self.user, self.repo_name)
82 return 0
82 return 0
83 else:
83 else:
84 if permission in self.write_perms:
84 if permission in self.write_perms:
85 log.info(
85 log.info(
86 'WRITE+ Permissions for User "%s" detected to repo "%s"!',
86 'WRITE, or Higher Permissions for User "%s" detected to repo "%s"!',
87 self.user, self.repo_name)
87 self.user, self.repo_name)
88 return 0
88 return 0
89
89
90 log.error('Cannot properly fetch or verify user `%s` permissions. '
90 log.error('Cannot properly fetch or verify user `%s` permissions. '
91 'Permissions: %s, vcs action: %s',
91 'Permissions: %s, vcs action: %s',
92 self.user, permission, action)
92 self.user, permission, action)
93 return -2
93 return -2
94
94
95 def update_environment(self, action, extras=None):
95 def update_environment(self, action, extras=None):
96
96
97 scm_data = {
97 scm_data = {
98 'ip': os.environ['SSH_CLIENT'].split()[0],
98 'ip': os.environ['SSH_CLIENT'].split()[0],
99 'username': self.user.username,
99 'username': self.user.username,
100 'user_id': self.user.user_id,
100 'user_id': self.user.user_id,
101 'action': action,
101 'action': action,
102 'repository': self.repo_name,
102 'repository': self.repo_name,
103 'scm': self.backend,
103 'scm': self.backend,
104 'config': self.ini_path,
104 'config': self.ini_path,
105 'repo_store': self.store,
105 'repo_store': self.store,
106 'make_lock': None,
106 'make_lock': None,
107 'locked_by': [None, None],
107 'locked_by': [None, None],
108 'server_url': None,
108 'server_url': None,
109 'user_agent': 'ssh-user-agent',
109 'user_agent': 'ssh-user-agent',
110 'hooks': ['push', 'pull'],
110 'hooks': ['push', 'pull'],
111 'hooks_module': 'rhodecode.lib.hooks_daemon',
111 'hooks_module': 'rhodecode.lib.hooks_daemon',
112 'is_shadow_repo': False,
112 'is_shadow_repo': False,
113 'detect_force_push': False,
113 'detect_force_push': False,
114 'check_branch_perms': False,
114 'check_branch_perms': False,
115
115
116 'SSH': True,
116 'SSH': True,
117 'SSH_PERMISSIONS': self.user_permissions.get(self.repo_name),
117 'SSH_PERMISSIONS': self.user_permissions.get(self.repo_name),
118 }
118 }
119 if extras:
119 if extras:
120 scm_data.update(extras)
120 scm_data.update(extras)
121 os.putenv("RC_SCM_DATA", json.dumps(scm_data))
121 os.putenv("RC_SCM_DATA", json.dumps(scm_data))
122
122
123 def get_root_store(self):
123 def get_root_store(self):
124 root_store = self.store
124 root_store = self.store
125 if not root_store.endswith('/'):
125 if not root_store.endswith('/'):
126 # always append trailing slash
126 # always append trailing slash
127 root_store = root_store + '/'
127 root_store = root_store + '/'
128 return root_store
128 return root_store
129
129
130 def _handle_tunnel(self, extras):
130 def _handle_tunnel(self, extras):
131 # pre-auth
131 # pre-auth
132 action = 'pull'
132 action = 'pull'
133 exit_code = self._check_permissions(action)
133 exit_code = self._check_permissions(action)
134 if exit_code:
134 if exit_code:
135 return exit_code, False
135 return exit_code, False
136
136
137 req = self.env['request']
137 req = self.env['request']
138 server_url = req.host_url + req.script_name
138 server_url = req.host_url + req.script_name
139 extras['server_url'] = server_url
139 extras['server_url'] = server_url
140
140
141 log.debug('Using %s binaries from path %s', self.backend, self._path)
141 log.debug('Using %s binaries from path %s', self.backend, self._path)
142 exit_code = self.tunnel.run(extras)
142 exit_code = self.tunnel.run(extras)
143
143
144 return exit_code, action == "push"
144 return exit_code, action == "push"
145
145
146 def run(self, tunnel_extras=None):
146 def run(self, tunnel_extras=None):
147 tunnel_extras = tunnel_extras or {}
147 tunnel_extras = tunnel_extras or {}
148 extras = {}
148 extras = {}
149 extras.update(tunnel_extras)
149 extras.update(tunnel_extras)
150
150
151 callback_daemon, extras = prepare_callback_daemon(
151 callback_daemon, extras = prepare_callback_daemon(
152 extras, protocol=vcs_settings.HOOKS_PROTOCOL,
152 extras, protocol=vcs_settings.HOOKS_PROTOCOL,
153 host=vcs_settings.HOOKS_HOST,
153 host=vcs_settings.HOOKS_HOST,
154 use_direct_calls=False)
154 use_direct_calls=False)
155
155
156 with callback_daemon:
156 with callback_daemon:
157 try:
157 try:
158 return self._handle_tunnel(extras)
158 return self._handle_tunnel(extras)
159 finally:
159 finally:
160 log.debug('Running cleanup with cache invalidation')
160 log.debug('Running cleanup with cache invalidation')
161 if self.repo_name:
161 if self.repo_name:
162 self._invalidate_cache(self.repo_name)
162 self._invalidate_cache(self.repo_name)
@@ -1,598 +1,598 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2020 RhodeCode GmbH
3 # Copyright (C) 2010-2020 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 """
21 """
22 permissions model for RhodeCode
22 permissions model for RhodeCode
23 """
23 """
24 import collections
24 import collections
25 import logging
25 import logging
26 import traceback
26 import traceback
27
27
28 from sqlalchemy.exc import DatabaseError
28 from sqlalchemy.exc import DatabaseError
29
29
30 from rhodecode import events
30 from rhodecode import events
31 from rhodecode.model import BaseModel
31 from rhodecode.model import BaseModel
32 from rhodecode.model.db import (
32 from rhodecode.model.db import (
33 User, Permission, UserToPerm, UserRepoToPerm, UserRepoGroupToPerm,
33 User, Permission, UserToPerm, UserRepoToPerm, UserRepoGroupToPerm,
34 UserUserGroupToPerm, UserGroup, UserGroupToPerm, UserToRepoBranchPermission)
34 UserUserGroupToPerm, UserGroup, UserGroupToPerm, UserToRepoBranchPermission)
35 from rhodecode.lib.utils2 import str2bool, safe_int
35 from rhodecode.lib.utils2 import str2bool, safe_int
36
36
37 log = logging.getLogger(__name__)
37 log = logging.getLogger(__name__)
38
38
39
39
40 class PermissionModel(BaseModel):
40 class PermissionModel(BaseModel):
41 """
41 """
42 Permissions model for RhodeCode
42 Permissions model for RhodeCode
43 """
43 """
44
44
45 cls = Permission
45 cls = Permission
46 global_perms = {
46 global_perms = {
47 'default_repo_create': None,
47 'default_repo_create': None,
48 # special case for create repos on write access to group
48 # special case for create repos on write access to group
49 'default_repo_create_on_write': None,
49 'default_repo_create_on_write': None,
50 'default_repo_group_create': None,
50 'default_repo_group_create': None,
51 'default_user_group_create': None,
51 'default_user_group_create': None,
52 'default_fork_create': None,
52 'default_fork_create': None,
53 'default_inherit_default_permissions': None,
53 'default_inherit_default_permissions': None,
54 'default_register': None,
54 'default_register': None,
55 'default_password_reset': None,
55 'default_password_reset': None,
56 'default_extern_activate': None,
56 'default_extern_activate': None,
57
57
58 # object permissions below
58 # object permissions below
59 'default_repo_perm': None,
59 'default_repo_perm': None,
60 'default_group_perm': None,
60 'default_group_perm': None,
61 'default_user_group_perm': None,
61 'default_user_group_perm': None,
62
62
63 # branch
63 # branch
64 'default_branch_perm': None,
64 'default_branch_perm': None,
65 }
65 }
66
66
67 def set_global_permission_choices(self, c_obj, gettext_translator):
67 def set_global_permission_choices(self, c_obj, gettext_translator):
68 _ = gettext_translator
68 _ = gettext_translator
69
69
70 c_obj.repo_perms_choices = [
70 c_obj.repo_perms_choices = [
71 ('repository.none', _('None'),),
71 ('repository.none', _('None'),),
72 ('repository.read', _('Read'),),
72 ('repository.read', _('Read'),),
73 ('repository.write', _('Write'),),
73 ('repository.write', _('Write'),),
74 ('repository.admin', _('Admin'),)]
74 ('repository.admin', _('Admin'),)]
75
75
76 c_obj.group_perms_choices = [
76 c_obj.group_perms_choices = [
77 ('group.none', _('None'),),
77 ('group.none', _('None'),),
78 ('group.read', _('Read'),),
78 ('group.read', _('Read'),),
79 ('group.write', _('Write'),),
79 ('group.write', _('Write'),),
80 ('group.admin', _('Admin'),)]
80 ('group.admin', _('Admin'),)]
81
81
82 c_obj.user_group_perms_choices = [
82 c_obj.user_group_perms_choices = [
83 ('usergroup.none', _('None'),),
83 ('usergroup.none', _('None'),),
84 ('usergroup.read', _('Read'),),
84 ('usergroup.read', _('Read'),),
85 ('usergroup.write', _('Write'),),
85 ('usergroup.write', _('Write'),),
86 ('usergroup.admin', _('Admin'),)]
86 ('usergroup.admin', _('Admin'),)]
87
87
88 c_obj.branch_perms_choices = [
88 c_obj.branch_perms_choices = [
89 ('branch.none', _('Protected/No Access'),),
89 ('branch.none', _('Protected/No Access'),),
90 ('branch.merge', _('Web merge'),),
90 ('branch.merge', _('Web merge'),),
91 ('branch.push', _('Push'),),
91 ('branch.push', _('Push'),),
92 ('branch.push_force', _('Force Push'),)]
92 ('branch.push_force', _('Force Push'),)]
93
93
94 c_obj.register_choices = [
94 c_obj.register_choices = [
95 ('hg.register.none', _('Disabled')),
95 ('hg.register.none', _('Disabled')),
96 ('hg.register.manual_activate', _('Allowed with manual account activation')),
96 ('hg.register.manual_activate', _('Allowed with manual account activation')),
97 ('hg.register.auto_activate', _('Allowed with automatic account activation')),]
97 ('hg.register.auto_activate', _('Allowed with automatic account activation')),]
98
98
99 c_obj.password_reset_choices = [
99 c_obj.password_reset_choices = [
100 ('hg.password_reset.enabled', _('Allow password recovery')),
100 ('hg.password_reset.enabled', _('Allow password recovery')),
101 ('hg.password_reset.hidden', _('Hide password recovery link')),
101 ('hg.password_reset.hidden', _('Hide password recovery link')),
102 ('hg.password_reset.disabled', _('Disable password recovery')),]
102 ('hg.password_reset.disabled', _('Disable password recovery')),]
103
103
104 c_obj.extern_activate_choices = [
104 c_obj.extern_activate_choices = [
105 ('hg.extern_activate.manual', _('Manual activation of external account')),
105 ('hg.extern_activate.manual', _('Manual activation of external account')),
106 ('hg.extern_activate.auto', _('Automatic activation of external account')),]
106 ('hg.extern_activate.auto', _('Automatic activation of external account')),]
107
107
108 c_obj.repo_create_choices = [
108 c_obj.repo_create_choices = [
109 ('hg.create.none', _('Disabled')),
109 ('hg.create.none', _('Disabled')),
110 ('hg.create.repository', _('Enabled'))]
110 ('hg.create.repository', _('Enabled'))]
111
111
112 c_obj.repo_create_on_write_choices = [
112 c_obj.repo_create_on_write_choices = [
113 ('hg.create.write_on_repogroup.false', _('Disabled')),
113 ('hg.create.write_on_repogroup.false', _('Disabled')),
114 ('hg.create.write_on_repogroup.true', _('Enabled'))]
114 ('hg.create.write_on_repogroup.true', _('Enabled'))]
115
115
116 c_obj.user_group_create_choices = [
116 c_obj.user_group_create_choices = [
117 ('hg.usergroup.create.false', _('Disabled')),
117 ('hg.usergroup.create.false', _('Disabled')),
118 ('hg.usergroup.create.true', _('Enabled'))]
118 ('hg.usergroup.create.true', _('Enabled'))]
119
119
120 c_obj.repo_group_create_choices = [
120 c_obj.repo_group_create_choices = [
121 ('hg.repogroup.create.false', _('Disabled')),
121 ('hg.repogroup.create.false', _('Disabled')),
122 ('hg.repogroup.create.true', _('Enabled'))]
122 ('hg.repogroup.create.true', _('Enabled'))]
123
123
124 c_obj.fork_choices = [
124 c_obj.fork_choices = [
125 ('hg.fork.none', _('Disabled')),
125 ('hg.fork.none', _('Disabled')),
126 ('hg.fork.repository', _('Enabled'))]
126 ('hg.fork.repository', _('Enabled'))]
127
127
128 c_obj.inherit_default_permission_choices = [
128 c_obj.inherit_default_permission_choices = [
129 ('hg.inherit_default_perms.false', _('Disabled')),
129 ('hg.inherit_default_perms.false', _('Disabled')),
130 ('hg.inherit_default_perms.true', _('Enabled'))]
130 ('hg.inherit_default_perms.true', _('Enabled'))]
131
131
132 def get_default_perms(self, object_perms, suffix):
132 def get_default_perms(self, object_perms, suffix):
133 defaults = {}
133 defaults = {}
134 for perm in object_perms:
134 for perm in object_perms:
135 # perms
135 # perms
136 if perm.permission.permission_name.startswith('repository.'):
136 if perm.permission.permission_name.startswith('repository.'):
137 defaults['default_repo_perm' + suffix] = perm.permission.permission_name
137 defaults['default_repo_perm' + suffix] = perm.permission.permission_name
138
138
139 if perm.permission.permission_name.startswith('group.'):
139 if perm.permission.permission_name.startswith('group.'):
140 defaults['default_group_perm' + suffix] = perm.permission.permission_name
140 defaults['default_group_perm' + suffix] = perm.permission.permission_name
141
141
142 if perm.permission.permission_name.startswith('usergroup.'):
142 if perm.permission.permission_name.startswith('usergroup.'):
143 defaults['default_user_group_perm' + suffix] = perm.permission.permission_name
143 defaults['default_user_group_perm' + suffix] = perm.permission.permission_name
144
144
145 # branch
145 # branch
146 if perm.permission.permission_name.startswith('branch.'):
146 if perm.permission.permission_name.startswith('branch.'):
147 defaults['default_branch_perm' + suffix] = perm.permission.permission_name
147 defaults['default_branch_perm' + suffix] = perm.permission.permission_name
148
148
149 # creation of objects
149 # creation of objects
150 if perm.permission.permission_name.startswith('hg.create.write_on_repogroup'):
150 if perm.permission.permission_name.startswith('hg.create.write_on_repogroup'):
151 defaults['default_repo_create_on_write' + suffix] = perm.permission.permission_name
151 defaults['default_repo_create_on_write' + suffix] = perm.permission.permission_name
152
152
153 elif perm.permission.permission_name.startswith('hg.create.'):
153 elif perm.permission.permission_name.startswith('hg.create.'):
154 defaults['default_repo_create' + suffix] = perm.permission.permission_name
154 defaults['default_repo_create' + suffix] = perm.permission.permission_name
155
155
156 if perm.permission.permission_name.startswith('hg.fork.'):
156 if perm.permission.permission_name.startswith('hg.fork.'):
157 defaults['default_fork_create' + suffix] = perm.permission.permission_name
157 defaults['default_fork_create' + suffix] = perm.permission.permission_name
158
158
159 if perm.permission.permission_name.startswith('hg.inherit_default_perms.'):
159 if perm.permission.permission_name.startswith('hg.inherit_default_perms.'):
160 defaults['default_inherit_default_permissions' + suffix] = perm.permission.permission_name
160 defaults['default_inherit_default_permissions' + suffix] = perm.permission.permission_name
161
161
162 if perm.permission.permission_name.startswith('hg.repogroup.'):
162 if perm.permission.permission_name.startswith('hg.repogroup.'):
163 defaults['default_repo_group_create' + suffix] = perm.permission.permission_name
163 defaults['default_repo_group_create' + suffix] = perm.permission.permission_name
164
164
165 if perm.permission.permission_name.startswith('hg.usergroup.'):
165 if perm.permission.permission_name.startswith('hg.usergroup.'):
166 defaults['default_user_group_create' + suffix] = perm.permission.permission_name
166 defaults['default_user_group_create' + suffix] = perm.permission.permission_name
167
167
168 # registration and external account activation
168 # registration and external account activation
169 if perm.permission.permission_name.startswith('hg.register.'):
169 if perm.permission.permission_name.startswith('hg.register.'):
170 defaults['default_register' + suffix] = perm.permission.permission_name
170 defaults['default_register' + suffix] = perm.permission.permission_name
171
171
172 if perm.permission.permission_name.startswith('hg.password_reset.'):
172 if perm.permission.permission_name.startswith('hg.password_reset.'):
173 defaults['default_password_reset' + suffix] = perm.permission.permission_name
173 defaults['default_password_reset' + suffix] = perm.permission.permission_name
174
174
175 if perm.permission.permission_name.startswith('hg.extern_activate.'):
175 if perm.permission.permission_name.startswith('hg.extern_activate.'):
176 defaults['default_extern_activate' + suffix] = perm.permission.permission_name
176 defaults['default_extern_activate' + suffix] = perm.permission.permission_name
177
177
178 return defaults
178 return defaults
179
179
180 def _make_new_user_perm(self, user, perm_name):
180 def _make_new_user_perm(self, user, perm_name):
181 log.debug('Creating new user permission:%s', perm_name)
181 log.debug('Creating new user permission:%s', perm_name)
182 new = UserToPerm()
182 new = UserToPerm()
183 new.user = user
183 new.user = user
184 new.permission = Permission.get_by_key(perm_name)
184 new.permission = Permission.get_by_key(perm_name)
185 return new
185 return new
186
186
187 def _make_new_user_group_perm(self, user_group, perm_name):
187 def _make_new_user_group_perm(self, user_group, perm_name):
188 log.debug('Creating new user group permission:%s', perm_name)
188 log.debug('Creating new user group permission:%s', perm_name)
189 new = UserGroupToPerm()
189 new = UserGroupToPerm()
190 new.users_group = user_group
190 new.users_group = user_group
191 new.permission = Permission.get_by_key(perm_name)
191 new.permission = Permission.get_by_key(perm_name)
192 return new
192 return new
193
193
194 def _keep_perm(self, perm_name, keep_fields):
194 def _keep_perm(self, perm_name, keep_fields):
195 def get_pat(field_name):
195 def get_pat(field_name):
196 return {
196 return {
197 # global perms
197 # global perms
198 'default_repo_create': 'hg.create.',
198 'default_repo_create': 'hg.create.',
199 # special case for create repos on write access to group
199 # special case for create repos on write access to group
200 'default_repo_create_on_write': 'hg.create.write_on_repogroup.',
200 'default_repo_create_on_write': 'hg.create.write_on_repogroup.',
201 'default_repo_group_create': 'hg.repogroup.create.',
201 'default_repo_group_create': 'hg.repogroup.create.',
202 'default_user_group_create': 'hg.usergroup.create.',
202 'default_user_group_create': 'hg.usergroup.create.',
203 'default_fork_create': 'hg.fork.',
203 'default_fork_create': 'hg.fork.',
204 'default_inherit_default_permissions': 'hg.inherit_default_perms.',
204 'default_inherit_default_permissions': 'hg.inherit_default_perms.',
205
205
206 # application perms
206 # application perms
207 'default_register': 'hg.register.',
207 'default_register': 'hg.register.',
208 'default_password_reset': 'hg.password_reset.',
208 'default_password_reset': 'hg.password_reset.',
209 'default_extern_activate': 'hg.extern_activate.',
209 'default_extern_activate': 'hg.extern_activate.',
210
210
211 # object permissions below
211 # object permissions below
212 'default_repo_perm': 'repository.',
212 'default_repo_perm': 'repository.',
213 'default_group_perm': 'group.',
213 'default_group_perm': 'group.',
214 'default_user_group_perm': 'usergroup.',
214 'default_user_group_perm': 'usergroup.',
215 # branch
215 # branch
216 'default_branch_perm': 'branch.',
216 'default_branch_perm': 'branch.',
217
217
218 }[field_name]
218 }[field_name]
219 for field in keep_fields:
219 for field in keep_fields:
220 pat = get_pat(field)
220 pat = get_pat(field)
221 if perm_name.startswith(pat):
221 if perm_name.startswith(pat):
222 return True
222 return True
223 return False
223 return False
224
224
225 def _clear_object_perm(self, object_perms, preserve=None):
225 def _clear_object_perm(self, object_perms, preserve=None):
226 preserve = preserve or []
226 preserve = preserve or []
227 _deleted = []
227 _deleted = []
228 for perm in object_perms:
228 for perm in object_perms:
229 perm_name = perm.permission.permission_name
229 perm_name = perm.permission.permission_name
230 if not self._keep_perm(perm_name, keep_fields=preserve):
230 if not self._keep_perm(perm_name, keep_fields=preserve):
231 _deleted.append(perm_name)
231 _deleted.append(perm_name)
232 self.sa.delete(perm)
232 self.sa.delete(perm)
233 return _deleted
233 return _deleted
234
234
235 def _clear_user_perms(self, user_id, preserve=None):
235 def _clear_user_perms(self, user_id, preserve=None):
236 perms = self.sa.query(UserToPerm)\
236 perms = self.sa.query(UserToPerm)\
237 .filter(UserToPerm.user_id == user_id)\
237 .filter(UserToPerm.user_id == user_id)\
238 .all()
238 .all()
239 return self._clear_object_perm(perms, preserve=preserve)
239 return self._clear_object_perm(perms, preserve=preserve)
240
240
241 def _clear_user_group_perms(self, user_group_id, preserve=None):
241 def _clear_user_group_perms(self, user_group_id, preserve=None):
242 perms = self.sa.query(UserGroupToPerm)\
242 perms = self.sa.query(UserGroupToPerm)\
243 .filter(UserGroupToPerm.users_group_id == user_group_id)\
243 .filter(UserGroupToPerm.users_group_id == user_group_id)\
244 .all()
244 .all()
245 return self._clear_object_perm(perms, preserve=preserve)
245 return self._clear_object_perm(perms, preserve=preserve)
246
246
247 def _set_new_object_perms(self, obj_type, object, form_result, preserve=None):
247 def _set_new_object_perms(self, obj_type, object, form_result, preserve=None):
248 # clear current entries, to make this function idempotent
248 # clear current entries, to make this function idempotent
249 # it will fix even if we define more permissions or permissions
249 # it will fix even if we define more permissions or permissions
250 # are somehow missing
250 # are somehow missing
251 preserve = preserve or []
251 preserve = preserve or []
252 _global_perms = self.global_perms.copy()
252 _global_perms = self.global_perms.copy()
253 if obj_type not in ['user', 'user_group']:
253 if obj_type not in ['user', 'user_group']:
254 raise ValueError("obj_type must be on of 'user' or 'user_group'")
254 raise ValueError("obj_type must be on of 'user' or 'user_group'")
255 global_perms = len(_global_perms)
255 global_perms = len(_global_perms)
256 default_user_perms = len(Permission.DEFAULT_USER_PERMISSIONS)
256 default_user_perms = len(Permission.DEFAULT_USER_PERMISSIONS)
257 if global_perms != default_user_perms:
257 if global_perms != default_user_perms:
258 raise Exception(
258 raise Exception(
259 'Inconsistent permissions definition. Got {} vs {}'.format(
259 'Inconsistent permissions definition. Got {} vs {}'.format(
260 global_perms, default_user_perms))
260 global_perms, default_user_perms))
261
261
262 if obj_type == 'user':
262 if obj_type == 'user':
263 self._clear_user_perms(object.user_id, preserve)
263 self._clear_user_perms(object.user_id, preserve)
264 if obj_type == 'user_group':
264 if obj_type == 'user_group':
265 self._clear_user_group_perms(object.users_group_id, preserve)
265 self._clear_user_group_perms(object.users_group_id, preserve)
266
266
267 # now kill the keys that we want to preserve from the form.
267 # now kill the keys that we want to preserve from the form.
268 for key in preserve:
268 for key in preserve:
269 del _global_perms[key]
269 del _global_perms[key]
270
270
271 for k in _global_perms.copy():
271 for k in _global_perms.copy():
272 _global_perms[k] = form_result[k]
272 _global_perms[k] = form_result[k]
273
273
274 # at that stage we validate all are passed inside form_result
274 # at that stage we validate all are passed inside form_result
275 for _perm_key, perm_value in _global_perms.items():
275 for _perm_key, perm_value in _global_perms.items():
276 if perm_value is None:
276 if perm_value is None:
277 raise ValueError('Missing permission for %s' % (_perm_key,))
277 raise ValueError('Missing permission for %s' % (_perm_key,))
278
278
279 if obj_type == 'user':
279 if obj_type == 'user':
280 p = self._make_new_user_perm(object, perm_value)
280 p = self._make_new_user_perm(object, perm_value)
281 self.sa.add(p)
281 self.sa.add(p)
282 if obj_type == 'user_group':
282 if obj_type == 'user_group':
283 p = self._make_new_user_group_perm(object, perm_value)
283 p = self._make_new_user_group_perm(object, perm_value)
284 self.sa.add(p)
284 self.sa.add(p)
285
285
286 def _set_new_user_perms(self, user, form_result, preserve=None):
286 def _set_new_user_perms(self, user, form_result, preserve=None):
287 return self._set_new_object_perms(
287 return self._set_new_object_perms(
288 'user', user, form_result, preserve)
288 'user', user, form_result, preserve)
289
289
290 def _set_new_user_group_perms(self, user_group, form_result, preserve=None):
290 def _set_new_user_group_perms(self, user_group, form_result, preserve=None):
291 return self._set_new_object_perms(
291 return self._set_new_object_perms(
292 'user_group', user_group, form_result, preserve)
292 'user_group', user_group, form_result, preserve)
293
293
294 def set_new_user_perms(self, user, form_result):
294 def set_new_user_perms(self, user, form_result):
295 # calculate what to preserve from what is given in form_result
295 # calculate what to preserve from what is given in form_result
296 preserve = set(self.global_perms.keys()).difference(set(form_result.keys()))
296 preserve = set(self.global_perms.keys()).difference(set(form_result.keys()))
297 return self._set_new_user_perms(user, form_result, preserve)
297 return self._set_new_user_perms(user, form_result, preserve)
298
298
299 def set_new_user_group_perms(self, user_group, form_result):
299 def set_new_user_group_perms(self, user_group, form_result):
300 # calculate what to preserve from what is given in form_result
300 # calculate what to preserve from what is given in form_result
301 preserve = set(self.global_perms.keys()).difference(set(form_result.keys()))
301 preserve = set(self.global_perms.keys()).difference(set(form_result.keys()))
302 return self._set_new_user_group_perms(user_group, form_result, preserve)
302 return self._set_new_user_group_perms(user_group, form_result, preserve)
303
303
304 def create_permissions(self):
304 def create_permissions(self):
305 """
305 """
306 Create permissions for whole system
306 Create permissions for whole system
307 """
307 """
308 for p in Permission.PERMS:
308 for p in Permission.PERMS:
309 if not Permission.get_by_key(p[0]):
309 if not Permission.get_by_key(p[0]):
310 new_perm = Permission()
310 new_perm = Permission()
311 new_perm.permission_name = p[0]
311 new_perm.permission_name = p[0]
312 new_perm.permission_longname = p[0] # translation err with p[1]
312 new_perm.permission_longname = p[0] # translation err with p[1]
313 self.sa.add(new_perm)
313 self.sa.add(new_perm)
314
314
315 def _create_default_object_permission(self, obj_type, obj, obj_perms,
315 def _create_default_object_permission(self, obj_type, obj, obj_perms,
316 force=False):
316 force=False):
317 if obj_type not in ['user', 'user_group']:
317 if obj_type not in ['user', 'user_group']:
318 raise ValueError("obj_type must be on of 'user' or 'user_group'")
318 raise ValueError("obj_type must be on of 'user' or 'user_group'")
319
319
320 def _get_group(perm_name):
320 def _get_group(perm_name):
321 return '.'.join(perm_name.split('.')[:1])
321 return '.'.join(perm_name.split('.')[:1])
322
322
323 defined_perms_groups = map(
323 defined_perms_groups = map(
324 _get_group, (x.permission.permission_name for x in obj_perms))
324 _get_group, (x.permission.permission_name for x in obj_perms))
325 log.debug('GOT ALREADY DEFINED:%s', obj_perms)
325 log.debug('GOT ALREADY DEFINED:%s', obj_perms)
326
326
327 if force:
327 if force:
328 self._clear_object_perm(obj_perms)
328 self._clear_object_perm(obj_perms)
329 self.sa.commit()
329 self.sa.commit()
330 defined_perms_groups = []
330 defined_perms_groups = []
331 # for every default permission that needs to be created, we check if
331 # for every default permission that needs to be created, we check if
332 # it's group is already defined, if it's not we create default perm
332 # it's group is already defined, if it's not we create default perm
333 for perm_name in Permission.DEFAULT_USER_PERMISSIONS:
333 for perm_name in Permission.DEFAULT_USER_PERMISSIONS:
334 gr = _get_group(perm_name)
334 gr = _get_group(perm_name)
335 if gr not in defined_perms_groups:
335 if gr not in defined_perms_groups:
336 log.debug('GR:%s not found, creating permission %s',
336 log.debug('GR:%s not found, creating permission %s',
337 gr, perm_name)
337 gr, perm_name)
338 if obj_type == 'user':
338 if obj_type == 'user':
339 new_perm = self._make_new_user_perm(obj, perm_name)
339 new_perm = self._make_new_user_perm(obj, perm_name)
340 self.sa.add(new_perm)
340 self.sa.add(new_perm)
341 if obj_type == 'user_group':
341 if obj_type == 'user_group':
342 new_perm = self._make_new_user_group_perm(obj, perm_name)
342 new_perm = self._make_new_user_group_perm(obj, perm_name)
343 self.sa.add(new_perm)
343 self.sa.add(new_perm)
344
344
345 def create_default_user_permissions(self, user, force=False):
345 def create_default_user_permissions(self, user, force=False):
346 """
346 """
347 Creates only missing default permissions for user, if force is set it
347 Creates only missing default permissions for user, if force is set it
348 resets the default permissions for that user
348 resets the default permissions for that user
349
349
350 :param user:
350 :param user:
351 :param force:
351 :param force:
352 """
352 """
353 user = self._get_user(user)
353 user = self._get_user(user)
354 obj_perms = UserToPerm.query().filter(UserToPerm.user == user).all()
354 obj_perms = UserToPerm.query().filter(UserToPerm.user == user).all()
355 return self._create_default_object_permission(
355 return self._create_default_object_permission(
356 'user', user, obj_perms, force)
356 'user', user, obj_perms, force)
357
357
358 def create_default_user_group_permissions(self, user_group, force=False):
358 def create_default_user_group_permissions(self, user_group, force=False):
359 """
359 """
360 Creates only missing default permissions for user group, if force is
360 Creates only missing default permissions for user group, if force is
361 set it resets the default permissions for that user group
361 set it resets the default permissions for that user group
362
362
363 :param user_group:
363 :param user_group:
364 :param force:
364 :param force:
365 """
365 """
366 user_group = self._get_user_group(user_group)
366 user_group = self._get_user_group(user_group)
367 obj_perms = UserToPerm.query().filter(UserGroupToPerm.users_group == user_group).all()
367 obj_perms = UserToPerm.query().filter(UserGroupToPerm.users_group == user_group).all()
368 return self._create_default_object_permission(
368 return self._create_default_object_permission(
369 'user_group', user_group, obj_perms, force)
369 'user_group', user_group, obj_perms, force)
370
370
371 def update_application_permissions(self, form_result):
371 def update_application_permissions(self, form_result):
372 if 'perm_user_id' in form_result:
372 if 'perm_user_id' in form_result:
373 perm_user = User.get(safe_int(form_result['perm_user_id']))
373 perm_user = User.get(safe_int(form_result['perm_user_id']))
374 else:
374 else:
375 # used mostly to do lookup for default user
375 # used mostly to do lookup for default user
376 perm_user = User.get_by_username(form_result['perm_user_name'])
376 perm_user = User.get_by_username(form_result['perm_user_name'])
377
377
378 try:
378 try:
379 # stage 1 set anonymous access
379 # stage 1 set anonymous access
380 if perm_user.username == User.DEFAULT_USER:
380 if perm_user.username == User.DEFAULT_USER:
381 perm_user.active = str2bool(form_result['anonymous'])
381 perm_user.active = str2bool(form_result['anonymous'])
382 self.sa.add(perm_user)
382 self.sa.add(perm_user)
383
383
384 # stage 2 reset defaults and set them from form data
384 # stage 2 reset defaults and set them from form data
385 self._set_new_user_perms(perm_user, form_result, preserve=[
385 self._set_new_user_perms(perm_user, form_result, preserve=[
386 'default_repo_perm',
386 'default_repo_perm',
387 'default_group_perm',
387 'default_group_perm',
388 'default_user_group_perm',
388 'default_user_group_perm',
389 'default_branch_perm',
389 'default_branch_perm',
390
390
391 'default_repo_group_create',
391 'default_repo_group_create',
392 'default_user_group_create',
392 'default_user_group_create',
393 'default_repo_create_on_write',
393 'default_repo_create_on_write',
394 'default_repo_create',
394 'default_repo_create',
395 'default_fork_create',
395 'default_fork_create',
396 'default_inherit_default_permissions',])
396 'default_inherit_default_permissions',])
397
397
398 self.sa.commit()
398 self.sa.commit()
399 except (DatabaseError,):
399 except (DatabaseError,):
400 log.error(traceback.format_exc())
400 log.error(traceback.format_exc())
401 self.sa.rollback()
401 self.sa.rollback()
402 raise
402 raise
403
403
404 def update_user_permissions(self, form_result):
404 def update_user_permissions(self, form_result):
405 if 'perm_user_id' in form_result:
405 if 'perm_user_id' in form_result:
406 perm_user = User.get(safe_int(form_result['perm_user_id']))
406 perm_user = User.get(safe_int(form_result['perm_user_id']))
407 else:
407 else:
408 # used mostly to do lookup for default user
408 # used mostly to do lookup for default user
409 perm_user = User.get_by_username(form_result['perm_user_name'])
409 perm_user = User.get_by_username(form_result['perm_user_name'])
410 try:
410 try:
411 # stage 2 reset defaults and set them from form data
411 # stage 2 reset defaults and set them from form data
412 self._set_new_user_perms(perm_user, form_result, preserve=[
412 self._set_new_user_perms(perm_user, form_result, preserve=[
413 'default_repo_perm',
413 'default_repo_perm',
414 'default_group_perm',
414 'default_group_perm',
415 'default_user_group_perm',
415 'default_user_group_perm',
416 'default_branch_perm',
416 'default_branch_perm',
417
417
418 'default_register',
418 'default_register',
419 'default_password_reset',
419 'default_password_reset',
420 'default_extern_activate'])
420 'default_extern_activate'])
421 self.sa.commit()
421 self.sa.commit()
422 except (DatabaseError,):
422 except (DatabaseError,):
423 log.error(traceback.format_exc())
423 log.error(traceback.format_exc())
424 self.sa.rollback()
424 self.sa.rollback()
425 raise
425 raise
426
426
427 def update_user_group_permissions(self, form_result):
427 def update_user_group_permissions(self, form_result):
428 if 'perm_user_group_id' in form_result:
428 if 'perm_user_group_id' in form_result:
429 perm_user_group = UserGroup.get(safe_int(form_result['perm_user_group_id']))
429 perm_user_group = UserGroup.get(safe_int(form_result['perm_user_group_id']))
430 else:
430 else:
431 # used mostly to do lookup for default user
431 # used mostly to do lookup for default user
432 perm_user_group = UserGroup.get_by_group_name(form_result['perm_user_group_name'])
432 perm_user_group = UserGroup.get_by_group_name(form_result['perm_user_group_name'])
433 try:
433 try:
434 # stage 2 reset defaults and set them from form data
434 # stage 2 reset defaults and set them from form data
435 self._set_new_user_group_perms(perm_user_group, form_result, preserve=[
435 self._set_new_user_group_perms(perm_user_group, form_result, preserve=[
436 'default_repo_perm',
436 'default_repo_perm',
437 'default_group_perm',
437 'default_group_perm',
438 'default_user_group_perm',
438 'default_user_group_perm',
439 'default_branch_perm',
439 'default_branch_perm',
440
440
441 'default_register',
441 'default_register',
442 'default_password_reset',
442 'default_password_reset',
443 'default_extern_activate'])
443 'default_extern_activate'])
444 self.sa.commit()
444 self.sa.commit()
445 except (DatabaseError,):
445 except (DatabaseError,):
446 log.error(traceback.format_exc())
446 log.error(traceback.format_exc())
447 self.sa.rollback()
447 self.sa.rollback()
448 raise
448 raise
449
449
450 def update_object_permissions(self, form_result):
450 def update_object_permissions(self, form_result):
451 if 'perm_user_id' in form_result:
451 if 'perm_user_id' in form_result:
452 perm_user = User.get(safe_int(form_result['perm_user_id']))
452 perm_user = User.get(safe_int(form_result['perm_user_id']))
453 else:
453 else:
454 # used mostly to do lookup for default user
454 # used mostly to do lookup for default user
455 perm_user = User.get_by_username(form_result['perm_user_name'])
455 perm_user = User.get_by_username(form_result['perm_user_name'])
456 try:
456 try:
457
457
458 # stage 2 reset defaults and set them from form data
458 # stage 2 reset defaults and set them from form data
459 self._set_new_user_perms(perm_user, form_result, preserve=[
459 self._set_new_user_perms(perm_user, form_result, preserve=[
460 'default_repo_group_create',
460 'default_repo_group_create',
461 'default_user_group_create',
461 'default_user_group_create',
462 'default_repo_create_on_write',
462 'default_repo_create_on_write',
463 'default_repo_create',
463 'default_repo_create',
464 'default_fork_create',
464 'default_fork_create',
465 'default_inherit_default_permissions',
465 'default_inherit_default_permissions',
466 'default_branch_perm',
466 'default_branch_perm',
467
467
468 'default_register',
468 'default_register',
469 'default_password_reset',
469 'default_password_reset',
470 'default_extern_activate'])
470 'default_extern_activate'])
471
471
472 # overwrite default repo permissions
472 # overwrite default repo permissions
473 if form_result['overwrite_default_repo']:
473 if form_result['overwrite_default_repo']:
474 _def_name = form_result['default_repo_perm'].split('repository.')[-1]
474 _def_name = form_result['default_repo_perm'].split('repository.')[-1]
475 _def = Permission.get_by_key('repository.' + _def_name)
475 _def = Permission.get_by_key('repository.' + _def_name)
476 for r2p in self.sa.query(UserRepoToPerm)\
476 for r2p in self.sa.query(UserRepoToPerm)\
477 .filter(UserRepoToPerm.user == perm_user)\
477 .filter(UserRepoToPerm.user == perm_user)\
478 .all():
478 .all():
479 # don't reset PRIVATE repositories
479 # don't reset PRIVATE repositories
480 if not r2p.repository.private:
480 if not r2p.repository.private:
481 r2p.permission = _def
481 r2p.permission = _def
482 self.sa.add(r2p)
482 self.sa.add(r2p)
483
483
484 # overwrite default repo group permissions
484 # overwrite default repo group permissions
485 if form_result['overwrite_default_group']:
485 if form_result['overwrite_default_group']:
486 _def_name = form_result['default_group_perm'].split('group.')[-1]
486 _def_name = form_result['default_group_perm'].split('group.')[-1]
487 _def = Permission.get_by_key('group.' + _def_name)
487 _def = Permission.get_by_key('group.' + _def_name)
488 for g2p in self.sa.query(UserRepoGroupToPerm)\
488 for g2p in self.sa.query(UserRepoGroupToPerm)\
489 .filter(UserRepoGroupToPerm.user == perm_user)\
489 .filter(UserRepoGroupToPerm.user == perm_user)\
490 .all():
490 .all():
491 g2p.permission = _def
491 g2p.permission = _def
492 self.sa.add(g2p)
492 self.sa.add(g2p)
493
493
494 # overwrite default user group permissions
494 # overwrite default user group permissions
495 if form_result['overwrite_default_user_group']:
495 if form_result['overwrite_default_user_group']:
496 _def_name = form_result['default_user_group_perm'].split('usergroup.')[-1]
496 _def_name = form_result['default_user_group_perm'].split('usergroup.')[-1]
497 # user groups
497 # user groups
498 _def = Permission.get_by_key('usergroup.' + _def_name)
498 _def = Permission.get_by_key('usergroup.' + _def_name)
499 for g2p in self.sa.query(UserUserGroupToPerm)\
499 for g2p in self.sa.query(UserUserGroupToPerm)\
500 .filter(UserUserGroupToPerm.user == perm_user)\
500 .filter(UserUserGroupToPerm.user == perm_user)\
501 .all():
501 .all():
502 g2p.permission = _def
502 g2p.permission = _def
503 self.sa.add(g2p)
503 self.sa.add(g2p)
504
504
505 # COMMIT
505 # COMMIT
506 self.sa.commit()
506 self.sa.commit()
507 except (DatabaseError,):
507 except (DatabaseError,):
508 log.exception('Failed to set default object permissions')
508 log.exception('Failed to set default object permissions')
509 self.sa.rollback()
509 self.sa.rollback()
510 raise
510 raise
511
511
512 def update_branch_permissions(self, form_result):
512 def update_branch_permissions(self, form_result):
513 if 'perm_user_id' in form_result:
513 if 'perm_user_id' in form_result:
514 perm_user = User.get(safe_int(form_result['perm_user_id']))
514 perm_user = User.get(safe_int(form_result['perm_user_id']))
515 else:
515 else:
516 # used mostly to do lookup for default user
516 # used mostly to do lookup for default user
517 perm_user = User.get_by_username(form_result['perm_user_name'])
517 perm_user = User.get_by_username(form_result['perm_user_name'])
518 try:
518 try:
519
519
520 # stage 2 reset defaults and set them from form data
520 # stage 2 reset defaults and set them from form data
521 self._set_new_user_perms(perm_user, form_result, preserve=[
521 self._set_new_user_perms(perm_user, form_result, preserve=[
522 'default_repo_perm',
522 'default_repo_perm',
523 'default_group_perm',
523 'default_group_perm',
524 'default_user_group_perm',
524 'default_user_group_perm',
525
525
526 'default_repo_group_create',
526 'default_repo_group_create',
527 'default_user_group_create',
527 'default_user_group_create',
528 'default_repo_create_on_write',
528 'default_repo_create_on_write',
529 'default_repo_create',
529 'default_repo_create',
530 'default_fork_create',
530 'default_fork_create',
531 'default_inherit_default_permissions',
531 'default_inherit_default_permissions',
532
532
533 'default_register',
533 'default_register',
534 'default_password_reset',
534 'default_password_reset',
535 'default_extern_activate'])
535 'default_extern_activate'])
536
536
537 # overwrite default branch permissions
537 # overwrite default branch permissions
538 if form_result['overwrite_default_branch']:
538 if form_result['overwrite_default_branch']:
539 _def_name = \
539 _def_name = \
540 form_result['default_branch_perm'].split('branch.')[-1]
540 form_result['default_branch_perm'].split('branch.')[-1]
541
541
542 _def = Permission.get_by_key('branch.' + _def_name)
542 _def = Permission.get_by_key('branch.' + _def_name)
543
543
544 user_perms = UserToRepoBranchPermission.query()\
544 user_perms = UserToRepoBranchPermission.query()\
545 .join(UserToRepoBranchPermission.user_repo_to_perm)\
545 .join(UserToRepoBranchPermission.user_repo_to_perm)\
546 .filter(UserRepoToPerm.user == perm_user).all()
546 .filter(UserRepoToPerm.user == perm_user).all()
547
547
548 for g2p in user_perms:
548 for g2p in user_perms:
549 g2p.permission = _def
549 g2p.permission = _def
550 self.sa.add(g2p)
550 self.sa.add(g2p)
551
551
552 # COMMIT
552 # COMMIT
553 self.sa.commit()
553 self.sa.commit()
554 except (DatabaseError,):
554 except (DatabaseError,):
555 log.exception('Failed to set default branch permissions')
555 log.exception('Failed to set default branch permissions')
556 self.sa.rollback()
556 self.sa.rollback()
557 raise
557 raise
558
558
559 def get_users_with_repo_write(self, db_repo):
559 def get_users_with_repo_write(self, db_repo):
560 write_plus = ['repository.write', 'repository.admin']
560 write_plus = ['repository.write', 'repository.admin']
561 default_user_id = User.get_default_user_id()
561 default_user_id = User.get_default_user_id()
562 user_write_permissions = collections.OrderedDict()
562 user_write_permissions = collections.OrderedDict()
563
563
564 # write+ and DEFAULT user for inheritance
564 # write or higher and DEFAULT user for inheritance
565 for perm in db_repo.permissions():
565 for perm in db_repo.permissions():
566 if perm.permission in write_plus or perm.user_id == default_user_id:
566 if perm.permission in write_plus or perm.user_id == default_user_id:
567 user_write_permissions[perm.user_id] = perm
567 user_write_permissions[perm.user_id] = perm
568 return user_write_permissions
568 return user_write_permissions
569
569
570 def get_user_groups_with_repo_write(self, db_repo):
570 def get_user_groups_with_repo_write(self, db_repo):
571 write_plus = ['repository.write', 'repository.admin']
571 write_plus = ['repository.write', 'repository.admin']
572 user_group_write_permissions = collections.OrderedDict()
572 user_group_write_permissions = collections.OrderedDict()
573
573
574 # write+ and DEFAULT user for inheritance
574 # write or higher and DEFAULT user for inheritance
575 for p in db_repo.permission_user_groups():
575 for p in db_repo.permission_user_groups():
576 if p.permission in write_plus:
576 if p.permission in write_plus:
577 user_group_write_permissions[p.users_group_id] = p
577 user_group_write_permissions[p.users_group_id] = p
578 return user_group_write_permissions
578 return user_group_write_permissions
579
579
580 def trigger_permission_flush(self, affected_user_ids=None):
580 def trigger_permission_flush(self, affected_user_ids=None):
581 affected_user_ids or User.get_all_user_ids()
581 affected_user_ids or User.get_all_user_ids()
582 events.trigger(events.UserPermissionsChange(affected_user_ids))
582 events.trigger(events.UserPermissionsChange(affected_user_ids))
583
583
584 def flush_user_permission_caches(self, changes, affected_user_ids=None):
584 def flush_user_permission_caches(self, changes, affected_user_ids=None):
585 affected_user_ids = affected_user_ids or []
585 affected_user_ids = affected_user_ids or []
586
586
587 for change in changes['added'] + changes['updated'] + changes['deleted']:
587 for change in changes['added'] + changes['updated'] + changes['deleted']:
588 if change['type'] == 'user':
588 if change['type'] == 'user':
589 affected_user_ids.append(change['id'])
589 affected_user_ids.append(change['id'])
590 if change['type'] == 'user_group':
590 if change['type'] == 'user_group':
591 user_group = UserGroup.get(safe_int(change['id']))
591 user_group = UserGroup.get(safe_int(change['id']))
592 if user_group:
592 if user_group:
593 group_members_ids = [x.user_id for x in user_group.members]
593 group_members_ids = [x.user_id for x in user_group.members]
594 affected_user_ids.extend(group_members_ids)
594 affected_user_ids.extend(group_members_ids)
595
595
596 self.trigger_permission_flush(affected_user_ids)
596 self.trigger_permission_flush(affected_user_ids)
597
597
598 return affected_user_ids
598 return affected_user_ids
@@ -1,245 +1,245 b''
1 <%namespace name="base" file="/base/base.mako"/>
1 <%namespace name="base" file="/base/base.mako"/>
2
2
3 <div class="panel panel-default">
3 <div class="panel panel-default">
4 <div class="panel-heading">
4 <div class="panel-heading">
5 <h3 class="panel-title">${_('Repository Access Permissions')}</h3>
5 <h3 class="panel-title">${_('Repository Access Permissions')}</h3>
6 </div>
6 </div>
7 <div class="panel-body">
7 <div class="panel-body">
8 ${h.secure_form(h.route_path('edit_repo_perms', repo_name=c.repo_name), request=request)}
8 ${h.secure_form(h.route_path('edit_repo_perms', repo_name=c.repo_name), request=request)}
9 <table id="permissions_manage" class="rctable permissions">
9 <table id="permissions_manage" class="rctable permissions">
10 <tr>
10 <tr>
11 <th class="td-radio">${_('None')}</th>
11 <th class="td-radio">${_('None')}</th>
12 <th class="td-radio">${_('Read')}</th>
12 <th class="td-radio">${_('Read')}</th>
13 <th class="td-radio">${_('Write')}</th>
13 <th class="td-radio">${_('Write')}</th>
14 <th class="td-radio">${_('Admin')}</th>
14 <th class="td-radio">${_('Admin')}</th>
15 <th class="td-owner">${_('User/User Group')}</th>
15 <th class="td-owner">${_('User/User Group')}</th>
16 <th class="td-action"></th>
16 <th class="td-action"></th>
17 <th class="td-action"></th>
17 <th class="td-action"></th>
18 </tr>
18 </tr>
19 ## USERS
19 ## USERS
20 %for _user in c.rhodecode_db_repo.permissions():
20 %for _user in c.rhodecode_db_repo.permissions():
21 %if getattr(_user, 'admin_row', None) or getattr(_user, 'owner_row', None):
21 %if getattr(_user, 'admin_row', None) or getattr(_user, 'owner_row', None):
22 <tr class="perm_admin_row">
22 <tr class="perm_admin_row">
23 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.none', disabled="disabled")}</td>
23 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.none', disabled="disabled")}</td>
24 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.read', disabled="disabled")}</td>
24 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.read', disabled="disabled")}</td>
25 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.write', disabled="disabled")}</td>
25 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.write', disabled="disabled")}</td>
26 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.admin', 'repository.admin', disabled="disabled")}</td>
26 <td class="td-radio">${h.radio('admin_perm_%s' % _user.user_id,'repository.admin', 'repository.admin', disabled="disabled")}</td>
27 <td class="td-user">
27 <td class="td-user">
28 ${base.gravatar(_user.email, 16, user=_user, tooltip=True)}
28 ${base.gravatar(_user.email, 16, user=_user, tooltip=True)}
29 ${h.link_to_user(_user.username)}
29 ${h.link_to_user(_user.username)}
30 %if getattr(_user, 'admin_row', None):
30 %if getattr(_user, 'admin_row', None):
31 (${_('super-admin')})
31 (${_('super-admin')})
32 %endif
32 %endif
33 %if getattr(_user, 'owner_row', None):
33 %if getattr(_user, 'owner_row', None):
34 (${_('owner')})
34 (${_('owner')})
35 %endif
35 %endif
36 </td>
36 </td>
37 <td></td>
37 <td></td>
38 <td class="quick_repo_menu">
38 <td class="quick_repo_menu">
39 % if c.rhodecode_user.is_admin:
39 % if c.rhodecode_user.is_admin:
40 <i class="icon-more"></i>
40 <i class="icon-more"></i>
41 <div class="menu_items_container" style="display: none;">
41 <div class="menu_items_container" style="display: none;">
42 <ul class="menu_items">
42 <ul class="menu_items">
43 <li>
43 <li>
44 ${h.link_to('show permissions', h.route_path('edit_user_perms_summary', user_id=_user.user_id, _anchor='repositories-permissions'))}
44 ${h.link_to('show permissions', h.route_path('edit_user_perms_summary', user_id=_user.user_id, _anchor='repositories-permissions'))}
45 </li>
45 </li>
46 </ul>
46 </ul>
47 </div>
47 </div>
48 % endif
48 % endif
49 </td>
49 </td>
50 </tr>
50 </tr>
51 %elif _user.username == h.DEFAULT_USER and c.rhodecode_db_repo.private:
51 %elif _user.username == h.DEFAULT_USER and c.rhodecode_db_repo.private:
52 <tr>
52 <tr>
53 <td colspan="4">
53 <td colspan="4">
54 <span class="private_repo_msg">
54 <span class="private_repo_msg">
55 <strong title="${h.tooltip(_user.permission)}">${_('private repository')}</strong>
55 <strong title="${h.tooltip(_user.permission)}">${_('private repository')}</strong>
56 </span>
56 </span>
57 </td>
57 </td>
58 <td class="private_repo_msg">
58 <td class="private_repo_msg">
59 ${base.gravatar(h.DEFAULT_USER_EMAIL, 16)}
59 ${base.gravatar(h.DEFAULT_USER_EMAIL, 16)}
60 ${h.DEFAULT_USER} - ${_('only users/user groups explicitly added here will have access')}</td>
60 ${h.DEFAULT_USER} - ${_('only users/user groups explicitly added here will have access')}</td>
61 <td class="td-action">
61 <td class="td-action">
62 <span class="noselect tooltip btn btn-link btn-default" onclick="setPrivateRepo(this, false); return false" title="${_('Private repositories are only visible to people explicitly added as collaborators. Default permissions wont apply')}">
62 <span class="noselect tooltip btn btn-link btn-default" onclick="setPrivateRepo(this, false); return false" title="${_('Private repositories are only visible to people explicitly added as collaborators. Default permissions wont apply')}">
63 ${_('un-set private mode')}
63 ${_('un-set private mode')}
64 </span>
64 </span>
65 </td>
65 </td>
66 <td class="quick_repo_menu">
66 <td class="quick_repo_menu">
67 % if c.rhodecode_user.is_admin:
67 % if c.rhodecode_user.is_admin:
68 <i class="icon-more"></i>
68 <i class="icon-more"></i>
69 <div class="menu_items_container" style="display: none;">
69 <div class="menu_items_container" style="display: none;">
70 <ul class="menu_items">
70 <ul class="menu_items">
71 <li>
71 <li>
72 ${h.link_to('show permissions', h.route_path('admin_permissions_overview', _anchor='repositories-permissions'))}
72 ${h.link_to('show permissions', h.route_path('admin_permissions_overview', _anchor='repositories-permissions'))}
73 </li>
73 </li>
74 </ul>
74 </ul>
75 </div>
75 </div>
76 % endif
76 % endif
77 </td>
77 </td>
78 </tr>
78 </tr>
79 %else:
79 %else:
80 <% used_by_n_rules = len(getattr(_user, 'branch_rules', None) or []) %>
80 <% used_by_n_rules = len(getattr(_user, 'branch_rules', None) or []) %>
81 <tr>
81 <tr>
82 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'repository.none', checked=_user.permission=='repository.none', disabled="disabled" if (used_by_n_rules and _user.username != h.DEFAULT_USER) else None)}</td>
82 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'repository.none', checked=_user.permission=='repository.none', disabled="disabled" if (used_by_n_rules and _user.username != h.DEFAULT_USER) else None)}</td>
83 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'repository.read', checked=_user.permission=='repository.read', disabled="disabled" if (used_by_n_rules and _user.username != h.DEFAULT_USER) else None)}</td>
83 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'repository.read', checked=_user.permission=='repository.read', disabled="disabled" if (used_by_n_rules and _user.username != h.DEFAULT_USER) else None)}</td>
84 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'repository.write', checked=_user.permission=='repository.write')}</td>
84 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'repository.write', checked=_user.permission=='repository.write')}</td>
85 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'repository.admin', checked=_user.permission=='repository.admin')}</td>
85 <td class="td-radio">${h.radio('u_perm_%s' % _user.user_id,'repository.admin', checked=_user.permission=='repository.admin')}</td>
86 <td class="td-user">
86 <td class="td-user">
87 ${base.gravatar(_user.email, 16, user=_user, tooltip=True)}
87 ${base.gravatar(_user.email, 16, user=_user, tooltip=True)}
88 <span class="user">
88 <span class="user">
89 % if _user.username == h.DEFAULT_USER:
89 % if _user.username == h.DEFAULT_USER:
90 ${h.DEFAULT_USER}
90 ${h.DEFAULT_USER}
91 % if _user.active:
91 % if _user.active:
92 <span class="user-perm-help-text"> - ${_('permission for other logged in and anonymous users')}</span>
92 <span class="user-perm-help-text"> - ${_('permission for other logged in and anonymous users')}</span>
93 % else:
93 % else:
94 <span class="user-perm-help-text"> - ${_('permission for other logged in users')}</span>
94 <span class="user-perm-help-text"> - ${_('permission for other logged in users')}</span>
95 % endif
95 % endif
96 % else:
96 % else:
97 % if getattr(_user, 'duplicate_perm', None):
97 % if getattr(_user, 'duplicate_perm', None):
98 <span class="user-perm-duplicate">
98 <span class="user-perm-duplicate">
99 ${h.link_to_user(_user.username)}
99 ${h.link_to_user(_user.username)}
100 <span class="tooltip" title="${_('This entry is a duplicate, most probably left-over from previously set permission. This user has a higher permission set, so this entry is inactive. Please revoke this permission manually.')}">(${_('inactive duplicate')})
100 <span class="tooltip" title="${_('This entry is a duplicate, most probably left-over from previously set permission. This user has a higher permission set, so this entry is inactive. Please revoke this permission manually.')}">(${_('inactive duplicate')})
101 </span>
101 </span>
102 </span>
102 </span>
103 % else:
103 % else:
104 ${h.link_to_user(_user.username)}
104 ${h.link_to_user(_user.username)}
105 % endif
105 % endif
106
106
107 %if getattr(_user, 'branch_rules', None):
107 %if getattr(_user, 'branch_rules', None):
108 % if used_by_n_rules == 1:
108 % if used_by_n_rules == 1:
109 (${_('used by {} branch rule, requires write+ permissions').format(used_by_n_rules)})
109 (${_('used by {} branch rule, requires write or higher permissions').format(used_by_n_rules)})
110 % else:
110 % else:
111 (${_('used by {} branch rules, requires write+ permissions').format(used_by_n_rules)})
111 (${_('used by {} branch rules, requires write or higher permissions').format(used_by_n_rules)})
112 % endif
112 % endif
113 %endif
113 %endif
114 % endif
114 % endif
115 </span>
115 </span>
116 </td>
116 </td>
117 <td class="td-action">
117 <td class="td-action">
118 %if _user.username != h.DEFAULT_USER and getattr(_user, 'branch_rules', None) is None:
118 %if _user.username != h.DEFAULT_USER and getattr(_user, 'branch_rules', None) is None:
119 <span class="btn btn-link btn-danger revoke_perm"
119 <span class="btn btn-link btn-danger revoke_perm"
120 member="${_user.user_id}" member_type="user">
120 member="${_user.user_id}" member_type="user">
121 ${_('Remove')}
121 ${_('Remove')}
122 </span>
122 </span>
123 %elif _user.username == h.DEFAULT_USER:
123 %elif _user.username == h.DEFAULT_USER:
124 <span class="noselect tooltip btn btn-link btn-default" onclick="setPrivateRepo(this, true); return false" title="${_('Private repositories are only visible to people explicitly added as collaborators. Default permissions wont apply')}">
124 <span class="noselect tooltip btn btn-link btn-default" onclick="setPrivateRepo(this, true); return false" title="${_('Private repositories are only visible to people explicitly added as collaborators. Default permissions wont apply')}">
125 ${_('set private mode')}
125 ${_('set private mode')}
126 </span>
126 </span>
127 %endif
127 %endif
128 </td>
128 </td>
129 <td class="quick_repo_menu">
129 <td class="quick_repo_menu">
130 % if c.rhodecode_user.is_admin:
130 % if c.rhodecode_user.is_admin:
131 <i class="icon-more"></i>
131 <i class="icon-more"></i>
132 <div class="menu_items_container" style="display: none;">
132 <div class="menu_items_container" style="display: none;">
133 <ul class="menu_items">
133 <ul class="menu_items">
134 <li>
134 <li>
135 % if _user.username == h.DEFAULT_USER:
135 % if _user.username == h.DEFAULT_USER:
136 ${h.link_to('show permissions', h.route_path('admin_permissions_overview', _anchor='repositories-permissions'))}
136 ${h.link_to('show permissions', h.route_path('admin_permissions_overview', _anchor='repositories-permissions'))}
137 % else:
137 % else:
138 ${h.link_to('show permissions', h.route_path('edit_user_perms_summary', user_id=_user.user_id, _anchor='repositories-permissions'))}
138 ${h.link_to('show permissions', h.route_path('edit_user_perms_summary', user_id=_user.user_id, _anchor='repositories-permissions'))}
139 % endif
139 % endif
140 </li>
140 </li>
141 </ul>
141 </ul>
142 </div>
142 </div>
143 % endif
143 % endif
144 </td>
144 </td>
145 </tr>
145 </tr>
146 %endif
146 %endif
147 %endfor
147 %endfor
148
148
149 ## USER GROUPS
149 ## USER GROUPS
150 %for _user_group in c.rhodecode_db_repo.permission_user_groups(with_members=True):
150 %for _user_group in c.rhodecode_db_repo.permission_user_groups(with_members=True):
151 <tr>
151 <tr>
152 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'repository.none', checked=_user_group.permission=='repository.none')}</td>
152 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'repository.none', checked=_user_group.permission=='repository.none')}</td>
153 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'repository.read', checked=_user_group.permission=='repository.read')}</td>
153 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'repository.read', checked=_user_group.permission=='repository.read')}</td>
154 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'repository.write', checked=_user_group.permission=='repository.write')}</td>
154 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'repository.write', checked=_user_group.permission=='repository.write')}</td>
155 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'repository.admin', checked=_user_group.permission=='repository.admin')}</td>
155 <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'repository.admin', checked=_user_group.permission=='repository.admin')}</td>
156 <td class="td-componentname">
156 <td class="td-componentname">
157 ${base.user_group_icon(_user_group, tooltip=True)}
157 ${base.user_group_icon(_user_group, tooltip=True)}
158 %if c.is_super_admin:
158 %if c.is_super_admin:
159 <a href="${h.route_path('edit_user_group',user_group_id=_user_group.users_group_id)}">
159 <a href="${h.route_path('edit_user_group',user_group_id=_user_group.users_group_id)}">
160 ${_user_group.users_group_name}
160 ${_user_group.users_group_name}
161 </a>
161 </a>
162 %else:
162 %else:
163 ${h.link_to_group(_user_group.users_group_name)}
163 ${h.link_to_group(_user_group.users_group_name)}
164 %endif
164 %endif
165 (${_('members')}: ${len(_user_group.members)})
165 (${_('members')}: ${len(_user_group.members)})
166 </td>
166 </td>
167 <td class="td-action">
167 <td class="td-action">
168 <span class="btn btn-link btn-danger revoke_perm"
168 <span class="btn btn-link btn-danger revoke_perm"
169 member="${_user_group.users_group_id}" member_type="user_group">
169 member="${_user_group.users_group_id}" member_type="user_group">
170 ${_('Remove')}
170 ${_('Remove')}
171 </span>
171 </span>
172 </td>
172 </td>
173 <td class="quick_repo_menu">
173 <td class="quick_repo_menu">
174 % if c.rhodecode_user.is_admin:
174 % if c.rhodecode_user.is_admin:
175 <i class="icon-more"></i>
175 <i class="icon-more"></i>
176 <div class="menu_items_container" style="display: none;">
176 <div class="menu_items_container" style="display: none;">
177 <ul class="menu_items">
177 <ul class="menu_items">
178 <li>
178 <li>
179 ${h.link_to('show permissions', h.route_path('edit_user_group_perms_summary', user_group_id=_user_group.users_group_id, _anchor='repositories-permissions'))}
179 ${h.link_to('show permissions', h.route_path('edit_user_group_perms_summary', user_group_id=_user_group.users_group_id, _anchor='repositories-permissions'))}
180 </li>
180 </li>
181 </ul>
181 </ul>
182 </div>
182 </div>
183 % endif
183 % endif
184 </td>
184 </td>
185 </tr>
185 </tr>
186 %endfor
186 %endfor
187 <tr class="new_members" id="add_perm_input"></tr>
187 <tr class="new_members" id="add_perm_input"></tr>
188
188
189 <tr>
189 <tr>
190 <td></td>
190 <td></td>
191 <td></td>
191 <td></td>
192 <td></td>
192 <td></td>
193 <td></td>
193 <td></td>
194 <td></td>
194 <td></td>
195 <td>
195 <td>
196 <span id="add_perm" class="link">
196 <span id="add_perm" class="link">
197 ${_('Add user/user group')}
197 ${_('Add user/user group')}
198 </span>
198 </span>
199 </td>
199 </td>
200 <td></td>
200 <td></td>
201 </tr>
201 </tr>
202
202
203 </table>
203 </table>
204
204
205 <div class="buttons">
205 <div class="buttons">
206 ${h.submit('save',_('Save'),class_="btn btn-primary")}
206 ${h.submit('save',_('Save'),class_="btn btn-primary")}
207 ${h.reset('reset',_('Reset'),class_="btn btn-danger")}
207 ${h.reset('reset',_('Reset'),class_="btn btn-danger")}
208 </div>
208 </div>
209 ${h.end_form()}
209 ${h.end_form()}
210 </div>
210 </div>
211 </div>
211 </div>
212
212
213 <script type="text/javascript">
213 <script type="text/javascript">
214 $('#add_perm').on('click', function(e){
214 $('#add_perm').on('click', function(e){
215 addNewPermInput($(this), 'repository');
215 addNewPermInput($(this), 'repository');
216 });
216 });
217 $('.revoke_perm').on('click', function(e){
217 $('.revoke_perm').on('click', function(e){
218 markRevokePermInput($(this), 'repository');
218 markRevokePermInput($(this), 'repository');
219 });
219 });
220 quick_repo_menu();
220 quick_repo_menu();
221
221
222 var setPrivateRepo = function (elem, private) {
222 var setPrivateRepo = function (elem, private) {
223 var $elem = $(elem)
223 var $elem = $(elem)
224 if ($elem.hasClass('disabled')) {
224 if ($elem.hasClass('disabled')) {
225 return
225 return
226 }
226 }
227 $elem.addClass('disabled');
227 $elem.addClass('disabled');
228 $elem.css({"opacity": 0.3})
228 $elem.css({"opacity": 0.3})
229
229
230 var postData = {
230 var postData = {
231 'csrf_token': CSRF_TOKEN,
231 'csrf_token': CSRF_TOKEN,
232 'private': private
232 'private': private
233 };
233 };
234
234
235 var success = function(o) {
235 var success = function(o) {
236 var defaultUrl = pyroutes.url('edit_repo_perms', {"repo_name": templateContext.repo_name});
236 var defaultUrl = pyroutes.url('edit_repo_perms', {"repo_name": templateContext.repo_name});
237 window.location = o.redirect_url || defaultUrl;
237 window.location = o.redirect_url || defaultUrl;
238 };
238 };
239
239
240 ajaxPOST(
240 ajaxPOST(
241 pyroutes.url('edit_repo_perms_set_private', {"repo_name": templateContext.repo_name}),
241 pyroutes.url('edit_repo_perms_set_private', {"repo_name": templateContext.repo_name}),
242 postData,
242 postData,
243 success);
243 success);
244 }
244 }
245 </script>
245 </script>
General Comments 0
You need to be logged in to leave comments. Login now