예제 #1
0
class PlannerApi(BaseObjectApi):
    def __init__(self, services):
        super().__init__(description='planner',
                         obj_class=Planner,
                         schema=PlannerSchema,
                         ram_key='planners',
                         id_property='planner_id',
                         auth_svc=services['auth_svc'])
        self._api_manager = BaseApiManager(data_svc=services['data_svc'],
                                           file_svc=services['file_svc'])

    def add_routes(self, app: web.Application):
        router = app.router
        router.add_get('/planners', self.get_planners)
        router.add_get('/planners/{planner_id}', self.get_planner_by_id)

    @aiohttp_apispec.docs(tags=['planners'])
    @aiohttp_apispec.querystring_schema(BaseGetAllQuerySchema)
    @aiohttp_apispec.response_schema(PlannerSchema(many=True, partial=True))
    async def get_planners(self, request: web.Request):
        planners = await self.get_all_objects(request)
        return web.json_response(planners)

    @aiohttp_apispec.docs(tags=['planners'])
    @aiohttp_apispec.querystring_schema(BaseGetOneQuerySchema)
    @aiohttp_apispec.response_schema(PlannerSchema(partial=True))
    async def get_planner_by_id(self, request: web.Request):
        planner = await self.get_object(request)
        return web.json_response(planner)
예제 #2
0
class OperationSchema(ma.Schema):
    id = ma.fields.String()
    name = ma.fields.String(required=True)
    host_group = ma.fields.List(ma.fields.Nested(AgentSchema()),
                                attribute='agents',
                                dump_only=True)
    adversary = ma.fields.Nested(AdversarySchema())
    jitter = ma.fields.String()
    planner = ma.fields.Nested(PlannerSchema())
    start = ma.fields.DateTime(format=BaseObject.TIME_FORMAT, dump_only=True)
    state = ma.fields.String()
    obfuscator = ma.fields.String()
    autonomous = ma.fields.Integer()
    chain = ma.fields.Function(lambda obj: [lnk.display for lnk in obj.chain])
    auto_close = ma.fields.Boolean()
    visibility = ma.fields.Integer()
    objective = ma.fields.Nested(ObjectiveSchema())
    use_learning_parsers = ma.fields.Boolean()
    group = ma.fields.String(missing='')
    source = ma.fields.Nested(SourceSchema())

    @ma.pre_load()
    def remove_properties(self, data, **_):
        data.pop('host_group', None)
        data.pop('start', None)
        data.pop('chain', None)
        data.pop('objective', None)
        return data

    @ma.post_load
    def build_operation(self, data, **kwargs):
        return None if kwargs.get('partial') is True else Operation(**data)
예제 #3
0
 async def _construct_and_dump_planner(self, planner_id: str):
     planner = await self.services['data_svc'].locate(
         'planners', match=dict(planner_id=planner_id))
     if not planner:
         planner = await self.services['data_svc'].locate(
             'planners', match=dict(name='atomic'))
     return PlannerSchema().dump(planner[0])
예제 #4
0
def test_planner(event_loop):
    expected_planner = {
        'name': 'test planner',
        'description': 'test planner',
        'module': 'test',
        'stopping_conditions': [],
        'params': {},
        'allow_repeatable_abilities': False,
        'ignore_enforcement_modules': [],
        'id': '123'
    }
    test_planner = PlannerSchema().load(expected_planner)
    event_loop.run_until_complete(
        BaseService.get_service('data_svc').store(test_planner))
    return test_planner
예제 #5
0
def test_operation(test_adversary, test_planner, test_source):
    expected_operation = {
        'name': '123',
        'adversary': AdversarySchema().dump(test_adversary),
        'state': 'paused',
        'id': '123',
        'group': 'red',
        'autonomous': 0,
        'planner': PlannerSchema().dump(test_planner),
        'source': SourceSchema().dump(test_source),
        'jitter': '2/8',
        'visibility': 50,
        'auto_close': False,
        'obfuscator': 'plain-text',
        'use_learning_parsers': False
    }
    return expected_operation
