Beispiel #1
1
def get_token(refresh_token=False):
    """
    Check if we have a valid token and if not get one
    """
    ctx = demisto.getIntegrationContext()
    if {'token', 'stored', 'expires'} <= set(ctx) and not refresh_token:
        if epoch_seconds() - ctx.get('stored') < ctx.get('expires'):
            return ctx.get('token')
    response = requests.get(
        DEMISTOBOT,
        headers=HEADERS,
        params={
            "tenant": TENANT,
            "product": PRODUCT
        },
        verify=USE_SSL,
    )
    data = response.json()
    if not response.ok:
        return_error(
            f'API call to MS Graph failed [{data.get("status")} {data.get("title")}] - {data.get("detail")}'
        )

    demisto.setIntegrationContext({
        'token': data.get('token'),
        'stored': epoch_seconds(),
        'expires': data.get('expires', 3600) - 30
    })
    return data.get('token')
def initialize():
    endpoint = '/login'
    commands = {
        'command': 'login',
        'api_token': API_KEY
    }

    state = demisto.getIntegrationContext()

    if not state.get('session_token'):
        session_token = None
        token_expires = None
    else:
        session_token = state.get('session_token')
        token_expires = state.get('token_expires')

    demisto.info('Initializing request...')

    if session_token is None or (token_expires is not None and token_expires < int(time.time())):
        if session_token is None:
            demisto.info('Session token missing - getting new session token...')
        elif token_expires is not None and token_expires < int(time.time()):
            demisto.info('Session token expired - getting new session token...')

        r = http_request(endpoint, commands)
        demisto.setIntegrationContext({'session_token': r['token'],
                                       'token_expires': int(time.time() + (10 * 60))
                                       })
        return

    demisto.info('Cached session token not expired.')
    return
    def get_access_token(self):
        """
           Obtains access and refresh token from server.
           Access token is used and stored in the integration context until expiration time.
           After expiration, new refresh token and access token are obtained and stored in the
           integration context.

           Returns:
               str: Access token that will be added to authorization header.
       """
        now = datetime.now()
        integration_context = demisto.getIntegrationContext()[0] \
            if isinstance(demisto.getIntegrationContext(), list) else demisto.getIntegrationContext()
        access_token = integration_context.get('access_token')
        valid_until = integration_context.get('valid_until')
        if access_token:
            if get_passed_mins(now, valid_until) >= TOKEN_LIFE_TIME:
                # token expired
                access_token = self.get_token_request()
                integration_context = {
                    'access_token': access_token,
                    'valid_until': date_to_timestamp(now) / 1000
                }
                demisto.setIntegrationContext(integration_context)
            return access_token
        else:
            # there's no token
            access_token = self.get_token_request()
            integration_context = {
                'access_token': access_token,
                'valid_until': date_to_timestamp(now) / 1000
            },
            demisto.setIntegrationContext(integration_context)
            return access_token
Beispiel #4
0
def update_access_token():
    """
    Check if we have a valid token and if not get one and update global HEADERS
    """
    ctx = demisto.getIntegrationContext()
    if ctx.get('token') and ctx.get('stored'):
        if epoch_seconds() - ctx.get('stored') < 60 * 60 - 30:
            HEADERS['Authorization'] = 'Bearer ' + ctx.get('token')
            return
    headers = {
        'Authorization': TOKEN,
        'Accept': 'application/json'
    }
    token_retrieval_url = 'https://demistobot.demisto.com/azurecompute-token'  # disable-secrets-detection
    parameters = {'tenant': TENANT_ID, 'product': 'AzureCompute'}
    r = requests.get(token_retrieval_url, headers=headers, params=parameters, verify=USE_SSL)
    if r.status_code not in {200, 201}:
        return_error('Error in authentication with the application. Try checking the credentials you entered.')
    try:
        response = r.json()
    except ValueError:
        err_msg = 'There was a problem in retrieving an updated access token.'
        err_msg += ' The response from the Demistobot server did not contain the expected content.'
        return_error(err_msg)
    demisto.setIntegrationContext({
        'token': response.get('token'),
        'stored': epoch_seconds(),
        'subscription_id': response.get('subscription_id')
    })
    HEADERS['Authorization'] = 'Bearer ' + response.get('token')
Beispiel #5
0
def set_subscription_id():
    """
    Setting subscription ID to the context and returning it
    """
    headers = {
        'Authorization': TOKEN,
        'Accept': 'application/json'
    }
    token_retrieval_url = 'https://demistobot.demisto.com/azurecompute-token'  # disable-secrets-detection
    parameters = {'tenant': TENANT_ID, 'product': 'AzureCompute'}
    r = requests.get(token_retrieval_url, headers=headers, params=parameters, verify=USE_SSL)
    try:
        response = r.json()
        if r.status_code != requests.codes.ok:
            return_error('Error: {}\nDescription:{}'.format(response.get('title'), response.get('detail')))
        sub_id = response.get('subscription_id')
        demisto.setIntegrationContext({
            'token': response.get('token'),
            'stored': epoch_seconds(),
            'subscription_id': sub_id
        })
        return sub_id
    except ValueError as e:
        if e.message == 'No JSON object could be decoded':
            return_error(response.content)
        else:
            raise e
