-
Notifications
You must be signed in to change notification settings - Fork 792
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch '3417-add-install-agent-plugin-archive' into develop
- Loading branch information
Showing
8 changed files
with
137 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 4 additions & 0 deletions
4
monkey/monkey_island/cc/services/agent_plugin_service/errors.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
class PluginInstallationError(ValueError): | ||
""" | ||
Raised when a service encounters an error while attempting to install a plugin | ||
""" |
32 changes: 32 additions & 0 deletions
32
...ey/monkey_island/cc/services/agent_plugin_service/flask_resources/install_agent_plugin.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import logging | ||
from http import HTTPStatus | ||
|
||
from flask import make_response, request | ||
from flask_security import auth_token_required, roles_accepted | ||
|
||
from monkey_island.cc.flask_utils import AbstractResource | ||
from monkey_island.cc.services.authentication_service import AccountRole | ||
|
||
from .. import IAgentPluginService | ||
from ..errors import PluginInstallationError | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class InstallAgentPlugin(AbstractResource): | ||
urls = ["/api/install-agent-plugin"] | ||
|
||
def __init__(self, agent_plugin_service: IAgentPluginService): | ||
self._agent_plugin_service = agent_plugin_service | ||
|
||
@auth_token_required | ||
@roles_accepted(AccountRole.ISLAND_INTERFACE.name) | ||
def put(self): | ||
""" | ||
Install the plugin archive. | ||
""" | ||
try: | ||
self._agent_plugin_service.install_agent_plugin_archive(request.data) | ||
return make_response({}, HTTPStatus.OK) | ||
except PluginInstallationError as err: | ||
return make_response(str(err), HTTPStatus.UNPROCESSABLE_ENTITY) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
...nkey_island/cc/services/agent_plugin_service/flask_resources/test_install_agent_plugin.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
from http import HTTPStatus | ||
from unittest.mock import MagicMock | ||
|
||
import pytest | ||
from tests.common import StubDIContainer | ||
from tests.unit_tests.monkey_island.conftest import get_url_for_resource | ||
|
||
from monkey_island.cc.repositories import RetrievalError, StorageError | ||
from monkey_island.cc.services import IAgentPluginService | ||
from monkey_island.cc.services.agent_plugin_service.errors import PluginInstallationError | ||
from monkey_island.cc.services.agent_plugin_service.flask_resources.install_agent_plugin import ( # noqa: E501 | ||
InstallAgentPlugin, | ||
) | ||
|
||
AGENT_PLUGIN = b"SomePlugin" | ||
|
||
|
||
@pytest.fixture | ||
def agent_plugin_service() -> IAgentPluginService: | ||
return MagicMock(spec=IAgentPluginService) | ||
|
||
|
||
@pytest.fixture | ||
def flask_client(build_flask_client, agent_plugin_service): | ||
container = StubDIContainer() | ||
container.register_instance(IAgentPluginService, agent_plugin_service) | ||
|
||
with build_flask_client(container) as flask_client: | ||
yield flask_client | ||
|
||
|
||
def test_install_plugin(agent_plugin_service, flask_client): | ||
resp = flask_client.put( | ||
get_url_for_resource(InstallAgentPlugin), | ||
data=AGENT_PLUGIN, | ||
follow_redirects=True, | ||
) | ||
|
||
assert resp.status_code == HTTPStatus.OK | ||
assert agent_plugin_service.install_agent_plugin_archive.call_count == 1 | ||
assert agent_plugin_service.install_agent_plugin_archive.call_args[0][0] == AGENT_PLUGIN | ||
|
||
|
||
def test_install_plugin__install_error(agent_plugin_service, flask_client): | ||
agent_plugin_service.install_agent_plugin_archive = MagicMock( | ||
side_effect=PluginInstallationError | ||
) | ||
resp = flask_client.put( | ||
get_url_for_resource(InstallAgentPlugin), | ||
data=AGENT_PLUGIN, | ||
follow_redirects=True, | ||
) | ||
|
||
assert resp.status_code == HTTPStatus.UNPROCESSABLE_ENTITY | ||
|
||
|
||
@pytest.mark.parametrize("error", [RetrievalError, StorageError, Exception]) | ||
def test_install_plugin__internal_server_error(agent_plugin_service, flask_client, error): | ||
agent_plugin_service.install_agent_plugin_archive = MagicMock(side_effect=error) | ||
resp = flask_client.put( | ||
get_url_for_resource(InstallAgentPlugin), | ||
data=AGENT_PLUGIN, | ||
follow_redirects=True, | ||
) | ||
|
||
assert resp.status_code == HTTPStatus.INTERNAL_SERVER_ERROR |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters