From 4b0f56d8d8871eff52a2a14e07fe6dd25ddec8e9 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Fri, 15 Jul 2022 16:50:44 +0300 Subject: [PATCH 01/25] Island: Fix mongo_credentials_repository.py to use correct database --- .../mongo_credentials_repository.py | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/monkey/monkey_island/cc/repository/mongo_credentials_repository.py b/monkey/monkey_island/cc/repository/mongo_credentials_repository.py index 5d58d510a..cfeb0874f 100644 --- a/monkey/monkey_island/cc/repository/mongo_credentials_repository.py +++ b/monkey/monkey_island/cc/repository/mongo_credentials_repository.py @@ -14,14 +14,20 @@ class MongoCredentialsRepository(ICredentialsRepository): """ def __init__(self, mongo: MongoClient, repository_encryptor: ILockableEncryptor): - self._mongo = mongo - self._repository_encryptor = repository_encryptor + self._database = mongo.monkeyisland + def get_configured_credentials(self) -> Sequence[Credentials]: - return self._get_credentials_from_collection(self._mongo.db.configured_credentials) + return MongoCredentialsRepository._get_credentials_from_collection( + self._database.configured_credentials + ) + def get_stolen_credentials(self) -> Sequence[Credentials]: - return self._get_credentials_from_collection(self._mongo.db.stolen_credentials) + return MongoCredentialsRepository._get_credentials_from_collection( + self._database.stolen_credentials + ) + def get_all_credentials(self) -> Sequence[Credentials]: configured_credentials = self.get_configured_credentials() @@ -31,19 +37,25 @@ class MongoCredentialsRepository(ICredentialsRepository): def save_configured_credentials(self, credentials: Sequence[Credentials]): # TODO: Fix deduplication of Credentials in mongo - self._save_credentials_to_collection(credentials, self._mongo.db.configured_credentials) + MongoCredentialsRepository._save_credentials_to_collection( + credentials, self._database.configured_credentials + ) + def save_stolen_credentials(self, credentials: Sequence[Credentials]): - self._save_credentials_to_collection(credentials, self._mongo.db.stolen_credentials) + MongoCredentialsRepository._save_credentials_to_collection( + credentials, self._database.stolen_credentials + ) + def remove_configured_credentials(self): MongoCredentialsRepository._remove_credentials_fom_collection( - self._mongo.db.configured_credentials + self._database.configured_credentials ) def remove_stolen_credentials(self): MongoCredentialsRepository._remove_credentials_fom_collection( - self._mongo.db.stolen_credentials + self._database.stolen_credentials ) def remove_all_credentials(self): From 47a87e14e6b62f77e74ef1910e591025514469a4 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Fri, 15 Jul 2022 17:18:18 +0300 Subject: [PATCH 02/25] Island: Add a patch method for PropagationConfig Patch method is required to change the whole collection with one request. We need to change all configured credentials for configuration use case --- .../cc/resources/propagation_credentials.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/monkey/monkey_island/cc/resources/propagation_credentials.py b/monkey/monkey_island/cc/resources/propagation_credentials.py index c5dfc42fe..9ef22f832 100644 --- a/monkey/monkey_island/cc/resources/propagation_credentials.py +++ b/monkey/monkey_island/cc/resources/propagation_credentials.py @@ -29,7 +29,7 @@ class PropagationCredentials(AbstractResource): return propagation_credentials, HTTPStatus.OK def post(self, collection=None): - credentials = [Credentials.from_json(c) for c in request.json] + credentials = [Credentials.from_mapping(c) for c in request.json] if collection == _configured_collection: self._credentials_repository.save_configured_credentials(credentials) @@ -42,6 +42,15 @@ class PropagationCredentials(AbstractResource): return {}, HTTPStatus.NO_CONTENT + def patch(self, collection=None): + if collection != _configured_collection: + return {}, HTTPStatus.METHOD_NOT_ALLOWED + + credentials = [Credentials.from_mapping(c) for c in request.json] + self._credentials_repository.remove_configured_credentials() + self._credentials_repository.save_configured_credentials(credentials) + return {}, HTTPStatus.NO_CONTENT + def delete(self, collection=None): if collection == _configured_collection: self._credentials_repository.remove_configured_credentials() From 0cee5ac00d90dbae077f426575527f82fb1aebf4 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Fri, 15 Jul 2022 17:41:49 +0300 Subject: [PATCH 03/25] UI: Separate credential configuration and config --- .../CredentialsConfig.tsx | 27 ++++++ .../PropagationConfig.tsx | 59 ++++++------ .../configuration-components/ReformatHook.js | 89 +++++++++++++++++-- .../ui/src/components/pages/ConfigurePage.js | 64 ++++++++++--- .../configuration/propagation/credentials.js | 8 ++ 5 files changed, 205 insertions(+), 42 deletions(-) create mode 100644 monkey/monkey_island/cc/ui/src/components/configuration-components/CredentialsConfig.tsx diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/CredentialsConfig.tsx b/monkey/monkey_island/cc/ui/src/components/configuration-components/CredentialsConfig.tsx new file mode 100644 index 000000000..dbe9e4e91 --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/CredentialsConfig.tsx @@ -0,0 +1,27 @@ +import Form from 'react-jsonschema-form-bs4'; +import React from 'react'; +import _ from 'lodash'; + +export default function CredentialsConfig(props) { + const { + schema, + uiSchema, + credentials, + onChange, + customFormats, + className + } = props; + + let credentialsCopy = _.clone(credentials); + + return (<> +
{onChange(formData.formData)}} + customFormats={customFormats} + className={className} + liveValidate + children={true}/> + ) +} diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/PropagationConfig.tsx b/monkey/monkey_island/cc/ui/src/components/configuration-components/PropagationConfig.tsx index b00e4653d..5418853be 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/PropagationConfig.tsx +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/PropagationConfig.tsx @@ -2,6 +2,7 @@ import Form from 'react-jsonschema-form-bs4'; import React, {useState, useEffect} from 'react'; import {Nav} from 'react-bootstrap'; import _ from 'lodash'; +import CredentialsConfig from './CredentialsConfig'; const sectionOrder = [ 'exploitation', @@ -19,30 +20,27 @@ export default function PropagationConfig(props) { onChange, customFormats, className, - formData + configuration, + credentials, + onCredentialChange } = props; const [selectedSection, setSelectedSection] = useState(initialSection); const [displayedSchema, setDisplayedSchema] = useState(getSchemaByKey(schema, initialSection)); const [displayedSchemaUi, setDisplayedSchemaUi] = useState(getUiSchemaByKey(uiSchema, initialSection)); - const [localFormData, setLocalFormData] = useState(formData[initialSection]); + const [localFormData, setLocalFormData] = useState(configuration[initialSection]); useEffect(() => { - setLocalFormData(formData[selectedSection]); + setLocalFormData(configuration[selectedSection]); setDisplayedSchema(getSchemaByKey(schema, selectedSection)); setDisplayedSchemaUi(getUiSchemaByKey(uiSchema, selectedSection)); - setLocalFormData(formData[selectedSection]); }, [selectedSection]) - useEffect(() => { - setLocalFormData(formData[selectedSection]); - }, [formData]) + const onFormDataChange = (formData) => { + let formDataClone = _.clone(formData.formData); + let configurationClone = _.clone(configuration); - const onInnerDataChange = (innerData) => { - let innerDataClone = _.clone(innerData); - let formDataClone = _.clone(formData); - - formDataClone[selectedSection] = innerDataClone.formData; - onChange({formData: formDataClone}); + configurationClone[selectedSection] = formDataClone; + onChange(configurationClone); } const setSection = (sectionKey) => { @@ -50,7 +48,7 @@ export default function PropagationConfig(props) { } const renderNav = () => { - return (