Beispiel #6
0
 def _get_access_token(self):
     """
     Checks if access token exists in the integration context and return it if it exists, if not, a new token
     is generated and saved in the integration context along with the query api_url and the instance_id
     Returns:
         The access token from the integration context or from the request.
     """
     integration_context = demisto.getIntegrationContext()
     access_token = integration_context.get(ACCESS_TOKEN_CONST)
     valid_until = integration_context.get(EXPIRES_IN)
     if access_token and valid_until:
         if int(time.time()) < valid_until:
             self.access_token = access_token
             self.api_url = integration_context.get(API_URL_CONST,
                                                    DEFAULT_API_URL)
             self.instance_id = integration_context.get(INSTANCE_ID_CONST)
     access_token, api_url, instance_id, refresh_token, expires_in = self._oproxy_authorize(
     )
     updated_integration_context = {
         ACCESS_TOKEN_CONST: access_token,
         EXPIRES_IN: int(time.time()) + expires_in - SECONDS_30,
         API_URL_CONST: api_url,
         INSTANCE_ID_CONST: instance_id
     }
     if refresh_token:
         updated_integration_context.update(
             {REFRESH_TOKEN_CONST: refresh_token})
     demisto.setIntegrationContext(updated_integration_context)
     self.access_token = access_token
     self.api_url = api_url
     self.instance_id = instance_id
Beispiel #7
0
def login():
    query_path = 'www/core-service/rest/LoginService/login'
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Accept': 'application/json'
    }
    params = {
        'login': demisto.get(demisto.params(), 'credentials.identifier'),
        'password': demisto.get(demisto.params(), 'credentials.password'),
        'alt': 'json'
    }
    res = send_request(query_path,
                       headers=headers,
                       params=params,
                       is_login=True)
    if not res.ok:
        demisto.debug(res.text)
        return_error('Failed to login, check integration parameters.')

    try:
        res_json = res.json()
        if 'log.loginResponse' in res_json and 'log.return' in res_json.get(
                'log.loginResponse'):
            auth_token = res_json.get('log.loginResponse').get('log.return')
            if demisto.command() not in ['test-module', 'fetch-incidents']:
                # this is done to bypass setting integration context outside of the cli
                demisto.setIntegrationContext({'auth_token': auth_token})
            return auth_token

        return_error('Failed to login. Have not received token after login')
    except ValueError:
        return_error('Failed to login. Please check integration parameters')
Beispiel #8
0
def fetch_indicators_command(client: Client, initial_count: int,
                             max_indicators: int,
                             update_context: bool) -> List[Dict]:
    integration_context = demisto.getIntegrationContext()
    offset = integration_context.get("offset")
    count = max_indicators
    if not offset:
        offset = client.get_offsets().get("endOffset")
        if initial_count > 0:
            offset = offset - initial_count + 1
            count = max_indicators + initial_count

    count = min(MAX_API_COUNT, count)

    entries = client.fetch_entries(offset, count)
    demisto.debug(f"pulled {len(entries)} for {client.feed_name}")
    indicators, max_offset = feed_entries_to_indicator(entries,
                                                       client.feed_name)
    demisto.debug(f"about to ingest {len(indicators)} for {client.feed_name}")

    if update_context:
        integration_context["offset"] = max_offset
        demisto.setIntegrationContext(integration_context)

    return indicators
Beispiel #9
0
def get_authorization_token() -> str:
    """
    :return: Returns the authorization token
    """
    integration_context: Dict = demisto.getIntegrationContext()
    token: str = integration_context.get('token', '')
    if token:
        return token
    url_suffix: str = '/api-token-auth/'
    data_for_request: Dict = {
        'username': USERNAME,
        'password': PASSWORD
    }
    response_content: Dict = http_request('POST', url_suffix, data=data_for_request, continue_err=True,
                                          api_request=False)
    token = response_content.get('token', '')
    if not token:
        if 'res_content' in response_content:
            raise Exception('Failure resolving URL.')
        error_msg_list: List = response_content.get('non_field_errors', [])
        if not error_msg_list:
            raise Exception('Unable to log in with provided credentials.')
        else:
            raise Exception(error_msg_list[0])
    demisto.setIntegrationContext({'token': token})
    return token
Beispiel #10
0
    def authenticate(self) -> None:
        """
        Perform authentication using API_KEY,
        stores token and stored timestamp in integration context,
        retrieves new token when expired
        """
        current_utc_timestamp = int(datetime.utcnow().timestamp())

        stored_token = demisto.getIntegrationContext()
        if (
            isinstance(stored_token, dict)
            and "token" in stored_token
            and "expires" in stored_token
            and current_utc_timestamp < int(stored_token["expires"])
        ):
            self._headers['Authorization'] = f'JWT {stored_token["token"]}'
        else:
            # fetch new token
            hdr = self._headers.copy()
            hdr["Authorization"] = f"Bearer {self.api_key}"

            r = self._http_request("GET", "/v1/IdToken", headers=hdr)
            if isinstance(r, dict) and r.get("token", None) is None:
                raise ValueError("Authorization failed")

            token_expiration = current_utc_timestamp + TOKEN_DURATION

            self._headers['Authorization'] = f'JWT {r["token"]}'
            demisto.setIntegrationContext(
                {"token": r["token"], "expires": token_expiration}
            )
