diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index c3598da..2516b0e 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -1,4 +1,7 @@ # Changelog +## [5.0.1](https://github.com/intelowlproject/pyintelowl/releases/tag/5.0.1) +- Updated documentation +- Removed old endpoints ## [5.0.0](https://github.com/intelowlproject/pyintelowl/releases/tag/5.0.0) - Fixes for Playbook Analysis diff --git a/.github/release_template.md b/.github/release_template.md index 06f03fc..868f541 100644 --- a/.github/release_template.md +++ b/.github/release_template.md @@ -1,7 +1,7 @@ # Checklist for creating a new release - [ ] Update `CHANGELOG.md` for the new version -- [ ] Change version number in `docs/conf.py`, `pyintelowl/version.py` +- [ ] Change version number in `pyintelowl/version.py` - [ ] Verify CI Tests - [ ] Merge the PR to the `master` branch. **Note:** Only use "Merge and commit" as the merge strategy and not "Squash and merge". Using "Squash and merge" makes history between branches misaligned. diff --git a/.readthedocs.yml b/.readthedocs.yml deleted file mode 100644 index 205039b..0000000 --- a/.readthedocs.yml +++ /dev/null @@ -1,24 +0,0 @@ -# .readthedocs.yml -# Read the Docs configuration file -# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details - -# Required -version: 2 - -build: - os: ubuntu-22.04 - tools: - python: "3.9" - -# Build all formats -formats: all - -# Optionally set the version of Python and requirements required to build your docs -python: - install: - - requirements: docs/requirements.txt - -# Build documentation in the docs/ directory with Sphinx -sphinx: - builder: html - configuration: docs/conf.py \ No newline at end of file diff --git a/README.md b/README.md index 7f2def5..b503b4a 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,6 @@ Robust Python **SDK** and **Command Line Client** for interacting with [IntelOwl - Choose whether you want to HTTP poll for the analysis to finish or not. - List all jobs or view one job in a prettified tabular form. - List all tags or view one tag in a prettified tabular form. -- Tabular view of the `analyzer_config.json` and `connector_config.json` from IntelOwl with RegEx matching capabilities. ## Demo @@ -51,8 +50,6 @@ Commands: analyzer-healthcheck Send healthcheck request for an analyzer... config Set or view config variables connector-healthcheck Send healthcheck request for a connector - get-analyzer-config Get current state of `analyzer_config.json` from... - get-connector-config Get current state of `connector_config.json` from... jobs Manage Jobs tags Manage tags ``` @@ -64,27 +61,18 @@ from pyintelowl import IntelOwl obj = IntelOwl("", "", "optional", "optional") ``` -For more comprehensive documentation, please see https://pyintelowl.readthedocs.io/. +For more comprehensive documentation, please see https://intelowlproject.github.io/docs/pyintelowl/. ## Changelog View [CHANGELOG.md](https://github.com/intelowlproject/pyintelowl/blob/master/.github/CHANGELOG.md). -## FAQ -#### Generate API key +## How to generate an API key You need a valid API key to interact with the IntelOwl server. -Keys should be created from the admin interface of [IntelOwl](https://github.com/intelowlproject/intelowl): you have to go in the _Durin_ section (click on `Auth tokens`) and generate a key there. +Keys can be created from the "API access" section of the user's menu in the IntelOwl's GUI. -#### Incompatibility after version 3.0 +![api_access](static/api_access.png) -We did a complete rewrite of the PyIntelOwl client and CLI both for the version `3.0.0`. We very much recommend you to update to the latest version to enjoy all new features. - -#### (old auth method) JWT Token Authentication - -> this auth was available in IntelOwl versions <1.8.0 and pyintelowl versions <2.0.0 - -From the admin interface of IntelOwl, you have to go in the _Outstanding tokens_ section and generate a token there. - -You can use it by pasting it into the file [api_token.txt](api_token.txt). +Otherwise, you can create them from the Django Admin Interface of the IntelOwl application with an administration account. Section "Durin" -> "Auth tokens" diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index d4bb2cb..0000000 --- a/docs/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/__init__.py b/docs/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/docs/conf.py b/docs/conf.py deleted file mode 100644 index 1b3bbc2..0000000 --- a/docs/conf.py +++ /dev/null @@ -1,83 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -import os -import sys - -VERSION = "5.0.0" -GITHUB_URL = "https://github.com/intelowlproject/pyintelowl" - -sys.path.append(os.path.abspath("../")) - - -# -- Project information ----------------------------------------------------- - -project = "PyIntelOwl" -copyright = "2021, Matteo Lodi" -author = "Matteo Lodi" - -# The full version, including alpha/beta/rc tags -release = VERSION - -# -- General configuration --------------------------------------------------- - -html_title = f"{project} Documentation ({VERSION})" - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - "sphinx_rtd_theme", - "sphinxcontrib.napoleon", - "sphinx.ext.autodoc", - "sphinx.ext.viewcode", - "sphinx.ext.todo", - "sphinxcontrib.asciinema", -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = "en" - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] - - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = "sphinx_rtd_theme" -html_theme_path = [ - "_themes", -] - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] - - -# -- Extension configuration ------------------------------------------------- - -# -- Options for todo extension ---------------------------------------------- - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = True diff --git a/docs/index.rst b/docs/index.rst deleted file mode 100644 index adc6e49..0000000 --- a/docs/index.rst +++ /dev/null @@ -1,104 +0,0 @@ -Welcome to PyIntelOwl's documentation! -====================================== - -Robust Python **SDK** and **Command Line Client** for interacting with `IntelOwl `__ API. - -Installation --------------------------- - -.. code-block:: bash - - $ pip install pyintelowl - - -Usage as CLI --------------------------- - -On successful installation, The ``pyintelowl`` entryscript should be directly invokable. For example, - -.. code-block:: bash - :emphasize-lines: 1 - - $ pyintelowl - Usage: pyintelowl [OPTIONS] COMMAND [ARGS]... - - Options: - -d, --debug Set log level to DEBUG - --version Show the version and exit. - -h, --help Show this message and exit. - - Commands: - analyse Send new analysis request - analyzer-healthcheck Send healthcheck request for an analyzer... - config Set or view config variables - connector-healthcheck Send healthcheck request for a connector - get-analyzer-config Get current state of `analyzer_config.json` from... - get-connector-config Get current state of `connector_config.json` from... - get-playbook-config Get current state of `playbook_config.json` from... - jobs Manage Jobs - tags Manage tags - -**Configuration:** - -You can use ``set`` to set the config variables and ``get`` to view them. - -.. code-block:: bash - :caption: `View on asciinema `__ - - $ pyintelowl config set -k 4bf03f20add626e7138f4023e4cf52b8 -u "http://localhost:80" - $ pyintelowl config get - -.. Hint:: - The CLI would is well-documented which will help you navigate various commands easily. - Invoke ``pyintelowl -h`` or ``pyintelowl -h`` to get help. - - -Usage as SDK/library --------------------------- - -.. code-block:: python - :linenos: - - from pyintelowl import IntelOwl, IntelOwlClientException - obj = IntelOwl( - "4bf03f20add626e7138f4023e4cf52b8", - "http://localhost:80", - None, - ) - """ - obj = IntelOwl( - "", - "", - "optional" - "optional" - ) - """ - - try: - ans = obj.get_analyzer_configs() - print(ans) - except IntelOwlClientException as e: - print("Oh no! Error: ", e) - -.. Tip:: We very much **recommend** going through the :class:`pyintelowl.pyintelowl.IntelOwl` docs. - -Index -------------------------------- - -.. toctree:: - :maxdepth: 2 - :caption: Usage - - pyintelowl - -.. toctree:: - :maxdepth: 2 - :caption: Development - - tests - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` diff --git a/docs/make.bat b/docs/make.bat deleted file mode 100644 index 2119f51..0000000 --- a/docs/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=. -set BUILDDIR=_build - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/docs/pyintelowl.rst b/docs/pyintelowl.rst deleted file mode 100644 index 2a6b8b3..0000000 --- a/docs/pyintelowl.rst +++ /dev/null @@ -1,18 +0,0 @@ -Modules -============================ - -``IntelOwl`` class --------------------------------- - -.. autoclass:: pyintelowl.pyintelowl.IntelOwl - :members: - :undoc-members: - :show-inheritance: - -``IntelOwlClientException`` class --------------------------------- - -.. autoclass:: pyintelowl.exceptions.IntelOwlClientException - :members: - :undoc-members: - :show-inheritance: \ No newline at end of file diff --git a/docs/requirements.txt b/docs/requirements.txt deleted file mode 100644 index e49e325..0000000 --- a/docs/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -Sphinx==5.1.1 -sphinx-rtd-theme -sphinxcontrib.asciinema -sphinxcontrib-napoleon \ No newline at end of file diff --git a/docs/serve_docs.sh b/docs/serve_docs.sh deleted file mode 100755 index 423fa20..0000000 --- a/docs/serve_docs.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash -make html -cd _build/html && python3 -m http.server 6969 && cd ../../ \ No newline at end of file diff --git a/docs/tests.rst b/docs/tests.rst deleted file mode 100644 index 88ddc44..0000000 --- a/docs/tests.rst +++ /dev/null @@ -1,44 +0,0 @@ -Tests -====================================== - -Configuration --------------------------------------- - -Some tests require file samples, which can be found in the encrypted folder ``tests/test_files.zip`` (password: "infected"). -Unzip the archive in ``tests/test_files`` folder before running the tests. - -**Please remember that these are dangerous malware! They come encrypted and locked for a reason! -Do NOT run them unless you are absolutely sure of what you are doing! -They are to be used only for launching specific tests that require them** (``__send_analysis_request``) - -* With the following constants in ``__init__.py``, you can customize your tests: - - * **MOCKING_CONNECTIONS:** Mock connections to external API to test functions without a real connection or a valid API Key. - -* If you prefer to use custom inputs for tests, you can change the following constants: - - * **TEST_JOB_ID** - * **TEST_HASH** - * **TEST_URL** - * **TEST_IP** - * **TEST_DOMAIN** - * **TEST_GENERIC** - * **TEST_FILE** - * **TEST_FILE_HASH** - -Launch Tests -------------------------------------- - -* The test requirements are specified in the ``test-requirements.txt`` file. Install them using, - -.. code-block:: bash - - $ pip3 install -r test-requirements.txt - -* Launch the tests using ``tox``: - -.. code-block:: bash - - $ tox - - diff --git a/pyintelowl/cli/commands.py b/pyintelowl/cli/commands.py index 592309e..9bef204 100644 --- a/pyintelowl/cli/commands.py +++ b/pyintelowl/cli/commands.py @@ -1,222 +1,9 @@ -import json -import re - import click -from rich import box from rich import print as rprint -from rich.console import Console -from rich.table import Table from pyintelowl.pyintelowl import IntelOwlClientException -from ..cli._utils import ( - ClickContext, - add_options, - get_json_syntax, - get_success_text, - json_flag_option, -) - - -@click.command( - help="Get current state of `analyzer_config.json` from the IntelOwl instance", -) -@click.option( - "-m", - "--re-match", - help="RegEx Pattern to filter analyzer names against", -) -@add_options(json_flag_option) -@click.option( - "-t", "--text", "as_text", is_flag=True, help="Print analyzer names as CSV" -) -@click.pass_context -def get_analyzer_config(ctx: ClickContext, re_match: str, as_json: bool, as_text: bool): - console = Console() - ctx.obj.logger.info("Requesting [italic blue]analyzer_config.json[/]..") - try: - res = ctx.obj.get_analyzer_configs() - # filter resulset if a regex pattern was provided - if re_match: - pat = re.compile(re_match) - res = {k: v for k, v in res.items() if pat.match(k) is not None} - except IntelOwlClientException as e: - ctx.obj.logger.fatal(str(e)) - ctx.exit(0) - if as_json: - with console.pager(styles=True): - console.print(json.dumps(res, indent=4)) - elif as_text: - click.echo(", ".join(res.keys())) - else: - # otherwise, print full table - headers = [ - "Name", - "Type", - "Description", - "Supported\nTypes", - "External\nService", - "Leaks\nInfo", - "Configuration", - "Parameters", - "Secrets", - "Configured", - ] - header_style = "bold blue" - table = Table( - show_header=True, - title="Analyzer Configurations", - box=box.DOUBLE_EDGE, - show_lines=True, - ) - for h in headers: - table.add_column(h, header_style=header_style, justify="center") - for name, obj in res.items(): - table.add_row( - name, - obj["type"], - obj.get("description", ""), - get_json_syntax( - obj.get( - "observable_supported", - obj.get("supported_filetypes", []), - ) - ), - get_success_text(obj.get("external_service", False)), - get_success_text(obj.get("leaks_info", False)), - get_json_syntax(obj.get("config", {})), - get_json_syntax(obj.get("params", {})), - get_json_syntax(obj.get("secrets", {})), - get_success_text(obj["verification"].get("configured", False)), - ) - with console.pager(styles=True): - console.print(table) - - -@click.command( - help="Get current state of `connector_config.json` from the IntelOwl instance", -) -@click.option( - "-m", - "--re-match", - help="RegEx Pattern to filter connector names against", -) -@add_options(json_flag_option) -@click.option( - "-t", "--text", "as_text", is_flag=True, help="Print connector names as CSV" -) -@click.pass_context -def get_connector_config( - ctx: ClickContext, re_match: str, as_json: bool, as_text: bool -): - console = Console() - ctx.obj.logger.info("Requesting [italic blue]connector_config.json[/]..") - try: - res = ctx.obj.get_connector_configs() - # filter resulset if a regex pattern was provided - if re_match: - pat = re.compile(re_match) - res = {k: v for k, v in res.items() if pat.match(k) is not None} - except IntelOwlClientException as e: - ctx.obj.logger.fatal(str(e)) - ctx.exit(0) - if as_json: - with console.pager(styles=True): - console.print(json.dumps(res, indent=4)) - elif as_text: - click.echo(", ".join(res.keys())) - else: - # otherwise, print full table - headers = [ - "Name", - "Description", - "Configuration", - "Parameters", - "Secrets", - "Configured", - ] - header_style = "bold blue" - table = Table( - show_header=True, - title="Connector Configurations", - box=box.DOUBLE_EDGE, - show_lines=True, - ) - for h in headers: - table.add_column(h, header_style=header_style, justify="center") - for name, obj in res.items(): - table.add_row( - name, - obj.get("description", ""), - get_json_syntax(obj.get("config", {})), - get_json_syntax(obj.get("params", {})), - get_json_syntax(obj.get("secrets", {})), - get_success_text(obj["verification"].get("configured", False)), - ) - with console.pager(styles=True): - console.print(table) - - -@click.command( - help="Get current state of `playbook_config.json` from the IntelOwl instance", -) -@click.option( - "-m", - "--re-match", - help="RegEx Pattern to filter analyzer names against", -) -@add_options(json_flag_option) -@click.option( - "-t", "--text", "as_text", is_flag=True, help="Print playbook names as CSV" -) -@click.pass_context -def get_playbook_config(ctx: ClickContext, re_match: str, as_json: bool, as_text: bool): - console = Console() - ctx.obj.logger.info("Requesting [italic blue]playbook_config.json[/]..") - try: - res = ctx.obj.get_playbook_configs() - # filter resulset if a regex pattern was provided - if re_match: - pat = re.compile(re_match) - res = {k: v for k, v in res.items() if pat.match(k) is not None} - except IntelOwlClientException as e: - ctx.obj.logger.fatal(str(e)) - ctx.exit(0) - if as_json: - with console.pager(styles=True): - console.print(json.dumps(res, indent=4)) - elif as_text: - click.echo(", ".join(res.keys())) - else: - # otherwise, print full table - headers = [ - "Name", - "Analyzers", - "Connectors", - "Description", - "Supports", - "Disabled", - ] - header_style = "bold blue" - table = Table( - show_header=True, - title="Playbook Configurations", - box=box.DOUBLE_EDGE, - show_lines=True, - ) - for h in headers: - table.add_column(h, header_style=header_style, justify="center") - for name, obj in res.items(): - table.add_row( - name, - get_json_syntax(obj.get("analyzers", {})), - get_json_syntax(obj.get("connectors", {})), - obj.get("description", ""), - get_json_syntax(obj.get("supports", [])), - get_success_text(obj.get("disabled", False)), - ) - with console.pager(styles=True): - console.print(table) +from ..cli._utils import ClickContext, get_success_text @click.command(help="Send healthcheck request for an analyzer (docker-based)") diff --git a/pyintelowl/pyintelowl.py b/pyintelowl/pyintelowl.py index 03b950a..b9e9afa 100644 --- a/pyintelowl/pyintelowl.py +++ b/pyintelowl/pyintelowl.py @@ -551,33 +551,6 @@ def edit_tag(self, tag_id: Union[int, str], label: str, color: str): response = self.__make_request("PUT", url=url, data=data) return response.json() - def get_analyzer_configs(self): - """ - Get current state of `analyzer_config.json` from the IntelOwl instance.\n - Endpoint: ``/api/get_analyzer_configs`` - """ - url = self.instance + "/api/get_analyzer_configs" - response = self.__make_request("GET", url=url) - return response.json() - - def get_connector_configs(self): - """ - Get current state of `connector_config.json` from the IntelOwl instance.\n - Endpoint: ``/api/get_connector_configs`` - """ - url = self.instance + "/api/get_connector_configs" - response = self.__make_request("GET", url=url) - return response.json() - - def get_playbook_configs(self): - """ - Get current state of `playbook_config.json` from the IntelOwl instance.\n - Endpoint: ``/api/get_playbook_configs`` - """ - url = self.instance + "/api/get_playbook_configs" - response = self.__make_request("GET", url=url) - return response.json() - def get_all_tags(self) -> List[Dict[str, str]]: """ Fetch list of all tags.\n @@ -702,8 +675,8 @@ def _new_analysis_cli( self.logger.info( f"""Requesting analysis.. {type_}: [blue]{obj}[/] - analyzers: [i green]{analyzers_list if analyzers_list else 'all'}[/] - connectors: [i green]{connectors_list if connectors_list else 'all'}[/] + analyzers: [i green]{analyzers_list if analyzers_list else 'none'}[/] + connectors: [i green]{connectors_list if connectors_list else 'none'}[/] tags: [i green]{tags_labels}[/] """ ) diff --git a/pyintelowl/version.py b/pyintelowl/version.py index ba7be38..2fe5fde 100644 --- a/pyintelowl/version.py +++ b/pyintelowl/version.py @@ -1 +1 @@ -__version__ = "5.0.0" +__version__ = "5.0.1" diff --git a/setup.py b/setup.py index 1db02ca..d513893 100644 --- a/setup.py +++ b/setup.py @@ -47,6 +47,7 @@ "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Topic :: Software Development :: Libraries :: Python Modules", ], packages=find_packages(), @@ -57,7 +58,7 @@ "Documentation": GITHUB_URL, "Funding": "https://liberapay.com/IntelOwlProject/", "Source": GITHUB_URL, - "Tracker": "{}/issues".format(GITHUB_URL), + "Tracker": f"{GITHUB_URL}/issues", }, keywords="intelowl sdk python command line osint threat intel malware", # List additional groups of dependencies here (e.g. development diff --git a/static/api_access.png b/static/api_access.png new file mode 100644 index 0000000..e5787d2 Binary files /dev/null and b/static/api_access.png differ diff --git a/tests/test_general.py b/tests/test_general.py index 9e5f28f..12fb627 100644 --- a/tests/test_general.py +++ b/tests/test_general.py @@ -1,11 +1,8 @@ from pyintelowl.exceptions import IntelOwlClientException from tests.mocked_requests import ( - mocked_analyzer_config, mocked_ask_analysis_no_job_id, mocked_ask_analysis_no_status, mocked_ask_analysis_success, - mocked_connector_config, - mocked_playbook_config, mocked_raise_exception, mocked_send_analysis_success, mocked_send_playbook_analysis_success, @@ -60,33 +57,6 @@ def test_ask_analysis_availability_failure(self, mocked_requests): analyzers=analyzers, ) - @mock_connections(patch("requests.Session.get", side_effect=mocked_analyzer_config)) - def test_get_analyzer_config_success(self, mocked_requests): - ac = self.client.get_analyzer_configs() - self.assertNotEqual({}, ac) - - @mock_connections(patch("requests.Session.get", side_effect=mocked_raise_exception)) - def test_get_analyzer_config_failure(self, mocked_requests): - with self.assertRaises(IntelOwlClientException): - self.client.get_analyzer_configs() - - @mock_connections( - patch("requests.Session.get", side_effect=mocked_connector_config) - ) - def test_get_connector_config_success(self, mocked_requests): - cc = self.client.get_connector_configs() - self.assertNotEqual({}, cc) - - @mock_connections(patch("requests.Session.get", side_effect=mocked_playbook_config)) - def test_get_playbook_config_success(self, mocked_requests): - cc = self.client.get_playbook_configs() - self.assertNotEqual({}, cc) - - @mock_connections(patch("requests.Session.get", side_effect=mocked_raise_exception)) - def test_get_connector_config_failure(self, mocked_requests): - with self.assertRaises(IntelOwlClientException): - self.client.get_connector_configs() - @mock_connections( patch("requests.Session.post", side_effect=mocked_send_analysis_success) )