import re
import base64
import hmac
import hashlib
import logging
import requests
from datetime import datetime


class AzureSentinel:

    def __init__(self, workspace_id, workspace_key, log_type, log_analytics_url=''):
        self._workspace_id = workspace_id
        self._workspace_key = workspace_key
        self._log_type = log_type
        if ((log_analytics_url in (None, '') or str(log_analytics_url).isspace())):
            log_analytics_url = 'https://' + self._workspace_id + '.ods.opinsights.azure.com'

        pattern = r"https:\/\/([\w\-]+)\.ods\.opinsights\.azure.([a-zA-Z\.]+)$"
        if not re.match(pattern, str(log_analytics_url)):
            raise Exception("Invalid Log Analytics Uri.")
        self._log_analytics_url = log_analytics_url

    def build_signature(self, date, content_length, method, content_type, resource):
        x_headers = 'x-ms-date:' + date
        string_to_hash = method + "\n" + \
            str(content_length) + "\n" + content_type + \
            "\n" + x_headers + "\n" + resource
        bytes_to_hash = bytes(string_to_hash, encoding="utf-8")
        decoded_key = base64.b64decode(self._workspace_key)
        encoded_hash = base64.b64encode(hmac.new(
            decoded_key, bytes_to_hash, digestmod=hashlib.sha256).digest()).decode()
        authorization = "SharedKey {}:{}".format(
            self._workspace_id, encoded_hash)
        return authorization

    def post_data(self, body):
        logging.info('constructing post to send to Azure Sentinel.')
        method = 'POST'
        content_type = 'application/json'
        resource = '/api/logs'
        rfc1123date = datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
        content_length = len(body)
        logging.info('build signature.')
        signature = self.build_signature(
            rfc1123date, content_length, method, content_type, resource)
        logging.info('signature built.')
        uri = self._log_analytics_url + resource + '?api-version=2016-04-01'
        headers = {
            'content-type': content_type,
            'Authorization': signature,
            'Log-Type': self._log_type,
            'x-ms-date': rfc1123date
        }
        logging.info('sending post to Azure Sentinel.')
        response = requests.post(uri, data=body, headers=headers)
        logging.info(response.status_code)
        if (response.status_code >= 200 and response.status_code <= 299):
            return response.status_code
        else:
            logging.warn("Events are not processed into Azure. Response code: {}".format(
                response.status_code))
            raise Exception(
                        f'Sending to Azure Sentinel failed with status code {response.status_code}')

[((30, 22, 30, 59), 'base64.b64decode', 'base64.b64decode', ({(30, 39, 30, 58): 'self._workspace_key'}, {}), '(self._workspace_key)', False, 'import base64\n'), ((38, 8, 38, 68), 'logging.info', 'logging.info', ({(38, 21, 38, 67): '"""constructing post to send to Azure Sentinel."""'}, {}), "('constructing post to send to Azure Sentinel.')", False, 'import logging\n'), ((44, 8, 44, 40), 'logging.info', 'logging.info', ({(44, 21, 44, 39): '"""build signature."""'}, {}), "('build signature.')", False, 'import logging\n'), ((47, 8, 47, 40), 'logging.info', 'logging.info', ({(47, 21, 47, 39): '"""signature built."""'}, {}), "('signature built.')", False, 'import logging\n'), ((55, 8, 55, 55), 'logging.info', 'logging.info', ({(55, 21, 55, 54): '"""sending post to Azure Sentinel."""'}, {}), "('sending post to Azure Sentinel.')", False, 'import logging\n'), ((56, 19, 56, 65), 'requests.post', 'requests.post', (), '', False, 'import requests\n'), ((57, 8, 57, 42), 'logging.info', 'logging.info', ({(57, 21, 57, 41): 'response.status_code'}, {}), '(response.status_code)', False, 'import logging\n'), ((42, 22, 42, 39), 'datetime.datetime.utcnow', 'datetime.utcnow', ({}, {}), '()', False, 'from datetime import datetime\n'), ((31, 40, 32, 65), 'hmac.new', 'hmac.new', (), '', False, 'import hmac\n')]