Backend refactoring: server environment and authentication
This commit is contained in:
parent
18dec0c652
commit
c8cf7d52a4
|
@ -6,5 +6,5 @@ class FailedExploitationError(Exception):
|
|||
""" Raise when exploiter fails instead of returning False """
|
||||
|
||||
|
||||
class ServerConfigFileChanged(Exception):
|
||||
class InvalidRegistrationCredentials(Exception):
|
||||
""" Raise when server config file changed and island needs to restart """
|
||||
|
|
|
@ -7,7 +7,7 @@ from werkzeug.exceptions import NotFound
|
|||
|
||||
from monkey_island.cc.auth import init_jwt
|
||||
from monkey_island.cc.database import mongo, database
|
||||
from monkey_island.cc.environment.environment import env
|
||||
from monkey_island.cc.environment.environment_singleton import env
|
||||
from monkey_island.cc.resources.client_run import ClientRun
|
||||
from monkey_island.cc.resources.edge import Edge
|
||||
from monkey_island.cc.resources.local_run import LocalRun
|
||||
|
@ -22,6 +22,7 @@ from monkey_island.cc.resources.netmap import NetMap
|
|||
from monkey_island.cc.resources.node import Node
|
||||
from monkey_island.cc.resources.node_states import NodeStates
|
||||
from monkey_island.cc.resources.monkey_control.remote_port_check import RemotePortCheck
|
||||
from monkey_island.cc.resources.registration import Registration
|
||||
from monkey_island.cc.resources.remote_run import RemoteRun
|
||||
from monkey_island.cc.resources.reporting.report import Report
|
||||
from monkey_island.cc.resources.root import Root
|
||||
|
@ -91,6 +92,7 @@ def init_app_url_rules(app):
|
|||
|
||||
def init_api_resources(api):
|
||||
api.add_resource(Root, '/api')
|
||||
api.add_resource(Registration, '/api/registration')
|
||||
api.add_resource(Monkey, '/api/monkey', '/api/monkey/', '/api/monkey/<string:guid>')
|
||||
api.add_resource(Bootloader, '/api/bootloader/<string:os>')
|
||||
api.add_resource(LocalRun, '/api/local-monkey', '/api/local-monkey/')
|
||||
|
|
|
@ -4,21 +4,11 @@ from flask import current_app, abort
|
|||
from flask_jwt import JWT, _jwt_required, JWTError
|
||||
from werkzeug.security import safe_str_cmp
|
||||
|
||||
from monkey_island.cc.environment.environment import env
|
||||
from monkey_island.cc.environment.environment_singleton import env
|
||||
|
||||
__author__ = 'itay.mizeretz'
|
||||
|
||||
|
||||
class User(object):
|
||||
def __init__(self, user_id, username, secret):
|
||||
self.id = user_id
|
||||
self.username = username
|
||||
self.secret = secret
|
||||
|
||||
def __str__(self):
|
||||
return "User(id='%s')" % self.id
|
||||
|
||||
|
||||
def init_jwt(app):
|
||||
users = env.get_auth_users()
|
||||
username_table = {u.username: u for u in users}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
__author__ = 'itay.mizeretz'
|
||||
|
||||
|
||||
class User(object):
|
||||
def __init__(self, user_id, username, secret):
|
||||
self.id = user_id
|
||||
self.username = username
|
||||
self.secret = secret
|
||||
|
||||
def __str__(self):
|
||||
return "User(id='%s')" % self.id
|
|
@ -1,15 +1,15 @@
|
|||
import json
|
||||
import hashlib
|
||||
import os
|
||||
from abc import ABCMeta, abstractmethod
|
||||
from datetime import timedelta
|
||||
import os
|
||||
import hashlib
|
||||
|
||||
__author__ = 'itay.mizeretz'
|
||||
|
||||
from typing import Dict
|
||||
|
||||
from common.utils.exceptions import ServerConfigFileChanged
|
||||
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
|
||||
|
||||
__author__ = 'itay.mizeretz'
|
||||
from common.utils.exceptions import InvalidRegistrationCredentials
|
||||
from monkey_island.cc.environment.environment_config import EnvironmentConfig
|
||||
from monkey_island.cc.environment.user_creds import UserCreds
|
||||
|
||||
|
||||
class Environment(object, metaclass=ABCMeta):
|
||||
|
@ -24,6 +24,10 @@ class Environment(object, metaclass=ABCMeta):
|
|||
|
||||
_testing = False
|
||||
|
||||
def __init__(self):
|
||||
self._config = None
|
||||
self._testing = False # Assume env is not for unit testing.
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def _credentials_required(self) -> bool:
|
||||
|
@ -31,22 +35,17 @@ class Environment(object, metaclass=ABCMeta):
|
|||
|
||||
@abstractmethod
|
||||
def get_auth_users(self):
|
||||
return
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def set_server_config(config: Dict):
|
||||
Environment.upload_server_configuration_to_file(config)
|
||||
raise ServerConfigFileChanged
|
||||
|
||||
@staticmethod
|
||||
def upload_server_configuration_to_file(config: Dict):
|
||||
file_path = Environment.get_server_config_file_path()
|
||||
with open(file_path, 'w') as f:
|
||||
f.write(json.dumps(config, indent=2))
|
||||
|
||||
@staticmethod
|
||||
def get_server_config_file_path():
|
||||
return os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc/server_config.json')
|
||||
def try_add_user(self, credentials: UserCreds):
|
||||
if self._credentials_required:
|
||||
if credentials:
|
||||
self._config.add_user(credentials)
|
||||
else:
|
||||
raise InvalidRegistrationCredentials("Missing part of credentials.")
|
||||
else:
|
||||
raise InvalidRegistrationCredentials("Can't add user because credentials are not required "
|
||||
"for current environment.")
|
||||
|
||||
def needs_registration(self) -> bool:
|
||||
if not self._credentials_required:
|
||||
|
@ -58,7 +57,7 @@ class Environment(object, metaclass=ABCMeta):
|
|||
return self._credentials_required and self._is_credentials_set_up()
|
||||
|
||||
def _is_credentials_set_up(self) -> bool:
|
||||
if 'user' in self.config and 'hash' in self.config:
|
||||
if self._config and self._config.user_creds:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
@ -71,12 +70,8 @@ class Environment(object, metaclass=ABCMeta):
|
|||
def testing(self, value):
|
||||
self._testing = value
|
||||
|
||||
def __init__(self):
|
||||
self.config = None
|
||||
self._testing = False # Assume env is not for unit testing.
|
||||
|
||||
def set_config(self, config):
|
||||
self.config = config
|
||||
def set_config(self, config: EnvironmentConfig):
|
||||
self._config = config
|
||||
|
||||
def get_island_port(self):
|
||||
return self._ISLAND_PORT
|
||||
|
@ -97,16 +92,10 @@ class Environment(object, metaclass=ABCMeta):
|
|||
return hash_obj.hexdigest()
|
||||
|
||||
def get_deployment(self):
|
||||
return self._get_from_config('deployment', 'unknown')
|
||||
|
||||
def is_develop(self):
|
||||
return self.get_deployment() == 'develop'
|
||||
|
||||
def _get_from_config(self, key, default_value=None):
|
||||
val = default_value
|
||||
if self.config is not None:
|
||||
val = self.config.get(key, val)
|
||||
return val
|
||||
deployment = 'unknown'
|
||||
if self._config and self._config.deployment:
|
||||
deployment = self._config.deployment
|
||||
return deployment
|
||||
|
||||
@property
|
||||
def mongo_db_name(self):
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import monkey_island.cc.auth
|
||||
from monkey_island.cc.auth_user import User
|
||||
from monkey_island.cc.environment import Environment
|
||||
from common.cloud.aws.aws_instance import AwsInstance
|
||||
|
||||
|
@ -24,5 +25,6 @@ class AwsEnvironment(Environment):
|
|||
|
||||
def get_auth_users(self):
|
||||
return [
|
||||
monkey_island.cc.auth.User(1, 'monkey', self.hash_secret(self._instance_id))
|
||||
# TODO change this to propper registration?
|
||||
User(1, 'monkey', self.hash_secret(self._instance_id))
|
||||
]
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
from typing import List, Dict
|
||||
|
||||
from monkey_island.cc.auth_user import User
|
||||
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
|
||||
from monkey_island.cc.environment.user_creds import UserCreds
|
||||
|
||||
|
||||
class EnvironmentConfig:
|
||||
def __init__(self,
|
||||
server_config: str,
|
||||
deployment: str,
|
||||
user_creds: UserCreds,
|
||||
aws=None):
|
||||
self.server_config = server_config
|
||||
self.deployment = deployment
|
||||
self.user_creds = user_creds
|
||||
self.aws = aws
|
||||
|
||||
@staticmethod
|
||||
def get_from_json(config_json: str) -> EnvironmentConfig:
|
||||
data = json.loads(config_json)
|
||||
return EnvironmentConfig.get_from_dict(data)
|
||||
|
||||
@staticmethod
|
||||
def get_from_dict(dict_data: Dict) -> EnvironmentConfig:
|
||||
user_creds = UserCreds.get_from_dict(dict_data)
|
||||
aws = dict_data['aws'] if 'aws' in dict_data else None
|
||||
return EnvironmentConfig(server_config=dict_data['server_config'],
|
||||
deployment=dict_data['deployment'],
|
||||
user_creds=user_creds,
|
||||
aws=aws)
|
||||
|
||||
def save_to_file(self):
|
||||
file_path = EnvironmentConfig.get_config_file_path()
|
||||
with open(file_path, 'w') as f:
|
||||
f.write(json.dumps(self.to_dict(), indent=2))
|
||||
|
||||
@staticmethod
|
||||
def get_from_file() -> EnvironmentConfig:
|
||||
file_path = EnvironmentConfig.get_config_file_path()
|
||||
with open(file_path, 'r') as f:
|
||||
config_content = f.read()
|
||||
return EnvironmentConfig.get_from_json(config_content)
|
||||
|
||||
@staticmethod
|
||||
def get_config_file_path() -> str:
|
||||
return os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc/server_config.json')
|
||||
|
||||
def to_dict(self) -> Dict:
|
||||
config_dict = {'server_config': self.server_config,
|
||||
'deployment': self.deployment}
|
||||
if self.aws:
|
||||
config_dict.update({'aws': self.aws})
|
||||
config_dict.update(self.user_creds.to_dict())
|
||||
return config_dict
|
||||
|
||||
def add_user(self, credentials: UserCreds):
|
||||
self.user_creds = credentials
|
||||
|
||||
def get_users(self) -> List[User]:
|
||||
auth_user = self.user_creds.to_auth_user()
|
||||
return [auth_user] if auth_user else []
|
|
@ -3,7 +3,7 @@ import logging
|
|||
|
||||
env = None
|
||||
|
||||
from monkey_island.cc.environment import standard, Environment
|
||||
from monkey_island.cc.environment import standard, EnvironmentConfig
|
||||
from monkey_island.cc.environment import testing
|
||||
from monkey_island.cc.environment import aws
|
||||
from monkey_island.cc.environment import password
|
||||
|
@ -24,24 +24,11 @@ ENV_DICT = {
|
|||
TESTING: testing.TestingEnvironment
|
||||
}
|
||||
|
||||
|
||||
def load_env_from_file():
|
||||
loaded_config_json = load_server_configuration_from_file()
|
||||
return loaded_config_json['server_config']
|
||||
|
||||
|
||||
def load_server_configuration_from_file():
|
||||
file_path = Environment.get_server_config_file_path()
|
||||
with open(file_path, 'r') as f:
|
||||
config_content = f.read()
|
||||
return json.loads(config_content)
|
||||
|
||||
|
||||
try:
|
||||
config_json = load_server_configuration_from_file()
|
||||
__env_type = config_json['server_config']
|
||||
config = EnvironmentConfig.get_from_file()
|
||||
__env_type = config.server_config
|
||||
env = ENV_DICT[__env_type]()
|
||||
env.set_config(config_json)
|
||||
env.set_config(config)
|
||||
logger.info('Monkey\'s env is: {0}'.format(env.__class__.__name__))
|
||||
except Exception:
|
||||
logger.error('Failed initializing environment', exc_info=True)
|
||||
|
|
|
@ -9,7 +9,7 @@ class PasswordEnvironment(Environment):
|
|||
_credentials_required = True
|
||||
|
||||
def get_auth_users(self):
|
||||
if 'user' in self.config and 'hash' in self.config:
|
||||
return [monkey_island.cc.auth.User(1, self.config['user'], self.config['hash'])]
|
||||
if self._is_registered():
|
||||
return self._config.get_users
|
||||
else:
|
||||
return []
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import monkey_island.cc.auth
|
||||
from monkey_island.cc.auth_user import User
|
||||
from monkey_island.cc.environment import Environment
|
||||
|
||||
__author__ = 'itay.mizeretz'
|
||||
|
@ -13,6 +13,4 @@ class StandardEnvironment(Environment):
|
|||
'8d2c8d0b1538d2208c1444ac66535b764a3d902b35e751df3faec1e477ed3557'
|
||||
|
||||
def get_auth_users(self):
|
||||
return [
|
||||
monkey_island.cc.auth.User(1, StandardEnvironment.NO_AUTH_CREDS, StandardEnvironment.NO_AUTH_CREDS)
|
||||
]
|
||||
return [User(1, StandardEnvironment.NO_AUTH_CREDS, StandardEnvironment.NO_AUTH_CREDS)]
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
import json
|
||||
import os
|
||||
from typing import Dict
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
|
||||
from common.utils.exceptions import ServerConfigFileChanged
|
||||
from monkey_island.cc.environment import Environment
|
||||
from monkey_island.cc.environment import Environment, EnvironmentConfig
|
||||
|
||||
|
||||
def get_server_config_file_path_test_version():
|
||||
|
@ -27,111 +25,72 @@ class TestEnvironment(TestCase):
|
|||
return []
|
||||
|
||||
# Username:test Password:test
|
||||
CONFIG_JSON_WITH_CREDENTIALS = {
|
||||
CONFIG_WITH_CREDENTIALS = {
|
||||
"server_config": "password",
|
||||
"deployment": "develop",
|
||||
"user": "test",
|
||||
"hash": "9ece086e9bac491fac5c1d1046ca11d737b92a2b2ebd93f005d7b710110c0a678288166e7fbe796883a"
|
||||
"password_hash": "9ece086e9bac491fac5c1d1046ca11d737b92a2b2ebd93f005d7b710110c0a678288166e7fbe796883a"
|
||||
"4f2e9b3ca9f484f521d0ce464345cc1aec96779149c14"
|
||||
}
|
||||
|
||||
CONFIG_JSON_NO_CREDENTIALS = {
|
||||
CONFIG_NO_CREDENTIALS = {
|
||||
"server_config": "password",
|
||||
"deployment": "develop"
|
||||
}
|
||||
|
||||
CONFIG_JSON_PARTIAL_CREDENTIALS = {
|
||||
CONFIG_PARTIAL_CREDENTIALS = {
|
||||
"server_config": "password",
|
||||
"deployment": "develop",
|
||||
"user": "test"
|
||||
}
|
||||
|
||||
CONFIG_JSON_STANDARD_ENV = {
|
||||
CONFIG_STANDARD_ENV = {
|
||||
"server_config": "standard",
|
||||
"deployment": "develop"
|
||||
}
|
||||
|
||||
CONFIG_JSON_STANDARD_WITH_CREDENTIALS = {
|
||||
CONFIG_STANDARD_WITH_CREDENTIALS = {
|
||||
"server_config": "standard",
|
||||
"deployment": "develop",
|
||||
"user": "test",
|
||||
"hash": "9ece086e9bac491fac5c1d1046ca11d737b92a2b2ebd93f005d7b710110c0a678288166e7fbe796883a"
|
||||
"password_hash": "9ece086e9bac491fac5c1d1046ca11d737b92a2b2ebd93f005d7b710110c0a678288166e7fbe796883a"
|
||||
"4f2e9b3ca9f484f521d0ce464345cc1aec96779149c14"
|
||||
}
|
||||
|
||||
@patch.object(target=Environment, attribute="get_server_config_file_path",
|
||||
new=MagicMock(return_value=get_server_config_file_path_test_version()))
|
||||
def test_upload_server_configuration_to_file(self):
|
||||
Environment.upload_server_configuration_to_file(TestEnvironment.CONFIG_JSON_WITH_CREDENTIALS)
|
||||
file_path = get_server_config_file_path_test_version()
|
||||
with open(file_path, 'r') as f:
|
||||
content_from_file = f.read()
|
||||
os.remove(file_path)
|
||||
|
||||
self.assertDictEqual(TestEnvironment.CONFIG_JSON_WITH_CREDENTIALS, json.loads(content_from_file))
|
||||
|
||||
def test_get_server_config_file_path(self):
|
||||
server_file_path = MONKEY_ISLAND_ABS_PATH + "\cc/server_config.json"
|
||||
self.assertEqual(Environment.get_server_config_file_path(), server_file_path)
|
||||
|
||||
@patch.object(Environment, "upload_server_configuration_to_file", MagicMock())
|
||||
def test_set_server_config(self):
|
||||
with self.assertRaises(ServerConfigFileChanged):
|
||||
Environment.set_server_config(TestEnvironment.CONFIG_JSON_WITH_CREDENTIALS)
|
||||
|
||||
def test_needs_registration(self):
|
||||
env = TestEnvironment.EnvironmentWithCredentials()
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_WITH_CREDENTIALS
|
||||
self.assertFalse(env.needs_registration())
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_NO_CREDENTIALS
|
||||
self.assertTrue(env.needs_registration())
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_PARTIAL_CREDENTIALS
|
||||
self.assertTrue(env.needs_registration())
|
||||
self._test_bool_env_method("needs_registration", env, TestEnvironment.CONFIG_WITH_CREDENTIALS, False)
|
||||
self._test_bool_env_method("needs_registration", env, TestEnvironment.CONFIG_NO_CREDENTIALS, True)
|
||||
self._test_bool_env_method("needs_registration", env, TestEnvironment.CONFIG_PARTIAL_CREDENTIALS, True)
|
||||
|
||||
env = TestEnvironment.EnvironmentNoCredentials()
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_STANDARD_ENV
|
||||
self.assertFalse(env.needs_registration())
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_STANDARD_WITH_CREDENTIALS
|
||||
self.assertFalse(env.needs_registration())
|
||||
self._test_bool_env_method("needs_registration", env, TestEnvironment.CONFIG_STANDARD_ENV, False)
|
||||
self._test_bool_env_method("needs_registration", env, TestEnvironment.CONFIG_STANDARD_WITH_CREDENTIALS, False)
|
||||
|
||||
def test_is_registered(self):
|
||||
env = TestEnvironment.EnvironmentWithCredentials()
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_WITH_CREDENTIALS
|
||||
self.assertTrue(env._is_registered())
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_NO_CREDENTIALS
|
||||
self.assertFalse(env._is_registered())
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_PARTIAL_CREDENTIALS
|
||||
self.assertFalse(env._is_registered())
|
||||
self._test_bool_env_method("_is_registered", env, TestEnvironment.CONFIG_WITH_CREDENTIALS, True)
|
||||
self._test_bool_env_method("_is_registered", env, TestEnvironment.CONFIG_NO_CREDENTIALS, False)
|
||||
self._test_bool_env_method("_is_registered", env, TestEnvironment.CONFIG_PARTIAL_CREDENTIALS, False)
|
||||
|
||||
env = TestEnvironment.EnvironmentNoCredentials()
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_STANDARD_ENV
|
||||
self.assertFalse(env._is_registered())
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_STANDARD_WITH_CREDENTIALS
|
||||
self.assertFalse(env._is_registered())
|
||||
self._test_bool_env_method("_is_registered", env, TestEnvironment.CONFIG_STANDARD_ENV, False)
|
||||
self._test_bool_env_method("_is_registered", env, TestEnvironment.CONFIG_STANDARD_WITH_CREDENTIALS, False)
|
||||
|
||||
def test_is_credentials_set_up(self):
|
||||
env = TestEnvironment.EnvironmentWithCredentials()
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_NO_CREDENTIALS
|
||||
self.assertFalse(env._is_credentials_set_up())
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_WITH_CREDENTIALS
|
||||
self.assertTrue(env._is_credentials_set_up())
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_PARTIAL_CREDENTIALS
|
||||
self.assertFalse(env._is_credentials_set_up())
|
||||
self._test_bool_env_method("_is_credentials_set_up", env, TestEnvironment.CONFIG_NO_CREDENTIALS, False)
|
||||
self._test_bool_env_method("_is_credentials_set_up", env, TestEnvironment.CONFIG_WITH_CREDENTIALS, True)
|
||||
self._test_bool_env_method("_is_credentials_set_up", env, TestEnvironment.CONFIG_PARTIAL_CREDENTIALS, False)
|
||||
|
||||
env = TestEnvironment.EnvironmentNoCredentials()
|
||||
self._test_bool_env_method("_is_credentials_set_up", env, TestEnvironment.CONFIG_STANDARD_ENV, False)
|
||||
|
||||
def _test_bool_env_method(self, method_name: str, env: Environment, config: Dict, expected_result: bool):
|
||||
env._config = EnvironmentConfig.get_from_json(json.dumps(config))
|
||||
method = getattr(env, method_name)
|
||||
if expected_result:
|
||||
self.assertTrue(method())
|
||||
else:
|
||||
self.assertFalse(method())
|
||||
|
||||
env.config = TestEnvironment.CONFIG_JSON_STANDARD_ENV
|
||||
self.assertFalse(env._is_credentials_set_up())
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from monkey_island.cc.auth import User
|
||||
from monkey_island.cc.auth_user import User
|
||||
from monkey_island.cc.testing.IslandTestCase import IslandTestCase
|
||||
from monkey_island.cc.environment.aws import AwsEnvironment
|
||||
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
import json
|
||||
import os
|
||||
import platform
|
||||
from typing import Dict
|
||||
from unittest import TestCase
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
|
||||
from monkey_island.cc.environment.environment_config import EnvironmentConfig
|
||||
from monkey_island.cc.environment.user_creds import UserCreds
|
||||
|
||||
|
||||
def get_server_config_file_path_test_version():
|
||||
return os.path.join(os.getcwd(), 'test_config.json')
|
||||
|
||||
|
||||
class TestEnvironmentConfig(TestCase):
|
||||
# Username:test Password:test
|
||||
CONFIG_WITH_CREDENTIALS = {
|
||||
"server_config": "password",
|
||||
"deployment": "develop",
|
||||
"user": "test",
|
||||
"password_hash": "9ece086e9bac491fac5c1d1046ca11d737b92a2b2ebd93f005d7b710110c0a678288166e7fbe796883a"
|
||||
"4f2e9b3ca9f484f521d0ce464345cc1aec96779149c14"
|
||||
}
|
||||
|
||||
CONFIG_NO_CREDENTIALS = {
|
||||
"server_config": "password",
|
||||
"deployment": "develop"
|
||||
}
|
||||
|
||||
CONFIG_PARTIAL_CREDENTIALS = {
|
||||
"server_config": "password",
|
||||
"deployment": "develop",
|
||||
"user": "test"
|
||||
}
|
||||
|
||||
CONFIG_BOGUS_VALUES = {
|
||||
"server_config": "password",
|
||||
"deployment": "develop",
|
||||
"user": "test",
|
||||
"aws": "test",
|
||||
"test": "test",
|
||||
"test2": "test2"
|
||||
}
|
||||
|
||||
CONFIG_STANDARD_ENV = {
|
||||
"server_config": "standard",
|
||||
"deployment": "develop"
|
||||
}
|
||||
|
||||
CONFIG_STANDARD_WITH_CREDENTIALS = {
|
||||
"server_config": "standard",
|
||||
"deployment": "develop",
|
||||
"user": "test",
|
||||
"password_hash": "9ece086e9bac491fac5c1d1046ca11d737b92a2b2ebd93f005d7b710110c0a678288166e7fbe796883a"
|
||||
"4f2e9b3ca9f484f521d0ce464345cc1aec96779149c14"
|
||||
}
|
||||
|
||||
def test_get_from_json(self):
|
||||
self._test_get_from_json(TestEnvironmentConfig.CONFIG_WITH_CREDENTIALS)
|
||||
self._test_get_from_json(TestEnvironmentConfig.CONFIG_NO_CREDENTIALS)
|
||||
self._test_get_from_json(TestEnvironmentConfig.CONFIG_PARTIAL_CREDENTIALS)
|
||||
|
||||
def _test_get_from_json(self, config: Dict):
|
||||
config_json = json.dumps(config)
|
||||
env_config_object = EnvironmentConfig.get_from_json(config_json)
|
||||
self.assertEqual(config['server_config'], env_config_object.server_config)
|
||||
self.assertEqual(config['deployment'], env_config_object.deployment)
|
||||
if 'user' in config:
|
||||
self.assertEqual(config['user'], env_config_object.user_creds.username)
|
||||
if 'password_hash' in config:
|
||||
self.assertEqual(config['password_hash'], env_config_object.user_creds.password_hash)
|
||||
if 'aws' in config:
|
||||
self.assertEqual(config['aws'], env_config_object.aws)
|
||||
|
||||
def test_save_to_file(self):
|
||||
self._test_save_to_file(TestEnvironmentConfig.CONFIG_WITH_CREDENTIALS)
|
||||
self._test_save_to_file(TestEnvironmentConfig.CONFIG_NO_CREDENTIALS)
|
||||
self._test_save_to_file(TestEnvironmentConfig.CONFIG_PARTIAL_CREDENTIALS)
|
||||
|
||||
@patch.object(target=EnvironmentConfig, attribute="get_config_file_path",
|
||||
new=MagicMock(return_value=get_server_config_file_path_test_version()))
|
||||
def _test_save_to_file(self, config: Dict):
|
||||
user_creds = UserCreds.get_from_dict(config)
|
||||
env_config = EnvironmentConfig(server_config=config['server_config'],
|
||||
deployment=config['deployment'],
|
||||
user_creds=user_creds)
|
||||
|
||||
env_config.save_to_file()
|
||||
file_path = get_server_config_file_path_test_version()
|
||||
with open(file_path, 'r') as f:
|
||||
content_from_file = f.read()
|
||||
os.remove(file_path)
|
||||
|
||||
self.assertDictEqual(config, json.loads(content_from_file))
|
||||
|
||||
def test_get_server_config_file_path(self):
|
||||
if platform.system() == "Windows":
|
||||
server_file_path = MONKEY_ISLAND_ABS_PATH + "\cc/server_config.json"
|
||||
else:
|
||||
server_file_path = MONKEY_ISLAND_ABS_PATH + "/cc/server_config.json"
|
||||
self.assertEqual(EnvironmentConfig.get_config_file_path(), server_file_path)
|
||||
|
||||
def test_get_from_dict(self):
|
||||
config_dict = TestEnvironmentConfig.CONFIG_WITH_CREDENTIALS
|
||||
env_conf = EnvironmentConfig.get_from_dict(config_dict)
|
||||
self.assertEqual(env_conf.server_config, config_dict['server_config'])
|
||||
self.assertEqual(env_conf.deployment, config_dict['deployment'])
|
||||
self.assertEqual(env_conf.user_creds.username, config_dict['user'])
|
||||
self.assertEqual(env_conf.aws, None)
|
||||
|
||||
config_dict = TestEnvironmentConfig.CONFIG_BOGUS_VALUES
|
||||
env_conf = EnvironmentConfig.get_from_dict(config_dict)
|
||||
self.assertEqual(env_conf.server_config, config_dict['server_config'])
|
||||
self.assertEqual(env_conf.deployment, config_dict['deployment'])
|
||||
self.assertEqual(env_conf.user_creds.username, config_dict['user'])
|
||||
self.assertEqual(env_conf.aws, config_dict['aws'])
|
||||
|
||||
def test_to_dict(self):
|
||||
conf_json1 = json.dumps(TestEnvironmentConfig.CONFIG_WITH_CREDENTIALS)
|
||||
self._test_to_dict(EnvironmentConfig.get_from_json(conf_json1))
|
||||
|
||||
conf_json2 = json.dumps(TestEnvironmentConfig.CONFIG_NO_CREDENTIALS)
|
||||
self._test_to_dict(EnvironmentConfig.get_from_json(conf_json2))
|
||||
|
||||
conf_json3 = json.dumps(TestEnvironmentConfig.CONFIG_PARTIAL_CREDENTIALS)
|
||||
self._test_to_dict(EnvironmentConfig.get_from_json(conf_json3))
|
||||
|
||||
def _test_to_dict(self, env_config_object: EnvironmentConfig):
|
||||
test_dict = {'server_config': env_config_object.server_config,
|
||||
'deployment': env_config_object.deployment}
|
||||
user_creds = env_config_object.user_creds
|
||||
if user_creds.username:
|
||||
test_dict.update({'user': user_creds.username})
|
||||
if user_creds.password_hash:
|
||||
test_dict.update({'password_hash': user_creds.password_hash})
|
||||
|
||||
self.assertDictEqual(test_dict, env_config_object.to_dict())
|
|
@ -0,0 +1,38 @@
|
|||
from unittest import TestCase
|
||||
|
||||
from monkey_island.cc.environment.user_creds import UserCreds
|
||||
|
||||
|
||||
class TestUserCreds(TestCase):
|
||||
|
||||
def test_to_dict(self):
|
||||
user_creds = UserCreds()
|
||||
self.assertDictEqual(user_creds.to_dict(), {})
|
||||
|
||||
user_creds = UserCreds(username="Test")
|
||||
self.assertDictEqual(user_creds.to_dict(), {'user': "Test"})
|
||||
|
||||
user_creds = UserCreds(password_hash="abc1231234")
|
||||
self.assertDictEqual(user_creds.to_dict(), {'password_hash': "abc1231234"})
|
||||
|
||||
user_creds = UserCreds(username="Test", password_hash="abc1231234")
|
||||
self.assertDictEqual(user_creds.to_dict(), {'user': "Test", 'password_hash': "abc1231234"})
|
||||
|
||||
def test_to_auth_user(self):
|
||||
user_creds = UserCreds(username="Test", password_hash="abc1231234")
|
||||
auth_user = user_creds.to_auth_user()
|
||||
self.assertEqual(auth_user.id, 1)
|
||||
self.assertEqual(auth_user.username, "Test")
|
||||
self.assertEqual(auth_user.secret, "abc1231234")
|
||||
|
||||
user_creds = UserCreds(username="Test")
|
||||
auth_user = user_creds.to_auth_user()
|
||||
self.assertEqual(auth_user.id, 1)
|
||||
self.assertEqual(auth_user.username, "Test")
|
||||
self.assertEqual(auth_user.secret, "")
|
||||
|
||||
user_creds = UserCreds(password_hash="abc1231234")
|
||||
auth_user = user_creds.to_auth_user()
|
||||
self.assertEqual(auth_user.id, 1)
|
||||
self.assertEqual(auth_user.username, "")
|
||||
self.assertEqual(auth_user.secret, "abc1231234")
|
|
@ -0,0 +1,41 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from typing import Dict
|
||||
|
||||
from monkey_island.cc.auth_user import User
|
||||
|
||||
|
||||
class UserCreds:
|
||||
|
||||
def __init__(self, username="", password_hash=""):
|
||||
self.username = username
|
||||
self.password_hash = password_hash
|
||||
|
||||
def __bool__(self) -> bool:
|
||||
return bool(self.username and self.password_hash)
|
||||
|
||||
def to_dict(self) -> Dict:
|
||||
cred_dict = {}
|
||||
if self.username:
|
||||
cred_dict.update({'user': self.username})
|
||||
if self.password_hash:
|
||||
cred_dict.update({'password_hash': self.password_hash})
|
||||
return cred_dict
|
||||
|
||||
def to_auth_user(self) -> User:
|
||||
return User(1, self.username, self.password_hash)
|
||||
|
||||
@staticmethod
|
||||
def get_from_dict(data_dict: Dict) -> UserCreds:
|
||||
creds = UserCreds()
|
||||
if 'user' in data_dict:
|
||||
creds.username = data_dict['user']
|
||||
if 'password_hash' in data_dict:
|
||||
creds.password_hash = data_dict['password_hash']
|
||||
return creds
|
||||
|
||||
@staticmethod
|
||||
def get_from_json(json_data: bytes) -> UserCreds:
|
||||
cred_dict = json.loads(json_data)
|
||||
return UserCreds.get_from_dict(cred_dict)
|
|
@ -23,7 +23,7 @@ logger = logging.getLogger(__name__)
|
|||
from monkey_island.cc.app import init_app
|
||||
from monkey_island.cc.services.reporting.exporter_init import populate_exporter_list
|
||||
from monkey_island.cc.network_utils import local_ip_addresses
|
||||
from monkey_island.cc.environment.environment import env
|
||||
from monkey_island.cc.environment.environment_singleton import env
|
||||
from monkey_island.cc.database import is_db_server_up, get_db_version
|
||||
from monkey_island.cc.resources.monkey_download import MonkeyDownload
|
||||
from common.version import get_version
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
import flask_restful
|
||||
from flask import request, make_response
|
||||
|
||||
from common.utils.exceptions import InvalidRegistrationCredentials
|
||||
from monkey_island.cc.environment.environment_singleton import env
|
||||
from monkey_island.cc.environment.user_creds import UserCreds
|
||||
|
||||
|
||||
class Registration(flask_restful.Resource):
|
||||
def get(self):
|
||||
return {'needs_registration': env.needs_registration()}
|
||||
|
||||
def post(self):
|
||||
credentials = UserCreds.get_from_json(request.data)
|
||||
try:
|
||||
env.try_add_user(credentials)
|
||||
return make_response({"error": ""}, 300)
|
||||
except InvalidRegistrationCredentials as e:
|
||||
return make_response({"error": e}, 400)
|
||||
|
|
@ -6,7 +6,7 @@ import boto3
|
|||
from botocore.exceptions import UnknownServiceError
|
||||
|
||||
from common.cloud.aws.aws_instance import AwsInstance
|
||||
from monkey_island.cc.environment.environment_singleton import load_server_configuration_from_file
|
||||
from monkey_island.cc.environment import EnvironmentConfig
|
||||
from monkey_island.cc.services.reporting.exporter import Exporter
|
||||
|
||||
__authors__ = ['maor.rayzin', 'shay.nehmad']
|
||||
|
@ -68,7 +68,7 @@ class AWSExporter(Exporter):
|
|||
# azure and conficker are not relevant issues for an AWS env
|
||||
}
|
||||
|
||||
configured_product_arn = load_server_configuration_from_file()['aws'].get('sec_hub_product_arn', '')
|
||||
configured_product_arn = EnvironmentConfig.get_from_file().aws.get('sec_hub_product_arn', '')
|
||||
product_arn = 'arn:aws:securityhub:{region}:{arn}'.format(region=region, arn=configured_product_arn)
|
||||
instance_arn = 'arn:aws:ec2:' + str(region) + ':instance:{instance_id}'
|
||||
# Not suppressing error here on purpose.
|
||||
|
|
Loading…
Reference in New Issue