Beispiel #11
0
def main():
    """
    PARSE AND VALIDATE INTEGRATION PARAMS
    """
    service_principal = demisto.params().get('credentials').get('identifier')
    secret = demisto.params().get('credentials').get('password')

    # Remove trailing slash to prevent wrong URL path to service
    server_url = demisto.params()['url'][:-1] \
        if (demisto.params()['url'] and demisto.params()['url'].endswith('/')) else demisto.params()['url']
    api_version = demisto.params().get('api_version')

    verify_certificate = not demisto.params().get('insecure', False)

    # How many time before the first fetch to retrieve incidents
    fetch_time = demisto.params().get('fetch_time', '3 days')

    threat_status = argToList(demisto.params().get('threat_status'))

    threat_type = argToList(demisto.params().get('threat_type'))

    event_type_filter = demisto.params().get('events_type')

    fetch_limit = 50
    # Remove proxy if not set to true in params
    proxies = handle_proxy()

    LOG('Command being called is %s' % (demisto.command()))

    try:
        client = Client(server_url, api_version, verify_certificate,
                        service_principal, secret, proxies)

        if demisto.command() == 'test-module':
            results = test_module(client, fetch_time, event_type_filter)
            return_outputs(results, None)

        elif demisto.command() == 'fetch-incidents':
            integration_context = demisto.getIntegrationContext()
            next_run, incidents, remained_incidents = fetch_incidents(
                client=client,
                last_run=demisto.getLastRun(),
                first_fetch_time=fetch_time,
                event_type_filter=event_type_filter,
                threat_status=threat_status,
                threat_type=threat_type,
                limit=fetch_limit,
                integration_context=integration_context)
            # Save last_run, incidents, remained incidents into integration
            demisto.setLastRun(next_run)
            demisto.incidents(incidents)
            # preserve context dict
            integration_context['incidents'] = remained_incidents
            demisto.setIntegrationContext(integration_context)

        elif demisto.command() == 'proofpoint-get-events':
            return_outputs(*get_events_command(client, demisto.args()))

    except Exception as e:
        return_error(str(e))
def fetch_indicators_command(client: Client,
                             time_to_stop_fetch: datetime = None):
    """Retrieves indicators from the feed

    Args:
        client: Client object with request
        time_to_stop_fetch: Time to stop the fetch before it falls on the docker timeout

    Returns:
        List. Processed indicator from feed.
    """
    current_date = arg_to_datetime('now').date()  # type:ignore
    while client.first_fetch.date() <= current_date:
        indicators, status = fetch_indicators(client, time_to_stop_fetch)
        if not status:
            return
        for iter_ in batch(indicators, batch_size=2000):
            demisto.createIndicators(iter_)
        # Each request returns one day's indicators, so we'll keep the date of the next day in IntegrationContext.
        next_fetch = (dateparser.parse(
            'tomorrow', settings={'RELATIVE_BASE':
                                  client.first_fetch}))  # type:ignore
        if client.first_fetch.date() < current_date:
            demisto.setIntegrationContext(
                {'last_fetch': next_fetch.isoformat()})  # type:ignore
        client.first_fetch = next_fetch
        demisto.debug(f'{len(indicators)} XSOAR Indicators were created.')
    return
    def test_generate_field_value_values_list_input(self, requests_mock):
        cache = demisto.getIntegrationContext()
        cache['fieldValueList'] = {}
        demisto.setIntegrationContext(cache)

        requests_mock.post(BASE_URL + 'api/core/security/login',
                           json={
                               'RequestedObject': {
                                   'SessionToken': 'session-id'
                               },
                               'IsSuccessful': True
                           })
        requests_mock.get(BASE_URL + 'api/core/system/fielddefinition/304',
                          json=GET_FIElD_DEFINITION_RES)
        requests_mock.get(BASE_URL +
                          'api/core/system/valueslistvalue/valueslist/62',
                          json=VALUE_LIST_RES)

        client = Client(BASE_URL, '', '', '', '', 400)
        field_key, field_value = generate_field_value(client, "", {
            'Type': 4,
            'FieldId': 304
        }, ["High"])
        assert field_key == 'Value'
        assert field_value == {'ValuesListIds': [473]}
Beispiel #14
0
def fetch_indicators_command(client,
                             indicator_type: list,
                             max_fetch: int,
                             tlp_color=None,
                             is_test=False) -> list:
    """ fetch indicators from the OpenCTI

    Args:
        client: OpenCTI Client object
        indicator_type(list): List of indicators types to get.
        max_fetch: (int) max indicators to fetch.
        tlp_color: (str)
        is_test: (bool) Indicates that it's a test and then does not save the last run.
    Returns:
        list of indicators(list)
    """
    last_run_id = demisto.getIntegrationContext().get('last_run_id')

    new_last_run, indicators_list = get_indicators(client,
                                                   indicator_type,
                                                   limit=max_fetch,
                                                   last_run_id=last_run_id,
                                                   tlp_color=tlp_color)

    if new_last_run and not is_test:
        demisto.setIntegrationContext({'last_run_id': new_last_run})

    return indicators_list
