Пример #1
0
def devices_route():
    
    # ingest request
    request_details = extract_request_details(request)
    flask_app.logger.debug(request_details)
    response_details = construct_response(request_details)
    if not response_details['error']:

        if request_details['method'] == 'GET':
            list_kwargs = {}
            params, error, code = ingest_query('devices-get', request_details, request_models)
            if error:
                response_details['error'] = error
                response_details['code'] = code
            else:
                list_kwargs = {
                    'sql_table': sql_tables['device_registration'],
                    'record_id': ''
                }
                if 'query' in params.keys():
                    list_kwargs['query_criteria'] = params['query']
                if 'results' in params.keys():
                    list_kwargs['max_results'] = params['results']
    
            if not response_details['error']:
    
                record_list, record_updates = list_records(**list_kwargs)
                response_details['details'] = record_list
                response_details['updated'] = record_updates
        
        # create a new device
        elif request_details['method'] == 'POST':

            response_details = construct_response(request_details, request_models['devices-post'])
            if not response_details['error']:

            # retrieve asset associated with device
                asset_id = request_details['json']['asset_id']
                asset_details = {}
                for asset in sql_tables['asset_registration'].list({'.id': {'equal_to': asset_id}}):
                    asset_details = asset

                if not asset_details:
                    response_details['error'] = 'Asset %s does not exist.' % asset_id
                    response_details['code'] = 400
                else:

            # create new record for device and associate with asset
                    device_details = {
                        'dt': time(),
                        'active': True
                    }
                    for key, value in request_details['json'].items():
                        device_details[key] = value
                    device_id = sql_tables['device_registration'].create(device_details)
                    asset_details['devices'].append(device_id)
                    sql_tables['asset_registration'].update(asset_details)
                    response_details['details'] = { 'device_id': device_id }

    return jsonify(response_details), response_details['code']
Пример #2
0
def device_route(device_id=''):

    # ingest request
    request_details = extract_request_details(request)
    flask_app.logger.debug(request_details)
    response_details = construct_response(request_details)
    if not response_details['error']:

    # validate device id exists
        if not response_details['error']:
            if not device_id:
                response_details['error'] = 'Method requires a device_id on endpoint.'
                response_details['code'] = 400
            elif not sql_tables['device_registration'].exists(device_id):
                response_details['error'] = 'Device ID does not exist.'
                response_details['code'] = 400

        # retrieve current record
            if request_details['method'] == 'GET':
                device_details = sql_tables['device_registration'].read(device_id)
                response_details['details'] = device_details

        # update record
            elif request_details['method'] == 'PATCH':

                response_details = construct_response(request_details, request_models['device-patch'])
                if not response_details['error']:
                    device_details = sql_tables['device_registration'].read(device_id)
                    device_details['dt'] = time()
                    for key, value in request_details['json'].items():
                        device_details[key] = value
                    sql_tables['device_registration'].update(device_details)
                    response_details['details'] = { 'device_id': device_id }
                    response_details['updated'] = device_details['dt']

        # delete device
            if request_details['method'] == 'DELETE':
            
            # remove device from asset
                device_details = sql_tables['device_registration'].read(device_id)
                if 'asset_id' in device_details.keys():
                    if device_details['asset_id']:
                        if sql_tables['asset_registration'].exists(device_details['asset_id']):
                            asset_details = sql_tables['asset_registration'].read(device_details['asset_id'])
                            device_index = asset_details['devices'].index(device_id)
                            if device_index > -1:
                                asset_details['devices'].pop(device_index)
                                sql_tables['asset_registration'].update(asset_details)
    
            # remove device
                sql_tables['device_registration'].delete(device_id)
                response_details['details'] = { 'status': 'ok' }
                
 
    return jsonify(response_details), response_details['code']
Пример #3
0
def works_route():
    
    # ingest request
    request_details = extract_request_details(request)
    flask_app.logger.debug(request_details)
    response_details = construct_response(request_details)
    if not response_details['error']:

        # get list of work requests
        if request_details['method'] == 'GET':
            list_kwargs = {}
            params, error, code = ingest_query('work-get', request_details, request_models)
            if error:
                response_details['error'] = error
                response_details['code'] = code
            else:
                list_kwargs = {
                    'sql_table': sql_tables['work_request'],
                    'record_id': ''
                }
                if 'query' in params.keys():
                    list_kwargs['query_criteria'] = params['query']
                if 'results' in params.keys():
                    list_kwargs['max_results'] = params['results']

            if not response_details['error']:

                record_list, record_updates = list_records(**list_kwargs)
                response_details['details'] = record_list
                response_details['updated'] = record_updates
        
        # create a new asset
        elif request_details['method'] == 'POST':

            response_details = construct_response(request_details, request_models['work-patch'])
            if not response_details['error']:

            # create new record for device and associate with asset
                record_id = labID().id24
                work_details = {
                    'id': record_id,
                    'dt': time(),
                    'active': True
                }
                work_details = sql_tables['work_request'].model.ingest(**work_details)
                sql_tables['work_request'].create(work_details)
                response_details['details'] = { 'work_id': record_id }
    
    return jsonify(response_details), response_details['code']
Пример #4
0
def work_route(work_id=''):
    
    # ingest request
    request_details = extract_request_details(request)
    flask_app.logger.debug(request_details)
    response_details = construct_response(request_details)
    if not response_details['error']:

    # validate device id exists
        if not response_details['error']:
            if not work_id:
                response_details['error'] = 'Method requires an work_id on endpoint.'
                response_details['code'] = 400
            elif not sql_tables['work_request'].exists(work_id):
                response_details['error'] = 'Work ID does not exist.'
                response_details['code'] = 400

        # retrieve current record
            if request_details['method'] == 'GET':
                work_details = sql_tables['work_request'].read(work_id)
                response_details['details'] = work_details

        # create new record
            elif request_details['method'] == 'PATCH':

                response_details = construct_response(request_details, request_models['work-patch'])
                if not response_details['error']:
                    work_details = sql_tables['work_request'].read(work_id)
                    work_details['dt'] = time()
                    for key, value in request_details['json'].items():
                        work_details[key] = value
                    sql_tables['work_request'].update(work_details)
                    response_details['details'] = { 'work_id': work_id }
                    response_details['updated'] = work_details['dt']

        # delete device
            elif request_details['method'] == 'DELETE':
                sql_tables['work_request'].delete(work_id)
                response_details['details'] = { 'status': 'ok' }
    
    return jsonify(response_details), response_details['code']
Пример #5
0
def users_route():

    # ingest request
    request_details = extract_request_details(request)
    app.logger.debug(request_details)
    response_details = construct_response(request_details)
    user_list = []
    for record in sql_tables['users'].list():
        user_list.append(record)
    response_details['details'] = user_list
    app.logger.debug(response_details)
    return jsonify(response_details), response_details['code']
Пример #6
0
def sources_route():
    
    ''' sources route '''
    
    # ingest request params
    from labpack.parsing.flask import extract_request_details
    request_details = extract_request_details(request)
    response_details = construct_response(request_details)
    
    # send response
    response_details['details'] = attesters_map
    app.logger.debug(response_details)
    return jsonify(response_details), response_details['code']
Пример #7
0
def query_route():
    
    ''' query route '''

    # ingest request params
    from labpack.parsing.flask import extract_request_details
    request_details = extract_request_details(request)
    user_token = request_details['params'].get('token', '')
    query_type = request_details['json'].get('type', '')
    query_text = request_details['json'].get('text', '')

    # construct generic response
    response_details = construct_response(request_details)
    details = {
        'msg': "Yeah... I didn't get that. Try again.",
        'audio': {},
        'content': {}
    }

    # parse text
    query_map = parse_query(query_text, producers_map)

    # request attestations
    if query_map['action'] == 'verify':
        attestation_list = get_attestations(query_map, attesters_map)
        msg, content = synthesize_attestations(attestation_list, producers_map, attesters_map)
        details['msg'] = msg
        details['content'] = content

    elif query_map['action'] == 'attest':
        attester_signature = user_token
        attestation_result = post_attestation(query_map, attester_signature)
        msg = synthesize_attestation(attestation_result, producers_map)
        details['msg'] = msg

    if query_type == 'speech' and details['msg']:
        from base64 import b64encode
        synthesize_response = speech_client.synthesize(details['msg'], voice_id='Nicole')
        audio_stream = synthesize_response['audio_stream']
        content_type = synthesize_response['content_type']
        base64_audio = b64encode(audio_stream).decode()
        details['audio'] = { 'audio_data': base64_audio, 'content_type': content_type, 'volume_level': 1.0 }

    response_details['details'] = details
    app.logger.debug(response_details)
    return jsonify(response_details), response_details['code']
Пример #8
0
def webhook_route(webhook_token=''):

# ingest request
    request_details = extract_request_details(request)
    # flask_app.logger.debug(request_details)
    response_details = construct_response(request_details)
    call_on_close = None
    if webhook_token not in webhook_map.keys():
        response_details['error'] = 'Invalid webhook token.'
        response_details['code'] = 404

# send webhook content to bot
    if not response_details['error']:
        if request_details['json']:
            observation_details = {
                'callback': False,
                'gateway': 'webhook',
                'details': request_details
            }
            for key, value in webhook_map[webhook_token].items():
                observation_details[key] = value
            if observation_details['callback']:
                response_details = bot_client.analyze_observation(**observation_details)
            else:
                def webhook_callable():
                    bot_client.analyze_observation(**observation_details)
                # add placeholder for telegram
                    if observation_details['service'] == 'telegram':
                        telegram_client.send_message(request_details['json']['message']['chat']['id'], message_text='Gotcha. Working on it...')
                call_on_close = webhook_callable

# response to request
    if call_on_close:
        response_kwargs = {
            'response': json.dumps(response_details),
            'status': response_details['code'],
            'mimetype': 'application/json'
        }
        response_object = Response(**response_kwargs)
        response_object.call_on_close(call_on_close)
        # flask_app.logger.debug(response_details)
        return response_object
    else:
        # flask_app.logger.debug(response_details)
        return jsonify(response_details), response_details['code']
Пример #9
0
def profile_route():
    ''' profile page route '''

    request_details = extract_request_details(request)
    app.logger.debug(request_details)
    response_details = construct_response(request_details)
    access_token = request_details['params'].get('token', '')
    if not access_token:
        response_details['error'] = 'Access token is missing'
    if not response_details['error']:

        # retrieve flightplan
        if request_details['method'] == 'GET':
            flightplan_details = retrieve_flightplan(access_token)
            response_details['details'] = flightplan_details

        # update flightplan
        elif request_details['method'] == 'POST':
            success = update_flightplan(access_token, request_details['json'])
            response_details['details'] = {'success': success}

    app.logger.debug(response_details)
    return jsonify(response_details), response_details['code']
Пример #10
0
def authorize_service_route(service_name=''):

    ''' a method to handle the oauth2 callback '''

# ingest request
    request_details = extract_request_details(request)
    flask_app.logger.debug(request_details)
    request_details['json'] = {'service': service_name}
    request_details['json'].update(**request_details['params'])
    response_details = construct_response(request_details, request_models['authorize-get'])

# validate existence of service
    if not response_details['error']:
        service_name = request_details['json']['service']
        if not service_name in oauth2_configs.keys():
            response_details['error'] = '%s is not an available oauth2 service.' % service_name
            response_details['code'] = 400

# retrieve state from record
    state_value = ''
    state_details = {}
    if not response_details['error']:
        state_value = request_details['json']['state']
        state_details = read_state(state_value)
        if not state_details:
            response_details['error'] = 'OAuth2 request does not exist or expired.'
            response_details['code'] = 400

# retrieve access token
    access_token = {}
    oauth2_config = {}
    if not response_details['error']:
        oauth2_config = oauth2_configs[service_name]
        oauth2_kwargs = {
            'client_id': oauth2_config['oauth2_client_id'],
            'client_secret': oauth2_config['oauth2_client_secret'],
            'auth_endpoint': oauth2_config['oauth2_auth_endpoint'],
            'token_endpoint': oauth2_config['oauth2_token_endpoint'],
            'redirect_uri': oauth2_config['oauth2_redirect_uri'],
            'request_mimetype': oauth2_config['oauth2_request_mimetype'],
            'requests_handler': handle_requests
        }
        oauth2_client = oauth2Client(**oauth2_kwargs)
        auth_code = request_details['json']['code']
        access_token = oauth2_client.get_token(auth_code)
        if access_token['error']:
            response_details['error'] = access_token['error']
            response_details['code'] = access_token['code']

# save access token
    if not response_details['error']:
        token_kwargs = {
            'account_id': state_details['account_id'],
            'service_scope': state_details['service_scope'],
            'service_name': service_name
        }
        if access_token['json']:
            token_kwargs['token_details'] = access_token['json']
            create_token(**token_kwargs)
        else:
            response_details['error'] = 'Access token response is blank.'
            response_details['code'] = 400

# remove state record
    if not response_details['error']:
        delete_state(state_value)
        service_title = service_name.replace('_', ' ').capitalize()
        authorize_kwargs = {
            'auth_name': service_title,
            'bot_name': bot_config['bot_brand_name']
        }
        authorize_kwargs.update(**landing_kwargs)
        authorize_kwargs['landing_page'] = False
        authorize_kwargs['page_details']['subtitle'] = 'OAuth2 Confirmation'
        if 'oauth2_service_logo' in oauth2_config.keys():
            authorize_kwargs['auth_logo'] = oauth2_config['oauth2_service_logo']
        return render_template('authorize.html', **authorize_kwargs), 200

    flask_app.logger.debug(response_details)
    return jsonify(response_details), response_details['code']
Пример #11
0
def telemetry_route():

    # ingest request
    request_details = extract_request_details(request)
    app.logger.debug(request_details)
    call_on_close = None

    # handle get telemetry
    if request_details['method'] == 'GET':
        response_details = construct_response(request_details)
        user_id = request_details['params'].get('user')
        start_date = request_details['params'].get('start')
        end_date = request_details['params'].get('end')
        telemetry_list = []
        if user_id and start_date and end_date:
            query_criteria = {
                '.user_id': {
                    'equal_to': user_id
                },
                '.date': {
                    'min_value': start_date,
                    'max_value': end_date
                }
            }
            for record in sql_tables['telemetry'].list(query_criteria):
                telemetry_list.append(record)
        else:
            for record in sql_tables['telemetry'].list():
                telemetry_list.append(record)
        response_details['details'] = telemetry_list
        app.logger.debug(response_details)
        return jsonify(response_details), response_details['code']

    # handle post telemetry
    if request_details['method'] == 'POST':
        response_details = construct_response(request_details, telemetry_model)
        if not response_details['error']:
            telemetry_dt = request_details['json']['dt']
            telemetry_record = {
                'date': labDT.fromEpoch(telemetry_dt).zulu()[0:10],
            }
            for key, value in request_details['json'].items():
                telemetry_record[key] = value
            telemetry_id = sql_tables['telemetry'].create(telemetry_record)
            response_details['details'] = {'id': telemetry_id}

            # test for consistent anomalies
            if telemetry_record['anomalous']:
                user_id = telemetry_record['user_id']
                query_criteria = {'user_id': user_id}
                sort_criteria = [{'.dt': 'descend'}]
                count = 0
                for record in sql_tables['telemetry'].list(
                        query_criteria, sort_criteria):
                    if not record['anomalous']:
                        break
                    count += 1
                    if count > 2:
                        # send alert
                        from server.utils import send_email

                        def alert_user():
                            user_email = ''
                            user_name = ''
                            for user in sql_tables['users'].list(
                                {'user_id': user_id}):
                                user_email = user['email']
                                user_name = user['name']
                                break
                            send_email(email_client, user_email, user_name)

                        # call_on_close = alert_user

        # compose response
        if call_on_close:
            response_kwargs = {
                'response': json.dumps(response_details),
                'status': response_details['code'],
                'mimetype': 'application/json'
            }
            response_object = Response(**response_kwargs)
            response_object.call_on_close(call_on_close)
            app.logger.debug(response_details)
            return response_object

        else:
            app.logger.debug(response_details)
            return jsonify(response_details), response_details['code']
Пример #12
0
def telemetry_route(device_id):
    
    # ingest request
    request_details = extract_request_details(request)
    flask_app.logger.debug(request_details)
    response_details = construct_response(request_details)
    if not response_details['error']:
        
    # retrieve telemetry from device
        if request_details['method'] == 'GET':

            list_kwargs = {}
            params, error, code = ingest_query('telemetry-get', request_details, request_models)
            if error:
                response_details['error'] = error
                response_details['code'] = code
            else:
                list_kwargs = {
                    'sql_table': sql_tables['device_telemetry'],
                    'record_id': '',
                    'query_criteria': {
                        '.device_id': { 'equal_to': device_id }
                    }
                }
                if 'query' in params.keys():
                    list_kwargs['query_criteria'].update(**params['query'])
                if 'results' in params.keys():
                    list_kwargs['max_results'] = params['results']
    
            if not response_details['error']:
    
                record_list, record_updates = list_records(**list_kwargs)
                response_details['details'] = record_list
                response_details['updated'] = record_updates

    # create new record
        if request_details['method'] == 'PUT':

            response_details = construct_response(request_details, request_models['telemetry-put'])
            if not response_details['error']:

            # TODO analyze acoustic signature
            
            # evaluate change in acoustics
                # filter_criteria = { '.device_id': { 'equal_to': device_id } }
                # sort_criteria = [ { '.dt': 'descend' } ]
                # for telemetry in sql_tables['device_telemetry'].list(filter_criteria, sort_criteria):
                #     if telemetry['fft'][0] < request_details['json']['fft'][0]:
                #         asset_status = 'anomalous'
                #     break

            # retrieve asset details
                device_details = sql_tables['device_registration'].read(device_id)
                asset_details = sql_tables['asset_registration'].read(device_details['asset_id'])

            # analyze temperature for range in manufacturers specs
                asset_status = 'normal'
                if asset_details['status'] == 'anomalous':
                    asset_status = 'anomalous'
                if asset_details['specs']['temp_high'] or asset_details['specs']['temp_low']:
                    device_temp = request_details['json']['temp']
                    if device_temp > asset_details['specs']['temp_high'] or device_temp < asset_details['specs']['temp_low']:
                        asset_status = 'anomalous'

            # update asset details
                asset_details['status'] = asset_status
                sql_tables['asset_registration'].update(asset_details)

            # add new telemetry record
                telemetry_details = {
                    'dt': time(),
                    'device_id': device_id
                }
                for key, value in request_details['json'].items():
                    if key not in telemetry_details.keys():
                        telemetry_details[key] = value
                telemetry_id = sql_tables['device_telemetry'].create(telemetry_details)
                response_details['details'] = { 'telemetry_id': telemetry_id }
            
    return jsonify(response_details), response_details['code']