Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions dpl/api/api_gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ def auth(self, username: str, password: str) -> str:
"""
return self._am.auth_user(username, password)

@property
def is_insecure(self) -> bool:
"""
Returns a value of 'is_insecure' property of AuthManager

:return: True if insecure mode is enabled, False otherwise
"""
return self._am.is_insecure

def _check_permission(self, token: str, requested_action):
"""
Checks is specified action is permitted for this token
Expand Down
2 changes: 1 addition & 1 deletion dpl/api/rest_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ async def proxy(self, request, *args, **kwargs):

token = headers.get("Authorization", None)

if token is None:
if (token is None) and (self._gateway.is_insecure is False):
return make_error_response(status=401, message="Authorization header is not available or is null")

return await decorated_callable(self, request, *args, **kwargs, token=token)
Expand Down
35 changes: 34 additions & 1 deletion dpl/auth/auth_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,41 @@ class AuthManager(object):
AuthManager is a class that controls users and their access to different
parts of the system
"""
def __init__(self):
def __init__(self, insecure: bool = False):
"""
Constructor. Allows to disable token checking ALTOGETHER.
USE INSECURE MODE ONLY WHEN YOU KNOW WHAT YOU ARE DOING!
:param insecure: disable token checking
"""
self._users = dict() # type: Dict[str, User]
self._root_user = None # type: User
self._token_manager = TokenManager()
self._is_insecure = insecure

@property
def is_insecure(self) -> bool:
"""
Indicates is AuthManager in insecure mode. Or, in other words, is token
checking disabled.
:return: True if insecure, False otherwise
"""
return self._is_insecure

@is_insecure.setter
def is_insecure(self, new_value: bool):
"""
Allows to enable secure mode. Only
:param new_value: new value of is_secure property
:return: None
"""
if not isinstance(new_value, bool):
raise TypeError("The value of 'new_value' parameter must to boolean")

if new_value: # if new_value == True:
raise ValueError("Insecure mode can't be enabled in runtime. Please, edit"
"persistent configuration and restart this application.")

self._is_insecure = new_value

@property
def users(self) -> Set[str]:
Expand Down Expand Up @@ -166,5 +197,7 @@ def is_token_grants(self, token: str, requested_action: object) -> bool:
:return: true if permission is granted, false otherwise
"""
# TODO: Implement permission checking
if self._is_insecure:
return True # WARNING: all token values are accepted in insecure mode

return self._token_manager.is_token_present(token)
8 changes: 5 additions & 3 deletions dpl/core/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ def __init__(self):
self._placements = PlacementManager()
self._bm = BindingManager()

self._auth_manager = auth.AuthManager()
self._conf.load_config()
core_settings = self._conf.get_by_subsystem('core') # type: dict
insecure_enabled = core_settings.get('insecure_enabled', False)

self._auth_manager = auth.AuthManager(insecure=insecure_enabled)

self._api_gateway = api.ApiGateway(self._auth_manager, self._bm, self._placements)
self._rest_api = api.RestApi(self._api_gateway)

async def start(self):
self._conf.load_config()

core_settings = self._conf.get_by_subsystem("core")
placement_settings = self._conf.get_by_subsystem("placements")
connection_settings = self._conf.get_by_subsystem("connections")
Expand Down
3 changes: 2 additions & 1 deletion samples/config/core/core.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"enabled_integrations": ["dummy"],
"debug": true
"debug": true,
"insecure_enabled": true
}
33 changes: 33 additions & 0 deletions unittests/auth/test_auth_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def test_creation(self):
am = AuthManager()

self.assertFalse(am.users) # Assert that there is no users after creation
self.assertFalse(am.is_insecure) # Assert that insecure mode is disabled by default

def test_root_user_creation(self):
am = AuthManager()
Expand Down Expand Up @@ -240,6 +241,38 @@ def test_password_change_invalidates_tokens(self):

self.assertFalse(am.is_token_grants(old_root_token, None))

def test_insecure_mode_token_not_checked(self):
am = AuthManager(insecure=True)

self.assertTrue(am.is_token_grants('abcdefgh', None))

def test_insecure_mode_runtime_disable(self):
am = AuthManager(insecure=True)
self.assertTrue(am.is_insecure)
self.assertTrue(am.is_token_grants('abcdefgh', None))

am.is_insecure = False
self.assertFalse(am.is_insecure)
self.assertFalse(am.is_token_grants('abcdefgh', None))

def test_insecure_mode_setter_only_bool(self):
am = AuthManager(insecure=True)

with self.assertRaises(TypeError):
am.is_insecure = 'foo'

with self.assertRaises(TypeError):
am.is_insecure = None

with self.assertRaises(TypeError):
am.is_insecure = self

def test_insecure_mode_runtime_enable(self):
am = AuthManager()

with self.assertRaises(ValueError):
am.is_insecure = True


if __name__ == '__main__':
unittest.main()