##// END OF EJS Templates
auth: add scope and login restrictions to rhodecode plugin, and scope restriction to token plugin....
marcink -
r3392:5cc5c872 default
parent child Browse files
Show More
@@ -109,7 +109,17 b' class TestLoginController(object):'
109 109
110 110 def test_login_regular_forbidden_when_super_admin_restriction(self):
111 111 from rhodecode.authentication.plugins.auth_rhodecode import RhodeCodeAuthPlugin
112 with fixture.login_restriction(RhodeCodeAuthPlugin.LOGIN_RESTRICTION_SUPER_ADMIN):
112 with fixture.auth_restriction(RhodeCodeAuthPlugin.AUTH_RESTRICTION_SUPER_ADMIN):
113 response = self.app.post(route_path('login'),
114 {'username': 'test_regular',
115 'password': 'test12'})
116
117 response.mustcontain('invalid user name')
118 response.mustcontain('invalid password')
119
120 def test_login_regular_forbidden_when_scope_restriction(self):
121 from rhodecode.authentication.plugins.auth_rhodecode import RhodeCodeAuthPlugin
122 with fixture.scope_restriction(RhodeCodeAuthPlugin.AUTH_RESTRICTION_SCOPE_VCS):
113 123 response = self.app.post(route_path('login'),
114 124 {'username': 'test_regular',
115 125 'password': 'test12'})
@@ -26,13 +26,13 b' import logging'
26 26
27 27 import colander
28 28
29 from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase
30 29 from rhodecode.translation import _
31
32 from rhodecode.authentication.base import RhodeCodeAuthPluginBase, hybrid_property
33 from rhodecode.authentication.routes import AuthnPluginResourceBase
34 30 from rhodecode.lib.utils2 import safe_str
35 31 from rhodecode.model.db import User
32 from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase
33 from rhodecode.authentication.base import (
34 RhodeCodeAuthPluginBase, hybrid_property, HTTP_TYPE, VCS_TYPE)
35 from rhodecode.authentication.routes import AuthnPluginResourceBase
36 36
37 37 log = logging.getLogger(__name__)
38 38
@@ -48,8 +48,11 b' class RhodecodeAuthnResource(AuthnPlugin'
48 48
49 49 class RhodeCodeAuthPlugin(RhodeCodeAuthPluginBase):
50 50 uid = 'rhodecode'
51 LOGIN_RESTRICTION_NONE = 'none'
52 LOGIN_RESTRICTION_SUPER_ADMIN = 'super_admin'
51 AUTH_RESTRICTION_NONE = 'user_all'
52 AUTH_RESTRICTION_SUPER_ADMIN = 'user_super_admin'
53 AUTH_RESTRICTION_SCOPE_ALL = 'scope_all'
54 AUTH_RESTRICTION_SCOPE_HTTP = 'scope_http'
55 AUTH_RESTRICTION_SCOPE_VCS = 'scope_vcs'
53 56
54 57 def includeme(self, config):
55 58 config.add_authn_plugin(self)
@@ -104,16 +107,32 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP'
104 107 return None
105 108
106 109 if userobj.extern_type != self.name:
107 log.warning(
108 "userobj:%s extern_type mismatch got:`%s` expected:`%s`",
109 userobj, userobj.extern_type, self.name)
110 log.warning("userobj:%s extern_type mismatch got:`%s` expected:`%s`",
111 userobj, userobj.extern_type, self.name)
112 return None
113
114 # check scope of auth
115 scope_restriction = settings.get('scope_restriction', '')
116
117 if scope_restriction == self.AUTH_RESTRICTION_SCOPE_HTTP \
118 and self.auth_type != HTTP_TYPE:
119 log.warning("userobj:%s tried scope type %s and scope restriction is set to %s",
120 userobj, self.auth_type, scope_restriction)
110 121 return None
111 122
112 login_restriction = settings.get('login_restriction', '')
113 if login_restriction == self.LOGIN_RESTRICTION_SUPER_ADMIN and userobj.admin is False:
114 log.info(
115 "userobj:%s is not super-admin and login restriction is set to %s",
116 userobj, login_restriction)
123 if scope_restriction == self.AUTH_RESTRICTION_SCOPE_VCS \
124 and self.auth_type != VCS_TYPE:
125 log.warning("userobj:%s tried scope type %s and scope restriction is set to %s",
126 userobj, self.auth_type, scope_restriction)
127 return None
128
129 # check super-admin restriction
130 auth_restriction = settings.get('auth_restriction', '')
131
132 if auth_restriction == self.AUTH_RESTRICTION_SUPER_ADMIN \
133 and userobj.admin is False:
134 log.warning("userobj:%s is not super-admin and auth restriction is set to %s",
135 userobj, auth_restriction)
117 136 return None
118 137
119 138 user_attrs = {
@@ -154,30 +173,45 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP'
154 173 elif userobj.username == username and password_match:
155 174 log.info('user `%s` authenticated correctly', userobj.username)
156 175 return user_attrs
157 log.warn("user `%s` used a wrong password when "
158 "authenticating on this plugin", userobj.username)
176 log.warning("user `%s` used a wrong password when "
177 "authenticating on this plugin", userobj.username)
159 178 return None
160 179 else:
161 log.warning(
162 'user `%s` failed to authenticate via %s, reason: account not '
163 'active.', username, self.name)
180 log.warning('user `%s` failed to authenticate via %s, reason: account not '
181 'active.', username, self.name)
164 182 return None
165 183
166 184
167 185 class RhodeCodeSettingsSchema(AuthnPluginSettingsSchemaBase):
168 login_restriction_choices = [
169 (RhodeCodeAuthPlugin.LOGIN_RESTRICTION_NONE, 'All users'),
170 (RhodeCodeAuthPlugin.LOGIN_RESTRICTION_SUPER_ADMIN, 'Super admins only')
186
187 auth_restriction_choices = [
188 (RhodeCodeAuthPlugin.AUTH_RESTRICTION_NONE, 'All users'),
189 (RhodeCodeAuthPlugin.AUTH_RESTRICTION_SUPER_ADMIN, 'Super admins only'),
190 ]
191
192 auth_scope_choices = [
193 (RhodeCodeAuthPlugin.AUTH_RESTRICTION_SCOPE_ALL, 'HTTP and VCS'),
194 (RhodeCodeAuthPlugin.AUTH_RESTRICTION_SCOPE_HTTP, 'HTTP only'),
171 195 ]
172 196
173 login_restriction = colander.SchemaNode(
197 auth_restriction = colander.SchemaNode(
174 198 colander.String(),
175 default=login_restriction_choices[0],
176 description=_('Choose login restrition for users.'),
177 title=_('Login restriction'),
178 validator=colander.OneOf([x[0] for x in login_restriction_choices]),
199 default=auth_restriction_choices[0],
200 description=_('Allowed user types for authentication using this plugin.'),
201 title=_('User restriction'),
202 validator=colander.OneOf([x[0] for x in auth_restriction_choices]),
179 203 widget='select_with_labels',
180 choices=login_restriction_choices
204 choices=auth_restriction_choices
205 )
206 scope_restriction = colander.SchemaNode(
207 colander.String(),
208 default=auth_scope_choices[0],
209 description=_('Allowed protocols for authentication using this plugin. '
210 'VCS means GIT/HG/SVN. HTTP is web based login.'),
211 title=_('Scope restriction'),
212 validator=colander.OneOf([x[0] for x in auth_scope_choices]),
213 widget='select_with_labels',
214 choices=auth_scope_choices
181 215 )
182 216
183 217
@@ -23,7 +23,9 b' RhodeCode authentication token plugin fo'
23 23 """
24 24
25 25 import logging
26 import colander
26 27
28 from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase
27 29 from rhodecode.translation import _
28 30 from rhodecode.authentication.base import (
29 31 RhodeCodeAuthPluginBase, VCS_TYPE, hybrid_property)
@@ -48,6 +50,7 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP'
48 50 Enables usage of authentication tokens for vcs operations.
49 51 """
50 52 uid = 'token'
53 AUTH_RESTRICTION_SCOPE_VCS = 'scope_vcs'
51 54
52 55 def includeme(self, config):
53 56 config.add_authn_plugin(self)
@@ -67,6 +70,9 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP'
67 70 route_name='auth_home',
68 71 context=RhodecodeAuthnResource)
69 72
73 def get_settings_schema(self):
74 return RhodeCodeSettingsSchema()
75
70 76 def get_display_name(self):
71 77 return _('Rhodecode Token')
72 78
@@ -142,16 +148,30 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP'
142 148 'user `%s` successfully authenticated via %s',
143 149 user_attrs['username'], self.name)
144 150 return user_attrs
145 log.warn(
146 'user `%s` failed to authenticate via %s, reason: bad or '
147 'inactive token.', username, self.name)
151 log.warning('user `%s` failed to authenticate via %s, reason: bad or '
152 'inactive token.', username, self.name)
148 153 else:
149 log.warning(
150 'user `%s` failed to authenticate via %s, reason: account not '
151 'active.', username, self.name)
154 log.warning('user `%s` failed to authenticate via %s, reason: account not '
155 'active.', username, self.name)
152 156 return None
153 157
154 158
155 159 def includeme(config):
156 160 plugin_id = 'egg:rhodecode-enterprise-ce#{}'.format(RhodeCodeAuthPlugin.uid)
157 161 plugin_factory(plugin_id).includeme(config)
162
163
164 class RhodeCodeSettingsSchema(AuthnPluginSettingsSchemaBase):
165 auth_scope_choices = [
166 (RhodeCodeAuthPlugin.AUTH_RESTRICTION_SCOPE_VCS, 'VCS only'),
167 ]
168
169 scope_restriction = colander.SchemaNode(
170 colander.String(),
171 default=auth_scope_choices[0],
172 description=_('Choose operation scope restriction when authenticating.'),
173 title=_('Scope restriction'),
174 validator=colander.OneOf([x[0] for x in auth_scope_choices]),
175 widget='select_with_labels',
176 choices=auth_scope_choices
177 )
@@ -122,15 +122,15 b' class Fixture(object):'
122 122
123 123 return context()
124 124
125 def login_restriction(self, login_restriction):
125 def auth_restriction(self, auth_restriction):
126 126 """
127 Context process for changing the builtin rhodecode plugin login restrictions.
127 Context process for changing the builtin rhodecode plugin auth restrictions.
128 128 Use like:
129 129 fixture = Fixture()
130 with fixture.login_restriction('super_admin'):
130 with fixture.auth_restriction('super_admin'):
131 131 #tests
132 132
133 after this block login restriction will be taken off
133 after this block auth restriction will be taken off
134 134 """
135 135
136 136 class context(object):
@@ -143,13 +143,45 b' class Fixture(object):'
143 143 def __enter__(self):
144 144 plugin = self._get_pluing()
145 145 plugin.create_or_update_setting(
146 'login_restriction', login_restriction)
146 'auth_restriction', auth_restriction)
147 147 Session().commit()
148 148
149 149 def __exit__(self, exc_type, exc_val, exc_tb):
150 150 plugin = self._get_pluing()
151 151 plugin.create_or_update_setting(
152 'login_restriction', RhodeCodeAuthPlugin.LOGIN_RESTRICTION_NONE)
152 'auth_restriction', RhodeCodeAuthPlugin.AUTH_RESTRICTION_NONE)
153 Session().commit()
154
155 return context()
156
157 def scope_restriction(self, scope_restriction):
158 """
159 Context process for changing the builtin rhodecode plugin scope restrictions.
160 Use like:
161 fixture = Fixture()
162 with fixture.scope_restriction('scope_http'):
163 #tests
164
165 after this block scope restriction will be taken off
166 """
167
168 class context(object):
169 def _get_pluing(self):
170 plugin_id = 'egg:rhodecode-enterprise-ce#{}'.format(
171 RhodeCodeAuthPlugin.uid)
172 plugin = RhodeCodeAuthPlugin(plugin_id)
173 return plugin
174
175 def __enter__(self):
176 plugin = self._get_pluing()
177 plugin.create_or_update_setting(
178 'scope_restriction', scope_restriction)
179 Session().commit()
180
181 def __exit__(self, exc_type, exc_val, exc_tb):
182 plugin = self._get_pluing()
183 plugin.create_or_update_setting(
184 'scope_restriction', RhodeCodeAuthPlugin.AUTH_RESTRICTION_SCOPE_ALL)
153 185 Session().commit()
154 186
155 187 return context()
General Comments 0
You need to be logged in to leave comments. Login now