Exemple #1
0
async def handler(values=None, **kwargs):
    try:
        expire_at = values.timestamp + datetime.timedelta(
            seconds=int(values.expire))
    except Exception:
        return 400, {'error': 'Invalid value for expire'}

    try:
        stored_data = await load('user', values.prompt_user_hash)
        if stored_data:
            if stored_data.get('state') in ('pending',
                                            'received') and not is_expired(
                                                stored_data.get('expireAt')):
                return 406, {'error': 'Prompt already pending'}
            if values.encrypted_data and sha3(
                    stored_data.get('encryptedData')) == sha3(
                        values.encrypted_data):
                return 406, {'error': 'Prompt already sent'}
    except Exception:
        pass

    prompt_identifier = str(uuid.uuid4())

    store_data = {
        'promptIdentifier': prompt_identifier,
        'promptUserHash': values.prompt_user_hash,
        'uniqueIdentifier': str(uuid.uuid4()),
        'state': 'pending',
        'encryptedData': values.encrypted_data,
        'timestamp': values.timestamp.strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
        'expireAt': expire_at.strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
        'respondedAt': None,
        'responseHash': None
    }

    await store('prompt', prompt_identifier, store_data)
    await store('user', values.prompt_user_hash, store_data)

    subscription_data = await load('subscription',
                                   values.prompt_user_hash)  # noqa
    if subscription_data and isinstance(subscription_data, list):
        for subscription in subscription_data:
            if subscription.get('promptUserHash') == values.prompt_user_hash:
                # todo send notification
                pass

    return 200, {
        'promptIdentifier': prompt_identifier,
        'state': store_data.get('state'),
        'expireAt': store_data.get('expireAt')
    }
Exemple #2
0
async def _load_s3(file_type, identifier, decode=True):
    client = _get_s3_client()

    try:
        object_data = await async_call(client.get_object(
            Bucket=settings.aws_s3_bucket,
            Key='{}/{}'.format(file_type, sha3(identifier))
        ))
    except botocore.exceptions.ClientError as e:
        if e.response['Error']['Code'] == 'NoSuchKey':
            return None
        if e.response['Error']['Code'] == 'AccessDenied':
            return None
        else:
            raise e

    data = await async_call(object_data.get('Body').read())

    if data:
        data = decrypt(data, identifier)

    try:
        if data and decode:
            return json.loads(data)
    except Exception:
        pass

    return data
Exemple #3
0
async def _store_s3(file_type, identifier, data, save_previous=False):
    client = _get_s3_client()
    key = '{}/{}'.format(file_type, sha3(identifier))

    if isinstance(data, str):
        data = data.encode('utf-8')
    if not isinstance(data, bytes):
        data = json.dumps(data).encode()

    if save_previous:
        try:
            await async_call(client.copy_object(
                Bucket=settings.aws_s3_bucket,
                Key=f'{key}.previousver',
                CopySource={'Bucket': settings.aws_s3_bucket, 'Key': key}
            ))
        except botocore.exceptions.ClientError as e:
            if e.response['Error']['Code'] == 'NoSuchKey':
                pass
            if e.response['Error']['Code'] == 'AccessDenied':
                pass
            else:
                raise e

    if data:
        data = encrypt(data, identifier)

    await async_call(client.put_object(
        Bucket=settings.aws_s3_bucket,
        Key=key,
        Body=data
    ))
Exemple #4
0
async def _delete_local(file_type, identifier, delete_previous=False):
    file_path = os.path.join(settings.data_path, file_type, sha3(identifier))

    if os.path.isfile(file_path):
        os.remove(file_path)

    if delete_previous:
        previousver_file_path = f'{file_path}.previousver'
        if os.path.isfile(previousver_file_path):
            os.remove(previousver_file_path)
Exemple #5
0
async def _delete_s3(file_type, identifier, delete_previous=False):
    client = _get_s3_client()
    key = '{}/{}'.format(file_type, sha3(identifier))

    await async_call(client.delete_object(
        Bucket=settings.aws_s3_bucket,
        Key=key
    ))

    if delete_previous:
        await async_call(client.delete_object(
            Bucket=settings.aws_s3_bucket,
            Key=f'{key}.previousver'
        ))
Exemple #6
0
async def _mtime_s3(file_type, identifier, decode=True):
    client = _get_s3_client()

    try:
        object_data = await async_call(client.head_object(  # noqa
            Bucket=settings.aws_s3_bucket,
            Key='{}/{}'.format(file_type, sha3(identifier))
        ))
    except botocore.exceptions.ClientError as e:
        if e.response['Error']['Code'] == 'NoSuchKey':
            return None
        if e.response['Error']['Code'] == 'AccessDenied':
            return None
        else:
            raise e

    return None
Exemple #7
0
async def _load_local(file_type, identifier, decode=True):
    file_path = os.path.join(settings.data_path, file_type, sha3(identifier))

    if os.path.isfile(file_path):
        with open(file_path, 'rb') as file:
            data = file.read()

            if data:
                data = decrypt(data, identifier)

            try:
                if data and decode:
                    return json.loads(data)
            except Exception:
                pass

            return data

    return None
Exemple #8
0
async def _store_local(file_type, identifier, data, save_previous=False):
    directory = os.path.join(settings.data_path, file_type)
    file_path = os.path.join(directory, sha3(identifier))

    if isinstance(data, str):
        data = data.encode('utf-8')
    if not isinstance(data, bytes):
        data = json.dumps(data).encode()

    if not os.path.isdir(directory):
        os.makedirs(directory)

    if save_previous and os.path.isfile(file_path):
        shutil.copyfile(file_path, f'{file_path}.previousver')

    if data:
        data = encrypt(data, identifier)

    with open(file_path, 'wb') as file:
        file.write(data)