Exemple #1
0
def m2m_changed(sender, instance, action, reverse, model, pk_set, using,
                **kwargs):
    """https://docs.djangoproject.com/es/1.10/ref/signals/#m2m-changed"""
    try:
        with transaction.atomic():
            if not should_audit(instance):
                return False

            if action not in ("post_add", "post_remove", "post_clear"):
                return False

            object_json_repr = serializers.serialize("json", [instance])

            if reverse:
                event_type = CRUDEvent.M2M_CHANGE_REV
                # add reverse M2M changes to event. must use json lib because
                # django serializers ignore extra fields.
                tmp_repr = json.loads(object_json_repr)

                m2m_rev_field = _m2m_rev_field_name(
                    instance._meta.concrete_model, model)
                related_instances = getattr(instance, m2m_rev_field).all()
                related_ids = [r.pk for r in related_instances]

                tmp_repr[0]['m2m_rev_model'] = force_text(model._meta)
                tmp_repr[0]['m2m_rev_pks'] = related_ids
                tmp_repr[0]['m2m_rev_action'] = action
                object_json_repr = json.dumps(tmp_repr)
            else:
                event_type = CRUDEvent.M2M_CHANGE

            # user
            try:
                user = get_current_user()
                # validate that the user still exists
                user = get_user_model().objects.get(pk=user.pk)
            except:
                user = None

            if isinstance(user, AnonymousUser):
                user = None

            crud_event = CRUDEvent.objects.create(
                event_type=event_type,
                object_repr=str(instance),
                object_json_repr=object_json_repr,
                content_type=ContentType.objects.get_for_model(instance),
                object_id=instance.pk,
                user=user,
                datetime=timezone.now(),
                user_pk_as_string=str(user.pk) if user else user,
                remote_ip=get_client_ip(get_current_request()),
                browser=get_client_browser_info(get_current_request()),
                operating_system=get_client_operating_system_info(
                    get_current_request()))
    except Exception:
        traceback.print_exc()
        logger.exception('easy audit had an m2m-changed exception.')
Exemple #2
0
def post_save(sender, instance, created, raw, using, update_fields, **kwargs):
    """https://docs.djangoproject.com/es/1.10/ref/signals/#post-save"""
    if raw:
        # Return if loading Fixtures
        return

    try:
        with transaction.atomic():
            if not should_audit(instance):
                return False
            object_json_repr = serializers.serialize("json", [instance])

            # created or updated?
            if created:
                event_type = CRUDEvent.CREATE

            # user
            try:
                user = get_current_user()
                # validate that the user still exists
                user = get_user_model().objects.get(pk=user.pk)
            except:
                user = None

            if isinstance(user, AnonymousUser):
                user = None

            # callbacks
            kwargs['request'] = get_current_request(
            )  # make request available for callbacks
            create_crud_event = all(
                callback(instance, object_json_repr, created, raw, using,
                         update_fields, **kwargs)
                for callback in CRUD_DIFFERENCE_CALLBACKS
                if callable(callback))

            # create crud event only if all callbacks returned True
            if create_crud_event and created:
                crud_event = CRUDEvent.objects.create(
                    event_type=event_type,
                    object_repr=str(instance),
                    object_json_repr=object_json_repr,
                    content_type=ContentType.objects.get_for_model(instance),
                    object_id=instance.pk,
                    user=user,
                    datetime=timezone.now(),
                    user_pk_as_string=str(user.pk) if user else user,
                    remote_ip=get_client_ip(get_current_request()),
                    browser=get_client_browser_info(get_current_request()),
                    operating_system=get_client_operating_system_info(
                        get_current_request()))
    except Exception:
        traceback.print_exc()
        logger.exception('easy audit had a post-save exception.')
def pre_save(sender, instance, raw, using, update_fields, **kwargs):
    """https://docs.djangoproject.com/es/1.10/ref/signals/#post-save"""
    if raw:
      # Return if loading Fixtures      
      return
    if instance.pk is None:
        # avoid many to many errors
        return
    
    try:
        with transaction.atomic():
            if not should_audit(instance):
                return False
            object_json_repr = serializers.serialize("json", [instance])

            if instance.pk is None:
                # avoid many to many errors
                return
            else:
                created = False

            # created or updated?
            if not created:
                old_model = sender.objects.get(pk=instance.pk)
                delta = model_delta(old_model, instance)
                changed_fields = json.dumps(delta)
                event_type = CRUDEvent.UPDATE

            # user
            try:
                user = get_current_user()
                # validate that the user still exists
                user = get_user_model().objects.get(pk=user.pk)
            except:
                user = None

            if isinstance(user, AnonymousUser):
                user = None

            # callbacks
            kwargs['request'] = get_current_request()  # make request available for callbacks
            create_crud_event = all(callback(instance, object_json_repr, created, raw, using, update_fields, **kwargs)
                                    for callback in CRUD_DIFFERENCE_CALLBACKS if callable(callback))

            # create crud event only if all callbacks returned True
            if create_crud_event and not created:
                crud_event = CRUDEvent.objects.create(
                    event_type=event_type,
                    object_repr=str(instance),
                    object_json_repr=object_json_repr,
                    changed_fields=changed_fields,
                    content_type=ContentType.objects.get_for_model(instance),
                    object_id=instance.pk,
                    user=user,
                    datetime=timezone.now(),
                    user_pk_as_string=str(user.pk) if user else user
                )
    except Exception:
        logger.exception('easy audit had a pre-save exception.')
Exemple #4
0
def post_save(sender, instance, created, raw, using, update_fields, **kwargs):
    """https://docs.djangoproject.com/es/1.10/ref/signals/#post-save"""
    if raw:
        # Return if loading Fixtures
        return

    # ignore this signal if it is intended for a DB we want to ignore
    if using in IGNORED_DB_ALIASES:
        return False

    try:
        with transaction.atomic(using=using):
            if not should_audit(instance):
                return False
            object_json_repr = serializers.serialize("json", [instance])

            # created or updated?
            if created:
                event_type = CRUDEvent.CREATE

            # user
            try:
                user = get_current_user()
                # validate that the user still exists
                if USER_MODEL_IS_ONLY_IN_DEFAULT_DB:
                    user = get_user_model().objects.get(pk=user.pk)
                else:
                    user = get_user_model().objects.using(using).get(
                        pk=user.pk)
            except:
                user = None

            if isinstance(user, AnonymousUser):
                user = None

            # callbacks
            kwargs['request'] = get_current_request(
            )  # make request available for callbacks
            create_crud_event = all(
                callback(instance, object_json_repr, created, raw, using,
                         update_fields, **kwargs)
                for callback in CRUD_DIFFERENCE_CALLBACKS
                if callable(callback))

            # create crud event only if all callbacks returned True
            if create_crud_event and created:
                crud_event = CRUDEvent.objects.using(using).create(
                    event_type=event_type,
                    object_repr=str(instance),
                    object_json_repr=object_json_repr,
                    content_type=ContentType.objects.get_for_model(instance),
                    object_id=instance.pk,
                    user=user if using == DEFAULT_DB_ALIAS
                    and USER_MODEL_IS_ONLY_IN_DEFAULT_DB else None,
                    datetime=timezone.now(),
                    user_pk_as_string=str(user.pk) if user else user)
    except Exception:
        logger.exception('easy audit had a post-save exception.')
Exemple #5
0
def user_login_failed(sender, credentials, **kwargs):
    try:
        request = get_current_request(
        )  # request argument not available in django < 1.11
        user_model = get_user_model()
        login_event = LoginEvent.objects.create(
            login_type=LoginEvent.FAILED,
            username=credentials[user_model.USERNAME_FIELD],
            remote_ip=request.META['REMOTE_ADDR'])
    except:
        pass
Exemple #6
0
    def test_request_is_cleared(self):
        # log in user
        user = UserProfileFactory().user
        self.client.login(
            username=user.username, password=settings.TEST_USER_PASSWORD)

        # do action
        self.client.get('/')
        # check if request is cleared
        self.assertIsNone(get_current_request())
        self.assertIsNone(get_current_user())
Exemple #7
0
def post_delete(sender, instance, using, **kwargs):
    """https://docs.djangoproject.com/es/1.10/ref/signals/#post-delete"""
    try:
        with transaction.atomic():
            if not should_audit(instance):
                return False

            object_json_repr = serializers.serialize("json", [instance])

            # user
            try:
                user = get_current_user()
                # validate that the user still exists
                user = get_user_model().objects.get(pk=user.pk)
            except:
                user = None

            if isinstance(user, AnonymousUser):
                user = None

            # crud event
            crud_event = CRUDEvent.objects.create(
                event_type=CRUDEvent.DELETE,
                object_repr=str(instance),
                object_json_repr=object_json_repr,
                content_type=ContentType.objects.get_for_model(instance),
                object_id=instance.pk,
                user=user,
                datetime=timezone.now(),
                user_pk_as_string=str(user.pk) if user else user,
                remote_ip=get_client_ip(get_current_request()),
                browser=get_client_browser_info(get_current_request()),
                operating_system=get_client_operating_system_info(
                    get_current_request()))
    except Exception:
        traceback.print_exc()
        logger.exception('easy audit had a post-delete exception.')
Exemple #8
0
def user_login_failed(sender, credentials, **kwargs):
    try:
        with transaction.atomic():
            request = get_current_request(
            )  # request argument not available in django < 1.11
            user_model = get_user_model()
            login_event = audit_logger.login({
                'login_type':
                LoginEvent.FAILED,
                'username':
                credentials[user_model.USERNAME_FIELD],
                'remote_ip':
                request.META[REMOTE_ADDR_HEADER]
            })
    except:
        pass
Exemple #9
0
def post_save(sender, instance, raw, created, using, update_fields, **kwargs):
    """https://docs.djangoproject.com/es/1.10/ref/signals/#post-save"""
    try:
        if not should_audit(instance):
            return False

        # new created obj
        if created:
            event_type = CRUDEvent.CREATE
            object_json_repr = content(instance)
        else:
            return
        try:
            user = get_current_user()
        except:
            user = None

        if isinstance(user, AnonymousUser):
            user = None

        # callbacks
        kwargs['request'] = get_current_request()  # make request available for callbacks
        create_crud_event = all(callback(instance, object_json_repr, created, raw, using, update_fields, **kwargs)
                                for callback in CRUD_DIFFERENCE_CALLBACKS if callable(callback))

        # create crud event only if all callbacks returned True
        if create_crud_event:
            crud_event = CRUDEvent.objects.create(
                event_type=event_type,
                object_repr=str(instance),
                object_json_repr=object_json_repr,
                content_type=ContentType.objects.get_for_model(instance),
                object_id=instance.pk,
                user=user,
                datetime=timezone.now(),
                user_pk_as_string=str(user.pk) if user else user
            )
    except Exception as e:
        logger.exception('easy audit had a post-save exception.  %s' % e)
Exemple #10
0
def pre_save(sender, instance, raw, using, update_fields, **kwargs):
    """https://docs.djangoproject.com/es/1.10/ref/signals/#post-save"""
    if raw:
        # Return if loading Fixtures
        return

    try:
        with transaction.atomic(using=using):
            if not should_audit(instance):
                return False
            try:
                object_json_repr = serializers.serialize("json", [instance])
                object_json_repr = scrub_sensitive_fields_object_json_repr(
                    object_json_repr)
            except Exception:
                # We need a better way for this to work. ManyToMany will fail on pre_save on create
                return None

            if instance.pk is None:
                created = True
            else:
                created = False

            # created or updated?
            if not created:
                try:
                    old_model = sender.objects.get(pk=instance.pk)
                    delta = model_delta(old_model, instance)
                    if not delta and getattr(
                            settings,
                            "DJANGO_EASY_AUDIT_CRUD_EVENT_NO_CHANGED_FIELDS_SKIP",
                            False):
                        return False
                    changed_fields = json.dumps(delta)
                    event_type = CRUDEvent.UPDATE
                except ObjectDoesNotExist:
                    created = True

            # user
            try:
                user = get_current_user()
                # validate that the user still exists
                user = get_user_model().objects.get(pk=user.pk)
            except:
                user = None

            if isinstance(user, AnonymousUser):
                user = None

            # callbacks
            kwargs['request'] = get_current_request(
            )  # make request available for callbacks
            create_crud_event = all(
                callback(instance, object_json_repr, created, raw, using,
                         update_fields, **kwargs)
                for callback in CRUD_DIFFERENCE_CALLBACKS
                if callable(callback))
            # create crud event only if all callbacks returned True
            if create_crud_event and not created:
                c_t = ContentType.objects.get_for_model(instance)

                def crud_flow():
                    try:
                        # atomicity based on the easyaudit database alias
                        with transaction.atomic(using=DATABASE_ALIAS):
                            crud_event = audit_logger.crud({
                                'event_type':
                                event_type,
                                'object_repr':
                                str(instance),
                                'object_json_repr':
                                object_json_repr,
                                'changed_fields':
                                changed_fields,
                                'content_type_id':
                                c_t.id,
                                'object_id':
                                instance.pk,
                                'user_id':
                                getattr(user, 'id', None),
                                'datetime':
                                timezone.now(),
                                'user_pk_as_string':
                                str(user.pk) if user else user
                            })
                    except Exception as e:
                        try:
                            logger.exception(
                                "easy audit had a pre_save exception on CRUDEvent creation. instance: {}, instance pk: {}"
                                .format(instance, instance.pk))
                        except Exception:
                            pass

                if getattr(settings, "TEST", False):
                    crud_flow()
                else:
                    transaction.on_commit(crud_flow, using=using)
    except Exception:
        logger.exception('easy audit had a pre-save exception.')
Exemple #11
0
def post_save(sender, instance, created, raw, using, update_fields, **kwargs):
    """https://docs.djangoproject.com/es/1.10/ref/signals/#post-save"""
    if raw:
        # Return if loading Fixtures
        return

    try:
        with transaction.atomic(using=using):
            if not should_audit(instance):
                return False
            object_json_repr = serializers.serialize("json", [instance])
            object_json_repr = scrub_sensitive_fields_object_json_repr(
                object_json_repr)

            # created or updated?
            if created:
                event_type = CRUDEvent.CREATE

            # user
            try:
                user = get_current_user()
                # validate that the user still exists
                user = get_user_model().objects.get(pk=user.pk)
            except:
                user = None

            if isinstance(user, AnonymousUser):
                user = None

            # callbacks
            kwargs['request'] = get_current_request(
            )  # make request available for callbacks
            create_crud_event = all(
                callback(instance, object_json_repr, created, raw, using,
                         update_fields, **kwargs)
                for callback in CRUD_DIFFERENCE_CALLBACKS
                if callable(callback))

            # create crud event only if all callbacks returned True
            if create_crud_event and created:
                c_t = ContentType.objects.get_for_model(instance)

                def crud_flow():
                    try:
                        with transaction.atomic(using=DATABASE_ALIAS):
                            crud_event = audit_logger.crud({
                                'event_type':
                                event_type,
                                'object_repr':
                                str(instance),
                                'object_json_repr':
                                object_json_repr,
                                'content_type_id':
                                c_t.id,
                                'object_id':
                                instance.pk,
                                'user_id':
                                getattr(user, 'id', None),
                                'datetime':
                                timezone.now(),
                                'user_pk_as_string':
                                str(user.pk) if user else user
                            })
                    except Exception as e:
                        try:
                            logger.exception(
                                "easy audit had a post_save exception on CRUDEvent creation. instance: {}, instance pk: {}"
                                .format(instance, instance.pk))
                        except Exception:
                            pass

                if getattr(settings, "TEST", False):
                    crud_flow()
                else:
                    transaction.on_commit(crud_flow, using=using)
    except Exception:
        logger.exception('easy audit had a post-save exception.')
def pre_save(sender, instance, raw, using, update_fields, **kwargs):
    """https://docs.djangoproject.com/es/1.10/ref/signals/#post-save"""
    if raw:
        # Return if loading Fixtures
        return

    try:
        with transaction.atomic():
            if not should_audit(instance):
                return False
            try:
                object_json_repr = serializers.serialize("json", [instance])
            except Exception:
                # We need a better way for this to work. ManyToMany will fail on pre_save on create
                return None

            if instance.pk is None:
                created = True
            else:
                created = False

            # created or updated?
            if not created:
                old_model = sender.objects.get(pk=instance.pk)
                delta = model_delta(old_model, instance)
                changed_fields = json.dumps(delta)
                event_type = CRUDEvent.UPDATE

            # user
            try:
                user = get_current_user()
                # validate that the user still exists
                user = get_user_model().objects.get(pk=user.pk)
            except:
                user = None

            if isinstance(user, AnonymousUser):
                user = None

            # callbacks
            kwargs['request'] = get_current_request(
            )  # make request available for callbacks
            create_crud_event = all(
                callback(instance, object_json_repr, created, raw, using,
                         update_fields, **kwargs)
                for callback in CRUD_DIFFERENCE_CALLBACKS
                if callable(callback))
            # create crud event only if all callbacks returned True
            if create_crud_event and not created:
                c_t = ContentType.objects.get_for_model(instance)
                sid = transaction.savepoint()
                try:
                    with transaction.atomic():
                        if any(
                                isinstance(instance, model)
                                for model in REGISTERED_CLASSES_BIGINTEGER):
                            crud_model = CRUDEventBigInteger
                        elif any(
                                isinstance(instance, model)
                                for model in REGISTERED_CLASSES_UUID):
                            crud_model = CRUDEventUUID
                        else:
                            crud_model = CRUDEvent
                        crud_event = crud_model.objects.create(
                            event_type=event_type,
                            object_repr=str(instance),
                            object_json_repr=object_json_repr,
                            changed_fields=changed_fields,
                            content_type_id=c_t.id,
                            object_id=instance.pk,
                            user_id=getattr(user, 'id', None),
                            datetime=timezone.now(),
                            user_pk_as_string=str(user.pk) if user else user)
                except Exception as e:
                    logger.exception(
                        "easy audit had a pre-save exception on CRUDEvent creation. instance: {}, instance pk: {}"
                        .format(instance, instance.pk))
                    transaction.savepoint_rollback(sid)
    except Exception:
        logger.exception('easy audit had a pre-save exception.')
