Skip to content

Commit

Permalink
#178 added possibility to enable admin page access to any user
Browse files Browse the repository at this point in the history
  • Loading branch information
bugy committed Feb 8, 2019
1 parent 768e885 commit 5460d85
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 9 deletions.
17 changes: 10 additions & 7 deletions src/auth/authorization.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
from collections import defaultdict

ANY_USER = 'ANY_USER'
ANY_USER = '__ANY_USER'
ADMIN_GROUP = 'admin_users'
GROUP_PREFIX = '@'


class Authorizer:
def __init__(self, app_allowed_users, admin_users, groups_provider):
if ANY_USER in app_allowed_users:
self._app_auth_check = AnyUserAuthorizationCheck()
else:
self._app_auth_check = ListBasedAuthorizationCheck(app_allowed_users)
self._app_auth_check = self.init_auth_check(app_allowed_users)
self._admin_check = self.init_auth_check(admin_users)

self._admin_users = admin_users
self._groups_provider = groups_provider

def init_auth_check(self, users):
if ANY_USER in users:
return AnyUserAuthorizationCheck()
else:
return ListBasedAuthorizationCheck(users)

def is_allowed_in_app(self, user_id):
return self._app_auth_check.is_allowed(user_id)

def is_admin(self, user_id):
return user_id in self._admin_users
return self._admin_check.is_allowed(user_id)

def is_allowed(self, user_id, allowed_users):
if not allowed_users:
Expand Down
9 changes: 8 additions & 1 deletion src/model/server_conf.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import logging
import os

import utils.file_utils as file_utils
Expand All @@ -7,6 +8,7 @@
from model.model_helper import read_list
from utils.string_utils import strip

LOGGER = logging.getLogger('server_conf')

class ServerConfig(object):
def __init__(self) -> None:
Expand Down Expand Up @@ -214,4 +216,9 @@ def parse_logging_config(json_object):


def _parse_admin_users(json_object, default_admins=None):
return strip(read_list(json_object, 'admin_users', default=default_admins))
admins = strip(read_list(json_object, 'admin_users', default=default_admins))
if '*' in admins:
LOGGER.warning('Any user is allowed to access admin page, be careful!')
return [ANY_USER]

return admins
53 changes: 52 additions & 1 deletion src/tests/authorization_test.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import unittest
from collections import defaultdict

from auth.authorization import Authorizer, ANY_USER, PreconfiguredGroupProvider, create_group_provider
from auth.authorization import Authorizer, ANY_USER, PreconfiguredGroupProvider, create_group_provider, \
EmptyGroupProvider


class TestIsAllowed(unittest.TestCase):
Expand Down Expand Up @@ -61,6 +62,56 @@ def setUp(self):
self.authorizer = Authorizer([], [], self)


class TestIsAllowedInApp(unittest.TestCase):
def test_single_user_allowed(self):
self.assertAllowed('user1', ['user1'], True)

def test_multiple_users_allowed(self):
self.assertAllowed('user2', ['user1', 'user2', 'user3'], True)

def test_multiple_users_not_allowed(self):
self.assertAllowed('user4', ['user1', 'user2', 'user3'], False)

def test_any_user_allowed(self):
self.assertAllowed('user5', [ANY_USER], True)

def test_any_user_allowed_when_mixed(self):
self.assertAllowed('user5', ['user1', ANY_USER, 'user2'], True)

def assertAllowed(self, user, allowed_users, expected_allowed):
authorizer = Authorizer(allowed_users, [], EmptyGroupProvider())

allowed = authorizer.is_allowed_in_app(user)
if allowed != expected_allowed:
self.fail('Expected ' + user + ' to be allowed=' + str(expected_allowed)
+ ' for ' + str(allowed_users) + ' but was ' + str(allowed))


class TestIsAdmin(unittest.TestCase):
def test_single_admin_allowed(self):
self.assertAdmin('admin1', ['admin1'], True)

def test_multiple_admins_allowed(self):
self.assertAdmin('admin2', ['admin1', 'admin2', 'admin3'], True)

def test_multiple_admins_not_allowed(self):
self.assertAdmin('user1', ['admin1', 'admin2', 'admin3'], False)

def test_any_user_is_admin(self):
self.assertAdmin('admin5', [ANY_USER], True)

def test_any_admin_when_mixed(self):
self.assertAdmin('admin5', ['admin1', ANY_USER, 'admin2'], True)

def assertAdmin(self, user, admin_users, expected_allowed):
authorizer = Authorizer([], admin_users, EmptyGroupProvider())

allowed = authorizer.is_admin(user)
if allowed != expected_allowed:
self.fail('Expected ' + user + ' to be admin=' + str(expected_allowed)
+ ' for ' + str(admin_users) + ' but was ' + str(allowed))


class TestPreconfiguredGroupProvider(unittest.TestCase):
def test_single_user_in_single_group(self):
provider = PreconfiguredGroupProvider({'group1': ['user1']})
Expand Down
48 changes: 48 additions & 0 deletions src/tests/server_conf_test.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import json
import os
import unittest

from auth.authorization import ANY_USER
from model import server_conf
from model.server_conf import _prepare_allowed_users
from tests import test_utils
from utils import file_utils


class TestPrepareAllowedUsers(unittest.TestCase):
Expand Down Expand Up @@ -62,3 +67,46 @@ def test_add_group_and_admin_users_when_same(self):
['user2', 'userX'],
{'group1': ['userY', 'user3']})
self.assertCountEqual(['user1', 'user2', 'user3', 'userX', 'userY'], allowed_users)


class TestAdminUsersInit(unittest.TestCase):
def test_single_list(self):
config = _from_json({'access': {'admin_users': ['userX']}})
self.assertEqual(['userX'], config.admin_users)

def test_single_string(self):
config = _from_json({'access': {'admin_users': 'abc'}})
self.assertEqual(['abc'], config.admin_users)

def test_missing_when_no_auth(self):
config = _from_json({})
self.assertEqual(['127.0.0.1', '::1'], config.admin_users)

def test_missing_when_auth_enabled(self):
config = _from_json({'auth': {'type': 'ldap', 'url': 'localhost'}})
self.assertEqual([], config.admin_users)

def test_list_with_multiple_values(self):
config = _from_json({'access': {'admin_users': ['user1', 'user2', 'user3']}})
self.assertCountEqual(['user1', 'user2', 'user3'], config.admin_users)

def test_list_with_any_user(self):
config = _from_json({'access': {'admin_users': ['user1', '*', 'user3']}})
self.assertEqual([ANY_USER], config.admin_users)

def test_list_any_user_single_string(self):
config = _from_json({'access': {'admin_users': '*'}})
self.assertCountEqual([ANY_USER], config.admin_users)

def setUp(self):
test_utils.setup()

def tearDown(self):
test_utils.cleanup()


def _from_json(content):
json_obj = json.dumps(content)
conf_path = os.path.join(test_utils.temp_folder, 'conf.json')
file_utils.write_file(conf_path, json_obj)
return server_conf.from_json(conf_path, test_utils.temp_folder)

0 comments on commit 5460d85

Please sign in to comment.