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 ) except Exception: logger.exception('easy audit had a post-delete exception.')
def post_delete(sender, instance, using, **kwargs): """https://docs.djangoproject.com/es/1.10/ref/signals/#post-delete""" try: if not should_audit(instance): return False object_json_repr = content(instance) # user try: user = get_current_user() 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 ) except Exception as e: logger.exception('easy audit had a post-delete exception. %s' % e)
def post_delete(sender, instance, using, **kwargs): """https://docs.djangoproject.com/es/1.10/ref/signals/#post-delete""" 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) # 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 c_t = ContentType.objects.get_for_model(instance) def crud_flow(): try: with transaction.atomic(using=DATABASE_ALIAS): # crud event crud_event = audit_logger.crud({ 'event_type': CRUDEvent.DELETE, '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_delete 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-delete 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.')
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: c_t = ContentType.objects.get_for_model(instance) sid = transaction.savepoint() try: with transaction.atomic(): crud_event = 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=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: traceback.print_exc() logger.exception('easy audit had a post-save exception.')
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.')
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.')
def post_delete(sender, instance, using, **kwargs): """https://docs.djangoproject.com/es/1.10/ref/signals/#post-delete""" try: with transaction.atomic(using=using): 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 c_t = ContentType.objects.get_for_model(instance) def crud_flow(): try: with transaction.atomic(using=DATABASE_ALIAS): # crud event 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=CRUDEvent.DELETE, 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: logger.exception( "easy audit had a pre-save exception on CRUDEvent creation. instance: {}, instance pk: {}" .format(instance, instance.pk)) if getattr(settings, "TEST", False): crud_flow() else: transaction.on_commit(crud_flow, using=using) except Exception: logger.exception('easy audit had a post-delete exception.')
def m2m_changed(sender, instance, action, reverse, model, pk_set, using, **kwargs): """https://docs.djangoproject.com/es/1.10/ref/signals/#m2m-changed""" try: if not should_audit(instance): return False if action not in ("post_add",):# "post_remove", "post_clear"): return False # object_json_repr_tmp = content(instance, change=True) # print(object_json_repr_tmp) # object_json_repr = serializers.serialize("json", [instance]) # print(action) # print(instance._meta.model) # print(model) # print(pk_set) content = '把{}的{}修改为:'.format(str(instance), model._meta.verbose_name) content += ' '.join([str(i) for i in model.objects.filter(pk__in=pk_set)]) object_json_repr = content # 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() 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 ) except Exception as e: logger.exception('easy audit had an m2m-changed exception. %s' % e)
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())
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 if reverse: event_type = CRUDEvent.M2M_CHANGE_REV 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 c_t = ContentType.objects.get_for_model(instance) sid = transaction.savepoint() try: with transaction.atomic(): crud_event = CRUDEvent.objects.create( event_type=event_type, object_repr=str(instance), 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 an m2m-changed exception.')
def request_started_handler(sender, environ, **kwargs): if not should_log_url(environ['PATH_INFO']): return # get the user from request user = get_current_user() if user and user.is_anonymous: user = None # get the user from cookies if not user and 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=get_client_ip(record('FakeRequest', { 'META': environ })), browser=get_client_browser_info(record('FakeRequest', { 'META': environ })), operating_system=get_client_operating_system_info(record('FakeRequest', { 'META': environ })), datetime=timezone.now())
def post_delete(sender, instance, using, **kwargs): """https://docs.djangoproject.com/es/1.10/ref/signals/#post-delete""" # 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(): 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 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 # crud event crud_event = CRUDEvent.objects.using(using).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 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-delete exception.')
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 c_t = ContentType.objects.get_for_model(instance) sid = transaction.savepoint() try: with transaction.atomic(): # crud event crud_event = CRUDEvent.objects.create( event_type=CRUDEvent.DELETE, 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: 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: traceback.print_exc() logger.exception('easy audit had a post-delete exception.')
def request_started_handler(sender, environ, **kwargs): if not should_log_url(environ['PATH_INFO']): return # try and get the user from the request user = get_current_user() # get the user from cookies if not user and 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 = audit_logger.request({ 'url': environ['PATH_INFO'], 'method': environ['REQUEST_METHOD'], 'query_string': environ['QUERY_STRING'], 'user_id': getattr(user, 'id', None), 'remote_ip': environ[REMOTE_ADDR_HEADER], 'datetime': timezone.now() })
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)
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.')
def m2m_changed(sender, instance, action, reverse, model, pk_set, using, **kwargs): """https://docs.djangoproject.com/es/1.10/ref/signals/#m2m-changed""" # 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 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 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 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 an m2m-changed exception.')
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(using=using): 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]) object_json_repr = scrub_sensitive_fields_object_json_repr( object_json_repr) 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 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 m2m_changed 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 an m2m-changed exception.')
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.')
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 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, 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 an m2m-changed exception.')
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())