Skip to content

Instantly share code, notes, and snippets.

@panki
Created September 15, 2016 09:00
Show Gist options
  • Save panki/ce67e68e72f01154d1f5a8cd08f2720d to your computer and use it in GitHub Desktop.
Save panki/ce67e68e72f01154d1f5a8cd08f2720d to your computer and use it in GitHub Desktop.
audit logs
# -*- coding: utf-8 -*-
import json
import logging
from .models import *
from . import tables
from payme import utm
from payme.forms import form_to_dict
logger = logging.getLogger(__name__)
# account
@db.atomic
def account_created(req, account_id, recipient=True, tx=None):
typ = ACCOUNT_RECIPIENT_CREATED if recipient else ACCOUNT_PAYER_CREATED
return _create(req, tx, typ, account_id=account_id)
# admin
@db.atomic
def admin_created(req, admin_id, tx=None):
return _create(req, tx, ADMIN_USERS_ADMIN_CREATED, admin_user_id=admin_id)
@db.atomic
def admin_user_recreated(req, user_id, tx=None):
return _create(req, tx, ADMIN_USERS_RECREATED, admin_user_id=user_id)
@db.atomic
def admin_user_deleted(req, user_id, tx=None):
return _create(req, tx, ADMIN_USERS_DELETED, admin_user_id=user_id)
@db.atomic
def admin_user_added_to_admins(req, user_id, tx=None):
return _create(req, tx, ADMIN_USERS_ADDED_TO_ADMINS, admin_user_id=user_id)
@db.atomic
def admin_user_deleted_from_admins(req, user_id, tx=None):
return _create(req, tx, ADMIN_USERS_DELETED_FROM_ADMINS, admin_user_id=user_id)
@db.atomic
def admin_user_email_confirmed(req, user_id, tx=None):
return _create(req, tx, ADMIN_USERS_EMAIL_CONFIRMED, admin_user_id=user_id)
@db.atomic
def admin_user_password_changed(req, user_id, tx=None):
return _create(req, tx, ADMIN_USERS_PASSWORD_CHANGED, admin_user_id=user_id)
# admin roles
@db.atomic
def admin_role_created(req, admin_role_id, tx=None):
return _create(req, tx, ADMIN_ROLES_CREATED, admin_role_id=admin_role_id)
@db.atomic
def admin_role_updated(req, admin_role_id, tx=None):
return _create(req, tx, ADMIN_ROLES_UPDATED, admin_role_id=admin_role_id)
@db.atomic
def admin_role_deleted(req, admin_role_id, tx=None):
return _create(req, tx, ADMIN_ROLES_DELETED, admin_role_id=admin_role_id)
@db.atomic
def admin_role_member_added(req, admin_role_id, admin_user_id, tx=None):
return _create(
req, tx, ADMIN_ROLES_MEMBER_ADDED,
admin_role_id=admin_role_id,
admin_user_id=admin_user_id)
@db.atomic
def admin_role_member_deleted(req, admin_role_id, admin_user_id, tx=None):
return _create(
req, tx, ADMIN_ROLES_MEMBER_DELETED,
admin_role_id=admin_role_id,
admin_user_id=admin_user_id)
# alfabank_tx
@db.atomic
def alfabank_tx_created(req, transaction, tx=None):
return _create(
req, tx, ALFABANK_TX_CREATED,
alfabank_tx_id=transaction.id,
invoice_id=transaction.invoice_id,
card_id=transaction.card_id)
@db.atomic
def alfabank_tx_start_response(req, transaction, response, tx=None):
return _create(
req, tx, ALFABANK_TX_START_RESPONSE,
alfabank_tx_id=transaction.id,
invoice_id=transaction.invoice_id,
card_id=transaction.card_id,
payload=response)
@db.atomic
def alfabank_tx_started(req, transaction, response, tx=None):
return _create(
req, tx, ALFABANK_TX_STARTED,
alfabank_tx_id=transaction.id,
invoice_id=transaction.invoice_id,
card_id=transaction.card_id,
payload=response.to_json(safe=True))
@db.atomic
def alfabank_tx_failed_to_start(req, transaction, e, tx=None):
return _create(
req, tx, ALFABANK_TX_FAILED_TO_START,
alfabank_tx_id=transaction.id,
invoice_id=transaction.invoice_id,
card_id=transaction.card_id,
payload=str(e))
@db.atomic
def alfabank_tx_confirmed(req, transaction, confirm_form, tx=None):
return _create(
req, tx, ALFABANK_TX_CONFIRMED,
alfabank_tx_id=transaction.id,
invoice_id=transaction.invoice_id,
card_id=transaction.card_id)
@db.atomic
def alfabank_tx_cofirm_request(req, transaction, confirm_form, tx=None):
payload = json.dumps(form_to_dict(confirm_form), ensure_ascii=False)
return _create(
req, tx, ALFABANK_TX_CONFIRM_REQUEST,
alfabank_tx_id=transaction.id,
invoice_id=transaction.invoice_id,
card_id=transaction.card_id,
payload=payload)
@db.atomic
def alfabank_tx_cofirm_failure(req, transaction, e, tx=None):
payload = str(e)
return _create(
req, tx, ALFABANK_TX_CONFIRM_FAILURE,
alfabank_tx_id=transaction.id,
invoice_id=transaction.invoice_id,
card_id=transaction.card_id,
payload=payload)
@db.atomic
def alfabank_tx_complete_request(req, transaction, client_form, tx=None):
return _create(
req, tx, ALFABANK_TX_COMPLETE_REQUEST,
alfabank_tx_id=transaction.id,
invoice_id=transaction.invoice_id,
card_id=transaction.card_id,
payload=client_form.to_json(safe=True))
@db.atomic
def alfabank_tx_complete_response(req, transaction, response, tx=None):
return _create(
req, tx, ALFABANK_TX_COMPLETE_RESPONSE,
alfabank_tx_id=transaction.id,
invoice_id=transaction.invoice_id,
card_id=transaction.card_id,
payload=response)
@db.atomic
def alfabank_tx_completed(req, transaction, tx=None):
return _create(
req, tx, ALFABANK_TX_COMPLETED,
alfabank_tx_id=transaction.id,
card_id=transaction.card_id,
invoice_id=transaction.invoice_id)
@db.atomic
def alfabank_tx_complete_failure(req, transaction, e, tx=None):
return _create(
req, tx, ALFABANK_TX_COMPLETE_FAILURE,
alfabank_tx_id=transaction.id,
invoice_id=transaction.invoice_id,
card_id=transaction.card_id,
payload=str(e))
# alfabank_fee
@db.atomic
def alfabank_fee_calc_started(req, invoice_id, client_form, tx=None):
return _create(
req, tx, ALFABANK_FEE_CALC_STARTED,
invoice_id=invoice_id,
payload=client_form.to_json(safe=True))
@db.atomic
def alfabank_fee_calc_failed(req, invoice_id, e, tx=None):
return _create(
req, tx, ALFABANK_FEE_CALC_FAILED,
invoice_id=invoice_id,
payload=str(e))
@db.atomic
def alfabank_fee_calc_response(req, invoice_id, resp, tx=None):
return _create(
req, tx, ALFABANK_FEE_CALC_RESPONSE,
invoice_id=invoice_id,
payload=resp.to_json(safe=True))
# auth
@db.atomic
def auth_token_created(req, token, tx=None):
return _create(
req, tx, AUTH_TOKEN_CREATED,
auth_token_id=token.id,
account_id=token.account_id,
invoice_id=token.invoice_id)
@db.atomic
def auth_session_created(req, session, tx=None):
return _create(
req, tx, AUTH_SESSION_CREATED,
account_id=session.account_id,
auth_token_id=session.token_id,
auth_session_id=session.id)
# cards
@db.atomic
def card_created(req, card, tx=None):
return _create(
req, tx, CARDS_CREATED,
account_id=card.account_id,
card_id=card.id,
payload=card.masked_number)
# devices
@db.atomic
def device_created(req, device, tx=None):
return _create(
req, tx, DEVICES_CREATED,
device_id=device.id)
# emails
@db.atomic
def email_created(req, email, tx=None):
return _create(
req, tx, EMAILS_CREATED,
email_id=email.id,
account_id=email.account_id,
invoice_id=email.invoice_id,
auth_token_id=email.auth_token_id)
@db.atomic
def email_cancelled(req, email, tx=None):
return _create(
req, tx, EMAILS_CANCELLED,
email_id=email.id,
account_id=email.account_id,
invoice_id=email.invoice_id)
@db.atomic
def email_failed(req, email, message, tx=None):
return _create(
req, tx, EMAILS_FAILED,
email_id=email.id,
account_id=email.account_id,
invoice_id=email.invoice_id,
payload=message)
@db.atomic
def email_sent(req, email, tx=None):
return _create(
req, tx, EMAILS_SENT,
email_id=email.id,
account_id=email.account_id,
invoice_id=email.invoice_id)
@db.atomic
def email_delivered(req, email, tx=None):
return _create(
req, tx, EMAILS_DELIVERED,
email_id=email.id,
account_id=email.account_id,
invoice_id=email.invoice_id)
@db.atomic
def email_opened(req, email, tx=None):
return _create(
req, tx, EMAILS_OPENED,
email_id=email.id,
account_id=email.account_id,
invoice_id=email.invoice_id)
# invoices
@db.atomic
def invoice_created(req, invoice, tx=None):
return _create(
req, tx, INVOICES_CREATED,
account_id=invoice.owner_id, # In case req.account_id != invoice.owner_id
invoice_id=invoice.id)
@db.atomic
def invoice_sent(req, invoice, tx=None):
return _create(req, tx, INVOICES_SENT, invoice_id=invoice.id)
@db.atomic
def invoice_cancelled(req, invoice, tx=None):
return _create(req, tx, INVOICES_CANCELLED, invoice_id=invoice.id)
@db.atomic
def invoice_refused(req, invoice, tx=None):
return _create(req, tx, INVOICES_REFUSED, invoice_id=invoice.id)
@db.atomic
def invoice_expired(req, invoice, tx=None):
return _create(req, tx, INVOICES_EXPIRED, invoice_id=invoice.id)
@db.atomic
def invoice_reminded(req, invoice, tx=None):
return _create(req, tx, INVOICES_REMINDED, invoice_id=invoice.id)
@db.atomic
def invoice_failed(req, invoice, message, tx=None):
return _create(req, tx, INVOICES_FAILED, invoice_id=invoice.id, payload=message)
@db.atomic
def invoice_paid(req, invoice, tx=None):
return _create(req, tx, INVOICES_PAID, invoice_id=invoice.id)
@db.atomic
def postback_sent(req, invoice_id, data, tx=None):
return _create(
req, tx, POSTBACK_SENT,
invoice_id=invoice_id,
payload=data)
@db.atomic
def postback_failed(req, invoice_id, data, tx=None):
return _create(
req, tx, POSTBACK_FAILED,
invoice_id=invoice_id,
payload=data)
def _create(req, tx, typ, **kwargs):
r = LogRecord()
r.type = typ
r.created_at = datetime.now()
utm.fill(req, r)
if req.account_id:
r.actor_id = req.account_id
if req.device_id:
r.actor_device_id = req.device_id
if req.session_id:
r.actor_session_id = req.session_id
if req.ua:
r.actor_ua = req.ua
if req.ip:
r.actor_ip = req.ip
for key, value in kwargs.items():
setattr(r, key, value)
tx.add(r)
tx.flush()
logger.debug('%s, r=%s, req=%s', typ, r, req)
return r
# Admin API
@db.fetch
def admin_query(req, query, tx=None):
return tables.query(query, tx)
@db.fetch
def admin_query_devices(req, query, tx=None):
return tables.query_devices(query, tx)
@db.fetch
def admin_query_by_id(req, record_id, tx=None):
return tables.record_by_id(record_id, tx)
# -*- coding: utf-8 -*-
from datetime import datetime
import sqlalchemy as sa
import sqlalchemy.orm as sa_orm
from payme import db, types
ADMIN_USERS_ADMIN_CREATED = 'admin/users/admin_created'
ADMIN_USERS_RECREATED = 'admin/users/recreated'
ADMIN_USERS_DELETED = 'admin/users/deleted'
ADMIN_USERS_ADDED_TO_ADMINS = 'admin/users/added_to_admins'
ADMIN_USERS_DELETED_FROM_ADMINS = 'admin/users/deleted_from_admins'
ADMIN_USERS_EMAIL_CONFIRMED = 'admin/users/email_confirmed'
ADMIN_USERS_PASSWORD_CHANGED = 'admin/users/password_changed'
ADMIN_ROLES_CREATED = 'admin/roles/created'
ADMIN_ROLES_UPDATED = 'admin/roles/updated'
ADMIN_ROLES_DELETED = 'admin/roles/deleted'
ADMIN_ROLES_MEMBER_ADDED = 'admin/roles/member_added'
ADMIN_ROLES_MEMBER_DELETED = 'admin/roles/member_deleted'
ACCOUNT_RECIPIENT_CREATED = 'accounts/recipient_created'
ACCOUNT_PAYER_CREATED = 'accounts/payer_created'
ALFABANK_TX_CREATED = 'alfabank/tx_created'
ALFABANK_TX_START_RESPONSE = 'alfabank/tx_start_response'
ALFABANK_TX_STARTED = 'alfabank/tx_started'
ALFABANK_TX_FAILED_TO_START = 'alfabank/tx_failed_to_start'
ALFABANK_TX_CONFIRMED = 'alfabank/tx_confirmed'
ALFABANK_TX_CONFIRM_REQUEST = 'alfabank/tx_confirm_request'
ALFABANK_TX_CONFIRM_FAILURE = 'alfabank/tx_confirm_failure'
ALFABANK_TX_COMPLETE_REQUEST = 'alfabank/tx_complete_request'
ALFABANK_TX_COMPLETE_RESPONSE = 'alfabank/tx_complete_response'
ALFABANK_TX_COMPLETED = 'alfabank/tx_completed'
ALFABANK_TX_COMPLETE_FAILURE = 'alfabank/tx_complete_failure'
ALFABANK_FEE_CALC_STARTED = 'alfabank/fee_calc_started'
ALFABANK_FEE_CALC_FAILED = 'alfabank/fee_calc_failed'
ALFABANK_FEE_CALC_RESPONSE = 'alfabank/fee_calc_response'
AUTH_TOKEN_CREATED = 'auth/token_created'
AUTH_SESSION_CREATED = 'auth/session_created'
CARDS_CREATED = 'cards/created'
DEVICES_CREATED = 'devices/created'
EMAILS_CREATED = 'emails/created'
EMAILS_CANCELLED = 'emails/cancelled'
EMAILS_FAILED = 'emails/failed'
EMAILS_SENT = 'emails/sent'
EMAILS_DELIVERED = 'emails/delivered'
EMAILS_OPENED = 'emails/opened'
INVOICES_CREATED = 'invoices/created'
INVOICES_SENT = 'invoices/sent'
INVOICES_CANCELLED = 'invoices/cancelled'
INVOICES_REFUSED = 'invoices/refused'
INVOICES_EXPIRED = 'invoices/expired'
INVOICES_REMINDED = 'invoices/reminded'
INVOICES_FAILED = 'invoices/failed'
INVOICES_PAID = 'invoices/paid'
POSTBACK_SENT = 'postback/sent'
POSTBACK_FAILED = 'postback/failed'
TITLES = {
# accounts
ACCOUNT_RECIPIENT_CREATED: 'Новый получатель',
ACCOUNT_PAYER_CREATED: 'Новый плательщик',
# alfabank_tx
ALFABANK_TX_CREATED: 'Транзакция создана',
ALFABANK_TX_START_RESPONSE: 'Получен ответ на начало транзакции',
ALFABANK_TX_STARTED: 'Транзакция начата',
ALFABANK_TX_FAILED_TO_START: 'Ошибка начала тразакции',
ALFABANK_TX_CONFIRM_REQUEST: 'Получен запрос на подтверждение транзакции',
ALFABANK_TX_CONFIRMED: 'Транзакция подтверждена',
ALFABANK_TX_CONFIRM_FAILURE: 'Ошибка подтверждения транзакции',
ALFABANK_TX_COMPLETE_REQUEST: 'Отправлен запрос на завершение транзакции',
ALFABANK_TX_COMPLETE_RESPONSE: 'Получен ответ на завершение транзакции',
ALFABANK_TX_COMPLETED: 'Транзакция завершена',
ALFABANK_TX_COMPLETE_FAILURE: 'Ошибка завершения транзакции',
# alfabank_fee
ALFABANK_FEE_CALC_STARTED: 'Начало расчета комиссии',
ALFABANK_FEE_CALC_FAILED: 'Ошибка расчета комиссии',
ALFABANK_FEE_CALC_RESPONSE: 'Комиссия рассчитана',
# auth
AUTH_TOKEN_CREATED: 'Авторизационный токен создан',
AUTH_SESSION_CREATED: 'Авторизационная сессия создана',
# cards
CARDS_CREATED: 'Карта создана',
# devices
DEVICES_CREATED: 'Устройство создано',
# emails
EMAILS_CREATED: 'Письмо создано',
EMAILS_CANCELLED: 'Письмо отменено',
EMAILS_FAILED: 'Ошибка доставки письма',
EMAILS_SENT: 'Письмо отправлено',
EMAILS_DELIVERED: 'Письмо доставлено',
EMAILS_OPENED: 'Письмо открыто',
# invoices
INVOICES_CREATED: 'Счет создан',
INVOICES_SENT: 'Счет отправлен плательщику',
INVOICES_CANCELLED: 'Счет отменен владельцем',
INVOICES_REFUSED: 'Плательщик отказался от оплаты счета',
INVOICES_EXPIRED: 'Истек срок оплаты счета',
INVOICES_FAILED: 'Ошибка счета',
INVOICES_PAID: 'Счет оплачен',
# postback
POSTBACK_SENT: 'Конверсия зарегистрирована',
POSTBACK_FAILED: 'Ошибка регистрации конверсии'
}
def type_title(t):
return TITLES.get(t, 'Неизвестное событие')
class LogRecord(db.Model):
__tablename__ = 'logs'
id = sa.Column(sa.BigInteger, primary_key=True)
type = sa.Column(sa.String)
created_at = sa.Column(sa.DateTime, default=datetime.now)
actor_id = sa.Column(types.UUID)
actor_device_id = sa.Column(types.UUID)
actor_session_id = sa.Column(types.UUID)
actor_ua = sa.Column(sa.String)
actor_ip = sa.Column(sa.String)
account_id = sa.Column(types.UUID, sa.ForeignKey('accounts.id'))
account = sa_orm.relation('Account', foreign_keys=account_id)
admin_role_id = sa.Column(types.UUID, sa.ForeignKey('admin_roles.id'))
admin_role = sa_orm.relation('Role', foreign_keys=admin_role_id)
admin_user_id = sa.Column(types.UUID, sa.ForeignKey('admin_user.id'))
admin_user = sa_orm.relation('User', foreign_keys=admin_user_id)
auth_token_id = sa.Column(types.UUID, sa.ForeignKey('auth_tokens.id'))
auth_token = sa_orm.relation('Token', foreign_keys=auth_token_id)
auth_session_id = sa.Column(types.UUID, sa.ForeignKey('auth_sessions.id'))
auth_session = sa_orm.relation('Session', foreign_keys=auth_session_id)
alfabank_tx_id = sa.Column(types.UUID, sa.ForeignKey('alfabank_transactions.id'))
alfabank_tx = sa_orm.relation('Transaction', foreign_keys=alfabank_tx_id)
card_id = sa.Column(types.UUID, sa.ForeignKey('cards.id'))
card = sa_orm.relation('Card', foreign_keys=card_id)
device_id = sa.Column(types.UUID, sa.ForeignKey('devices.id'))
device = sa_orm.relation('Device', foreign_keys=device_id)
email_id = sa.Column(types.UUID, sa.ForeignKey('emails.id'))
email = sa_orm.relation('Email', foreign_keys=email_id)
invoice_id = sa.Column(types.UUID, sa.ForeignKey('invoices.id'))
invoice = sa_orm.relation('Invoice', foreign_keys=invoice_id)
payload = sa.Column(sa.UnicodeText)
utm_source = sa.Column(sa.String)
utm_medium = sa.Column(sa.String)
utm_campaign = sa.Column(sa.String)
utm_content = sa.Column(sa.String)
utm_term = sa.Column(sa.String)
utm_referrer = sa.Column(sa.String)
utm_tid = sa.Column(sa.String)
def __str__(self):
cls = self.__class__.__name__
attrs = ', '.join('%s=%s' % (k, v) for k, v in self.__dict__.items() if v)
return '<%s %s>' % (cls, attrs)
@property
def title(self):
return type_title(self.type)
class Query(types.PageQuery):
account_id = types.String
alfabank_tx_id = types.String
card_id = types.String
device_id = types.String
email_id = types.String
invoice_id = types.String
def __init__(self, page=1, per_page=1000, **kwargs):
super().__init__(page, per_page, **kwargs)
# -*- coding: utf-8 -*-
from .models import LogRecord
def record_by_id(record_id, tx):
return tx.query(LogRecord).get(record_id)
def query(query, tx):
if not query.is_valid:
return []
q = tx.query(LogRecord)
if query.account_id:
q = q.filter(LogRecord.account_id == query.account_id)
if query.alfabank_tx_id:
q = q.filter(LogRecord.alfabank_tx_id == query.alfabank_tx_id)
if query.card_id:
q = q.filter(LogRecord.card_id == query.card_id)
if query.device_id:
q = q.filter(LogRecord.device_id == query.device_id)
if query.email_id:
q = q.filter(LogRecord.email_id == query.email_id)
if query.invoice_id:
q = q.filter(LogRecord.invoice_id == query.invoice_id)
return q.order_by(LogRecord.created_at.desc()) \
.limit(query.limit).offset(query.offset).all()
def query_devices(query, tx):
from payme.devices.models import Device
if not query.is_valid:
return []
q = tx.query(Device).join(LogRecord, LogRecord.actor_device_id == Device.id)
if query.account_id:
q = q.filter(LogRecord.account_id == query.account_id)
if query.alfabank_tx_id:
q = q.filter(LogRecord.alfabank_tx_id == query.alfabank_tx_id)
if query.card_id:
q = q.filter(LogRecord.card_id == query.card_id)
if query.device_id:
q = q.filter(LogRecord.device_id == query.device_id)
if query.email_id:
q = q.filter(LogRecord.email_id == query.email_id)
if query.invoice_id:
q = q.filter(LogRecord.invoice_id == query.invoice_id)
return q.distinct().order_by(Device.created_at.desc()) \
.limit(query.limit).offset(query.offset).all()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment