authentication: introduce login restriction option for builtin rhodecode plugin.
This commit is contained in:
parent
1ead0d3876
commit
26b57aead0
4 changed files with 75 additions and 14 deletions
|
|
@ -107,6 +107,16 @@ class TestLoginController(object):
|
|||
|
||||
response.mustcontain('/%s' % HG_REPO)
|
||||
|
||||
def test_login_regular_forbidden_when_super_admin_restriction(self):
|
||||
from rhodecode.authentication.plugins.auth_rhodecode import RhodeCodeAuthPlugin
|
||||
with fixture.login_restriction(RhodeCodeAuthPlugin.LOGIN_RESTRICTION_SUPER_ADMIN):
|
||||
response = self.app.post(route_path('login'),
|
||||
{'username': 'test_regular',
|
||||
'password': 'test12'})
|
||||
|
||||
response.mustcontain('invalid user name')
|
||||
response.mustcontain('invalid password')
|
||||
|
||||
def test_login_ok_came_from(self):
|
||||
test_came_from = '/_admin/users?branch=stable'
|
||||
_url = '{}?came_from={}'.format(route_path('login'), test_came_from)
|
||||
|
|
|
|||
|
|
@ -46,20 +46,10 @@ class RhodecodeAuthnResource(AuthnPluginResourceBase):
|
|||
pass
|
||||
|
||||
|
||||
class RhodeCodeSettingsSchema(AuthnPluginSettingsSchemaBase):
|
||||
|
||||
superadmin_restriction = colander.SchemaNode(
|
||||
colander.Bool(),
|
||||
default=False,
|
||||
description=_('Only allow super-admins to log-in using this plugin.'),
|
||||
missing=False,
|
||||
title=_('Enabled'),
|
||||
widget='bool',
|
||||
)
|
||||
|
||||
|
||||
class RhodeCodeAuthPlugin(RhodeCodeAuthPluginBase):
|
||||
uid = 'rhodecode'
|
||||
LOGIN_RESTRICTION_NONE = 'none'
|
||||
LOGIN_RESTRICTION_SUPER_ADMIN = 'super_admin'
|
||||
|
||||
def includeme(self, config):
|
||||
config.add_authn_plugin(self)
|
||||
|
|
@ -112,12 +102,20 @@ class RhodeCodeAuthPlugin(RhodeCodeAuthPluginBase):
|
|||
if not userobj:
|
||||
log.debug('userobj was:%s skipping', userobj)
|
||||
return None
|
||||
|
||||
if userobj.extern_type != self.name:
|
||||
log.warning(
|
||||
"userobj:%s extern_type mismatch got:`%s` expected:`%s`",
|
||||
userobj, userobj.extern_type, self.name)
|
||||
return None
|
||||
|
||||
login_restriction = settings.get('login_restriction', '')
|
||||
if login_restriction == self.LOGIN_RESTRICTION_SUPER_ADMIN and userobj.admin is False:
|
||||
log.info(
|
||||
"userobj:%s is not super-admin and login restriction is set to %s",
|
||||
userobj, login_restriction)
|
||||
return None
|
||||
|
||||
user_attrs = {
|
||||
"username": userobj.username,
|
||||
"firstname": userobj.firstname,
|
||||
|
|
@ -149,8 +147,8 @@ class RhodeCodeAuthPlugin(RhodeCodeAuthPluginBase):
|
|||
user_attrs['_hash_migrate'] = new_hash
|
||||
|
||||
if userobj.username == User.DEFAULT_USER and userobj.active:
|
||||
log.info(
|
||||
'user `%s` authenticated correctly as anonymous user', userobj.username)
|
||||
log.info('user `%s` authenticated correctly as anonymous user',
|
||||
userobj.username)
|
||||
return user_attrs
|
||||
|
||||
elif userobj.username == username and password_match:
|
||||
|
|
@ -166,6 +164,23 @@ class RhodeCodeAuthPlugin(RhodeCodeAuthPluginBase):
|
|||
return None
|
||||
|
||||
|
||||
class RhodeCodeSettingsSchema(AuthnPluginSettingsSchemaBase):
|
||||
login_restriction_choices = [
|
||||
(RhodeCodeAuthPlugin.LOGIN_RESTRICTION_NONE, 'All users'),
|
||||
(RhodeCodeAuthPlugin.LOGIN_RESTRICTION_SUPER_ADMIN, 'Super admins only')
|
||||
]
|
||||
|
||||
login_restriction = colander.SchemaNode(
|
||||
colander.String(),
|
||||
default=login_restriction_choices[0],
|
||||
description=_('Choose login restrition for users.'),
|
||||
title=_('Login restriction'),
|
||||
validator=colander.OneOf([x[0] for x in login_restriction_choices]),
|
||||
widget='select_with_labels',
|
||||
choices=login_restriction_choices
|
||||
)
|
||||
|
||||
|
||||
def includeme(config):
|
||||
plugin_id = 'egg:rhodecode-enterprise-ce#{}'.format(RhodeCodeAuthPlugin.uid)
|
||||
plugin_factory(plugin_id).includeme(config)
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@
|
|||
<div class="checkbox">${h.checkbox(node.name, True, checked=defaults.get(node.name))}</div>
|
||||
%elif node.widget == "select":
|
||||
${h.select(node.name, defaults.get(node.name), node.validator.choices, class_="select2AuthSetting")}
|
||||
%elif node.widget == "select_with_labels":
|
||||
${h.select(node.name, defaults.get(node.name), node.choices, class_="select2AuthSetting")}
|
||||
%elif node.widget == "textarea":
|
||||
<div class="textarea" style="margin-left: 0px">${h.textarea(node.name, defaults.get(node.name), rows=10)}</div>
|
||||
%elif node.widget == "readonly":
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ from rhodecode.model.repo_group import RepoGroupModel
|
|||
from rhodecode.model.user_group import UserGroupModel
|
||||
from rhodecode.model.gist import GistModel
|
||||
from rhodecode.model.auth_token import AuthTokenModel
|
||||
from rhodecode.authentication.plugins.auth_rhodecode import \
|
||||
RhodeCodeAuthPlugin
|
||||
|
||||
dn = os.path.dirname
|
||||
FIXTURES = os.path.join(dn(dn(os.path.abspath(__file__))), 'tests', 'fixtures')
|
||||
|
|
@ -120,6 +122,38 @@ class Fixture(object):
|
|||
|
||||
return context()
|
||||
|
||||
def login_restriction(self, login_restriction):
|
||||
"""
|
||||
Context process for changing the builtin rhodecode plugin login restrictions.
|
||||
Use like:
|
||||
fixture = Fixture()
|
||||
with fixture.login_restriction('super_admin'):
|
||||
#tests
|
||||
|
||||
after this block login restriction will be taken off
|
||||
"""
|
||||
|
||||
class context(object):
|
||||
def _get_pluing(self):
|
||||
plugin_id = 'egg:rhodecode-enterprise-ce#{}'.format(
|
||||
RhodeCodeAuthPlugin.uid)
|
||||
plugin = RhodeCodeAuthPlugin(plugin_id)
|
||||
return plugin
|
||||
|
||||
def __enter__(self):
|
||||
plugin = self._get_pluing()
|
||||
plugin.create_or_update_setting(
|
||||
'login_restriction', login_restriction)
|
||||
Session().commit()
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
plugin = self._get_pluing()
|
||||
plugin.create_or_update_setting(
|
||||
'login_restriction', RhodeCodeAuthPlugin.LOGIN_RESTRICTION_NONE)
|
||||
Session().commit()
|
||||
|
||||
return context()
|
||||
|
||||
def _get_repo_create_params(self, **custom):
|
||||
defs = {
|
||||
'repo_name': None,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue