<commit_before>import json
import datetime

from collections import defaultdict
from functools import wraps
from flask import request, current_app, render_template, abort

from alerta.app import app, db, mq
from alerta.app.switch import Switch
from alerta.common import config
from alerta.common import log as logging
from alerta.common.alert import Alert
from alerta.common.heartbeat import Heartbeat
from alerta.common import status_code, severity_code
from alerta.common.utils import DateEncoder
from alerta.app.utils import parse_fields, crossdomain
from alerta.common.amqp import DirectPublisher, FanoutPublisher
from alerta.common.metrics import Gauge, Counter, Timer


__version__ = '3.0.7'

LOG = logging.getLogger(__name__)
CONF = config.CONF

if CONF.amqp_queue:
    direct = DirectPublisher(mq.connection)
if CONF.amqp_topic:
    notify = FanoutPublisher(mq.connection)

# Set-up metrics
gets_timer = Timer('alerts', 'queries', 'Alert queries', 'Total time to process number of alert queries')
receive_timer = Timer('alerts', 'received', 'Received alerts', 'Total time to process number of received alerts')
duplicate_timer = Timer('alerts', 'duplicate', 'Duplicate alerts', 'Total time to process number of duplicate alerts')
correlate_timer = Timer('alerts', 'correlate', 'Correlated alerts', 'Total time to process number of correlated alerts')
create_timer = Timer('alerts', 'create', 'Newly created alerts', 'Total time to process number of new alerts')
delete_timer = Timer('alerts', 'deleted', 'Deleted alerts', 'Total time to process number of deleted alerts')
status_timer = Timer('alerts', 'status', 'Alert status change', 'Total time and number of alerts with status changed')
tag_timer = Timer('alerts', 'tagged', 'Tagging alerts', 'Total time to tag number of alerts')
untag_timer = Timer('alerts', 'untagged', 'Removing tags from alerts', 'Total time to un-tag number of alerts')


# Over-ride jsonify to support Date Encoding
def jsonify(*args, **kwargs):
    return current_app.response_class(json.dumps(dict(*args, **kwargs), cls=DateEncoder,
                                                 indent=None if request.is_xhr else 2), mimetype='application/json')


def auth_required(func):
    @wraps(func)
    def decorated(*args, **kwargs):
        if 'Authorization' in request.headers:
            auth = request.headers['Authorization']
            LOG.debug(auth)
            if auth.startswith('Token'):
                LOG.debug('we got a token auth, verify token externally and respond with API key')
            elif auth.startswith('Key'):
                LOG.debug('we got a api key, verify key internally and respond with requested data')
            else:
                authenticate = jsonify(status="error", message="authentication required")
                authenticate.status_code = 401
                return authenticate
        return func(*args, **kwargs)
    return decorated


def jsonp(func):
    """Wraps JSONified output for JSONP requests."""
    @wraps(func)
    def decorated(*args, **kwargs):
        callback = request.args.get('callback', False)
        if callback:
            data = str(func(*args, **kwargs).data)
            content = str(callback) + '(' + data + ')'
            mimetype = 'application/javascript'
            return current_app.response_class(content, mimetype=mimetype)
        else:
            return func(*args, **kwargs)
    return decorated


@app.route('/_', methods=['OPTIONS', 'PUT', 'POST', 'DELETE', 'GET'])
@crossdomain(origin='*', headers=['Origin', 'X-Requested-With', 'Content-Type', 'Accept'])
@jsonp
def test():<commit_msg>stubs for verifying tokens and keys<commit_after>import json
import datetime

from collections import defaultdict
from functools import wraps
from flask import request, current_app, render_template, abort, Response

from alerta.app import app, db, mq
from alerta.app.switch import Switch
from alerta.common import config
from alerta.common import log as logging
from alerta.common.alert import Alert
from alerta.common.heartbeat import Heartbeat
from alerta.common import status_code, severity_code
from alerta.common.utils import DateEncoder
from alerta.app.utils import parse_fields, crossdomain
from alerta.common.amqp import DirectPublisher, FanoutPublisher
from alerta.common.metrics import Gauge, Counter, Timer


