Skip to content

Commit e23317c

Browse files
committed
Merge branch '3076-add-mock-agent-registration-resource' into develop
Issue #3076 PR #3084
2 parents c254126 + 69eff25 commit e23317c

File tree

6 files changed

+71
-0
lines changed

6 files changed

+71
-0
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
99
### Added
1010
- Add an option to the Hadoop exploiter to try all discovered HTTP ports. #2136
1111
- `GET /api/agent-otp`. #3076
12+
- `POST /api/agent-otp-login` endpoint. #3076
1213

1314
### Changed
1415
### Removed

monkey/monkey_island/cc/services/authentication_service/flask_resources/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
from .logout import Logout
55
from .register_resources import register_resources
66
from .agent_otp import AgentOTP
7+
from .agent_otp_login import AgentOTPLogin
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import json
2+
3+
from flask import make_response, request
4+
5+
from monkey_island.cc.flask_utils import AbstractResource
6+
from monkey_island.cc.server_utils.response_utils import response_to_invalid_request
7+
8+
9+
class AgentOTPLogin(AbstractResource):
10+
"""
11+
A resource for logging in using an OTP
12+
13+
A client may authenticate with the Island by providing a one-time password.
14+
"""
15+
16+
urls = ["/api/agent-otp-login"]
17+
18+
def post(self):
19+
"""
20+
Gets the one-time password from the request, and returns an authentication token
21+
22+
:return: Authentication token in the response body
23+
"""
24+
25+
try:
26+
cred_dict = json.loads(request.data)
27+
otp = cred_dict.get("otp", "")
28+
if self._validate_otp(otp):
29+
return make_response({"token": "supersecrettoken"})
30+
except Exception:
31+
pass
32+
33+
return response_to_invalid_request()
34+
35+
def _validate_otp(self, otp: str):
36+
return len(otp) > 0

monkey/monkey_island/cc/services/authentication_service/flask_resources/register_resources.py

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from ..authentication_facade import AuthenticationFacade
66
from .agent_otp import AgentOTP
7+
from .agent_otp_login import AgentOTPLogin
78
from .login import Login
89
from .logout import Logout
910
from .register import Register
@@ -20,3 +21,4 @@ def register_resources(api: flask_restful.Api, container: DIContainer):
2021
api.add_resource(Login, *Login.urls, resource_class_args=(authentication_facade,))
2122
api.add_resource(Logout, *Logout.urls, resource_class_args=(authentication_facade,))
2223
api.add_resource(AgentOTP, *AgentOTP.urls)
24+
api.add_resource(AgentOTPLogin, *AgentOTPLogin.urls)

monkey/tests/unit_tests/monkey_island/cc/services/authentication_service/conftest.py

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
)
99
from monkey_island.cc.services.authentication_service.flask_resources import (
1010
AgentOTP,
11+
AgentOTPLogin,
1112
Login,
1213
Logout,
1314
Register,
@@ -39,6 +40,7 @@ def get_mock_auth_app(authentication_facade: AuthenticationFacade):
3940
RegistrationStatus, *RegistrationStatus.urls, resource_class_args=(authentication_facade,)
4041
)
4142
api.add_resource(AgentOTP, *AgentOTP.urls)
43+
api.add_resource(AgentOTPLogin, *AgentOTPLogin.urls)
4244

4345
return app
4446

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import pytest
2+
3+
from monkey_island.cc.services.authentication_service.flask_resources.agent_otp_login import (
4+
AgentOTPLogin,
5+
)
6+
7+
8+
@pytest.fixture
9+
def agent_otp_login(flask_client):
10+
url = AgentOTPLogin.urls[0]
11+
12+
def _agent_otp_login(request_body):
13+
return flask_client.post(url, data=request_body, follow_redirects=True)
14+
15+
return _agent_otp_login
16+
17+
18+
def test_agent_otp_login__successful(agent_otp_login):
19+
response = agent_otp_login('{"otp": "supersecretpassword"}')
20+
21+
assert response.status_code == 200
22+
assert response.json["token"] == "supersecrettoken"
23+
24+
25+
@pytest.mark.parametrize("data", [{}, [], '{"otp": ""}'])
26+
def test_agent_otp_login__failure(agent_otp_login, data):
27+
response = agent_otp_login(data)
28+
29+
assert response.status_code == 400

0 commit comments

Comments
 (0)