authentication: introduce login restriction option for builtin rhodecode plugin.

This commit is contained in:
Marcin Kuzminski 2019-01-15 11:26:25 +01:00
parent 1ead0d3876
commit 26b57aead0
4 changed files with 75 additions and 14 deletions

View file

@ -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)

View file

@ -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)

View file

@ -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":

View file

@ -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,