Metadata-Version: 2.1
Name: lookout_mra_client
Version: 2.6.1
Summary: Lookout's Mobile Risk API in Python
Author-email: Lookout <esupport@lookout.com>
Classifier: Development Status :: 5 - Production/Stable
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.9
Requires-Python: >=3.6
Description-Content-Type: text/markdown
License-File: LICENSE.txt
Requires-Dist: requests
Requires-Dist: oauthlib>=3.2
Requires-Dist: requests-oauthlib>=1.3
Provides-Extra: models
Requires-Dist: peewee>=3.15; extra == "models"
Requires-Dist: wtforms>=3.0; extra == "models"
Requires-Dist: flask-wtf>=1.0; extra == "models"
Requires-Dist: furl>=2.1; extra == "models"

# Mobile Risk API Client `lookout_mra_client`

This package contains the code required to create a Mobile Risk API client in Python.

## Requirements
This module requires Python 3.9.

## Installation
```bash
pip install lookout_mra_client
```

## Demo script
The module will install a script called `mra-v2-demo`.
```sh
# read MRA API key from /var/opt/apikey.txt
# log events to /var/log/output.txt
mra-v2-demo file \\
    --output /var/log/output.txt \\
    --api_key /var/opt/apikey.txt \\
    --event_type THREAT DEVICE
```
Run `mra-v2-demo -h` to view more usage options.

## Usage

### Simple Event Reader
Write the following into a file named `mra_event_reader.py`:
```python
import datetime

from lookout_mra_client.event_forwarders.event_forwarder import EventForwarder
from lookout_mra_client.mra_v2_stream_thread import MRAv2StreamThread

class StdoutForwarder(EventForwarder):
    def write(self, event: dict, entName: str = ""):
        println(event)

def main():
    start_time = datetime.datetime.now() - datetime.timedelta(days=1)
    start_time = start_time.replace(tzinfo=datetime.timezone.utc)
    event_type = [ "THREAT", "DEVICE" ]
    stream_args = {
        "api_domain": "https://api.lookout.com",
        "api_key": your_lookout_api_key_here,
        "start_time": start_time,
        "event_type": ",".join(event_type),
    }
    mra = MRAv2StreamThread("demoEnt", forwarder, **stream_args)

    try:
        mra.start()
        while True:
            time.sleep(100)
    except KeyboardInterrupt:
        mra.shutdown_flag.set()
        mra.join()

if __name__ == "__main__":
    main()
```
Then, run the file using `python mra_event_reader.py`. This will read events from MRA APIs
and print them to the console.

### Event Forwarder
The event forwarder decides the output of the program. Define an event forwarder and pass it
as a parameter to the MRA client as shown in the example above.

To define an event forwarder, extend the base class EventForwarder and implement the write
method.
```python
from lookout_mra_client.event_forwarders.event_forwarder import EventForwarder

class StdoutForwarder(EventForwarder):
    def write(self, event: dict, entName: str = ""):
        println(event)
```

### `event_translators`

Translate MRA events to third party event formats.

Currently Supported:
* IBM QRadar LEEF - `leef_translator.py`

### `init_lookout_logger`

Initialize a log file for the MRA client to write debug and application logs to. It is
best called inside the `main` function before any other code.
```python
from lookout_mra_client.lookout_logger import init_lookout_logger
...
def main():
    init_lookout_logger("./mra_v2_demo_script.log")
...
```
The MRA client will send logs to the file `mra_v2_demo_script.log`.

## Customization
The `transform_event` utility can be used to change the field names in the received event object. The event
forwarder is an ideal place for calling this function.

The fields in the event can be renamed as required. In the below example, the `targetGuid`
key is renamed to `lookoutDeviceGuid`.

```python
from lookout_mra_client.event_translators.utilities import transform_event
from lookout_mra_client.event_forwarders.event_forwarder import EventForwarder

class StdoutForwarder(EventForwarder):
    event_mappings = (("targetGuid", "lookoutDeviceGuid"))

    def write(self, event: dict, entName: str = ""):
        # targetGuid: guid -> lookoutDeviceGuid: guid
        newEvent = transform_event(self.event_mappings, event)
        println(newEvent)
```

The corresponding value of a field can also be transformed. The following code prefixes `new_` to
the value against `targetGuid` while also renaming the field.

```python
from lookout_mra_client.event_translators.utilities import transform_event
from lookout_mra_client.event_forwarders.event_forwarder import EventForwarder

class StdoutForwarder(EventForwarder):
    event_mappings = (("targetGuid", "lookoutDeviceGuid", lambda value: "new_" + value))

    def write(self, event: dict, entName: str = ""):
        # targetGuid: guid -> lookoutDeviceGuid: new_guid
        newEvent = transform_event(event_mappings, event)
        println(newEvent)
```

Multiple fields can be combined into a single field. Eg: if a new field is required that
combines `targetGuid` and `entGuid`, it can be done as follows.

```python
from lookout_mra_client.src.lookout_mra_client.event_translators.utilities import transform_event
from lookout_mra_client.event_forwarders.event_forwarder import EventForwarder

class StdoutForwarder(EventForwarder):
    event_mappings = ((
        "targetGuid", "entGuid", "guid",
        lambda value1, value2: value1 + "_" + value
    ))

    def write(self, event: dict, entName: str = ""):
        # targetGuid: guid1, entGuid: guid2 -> guid: guid1_guid2
        newEvent = transform_event(event_mappings, event)
        println(newEvent)
```
