forked from p15670423/monkey
Island: Extract jwt_required decorator into separate file
This commit is contained in:
parent
84c78c4d8f
commit
0cdf84cac5
|
@ -3,7 +3,7 @@ import json
|
||||||
from flask import make_response, request
|
from flask import make_response, request
|
||||||
|
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.resources.utils.semaphores import agent_killing_mutex
|
from monkey_island.cc.resources.utils.semaphores import agent_killing_mutex
|
||||||
from monkey_island.cc.services.infection_lifecycle import set_stop_all, should_agent_die
|
from monkey_island.cc.services.infection_lifecycle import set_stop_all, should_agent_die
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from flask import current_app, json
|
from flask import current_app, json
|
||||||
|
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services.attack.attack_report import AttackReportService
|
from monkey_island.cc.services.attack.attack_report import AttackReportService
|
||||||
from monkey_island.cc.services.attack.attack_schema import SCHEMA
|
from monkey_island.cc.services.attack.attack_schema import SCHEMA
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ from flask import make_response, request
|
||||||
from common.utils.exceptions import IncorrectCredentialsError
|
from common.utils.exceptions import IncorrectCredentialsError
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.credential_utils import get_username_password_from_request
|
from monkey_island.cc.resources.auth.credential_utils import get_username_password_from_request
|
||||||
|
from monkey_island.cc.resources.request_authentication import create_access_token
|
||||||
from monkey_island.cc.services import AuthenticationService
|
from monkey_island.cc.services import AuthenticationService
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -39,30 +40,8 @@ class Authenticate(AbstractResource):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
AuthenticationService.authenticate(username, password)
|
AuthenticationService.authenticate(username, password)
|
||||||
access_token = _create_access_token(username)
|
access_token = create_access_token(username)
|
||||||
except IncorrectCredentialsError:
|
except IncorrectCredentialsError:
|
||||||
return make_response({"error": "Invalid credentials"}, 401)
|
return make_response({"error": "Invalid credentials"}, 401)
|
||||||
|
|
||||||
return make_response({"access_token": access_token, "error": ""}, 200)
|
return make_response({"access_token": access_token, "error": ""}, 200)
|
||||||
|
|
||||||
|
|
||||||
def _create_access_token(username):
|
|
||||||
access_token = flask_jwt_extended.create_access_token(identity=username)
|
|
||||||
logger.debug(f"Created access token for user {username} that begins with {access_token[:4]}")
|
|
||||||
|
|
||||||
return access_token
|
|
||||||
|
|
||||||
|
|
||||||
# See https://flask-jwt-extended.readthedocs.io/en/stable/custom_decorators/
|
|
||||||
def jwt_required(fn):
|
|
||||||
@wraps(fn)
|
|
||||||
def wrapper(*args, **kwargs):
|
|
||||||
try:
|
|
||||||
flask_jwt_extended.verify_jwt_in_request()
|
|
||||||
return fn(*args, **kwargs)
|
|
||||||
# Catch authentication related errors in the verification or inside the called function.
|
|
||||||
# All other exceptions propagate
|
|
||||||
except (JWTExtendedException, PyJWTError) as e:
|
|
||||||
return make_response({"error": f"Authentication error: {str(e)}"}, 401)
|
|
||||||
|
|
||||||
return wrapper
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import logging
|
||||||
import flask_restful
|
import flask_restful
|
||||||
|
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services.attack.attack_report import AttackReportService
|
from monkey_island.cc.services.attack.attack_report import AttackReportService
|
||||||
from monkey_island.cc.services.reporting.report import ReportService
|
from monkey_island.cc.services.reporting.report import ReportService
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ from flask import request
|
||||||
|
|
||||||
from monkey_island.cc.database import database, mongo
|
from monkey_island.cc.database import database, mongo
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
|
|
||||||
|
|
||||||
class LogBlackboxEndpoint(AbstractResource):
|
class LogBlackboxEndpoint(AbstractResource):
|
||||||
|
|
|
@ -3,7 +3,7 @@ from flask import request
|
||||||
|
|
||||||
from monkey_island.cc.database import mongo
|
from monkey_island.cc.database import mongo
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
|
|
||||||
|
|
||||||
class MonkeyBlackboxEndpoint(AbstractResource):
|
class MonkeyBlackboxEndpoint(AbstractResource):
|
||||||
|
|
|
@ -3,7 +3,7 @@ from flask import request
|
||||||
|
|
||||||
from monkey_island.cc.models.telemetries import get_telemetry_by_query
|
from monkey_island.cc.models.telemetries import get_telemetry_by_query
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
|
|
||||||
|
|
||||||
class TelemetryBlackboxEndpoint(AbstractResource):
|
class TelemetryBlackboxEndpoint(AbstractResource):
|
||||||
|
|
|
@ -3,7 +3,7 @@ import json
|
||||||
from flask import request
|
from flask import request
|
||||||
|
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.server_utils.encryption import PasswordBasedStringEncryptor
|
from monkey_island.cc.server_utils.encryption import PasswordBasedStringEncryptor
|
||||||
from monkey_island.cc.services.config import ConfigService
|
from monkey_island.cc.services.config import ConfigService
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ from flask import request
|
||||||
|
|
||||||
from common.utils.exceptions import InvalidConfigurationError
|
from common.utils.exceptions import InvalidConfigurationError
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.server_utils.encryption import (
|
from monkey_island.cc.server_utils.encryption import (
|
||||||
InvalidCiphertextError,
|
InvalidCiphertextError,
|
||||||
InvalidCredentialsError,
|
InvalidCredentialsError,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services.reporting.exploitations.manual_exploitation import (
|
from monkey_island.cc.services.reporting.exploitations.manual_exploitation import (
|
||||||
get_manual_exploitations,
|
get_manual_exploitations,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services.reporting.exploitations.monkey_exploitation import (
|
from monkey_island.cc.services.reporting.exploitations.monkey_exploitation import (
|
||||||
get_monkey_exploited,
|
get_monkey_exploited,
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,7 +3,7 @@ import json
|
||||||
from flask import abort, jsonify, request
|
from flask import abort, jsonify, request
|
||||||
|
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services.config import ConfigService
|
from monkey_island.cc.services.config import ConfigService
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services.island_logs import IslandLogService
|
from monkey_island.cc.services.island_logs import IslandLogService
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
|
@ -4,7 +4,7 @@ import logging
|
||||||
from flask import make_response, request
|
from flask import make_response, request
|
||||||
|
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services.config_manipulator import update_config_on_mode_set
|
from monkey_island.cc.services.config_manipulator import update_config_on_mode_set
|
||||||
from monkey_island.cc.services.mode.island_mode_service import ModeNotSetError, get_mode, set_mode
|
from monkey_island.cc.services.mode.island_mode_service import ModeNotSetError, get_mode, set_mode
|
||||||
from monkey_island.cc.services.mode.mode_enum import IslandModeEnum
|
from monkey_island.cc.services.mode.mode_enum import IslandModeEnum
|
||||||
|
|
|
@ -4,7 +4,7 @@ from flask import jsonify, make_response, request
|
||||||
|
|
||||||
from monkey_island.cc.models import Monkey
|
from monkey_island.cc.models import Monkey
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services.node import NodeService
|
from monkey_island.cc.services.node import NodeService
|
||||||
from monkey_island.cc.services.run_local_monkey import LocalMonkeyRunService
|
from monkey_island.cc.services.run_local_monkey import LocalMonkeyRunService
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@ from flask import request
|
||||||
|
|
||||||
from monkey_island.cc.database import mongo
|
from monkey_island.cc.database import mongo
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
|
||||||
from monkey_island.cc.resources.blackbox.utils.telem_store import TestTelemStore
|
from monkey_island.cc.resources.blackbox.utils.telem_store import TestTelemStore
|
||||||
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services.log import LogService
|
from monkey_island.cc.services.log import LogService
|
||||||
from monkey_island.cc.services.node import NodeService
|
from monkey_island.cc.services.node import NodeService
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services.netmap.net_edge import NetEdgeService
|
from monkey_island.cc.services.netmap.net_edge import NetEdgeService
|
||||||
from monkey_island.cc.services.netmap.net_node import NetNodeService
|
from monkey_island.cc.services.netmap.net_node import NetNodeService
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from flask import request
|
from flask import request
|
||||||
|
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services.node import NodeService
|
from monkey_island.cc.services.node import NodeService
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services.utils.node_states import NodeStates as NodeStateList
|
from monkey_island.cc.services.utils.node_states import NodeStates as NodeStateList
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ from werkzeug.utils import secure_filename as sanitize_filename
|
||||||
|
|
||||||
from common.config_value_paths import PBA_LINUX_FILENAME_PATH, PBA_WINDOWS_FILENAME_PATH
|
from common.config_value_paths import PBA_LINUX_FILENAME_PATH, PBA_WINDOWS_FILENAME_PATH
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services import FileRetrievalError, IFileStorageService
|
from monkey_island.cc.services import FileRetrievalError, IFileStorageService
|
||||||
from monkey_island.cc.services.config import ConfigService
|
from monkey_island.cc.services.config import ConfigService
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from flask import jsonify
|
from flask import jsonify
|
||||||
|
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services.ransomware import ransomware_report
|
from monkey_island.cc.services.ransomware import ransomware_report
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ from botocore.exceptions import ClientError, NoCredentialsError
|
||||||
from flask import jsonify, make_response, request
|
from flask import jsonify, make_response, request
|
||||||
|
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services import AWSService
|
from monkey_island.cc.services import AWSService
|
||||||
from monkey_island.cc.services.aws import AWSCommandResults
|
from monkey_island.cc.services.aws import AWSCommandResults
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
import logging
|
||||||
|
from functools import wraps
|
||||||
|
|
||||||
|
import flask_jwt_extended
|
||||||
|
from flask import make_response
|
||||||
|
from flask_jwt_extended.exceptions import JWTExtendedException
|
||||||
|
from jwt import PyJWTError
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def create_access_token(username):
|
||||||
|
access_token = flask_jwt_extended.create_access_token(identity=username)
|
||||||
|
logger.debug(f"Created access token for user {username} that begins with {access_token[:4]}")
|
||||||
|
|
||||||
|
return access_token
|
||||||
|
|
||||||
|
|
||||||
|
# See https://flask-jwt-extended.readthedocs.io/en/stable/custom_decorators/
|
||||||
|
def jwt_required(fn):
|
||||||
|
@wraps(fn)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
try:
|
||||||
|
flask_jwt_extended.verify_jwt_in_request()
|
||||||
|
return fn(*args, **kwargs)
|
||||||
|
# Catch authentication related errors in the verification or inside the called function.
|
||||||
|
# All other exceptions propagate
|
||||||
|
except (JWTExtendedException, PyJWTError) as e:
|
||||||
|
return make_response({"error": f"Authentication error: {str(e)}"}, 401)
|
||||||
|
|
||||||
|
return wrapper
|
|
@ -4,7 +4,7 @@ from flask import jsonify, make_response, request
|
||||||
|
|
||||||
from monkey_island.cc.database import mongo
|
from monkey_island.cc.database import mongo
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services.database import Database
|
from monkey_island.cc.services.database import Database
|
||||||
from monkey_island.cc.services.infection_lifecycle import get_completed_steps
|
from monkey_island.cc.services.infection_lifecycle import get_completed_steps
|
||||||
from monkey_island.cc.services.utils.network_utils import local_ip_addresses
|
from monkey_island.cc.services.utils.network_utils import local_ip_addresses
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services.reporting.report import ReportService
|
from monkey_island.cc.services.reporting.report import ReportService
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@ from monkey_island.cc.database import mongo
|
||||||
from monkey_island.cc.models.monkey import Monkey
|
from monkey_island.cc.models.monkey import Monkey
|
||||||
from monkey_island.cc.models.telemetries import get_telemetry_by_query
|
from monkey_island.cc.models.telemetries import get_telemetry_by_query
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
|
||||||
from monkey_island.cc.resources.blackbox.utils.telem_store import TestTelemStore
|
from monkey_island.cc.resources.blackbox.utils.telem_store import TestTelemStore
|
||||||
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services.node import NodeService
|
from monkey_island.cc.services.node import NodeService
|
||||||
from monkey_island.cc.services.telemetry.processing.processing import process_telemetry
|
from monkey_island.cc.services.telemetry.processing.processing import process_telemetry
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ from flask import request
|
||||||
from common.common_consts.telem_categories import TelemCategoryEnum
|
from common.common_consts.telem_categories import TelemCategoryEnum
|
||||||
from monkey_island.cc.database import mongo
|
from monkey_island.cc.database import mongo
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services.node import NodeService
|
from monkey_island.cc.services.node import NodeService
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services.zero_trust.monkey_findings.monkey_zt_finding_service import (
|
from monkey_island.cc.services.zero_trust.monkey_findings.monkey_zt_finding_service import (
|
||||||
MonkeyZTFindingService,
|
MonkeyZTFindingService,
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,7 +4,7 @@ import flask_restful
|
||||||
from flask import jsonify
|
from flask import jsonify
|
||||||
|
|
||||||
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
from monkey_island.cc.resources.AbstractResource import AbstractResource
|
||||||
from monkey_island.cc.resources.auth.auth import jwt_required
|
from monkey_island.cc.resources.request_authentication import jwt_required
|
||||||
from monkey_island.cc.services.zero_trust.zero_trust_report.finding_service import FindingService
|
from monkey_island.cc.services.zero_trust.zero_trust_report.finding_service import FindingService
|
||||||
from monkey_island.cc.services.zero_trust.zero_trust_report.pillar_service import PillarService
|
from monkey_island.cc.services.zero_trust.zero_trust_report.pillar_service import PillarService
|
||||||
from monkey_island.cc.services.zero_trust.zero_trust_report.principle_service import (
|
from monkey_island.cc.services.zero_trust.zero_trust_report.principle_service import (
|
||||||
|
|
Loading…
Reference in New Issue