diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d9457f92..69408a7fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ Changelog](https://keepachangelog.com/en/1.0.0/). ### Changed - The name of the "Communicate as new user" post-breach action to "Communicate as backdoor user". #1410 +- Resetting login credentials also cleans the contents of the database. #1495 - ATT&CK report messages (more accurate now). #1483 ### Removed diff --git a/docs/content/FAQ/_index.md b/docs/content/FAQ/_index.md index a02b5b32d..bec25b6b6 100644 --- a/docs/content/FAQ/_index.md +++ b/docs/content/FAQ/_index.md @@ -56,6 +56,12 @@ When you first access the Monkey Island server, you'll be prompted to create an To reset the credentials, edit the `server_config.json` file manually (located in the [data directory](/reference/data_directory)). +{{% notice warning %}} +If you reset the credentials, the database will be cleared. Any findings of the Infection Monkey from previous runs will be lost.

+However, you can save the Monkey's existing configuration by logging in with your current credentials and clicking on the **Export config** button on the configuration page. +{{% /notice %}} + + In order to reset the credentials, the following edits need to be made: 1. Delete the `user` field. It will look like this: ```json diff --git a/monkey/monkey_island/cc/resources/auth/registration.py b/monkey/monkey_island/cc/resources/auth/registration.py index 121b03d71..12c17d6e5 100644 --- a/monkey/monkey_island/cc/resources/auth/registration.py +++ b/monkey/monkey_island/cc/resources/auth/registration.py @@ -1,4 +1,5 @@ import json +import logging import flask_restful from flask import make_response, request @@ -7,17 +8,22 @@ import monkey_island.cc.environment.environment_singleton as env_singleton import monkey_island.cc.resources.auth.password_utils as password_utils from common.utils.exceptions import InvalidRegistrationCredentialsError, RegistrationNotNeededError from monkey_island.cc.environment.user_creds import UserCreds +from monkey_island.cc.setup.mongo.database_initializer import reset_database + +logger = logging.getLogger(__name__) class Registration(flask_restful.Resource): def get(self): - return {"needs_registration": env_singleton.env.needs_registration()} + is_registration_needed = env_singleton.env.needs_registration() + return {"needs_registration": is_registration_needed} def post(self): credentials = _get_user_credentials_from_request(request) try: env_singleton.env.try_add_user(credentials) + reset_database() return make_response({"error": ""}, 200) except (InvalidRegistrationCredentialsError, RegistrationNotNeededError) as e: return make_response({"error": str(e)}, 400) diff --git a/monkey/monkey_island/cc/server_setup.py b/monkey/monkey_island/cc/server_setup.py index a4e4da485..69ab0437a 100644 --- a/monkey/monkey_island/cc/server_setup.py +++ b/monkey/monkey_island/cc/server_setup.py @@ -36,7 +36,6 @@ from monkey_island.cc.setup import island_config_options_validator # noqa: E402 from monkey_island.cc.setup.gevent_hub_error_handler import GeventHubErrorHandler # noqa: E402 from monkey_island.cc.setup.island_config_options import IslandConfigOptions # noqa: E402 from monkey_island.cc.setup.mongo import mongo_setup # noqa: E402 -from monkey_island.cc.setup.mongo.database_initializer import init_collections # noqa: E402 from monkey_island.cc.setup.mongo.mongo_db_process import MongoDbProcess # noqa: E402 logger = logging.getLogger(__name__) @@ -131,8 +130,6 @@ def _start_island_server(should_setup_only, config_options: IslandConfigOptions) populate_exporter_list() app = init_app(mongo_setup.MONGO_URL) - init_collections() - if should_setup_only: logger.warning("Setup only flag passed. Exiting.") return diff --git a/monkey/monkey_island/cc/services/database.py b/monkey/monkey_island/cc/services/database.py index d0656f946..afd4ecc02 100644 --- a/monkey/monkey_island/cc/services/database.py +++ b/monkey/monkey_island/cc/services/database.py @@ -37,3 +37,7 @@ class Database(object): def init_db(): if not mongo.db.collection_names(): Database.reset_db() + + @staticmethod + def is_mitigations_missing() -> bool: + return bool(AttackMitigations.COLLECTION_NAME not in mongo.db.list_collection_names()) diff --git a/monkey/monkey_island/cc/setup/mongo/database_initializer.py b/monkey/monkey_island/cc/setup/mongo/database_initializer.py index 34914c7ce..32e3c8486 100644 --- a/monkey/monkey_island/cc/setup/mongo/database_initializer.py +++ b/monkey/monkey_island/cc/setup/mongo/database_initializer.py @@ -5,13 +5,16 @@ from pymongo import errors from monkey_island.cc.database import mongo from monkey_island.cc.models.attack.attack_mitigations import AttackMitigations from monkey_island.cc.services.attack.mitre_api_interface import MitreApiInterface +from monkey_island.cc.services.database import Database logger = logging.getLogger(__name__) -def init_collections(): - logger.info("Setting up the Monkey Island, this might take a while...") - _try_store_mitigations_on_mongo() +def reset_database(): + Database.reset_db() + if Database.is_mitigations_missing(): + logger.info("Populating Monkey Island with ATT&CK mitigations.") + _try_store_mitigations_on_mongo() def _try_store_mitigations_on_mongo(): diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RegisterPage.js b/monkey/monkey_island/cc/ui/src/components/pages/RegisterPage.js index 55a5fcebf..596a86f5a 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/RegisterPage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/RegisterPage.js @@ -4,11 +4,13 @@ import {Row, Col, Container, Form, Button} from 'react-bootstrap'; import AuthService from '../../services/AuthService'; import monkeyDetective from '../../images/detective-monkey.svg'; import ParticleBackground from '../ui-components/ParticleBackground'; +import LoadingIcon from '../ui-components/LoadingIcon'; class RegisterPageComponent extends React.Component { register = (event) => { event.preventDefault(); + this.setState({loading: true}) this.auth.register(this.username, this.password).then(res => { this.setState({failed: false, error: ''}); if (res['result']) { @@ -68,7 +70,12 @@ class RegisterPageComponent extends React.Component { this.updateUsername(evt)} type='text' placeholder='Username'/> this.updatePassword(evt)} type='password' placeholder='Password'/> diff --git a/monkey/monkey_island/cc/ui/src/styles/pages/AuthPage.scss b/monkey/monkey_island/cc/ui/src/styles/pages/AuthPage.scss index 80bd54507..3392fcee7 100644 --- a/monkey/monkey_island/cc/ui/src/styles/pages/AuthPage.scss +++ b/monkey/monkey_island/cc/ui/src/styles/pages/AuthPage.scss @@ -35,3 +35,11 @@ margin-bottom: 20px; text-align: center; } + +.auth-container .monkey-submit-button:hover .loading-icon { + color: $monkey-black; +} + +.auth-container .monkey-submit-button:focus .loading-icon { + color: $monkey-black; +}