def long_running_execution_command(client: Client, params: Dict):
    """
    Long running execution of fetching incidents from Palo Alto Networks Enterprise DLP.
    Will continue to fetch in an infinite loop.
    Args:
        params (Dict): Demisto params.

    """
    demisto.setIntegrationContext({ACCESS_TOKEN: ''})
    regions = demisto.get(params, 'dlp_regions', '')
    sleep_time = FETCH_SLEEP
    last_time_sleep_interval_queries = math.floor(datetime.now().timestamp())
    while True:
        try:
            current_time = math.floor(datetime.now().timestamp())
            fetch_notifications(client, regions)

            if current_time - last_time_sleep_interval_queries > 5 * 60:
                overriden_sleep_time = client.query_for_sleep_time()
                last_time_sleep_interval_queries = current_time
                if overriden_sleep_time:
                    print_debug_msg(
                        f'Setting sleep time to value from backend: {overriden_sleep_time}'
                    )
                    sleep_time = overriden_sleep_time

        except Exception:
            demisto.error('Error occurred during long running loop')
            demisto.error(traceback.format_exc())

        finally:
            print_debug_msg('Finished fetch loop')
            time.sleep(sleep_time)
def edl_update():
    """
    Updates the instance context with the list name and items given
    Overrides external file path with internal list
    """
    file_path = demisto.args().get('file_path')
    if DOCUMENT_ROOT:
        file_path = os.path.join(DOCUMENT_ROOT, file_path)
    list_name = demisto.args().get('list_name')
    list_items = argToList(demisto.args().get('list_items'))
    add = demisto.args().get('add_or_remove') == 'add'
    verbose = demisto.args().get('verbose') == 'true'

    # update internal list
    dict_of_lists = demisto.getIntegrationContext()
    if not dict_of_lists:
        dict_of_lists = {list_name: list_items}
        if verbose:
            md = tableToMarkdown('List items:', list_items, headers=[list_name])
        else:
            md = 'Instance context updated successfully'
    else:
        if not dict_of_lists.get(list_name, None) and not add:
            return_error('Cannot remove items from an empty list')
        if dict_of_lists.get(list_name, None):
            if add:
                list_items = list(set(dict_of_lists.get(list_name) + list_items))
            else:
                list_items = [item for item in dict_of_lists.get(list_name) if item not in list_items]

        if len(list_items) == 0:  # delete list from instance context
            dict_of_lists.pop(list_name, None)
            md = 'List is empty, deleted from instance context.'
        else:
            dict_of_lists.update({list_name: list_items})
            if verbose:
                md = tableToMarkdown('List items:', list_items, headers=[list_name])
            else:
                md = 'Instance context updated successfully'

    demisto.setIntegrationContext(dict_of_lists)
    demisto.results({
        'ContentsFormat': formats['markdown'],
        'Type': entryTypes['note'],
        'Contents': md
    })

    # scp internal list to file_path
    result = edl_update_external_file(file_path, list_name, verbose)
    if result:
        if verbose:
            md = tableToMarkdown('Updated File Data:', result, headers=['Data'])
        else:
            md = 'External file updated successfully'

        demisto.results({
            'Type': entryTypes['note'],
            'Contents': md,
            'ContentsFormat': formats['markdown']
        })
Beispiel #17
0
    def get_session_token(self, get_new_token: bool = False):
        if get_new_token:
            response = self.fortimanager_http_request('exec',
                                                      "/sys/login/user",
                                                      json_data={
                                                          'user':
                                                          self.username,
                                                          'passwd':
                                                          self.password
                                                      },
                                                      add_session_token=False)

            if response.get('result')[0].get('status', {}).get('code') != 0:
                raise DemistoException(
                    f"Unable to get new session token. Reason - "
                    f"{response.get('result')[0].get('status').get('message')}"
                )

            demisto.setIntegrationContext({'session': response.get('session')})
            return response.get('session')

        else:
            current_token = demisto.getIntegrationContext().get('session')
            return current_token if current_token else self.get_session_token(
                get_new_token=True)
Beispiel #18
0
 def __prime_set_cache_keys_to_none(self, *keys):
     integration_context = demisto.getIntegrationContext()
     for key in keys:
         if key in integration_context:
             integration_context[key] = None
     if integration_context:
         demisto.setIntegrationContext(integration_context)
Beispiel #19
0
def refresh_outbound_context(indicator_query: str,
                             out_format: str,
                             limit: int = 0,
                             offset: int = 0) -> str:
    """
    Refresh the cache values and format using an indicator_query to call demisto.searchIndicators
    Returns: List(IoCs in output format)
    """
    now = datetime.now()
    iocs = find_indicators_with_limit(
        indicator_query, limit,
        offset)  # poll indicators into list from demisto
    out_dict = create_values_out_dict(iocs, out_format)
    out_dict[
        CTX_MIMETYPE_KEY] = 'application/json' if out_format == FORMAT_JSON else 'text/plain'
    demisto.setIntegrationContext({
        "last_output": out_dict,
        'last_run': date_to_timestamp(now),
        'last_limit': limit,
        'last_offset': offset,
        'last_format': out_format,
        'last_query': indicator_query,
        'current_iocs': iocs
    })
    return out_dict[CTX_VALUES_KEY]
Beispiel #20
0
def shaping_fetch(client: Client, fetch_queue_id: list) -> str:
    """
    Create and Update shaping fields once a day and saves them in integration context.
    Args:
        client: Client for the api.
        fetch_queue_id:
    Returns:
        the current shaping.
    """
    integration_context = demisto.getIntegrationContext()
    if integration_context:
        valid_until = integration_context.get('valid_until')
        time_now = int(time.time())
        if time_now < valid_until:
            fetch_shaping = integration_context.get('shaping_fields')
        else:
            fetch_shaping = set_shaping(client, fetch_queue_id)
            integration_context = {
                'shaping_fields': fetch_shaping,
                'valid_until': int(time.time()) + 3600 * 24
            }
            demisto.setIntegrationContext(integration_context)
    else:
        fetch_shaping = set_shaping(client, fetch_queue_id)
        integration_context = {
            'shaping_fields': fetch_shaping,
            'valid_until': int(time.time()) + 3600 * 24
        }
        demisto.setIntegrationContext(integration_context)
    return fetch_shaping
Beispiel #21
0
def update_access_token():
    """
    Check if we have a valid token and if not get one and update global HEADERS
    """
    ctx = demisto.getIntegrationContext()
    if ctx.get('token') and ctx.get('stored'):
        if epoch_seconds() - ctx.get('stored') < 60 * 60 - 30:
            HEADERS['Authorization'] = 'Bearer ' + ctx.get('token')
            return
    headers = {
        'Authorization': TOKEN,
        'Accept': 'application/json'
    }
    token_retrieval_url = 'https://demistobot.demisto.com/azurecompute-token'  # disable-secrets-detection
    parameters = {'tenant': TENANT_ID, 'product': 'AzureCompute'}
    r = requests.get(token_retrieval_url, headers=headers, params=parameters, verify=USE_SSL)
    if r.status_code not in {200, 201}:
        return_error('Error in authentication with the application. Try checking the credentials you entered.')
    try:
        response = r.json()
    except ValueError:
        err_msg = 'There was a problem in retrieving an updated access token.'
        err_msg += ' The response from the Demistobot server did not contain the expected content.'
        return_error(err_msg)
    demisto.setIntegrationContext({
        'token': response.get('token'),
        'stored': epoch_seconds(),
        'subscription_id': response.get('subscription_id')
    })
    HEADERS['Authorization'] = 'Bearer ' + response.get('token')
Beispiel #22
0
def login():
    query_path = 'www/core-service/rest/LoginService/login'
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Accept': 'application/json'
    }
    params = {
        'login': demisto.get(demisto.params(), 'credentials.identifier'),
        'password': demisto.get(demisto.params(), 'credentials.password'),
        'alt': 'json'
    }
    res = send_request(query_path, headers=headers, params=params, is_login=True)
    if not res.ok:
        demisto.debug(res.text)
        return_error('Failed to login, check integration parameters.')

    try:
        res_json = res.json()
        if 'log.loginResponse' in res_json and 'log.return' in res_json.get('log.loginResponse'):
            auth_token = res_json.get('log.loginResponse').get('log.return')
            if demisto.command() not in ['test-module', 'fetch-incidents']:
                # this is done to bypass setting integration context outside of the cli
                demisto.setIntegrationContext({'auth_token': auth_token})
            return auth_token

        return_error('Failed to login. Have not received token after login')
    except ValueError:
        return_error('Failed to login. Please check integration parameters')
Beispiel #23
0
 def _set_access_token(self):
     """
     Checks if access token exists in the integration context and set it to the object properties, if not, a new token
     is generated and saved in the integration context along with the query api_url and the instance_id
     Returns:
         None
     """
     integration_context = demisto.getIntegrationContext()
     access_token = integration_context.get(ACCESS_TOKEN_CONST)
     valid_until = integration_context.get(EXPIRES_IN)
     if access_token and valid_until:
         if int(time.time()) < valid_until:
             self.access_token = access_token
             self.api_url = integration_context.get(API_URL_CONST, DEFAULT_API_URL)
             self.instance_id = integration_context.get(INSTANCE_ID_CONST)
             return
     demisto.debug(f'access token time: {valid_until} expired/none. Will call oproxy')
     access_token, api_url, instance_id, refresh_token, expires_in = self._oproxy_authorize()
     updated_integration_context = {
         ACCESS_TOKEN_CONST: access_token,
         EXPIRES_IN: int(time.time()) + expires_in - SECONDS_30,
         API_URL_CONST: api_url,
         INSTANCE_ID_CONST: instance_id
     }
     if refresh_token:
         updated_integration_context.update({REFRESH_TOKEN_CONST: refresh_token})
     demisto.setIntegrationContext(updated_integration_context)
     self.access_token = access_token
     self.api_url = api_url
     self.instance_id = instance_id