__version__ = '3.0.7'

LOG = logging.getLogger(__name__)
CONF = config.CONF

if CONF.amqp_queue:
    direct = DirectPublisher(mq.connection)
if CONF.amqp_topic:
    notify = FanoutPublisher(mq.connection)

# Set-up metrics
gets_timer = Timer('alerts', 'queries', 'Alert queries', 'Total time to process number of alert queries')
receive_timer = Timer('alerts', 'received', 'Received alerts', 'Total time to process number of received alerts')
duplicate_timer = Timer('alerts', 'duplicate', 'Duplicate alerts', 'Total time to process number of duplicate alerts')
correlate_timer = Timer('alerts', 'correlate', 'Correlated alerts', 'Total time to process number of correlated alerts')
create_timer = Timer('alerts', 'create', 'Newly created alerts', 'Total time to process number of new alerts')
delete_timer = Timer('alerts', 'deleted', 'Deleted alerts', 'Total time to process number of deleted alerts')
status_timer = Timer('alerts', 'status', 'Alert status change', 'Total time and number of alerts with status changed')
tag_timer = Timer('alerts', 'tagged', 'Tagging alerts', 'Total time to tag number of alerts')
untag_timer = Timer('alerts', 'untagged', 'Removing tags from alerts', 'Total time to un-tag number of alerts')


# Over-ride jsonify to support Date Encoding
def jsonify(*args, **kwargs):
    return current_app.response_class(json.dumps(dict(*args, **kwargs), cls=DateEncoder,
                                                 indent=None if request.is_xhr else 2), mimetype='application/json')


def authenticate():

    response = jsonify(status="error", message="authentication required")
    response.status_code = 401

    return response


def verify_token(token):

    LOG.debug('we got a token %s, verify token externally and save session id', token)

    return False


def verify_api_key(key):

    LOG.debug('we got a api key %s, verify key internally', key)

    return False


def auth_required(func):
    @wraps(func)
    def decorated(*args, **kwargs):
        # check is session variable?

        if 'Authorization' in request.headers:
            auth = request.headers['Authorization']
            LOG.debug(auth)
            if auth.startswith('Token'):
                token = auth.replace('Token ', '')
                if not verify_token(token):
                    return authenticate()
            elif auth.startswith('Key'):
                key = auth.replace('Key ', '')
                if not verify_api_key(key):
                    return authenticate()
            else:
                return authenticate()
        else:
            return authenticate()
        return func(*args, **kwargs)
    return decorated


import base64
import hmac
import random
import hashlib

SECRET_KEY = '<insert secret key here>'


def generate_api_key():

    api_key = hmac.new(SECRET_KEY, msg=str(random.getrandbits(32)), digestmod=hashlib.sha256).digest()
    return base64.encodestring(api_key).rstrip()


def jsonp(func):
    """Wraps JSONified output for JSONP requests."""
    @wraps(func)
    def decorated(*args, **kwargs):
        callback = request.args.get('callback', False)
        if callback:
            data = str(func(*args, **kwargs).data)
            content = str(callback) + '(' + data + ')'
            mimetype = 'application/javascript'
            return current_app.response_class(content, mimetype=mimetype)
        else:
            return func(*args, **kwargs)
    return decorated


@app.route('/_', methods=['OPTIONS', 'PUT', 'POST', 'DELETE', 'GET'])
@crossdomain(origin='*', headers=['Origin', 'X-Requested-With', 'Content-Type', 'Accept'])
@jsonp
def test():
{'fraction_non_alphanumeric': 0.11140383891607075, 'fraction_numerical': 0.0028854597917450757, 'mean_word_length': 3.667447306791569, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5352450', 'n_tokens_mistral': 2306, 'n_tokens_neox': 2165, 'n_words': 720}