예제 #6
0
class OperationSchema(ma.Schema):
    id = ma.fields.Integer()
    name = ma.fields.String()
    host_group = ma.fields.List(ma.fields.Nested(AgentSchema()), attribute='agents')
    adversary = ma.fields.Nested(AdversarySchema())
    jitter = ma.fields.String()
    planner = ma.fields.Nested(PlannerSchema())
    start = ma.fields.DateTime(format='%Y-%m-%d %H:%M:%S')
    state = ma.fields.String()
    obfuscator = ma.fields.String()
    autonomous = ma.fields.Integer()
    chain = ma.fields.Function(lambda obj: [lnk.display for lnk in obj.chain])
    auto_close = ma.fields.Boolean()
    visibility = ma.fields.Integer()

    @ma.post_load
    def build_planner(self, data, **_):
        return Operation(**data)
예제 #7
0
class PlannerApi(BaseApi):
    def __init__(self, services):
        super().__init__(auth_svc=services['auth_svc'])
        self._api_manager = BaseApiManager(data_svc=services['data_svc'])

    def add_routes(self, app: web.Application):
        router = app.router
        router.add_get('/planners', self.get_planners)
        router.add_get('/planners/{planner_id}', self.get_planner_by_id)

    @aiohttp_apispec.docs(tags=['planners'])
    @aiohttp_apispec.querystring_schema(BaseGetAllQuerySchema)
    @aiohttp_apispec.response_schema(PlannerSchema(many=True))
    async def get_planners(self, request: web.Request):
        sort = request['querystring'].get('sort', 'name')
        include = request['querystring'].get('include')
        exclude = request['querystring'].get('exclude')

        planners = self._api_manager.get_objects_with_filters('planners',
                                                              sort=sort,
                                                              include=include,
                                                              exclude=exclude)
        return web.json_response(planners)

    @aiohttp_apispec.docs(tags=['planners'])
    @aiohttp_apispec.querystring_schema(BaseGetOneQuerySchema)
    @aiohttp_apispec.response_schema(PlannerSchema)
    async def get_planner_by_id(self, request: web.Request):
        planner_id = request.match_info['planner_id']
        include = request['querystring'].get('include')
        exclude = request['querystring'].get('exclude')

        search = dict(planner_id=planner_id)

        planner = self._api_manager.get_object_with_filters('planners',
                                                            search=search,
                                                            include=include,
                                                            exclude=exclude)
        if not planner:
            raise JsonHttpNotFound(f'Planner not found: {planner_id}')

        return web.json_response(planner)
예제 #8
0
class PlannerApi(BaseObjectApi):
    def __init__(self, services):
        super().__init__(description='planner',
                         obj_class=Planner,
                         schema=PlannerSchema,
                         ram_key='planners',
                         id_property='planner_id',
                         auth_svc=services['auth_svc'])
        self._api_manager = BaseApiManager(data_svc=services['data_svc'],
                                           file_svc=services['file_svc'])

    def add_routes(self, app: web.Application):
        router = app.router
        router.add_get('/planners', self.get_planners)
        router.add_get('/planners/{planner_id}', self.get_planner_by_id)

    @aiohttp_apispec.docs(
        tags=['planners'],
        summary='Retrieve planners',
        description=
        'Retrieve CALDERA planners by criteria. Supply fields from the `PlannerSchema` '
        'to the `include` and `exclude` fields of the `BaseGetAllQuerySchema` in the '
        'request body to filter retrieved planners.')
    @aiohttp_apispec.querystring_schema(BaseGetAllQuerySchema)
    @aiohttp_apispec.response_schema(
        PlannerSchema(many=True, partial=True),
        description=
        'Returns a list of matching planners in `PlannerSchema` format.')
    async def get_planners(self, request: web.Request):
        planners = await self.get_all_objects(request)
        return web.json_response(planners)

    @aiohttp_apispec.docs(
        tags=['planners'],
        summary='Retrieve a planner by planner id',
        description=
        'Retrieve one CALDERA planner based on the planner id (String `UUID`). '
        'Supply fields from the `PlannerSchema` to the `include` and `exclude` fields '
        'of the `BaseGetOneQuerySchema` in the request body to filter retrieved '
        'planners.',
        parameters=[{
            'in':
            'path',
            'name':
            'planner_id',
            'schema': {
                'type': 'string'
            },
            'required':
            'true',
            'description':
            'UUID of the Planner object to be retrieved.'
        }])
    @aiohttp_apispec.querystring_schema(BaseGetOneQuerySchema)
    @aiohttp_apispec.response_schema(
        PlannerSchema(partial=True),
        description=
        'Returns a planner with the specified id in `PlannerSchema` format.')
    async def get_planner_by_id(self, request: web.Request):
        planner = await self.get_object(request)
        return web.json_response(planner)