HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux spn-python 5.15.0-89-generic #99-Ubuntu SMP Mon Oct 30 20:42:41 UTC 2023 x86_64
User: arjun (1000)
PHP: 8.1.2-1ubuntu2.20
Disabled: NONE
Upload Files
File: //home/arjun/projects/buyercall_forms/buyercall/buyercall/blueprints/activity/models.py
import logging as log
from enum import Enum
import datetime

from flask_login import current_user
from sqlalchemy import DateTime
from buyercall.extensions import db
from buyercall.lib.supervisor_manager import current_supervisor_user
from buyercall.lib.util_sqlalchemy import AwareDateTime, ResourceMixin
from buyercall.lib.util_datetime import tzware_datetime, timedelta_months
from buyercall.blueprints.user.models import User
from user_agents import parse

class ActivityType(str, Enum):
    AUTHORIZATION = 'authorization',
    PAGE = 'page',
    MODAL= 'modal',
    DATA = 'data',
    CREDIT = 'credit'


class ActivityName(str, Enum):
    LOGOUT = 'logout.success',
    LOGIN_SUCCESS = 'login.success',
    LOGIN_FAILED = 'login.failed',
    TWOFACTAUTH_SUCCESS = 'login.twofactauth.success',
    TWOFACTAUTH_FAILED = 'login.twofactauth.failed',
    LOGIN_ACCEPTTERMS = 'login.acceptterms',
    LOGIN_DECLINETERMS = 'login.declineterms',
    PASSWORDRESET_SUCCESS = 'login.passwordreset.success'
    PASSWORDRESET_FAILED =' login.passwordreset.failed'
    VIEW = 'view',
    EDIT = 'edit',
    PDF = 'pdf',
    DOWNLOAD = 'download'


class ActivityLogs(ResourceMixin, db.Model):
    __tablename__ = 'activity_logs'

    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id',
                                                  name='activity_logs_user_id_fkey',
                                                  onupdate='CASCADE',
                                                  ondelete='CASCADE'),
                        index=True, nullable=False)
    type = db.Column(db.String(64), nullable=False, server_default='')
    name = db.Column(db.String(64), nullable=False, server_default='')
    description = db.Column(db.String(64), nullable=False, server_default='')
    ip_address = db.Column(db.String(64), nullable=False, server_default='')
    device_browser = db.Column(db.String(64), nullable=False, server_default='')
    device_os = db.Column(db.String(64), nullable=False, server_default='')
    resource_address = db.Column(db.String(64), nullable=False, server_default='')
    resource_id = db.Column(db.Integer, nullable=True)
    partnership_id = db.Column(db.Integer, db.ForeignKey('partnerships.id',
                                                         onupdate='CASCADE',
                                                         ondelete='CASCADE'),
                               index=True, nullable=True)

    partnership_account_id = db.Column(db.Integer, db.ForeignKey('partnership_accounts.id',
                                                                 onupdate='CASCADE',
                                                                 ondelete='CASCADE'),
                                       index=True, nullable=True)

    @classmethod
    def add_log(cls, user_id, type_, name, request, resource_id=None, description=''):
        """
        Create new user activity log entry

        """
        if hasattr(current_supervisor_user, 'id'):
            user_id = current_supervisor_user.id

        p_id = None
        pa_id = None
        user = User.query.filter(User.id == user_id).first()
        if user:
            p_id = user.partnership_id
            pa_id = user.partnership_account_id
        try:
            new_activity = ActivityLogs(
                user_id=user_id,
                type=type_,
                name=name,
                description=description,
                ip_address=cls.get_ip_address_from_request(request),
                device_browser=cls.get_device_browser_from_request(request),
                device_os=cls.get_device_os_from_request(request),
                resource_address=cls.get_resource_address_from_request(request),
                resource_id=resource_id,
                partnership_id=p_id,
                partnership_account_id=pa_id
            )
            db.session.add(new_activity)
            db.session.commit()
        except Exception as e:
            log.error('Error adding to activity log. Error: ' + str(e))

    @classmethod
    def get_ip_address_from_request(cls, request):
        """
        Retrieves the user IP address

        """
        try:
            if request.environ.get('HTTP_X_FORWARDED_FOR') is None:
                return request.environ['REMOTE_ADDR']
            else:
                return request.environ['HTTP_X_FORWARDED_FOR']
        except Exception as e:
            log.error('Error retrieving user IP address for activity log. Error: ' + str(e))
            return ''

    @classmethod
    def get_device_browser_from_request(cls, request):
        """
        Retrieves the user device browser details

        """
        try:
            if request:
                user_agent = parse(request.user_agent.string)
                return user_agent.browser.family + '|' + user_agent.browser.version_string
            else:
                return ''
        except Exception as e:
            log.error('Error retrieving user device browser for activity log. Error: ' + str(e))
            return ''

    @classmethod
    def get_device_os_from_request(cls, request):
        """
        Retrieves the user device os details

        """
        try:
            if request:
                user_agent = parse(request.user_agent.string)
                return user_agent.os.family
            else:
                return ''
        except Exception as e:
            log.error('Error retrieving user device os for activity log. Error: ' + str(e))
            return ''

    @classmethod
    def get_resource_address_from_request(cls, request):
        """
        Retrieves the requested url path

        """
        try:
            if request:
                return request.path
            else:
                return ''
        except Exception as e:
            log.error('Error retrieving requested url path for activity log. Error: ' + str(e))
            return ''

    @classmethod
    def delete_old_activity_logs(cls):
        """
        Delete activity logs 6 months and older.

        :return: int
        """
        from buyercall.app import create_app
        # Create a context for the database connection.
        app = create_app()
        db.app = app
        with app.app_context():
            delete_count = 0
            expiration_days = 60
            limit = timedelta_months(-6)
            delete_count = ActivityLogs.query.filter(ActivityLogs.created_on <= limit).count()
            ActivityLogs.query.filter(ActivityLogs.created_on <= limit).delete()
            db.session.commit()
            return delete_count
        pass