Island: Move registration logic into AuthenticationService

Resoures should be kept relatively thin and serve as the layer between
the API and the backend.
This commit is contained in:
Mike Salvatore 2021-10-06 14:10:38 -04:00
parent 953816b536
commit a5d3c218b4
3 changed files with 22 additions and 26 deletions

View File

@ -4,27 +4,11 @@ from typing import Tuple
import bcrypt import bcrypt
from flask import Request, request from flask import Request, request
from monkey_island.cc.environment.user_creds import UserCreds
def hash_password(plaintext_password):
salt = bcrypt.gensalt()
password_hash = bcrypt.hashpw(plaintext_password.encode("utf-8"), salt)
return password_hash.decode()
def password_matches_hash(plaintext_password, password_hash): def password_matches_hash(plaintext_password, password_hash):
return bcrypt.checkpw(plaintext_password.encode("utf-8"), password_hash.encode("utf-8")) return bcrypt.checkpw(plaintext_password.encode("utf-8"), password_hash.encode("utf-8"))
def get_user_credentials_from_request(_request) -> UserCreds:
username, password = get_username_password_from_request(_request)
password_hash = hash_password(password)
return UserCreds(username, password_hash)
def get_username_password_from_request(_request: Request) -> Tuple[str, str]: def get_username_password_from_request(_request: Request) -> Tuple[str, str]:
cred_dict = json.loads(request.data) cred_dict = json.loads(request.data)
username = cred_dict.get("username", "") username = cred_dict.get("username", "")

View File

@ -5,12 +5,8 @@ from flask import make_response, request
import monkey_island.cc.environment.environment_singleton as env_singleton import monkey_island.cc.environment.environment_singleton as env_singleton
from common.utils.exceptions import InvalidRegistrationCredentialsError, RegistrationNotNeededError from common.utils.exceptions import InvalidRegistrationCredentialsError, RegistrationNotNeededError
from monkey_island.cc.resources.auth.credential_utils import ( from monkey_island.cc.resources.auth.credential_utils import get_username_password_from_request
get_user_credentials_from_request,
get_username_password_from_request,
)
from monkey_island.cc.services.authentication import AuthenticationService from monkey_island.cc.services.authentication import AuthenticationService
from monkey_island.cc.setup.mongo.database_initializer import reset_database
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -21,13 +17,10 @@ class Registration(flask_restful.Resource):
return {"needs_registration": is_registration_needed} return {"needs_registration": is_registration_needed}
def post(self): def post(self):
credentials = get_user_credentials_from_request(request) username, password = get_username_password_from_request(request)
try: try:
env_singleton.env.try_add_user(credentials) AuthenticationService.register_new_user(username, password)
username, password = get_username_password_from_request(request)
AuthenticationService.reset_datastore_encryptor(username, password)
reset_database()
return make_response({"error": ""}, 200) return make_response({"error": ""}, 200)
except (InvalidRegistrationCredentialsError, RegistrationNotNeededError) as e: except (InvalidRegistrationCredentialsError, RegistrationNotNeededError) as e:
return make_response({"error": str(e)}, 400) return make_response({"error": str(e)}, 400)

View File

@ -1,7 +1,12 @@
import bcrypt
import monkey_island.cc.environment.environment_singleton as env_singleton
from monkey_island.cc.environment.user_creds import UserCreds
from monkey_island.cc.server_utils.encryption import ( from monkey_island.cc.server_utils.encryption import (
reset_datastore_encryptor, reset_datastore_encryptor,
unlock_datastore_encryptor, unlock_datastore_encryptor,
) )
from monkey_island.cc.setup.mongo.database_initializer import reset_database
class AuthenticationService: class AuthenticationService:
@ -14,6 +19,13 @@ class AuthenticationService:
def initialize(cls, key_file_directory): def initialize(cls, key_file_directory):
cls.KEY_FILE_DIRECTORY = key_file_directory cls.KEY_FILE_DIRECTORY = key_file_directory
@classmethod
def register_new_user(cls, username: str, password: str):
credentials = UserCreds(username, _hash_password(password))
env_singleton.env.try_add_user(credentials)
AuthenticationService.reset_datastore_encryptor(username, password)
reset_database()
@staticmethod @staticmethod
def unlock_datastore_encryptor(username: str, password: str): def unlock_datastore_encryptor(username: str, password: str):
secret = AuthenticationService._get_secret_from_credentials(username, password) secret = AuthenticationService._get_secret_from_credentials(username, password)
@ -27,3 +39,10 @@ class AuthenticationService:
@staticmethod @staticmethod
def _get_secret_from_credentials(username: str, password: str) -> str: def _get_secret_from_credentials(username: str, password: str) -> str:
return f"{username}:{password}" return f"{username}:{password}"
def _hash_password(plaintext_password):
salt = bcrypt.gensalt()
password_hash = bcrypt.hashpw(plaintext_password.encode("utf-8"), salt)
return password_hash.decode()