Beispiel #24
0
def get_token() -> str:
    """
    Check if we have a valid token and if not get one from demistobot

    Returns:
        str: token from demistobot

    """
    product = 'MicrosoftGraphMail'
    token = CONTEXT.get('token')
    stored = CONTEXT.get('stored')
    if token and stored:
        if epoch_seconds() - stored < 60 * 60 - 30:
            return token
    headers = {'Authorization': TOKEN, 'Accept': 'application/json'}

    r = requests.get(DEMISTOBOT,
                     headers=headers,
                     params={
                         'tenant': TENANT_ID,
                         'product': product
                     },
                     verify=USE_SSL)
    if r.status_code != requests.codes.ok:
        return_error(
            f'Error when trying to get token from Demisto Bot: [{r.status_code}] - {r.text}'
        )
    data = r.json()

    demisto.setIntegrationContext({
        'token': data.get('token'),
        'stored': epoch_seconds()
    })
    return data.get('token')
Beispiel #25
0
def get_token(new_token=False):
    """
        Retrieves the token from the server if it's expired and updates the global HEADERS to include it

        :param new_token: If set to True will generate a new token regardless of time passed

        :rtype: ``str``
        :return: Token
    """
    now = datetime.now()
    ctx = demisto.getIntegrationContext()
    if ctx and not new_token:
        passed_mins = get_passed_mins(now, ctx.get('time'))
        if passed_mins >= TOKEN_LIFE_TIME:
            # token expired
            auth_token = get_token_request()
            demisto.setIntegrationContext({
                'auth_token': auth_token,
                'time': date_to_timestamp(now) / 1000
            })
        else:
            # token hasn't expired
            auth_token = ctx.get('auth_token')
    else:
        # there is no token
        auth_token = get_token_request()
        demisto.setIntegrationContext({
            'auth_token': auth_token,
            'time': date_to_timestamp(now) / 1000
        })
    return auth_token
Beispiel #26
0
    def get_level_by_app_id(self, app_id):
        cache = demisto.getIntegrationContext()
        if cache.get(app_id):
            return cache[app_id]

        levels = []
        all_levels_res = self.do_request('GET', f'/api/core/system/level/module/{app_id}')
        for level in all_levels_res:
            if level.get('RequestedObject') and level.get('IsSuccessful'):
                level_id = level.get('RequestedObject').get('Id')

                fields = {}
                level_res = self.do_request('GET', f'/api/core/system/fielddefinition/level/{level_id}')
                for field in level_res:
                    if field.get('RequestedObject') and field.get('IsSuccessful'):
                        field_item = field.get('RequestedObject')
                        field_id = str(field_item.get('Id'))
                        fields[field_id] = {'Type': field_item.get('Type'),
                                            'Name': field_item.get('Name'),
                                            'FieldId': field_id,
                                            'IsRequired': field_item.get('IsRequired', False),
                                            'RelatedValuesListId': field_item.get('RelatedValuesListId')}

                levels.append({'level': level_id, 'mapping': fields})

        if levels:
            cache[int(app_id)] = levels
            demisto.setIntegrationContext(cache)
            return levels
        return []
Beispiel #27
0
def set_subscription_id():
    """
    Setting subscription ID to the context and returning it
    """
    headers = {
        'Authorization': TOKEN,
        'Accept': 'application/json'
    }
    token_retrieval_url = 'https://demistobot.demisto.com/azurecompute-token'  # disable-secrets-detection
    parameters = {'tenant': TENANT_ID, 'product': 'AzureCompute'}
    r = requests.get(token_retrieval_url, headers=headers, params=parameters, verify=USE_SSL)
    try:
        response = r.json()
        if r.status_code != requests.codes.ok:
            return_error('Error: {}\nDescription:{}'.format(response.get('title'), response.get('detail')))
        sub_id = response.get('subscription_id')
        demisto.setIntegrationContext({
            'token': response.get('token'),
            'stored': epoch_seconds(),
            'subscription_id': sub_id
        })
        return sub_id
    except ValueError as e:
        if e.message == 'No JSON object could be decoded':
            return_error(response.content)
        else:
            raise e
Beispiel #28
0
    def get_field_value_list(self, field_id):
        cache = demisto.getIntegrationContext()

        if cache['fieldValueList'].get(field_id):
            return cache.get('fieldValueList').get(field_id)

        res = self.do_request('GET', f'/api/core/system/fielddefinition/{field_id}')

        errors = get_errors_from_res(res)
        if errors:
            return_error(errors)

        if res.get('RequestedObject') and res.get('IsSuccessful'):
            list_id = res['RequestedObject']['RelatedValuesListId']
            values_list_res = self.do_request('GET', f'/api/core/system/valueslistvalue/valueslist/{list_id}')
            if values_list_res.get('RequestedObject') and values_list_res.get('IsSuccessful'):
                values_list = []
                for value in values_list_res['RequestedObject'].get('Children'):
                    values_list.append({'Id': value['Data']['Id'],
                                        'Name': value['Data']['Name'],
                                        'IsSelectable': value['Data']['IsSelectable']})
                field_data = {'FieldId': field_id, 'ValuesList': values_list}

                cache['fieldValueList'][field_id] = field_data
                demisto.setIntegrationContext(cache)

        return field_data
Beispiel #29
0
    def __init__(self, app_id, subscription_id, resource_group_name, verify,
                 proxy):

        # for dev environment use:
        if '@' in app_id:
            app_id, refresh_token = app_id.split('@')
            integration_context = demisto.getIntegrationContext()
            integration_context.update(current_refresh_token=refresh_token)
            demisto.setIntegrationContext(integration_context)
        base_url = f'{BASE_URL}/{SUBSCRIPTION_PATH.format(subscription_id)}'
        self.subscription_id = subscription_id
        self.resource_group_name = resource_group_name
        client_args = {
            'self_deployed':
            True,  # We always set the self_deployed key as True because when not using a self
            # deployed machine, the DEVICE_CODE flow should behave somewhat like a self deployed
            # flow and most of the same arguments should be set, as we're !not! using OProxy.
            'auth_id': app_id,
            'token_retrieval_url':
            'https://login.microsoftonline.com/organizations/oauth2/v2.0/token',
            'grant_type': DEVICE_CODE,
            'base_url': base_url,
            'verify': verify,
            'proxy': proxy,
            'resource':
            'https://management.core.windows.net',  # disable-secrets-detection
            'scope':
            'https://management.azure.com/user_impersonation offline_access user.read',
            'ok_codes': (200, 201, 202, 204)
        }

        self.ms_client = MicrosoftClient(**client_args)
Beispiel #30
0
def get_ioc_values_str_from_context(integration_context: dict,
                                    request_args: RequestArguments,
                                    iocs: list = None) -> str:
    """
    Extracts output values from cache

    Args:
        integration_context: The integration context
        request_args: The request args
        iocs: The current raw iocs data saved in the integration context
    Returns:
        string representation of the iocs
    """
    if iocs:
        if request_args.offset > len(iocs):
            return ''

        iocs = iocs[request_args.offset:request_args.limit +
                    request_args.offset]
        returned_dict, _ = create_values_for_returned_dict(
            iocs, request_args=request_args)
        integration_context['last_output'] = returned_dict
        demisto.setIntegrationContext(integration_context)

    else:
        returned_dict = integration_context.get('last_output', {})

    return returned_dict.get(EDL_VALUES_KEY, '')
Beispiel #31
0
    def get_access_token(self, resource=''):
        """
        Obtains access and refresh token from oproxy server or just a token from a self deployed app.
        Access token is used and stored in the integration context
        until expiration time. After expiration, new refresh token and access token are obtained and stored in the
        integration context.

        Returns:
            str: Access token that will be added to authorization header.
        """
        integration_context = demisto.getIntegrationContext()
        refresh_token = integration_context.get('current_refresh_token', '')

        if self.multi_resource:
            access_token = integration_context.get(resource)
        else:
            access_token = integration_context.get('access_token')

        valid_until = integration_context.get('valid_until')

        if access_token and valid_until:
            if self.epoch_seconds() < valid_until:
                return access_token

        auth_type = self.auth_type
        if auth_type == OPROXY_AUTH_TYPE:
            if not self.multi_resource:
                access_token, expires_in, refresh_token = self._oproxy_authorize(
                )
            else:
                for resource_str in self.resources:
                    access_token, expires_in, refresh_token = self._oproxy_authorize(
                        resource_str)
                    self.resource_to_access_token[resource_str] = access_token
                    self.refresh_token = refresh_token
        else:
            access_token, expires_in, refresh_token = self._get_self_deployed_token(
                refresh_token)
        time_now = self.epoch_seconds()
        time_buffer = 5  # seconds by which to shorten the validity period
        if expires_in - time_buffer > 0:
            # err on the side of caution with a slightly shorter access token validity period
            expires_in = expires_in - time_buffer

        integration_context = {
            'access_token': access_token,
            'current_refresh_token': refresh_token,
            'valid_until': time_now + expires_in,
        }

        if self.multi_resource:
            integration_context.update(self.resource_to_access_token)

        demisto.setIntegrationContext(integration_context)

        if self.multi_resource:
            return self.resource_to_access_token[resource]

        return access_token
Beispiel #32
0
 def set_last_run():
     """
     Returns: Current timestamp
     """
     current_time = datetime.now()
     current_timestamp = datetime.timestamp(current_time)
     timestamp = str(int(current_timestamp))
     demisto.setIntegrationContext({'last_run': timestamp})
def reset_last_fetch_dict() -> CommandResults:
    """Reset the last fetch from the integration context

    :return: A ``CommandResults`` object that is then passed to ``return_results``.
    :rtype: ``CommandResults``
    """
    demisto.setIntegrationContext({})
    return CommandResults(readable_output='Fetch history has been successfully deleted!')