Exemple #13
0
def request_started_handler(sender, environ, **kwargs):
    if not should_log_url(environ['PATH_INFO']):
        return

    user = None

    if not USING_DRF:
        # get the user from cookies
        if environ.get('HTTP_COOKIE'):
            cookie = SimpleCookie()  # python3 compatibility
            cookie.load(environ['HTTP_COOKIE'])

            session_cookie_name = settings.SESSION_COOKIE_NAME
            if session_cookie_name in cookie:
                session_id = cookie[session_cookie_name].value

                try:
                    session = Session.objects.get(session_key=session_id)
                except Session.DoesNotExist:
                    session = None

                if session:
                    user_id = session.get_decoded().get('_auth_user_id')
                    try:
                        user = get_user_model().objects.get(id=user_id)
                    except:
                        user = None

        request_event = RequestEvent.objects.create(
            url=environ['PATH_INFO'],
            method=environ['REQUEST_METHOD'],
            query_string=environ['QUERY_STRING'],
            user=user,
            remote_ip=environ[REMOTE_ADDR_HEADER],
            datetime=timezone.now())

    # Use a Middleware to obtain the user from the Request
    else:
        if get_current_request():
            try:
                user = get_current_user()
            except:
                user = None
            else:
                request = get_current_request()

                query_dict = getattr(get_current_request(), 'GET')
                if query_dict:
                    query_string = ','.join([
                        '{}={}'.format(key, value)
                        for key, value in query_dict.items()
                    ])
                else:
                    query_string = ''

                request_event = RequestEvent.objects.create(
                    url=getattr(request, 'path_info'),
                    method=getattr(request, 'method'),
                    query_string=query_string,
                    user=user,
                    remote_ip=getattr(request, 'path_info'),
                    datetime=timezone.now())
def post_save(sender, instance, created, raw, using, update_fields, **kwargs):
    """https://docs.djangoproject.com/es/1.10/ref/signals/#post-save"""
    if raw:
        # Return if loading Fixtures
        return

    try:
        with transaction.atomic():
            if not should_audit(instance):
                return False
            object_json_repr = serializers.serialize("json", [instance])

            # created or updated?
            if created:
                event_type = CRUDEvent.CREATE

            # user
            try:
                user = get_current_user()
                # validate that the user still exists
                user = get_user_model().objects.get(pk=user.pk)
            except:
                user = None

            if isinstance(user, AnonymousUser):
                user = None

            # callbacks
            # make request available for callbacks
            kwargs['request'] = get_current_request()
            create_crud_event = all(
                callback(instance, object_json_repr, created, raw, using,
                         update_fields, **kwargs)
                for callback in CRUD_DIFFERENCE_CALLBACKS
                if callable(callback))

            # create crud event only if all callbacks returned True
            if create_crud_event and created:
                c_t = ContentType.objects.get_for_model(instance)
                sid = transaction.savepoint()
                try:
                    user_id = getattr(user, 'id', None)
                    if not user_id:
                        return None
                    try:
                        user_id = int(user_id)
                    except ValueError:
                        return None
                    with transaction.atomic():
                        CRUDEvent.objects.create(
                            event_type=event_type,
                            object_repr=str(instance),
                            object_json_repr=object_json_repr,
                            content_type_id=c_t.id,
                            object_id=instance.pk,
                            user_id=user_id,
                            datetime=timezone.now(),
                            user_pk_as_string=str(user.username)
                            if user else user)
                except Exception as e:
                    transaction.savepoint_rollback(sid)
    except Exception:
        logger.exception('easy audit had a post-save exception.')