Beispiel #34
0
def get_new_access_token(is_fetch=False):
    response = request_new_access_token(True)
    if not response.status_code == HTTP_CODES['success']:
        response = request_new_access_token(False)
    res_json = parse_response(response,
                              "Could not get token. Check your credentials (user/password/client id) and try again",
                              is_fetch=is_fetch)
    token_expiration_time = int(date_to_timestamp(res_json.get('.expires'), '%a, %d %b %Y %H:%M:%S GMT'))
    demisto.setIntegrationContext({
        'refresh_token': res_json.get('refresh_token'),
        'token_expiration_time': token_expiration_time,
        'access_token': res_json.get('access_token')
    })
    return res_json.get('access_token')
def get_access_token():
    integration_context = demisto.getIntegrationContext()
    access_token = integration_context.get('access_token')
    stored = integration_context.get('stored')
    if access_token and stored:
        if epoch_seconds() - stored < 60 * 60 - 30:
            return access_token
    headers = {
        'Authorization': AUTH_ID,
        'Accept': 'application/json'
    }

    dbot_response = requests.get(
        TOKEN_RETRIEVAL_URL,
        headers=headers,
        params={'token': get_encrypted(TOKEN, ENC_KEY)},
        verify=USE_SSL
    )
    if dbot_response.status_code not in {200, 201}:
        msg = 'Error in authentication. Try checking the credentials you entered.'
        try:
            demisto.info('Authentication failure from server: {} {} {}'.format(
                dbot_response.status_code, dbot_response.reason, dbot_response.text))
            err_response = dbot_response.json()
            server_msg = err_response.get('message')
            if server_msg:
                msg += ' Server message: {}'.format(server_msg)
        except Exception as ex:
            demisto.error('Failed parsing error response: [{}]. Exception: {}'.format(err_response.content, ex))
        raise Exception(msg)
    try:
        parsed_response = dbot_response.json()
    except ValueError:
        raise Exception(
            'There was a problem in retrieving an updated access token.\n'
            'The response from the Demistobot server did not contain the expected content.'
        )
    access_token = parsed_response.get('access_token')
    api_url = parsed_response.get('url')
    token = parsed_response.get('token')

    demisto.setIntegrationContext({
        'access_token': access_token,
        'stored': epoch_seconds(),
        'api_url': api_url,
        'token': token
    })
    return access_token
Beispiel #36
0
def load_extended_keys():
    global EXTENDED_KEYS
    if demisto.command() == 'fetch-incidents':
        last_run = demisto.getLastRun()
        EXTENDED_KEYS = last_run.get('extended_keys', {})
    else:
        integration_context = demisto.getIntegrationContext()
        EXTENDED_KEYS = integration_context.get('extended_keys', {})

    if not EXTENDED_KEYS:
        session = login()
        url = REST_ADDRESS + '/eventAttributeType/all'
        response = session.get(url, verify=VERIFY_SSL, auth=AUTH)
        EXTENDED_KEYS = dict((attr['attributeId'], attr['displayName']) for attr in response.json())

        if demisto.command() != 'fetch-incidents':
            demisto.setIntegrationContext({'extended_keys': EXTENDED_KEYS})
Beispiel #37
0
def get_token() -> str:
    """
    Check if we have a valid token and if not get one from demistobot

    Returns:
        str: token from demistobot

    """
    product = 'MicrosoftGraphMail'
    token = CONTEXT.get('token')
    stored = CONTEXT.get('stored')
    if token and stored:
        if epoch_seconds() - stored < 60 * 60 - 30:
            return token
    headers = {
        'Authorization': TOKEN,
        'Accept': 'application/json'
    }

    r = requests.get(
        DEMISTOBOT,
        headers=headers,
        params={
            'tenant': TENANT_ID,
            'product': product
        },
        verify=USE_SSL
    )
    if r.status_code != requests.codes.ok:
        return_error(
            f'Error when trying to get token from Demisto Bot: [{r.status_code}] - {r.text}')
    data = r.json()

    demisto.setIntegrationContext(
        {
            'token': data.get('token'),
            'stored': epoch_seconds()
        }
    )
    return data.get('token')
Beispiel #38
0
def get_token(refresh_token=False):
    """
    Check if we have a valid token and if not get one
    """
    ctx = demisto.getIntegrationContext()
    if {'token', 'stored', 'expires'} <= set(ctx) and not refresh_token:
        if epoch_seconds() - ctx.get('stored') < ctx.get('expires'):
            return ctx.get('token')
    response = requests.get(
        DEMISTOBOT,
        headers=HEADERS,
        params={"tenant": TENANT, "product": PRODUCT},
        verify=USE_SSL,
    )
    data = response.json()
    if not response.ok:
        return_error(f'API call to MS Graph failed [{data.get("status")} {data.get("title")}] - {data.get("detail")}')

    demisto.setIntegrationContext({
        'token': data.get('token'),
        'stored': epoch_seconds(),
        'expires': data.get('expires', 3600) - 30
    })
    return data.get('token')