def handler500(request): """500 Handler.""" print colored("***" * 27, "green") print colored("*** INSIDE `%s`" % inspect.stack()[0][3], "green") try: clear_cache.Command().handle() # --------------------------------------------------------------------- # --- Save the Log papertrail.log( event_type="500-exception", message="Cache cleared", data={ "success": True, }, # timestamp=timezone.now(), targets={}, ) except Exception as e: print colored("###" * 27, "white", "on_red") print colored("### EXCEPTION @ `{module}`: {msg}".format( module=inspect.stack()[0][3], msg=str(e), ), "white", "on_red") return render(request, "error-pages/500.html", status=500)
def test_json_field_filtering(self): log('test', 'test', data={ 'field': 'value', }) self.assertTrue( Entry.objects.filter(data__field='value').exists() )
def save(self, *args, **kwargs): papertrail.log("Country", serializers.serialize("json", [ self, ]), data=serializers.serialize("json", [ self, ])) super(Country, self).save(*args, **kwargs)
def test_signals(self): event_logged_counter = [0] @receiver(signals.event_logged) def on_event_logged(sender, **kwargs): event_logged_counter[0] += 1 log('test', 'Testing signal') self.assertEqual(event_logged_counter[0], 1)
def topic_post_edit(request, topic_post_id): """Docstring.""" print colored("***" * 27, "green") print colored("*** INSIDE `%s`" % inspect.stack()[0][3], "green") # ------------------------------------------------------------------------- # --- Retrieve Topic # ------------------------------------------------------------------------- topic = get_object_or_404( Topic, id=topic_post_id, ) # ------------------------------------------------------------------------- # --- Prepare Form(s) # ------------------------------------------------------------------------- form = CreateEditTopicForm(request.POST or None, request.FILES or None, user=request.user, instance=topic) if request.method == "POST": if form.is_valid(): topic = form.save(commit=False) topic.save() # ----------------------------------------------------------------- # --- Save the Log papertrail.log( event_type="forum-topic-post-edited", message="Forum Topic Post was edited", data={ "user": request.user.email, "author": topic.author.email, "title": topic.title, }, # timestamp=timezone.now(), targets={ "user": request.user, "author": topic.author, "forum": topic.forum, "topic": topic, "post": topic, }, ) return HttpResponseRedirect( reverse("topic-list", kwargs={ "forum_id": topic.forum_id, })) return render(request, "forum/topic-post-edit.html", { "topic": topic, "form": form, })
def index(request): papertrail.log( 'hello-world', 'Hi!', targets={ 'user': request.user if request.user.is_authenticated else None, }, data={ 'now': timezone.now(), }, ) return HttpResponse("Hello, world.")
def forum_edit(request, forum_id): """Docstring.""" print colored("***" * 27, "green") print colored("*** INSIDE `%s`" % inspect.stack()[0][3], "green") # ------------------------------------------------------------------------- # --- Retrieve Forum # ------------------------------------------------------------------------- forum = get_object_or_404( Forum, id=forum_id, ) # ------------------------------------------------------------------------- # --- Prepare Form(s) # ------------------------------------------------------------------------- form = CreateEditForumForm( request.POST or None, request.FILES or None, user=request.user, instance=forum, ) if request.method == "POST": if form.is_valid(): forum = form.save(commit=False) forum.save() # ----------------------------------------------------------------- # --- Save the Log papertrail.log( event_type="forum-edited", message="Forum was edited", data={ "user": request.user.email, "author": forum.author.email, "title": forum.title, }, # timestamp=timezone.now(), targets={ "user": request.user, "author": forum.author, "forum": forum, }, ) return redirect("forum-list") return render(request, "forum/forum-edit.html", { "forum": forum, "form": form, })
def test_objects_represented(self): user1 = User.objects.create_user('testuser1', '*****@*****.**') user2 = User.objects.create_user('testuser2', '*****@*****.**') user3 = User.objects.create_user('testuser3', '*****@*****.**') some_group = Group.objects.create(name='some group') some_group2 = Group.objects.create(name='some group 2') some_group3 = Group.objects.create(name='some group 3') log('test-entry', 'Test 1', targets={ 'user': user1, 'group': some_group }) log('test-entry', 'Test 2', targets={ 'user': user2, 'group': some_group }) log('test-entry', 'Test 3', targets={ 'user': user2, 'group': some_group2 }) log('test-entry', 'Test 4', targets={ 'blah': user1, 'group': some_group3 }) all_users = User.objects.all() self.assertEqual( set( Entry.objects.filter(type='test-entry').objects_represented( all_users, 'user')), set([user1, user2])) self.assertEqual( set( Entry.objects.filter(type='test-entry').related_to( group=some_group).objects_represented(all_users, 'user')), set([user1, user2]), ) self.assertEqual( Entry.objects.filter(type='test-entry').related_to( group=some_group2).objects_represented(all_users, 'user').get(), user2, ) self.assertTrue( Entry.objects.filter(type='test-entry').related_to( group=some_group3).exists(), ) self.assertFalse( Entry.objects.filter(type='test-entry').related_to( group=some_group3).objects_represented(all_users, 'user').exists(), ) self.assertEqual( Entry.objects.filter(type='test-entry').objects_not_represented( all_users, 'user').get(), user3)
def test_setters_and_getters(self): e = log('test-entry', 'Test Entry') self.assertEqual(e.targets_map, {}) user = User.objects.create_user('testuser', '*****@*****.**') e.set('target1', user) # Basic lookup self.assertEqual(e.get('target1'), user) self.assertEqual(e['target1'], user) # Invalid key lookup and getting a default for non-existent targets with self.assertRaises(KeyError): e['target2'] self.assertEqual(e.get('target2'), None) self.assertEqual(e.get('target2', 'a-default-value'), 'a-default-value') # Contains ('in') implementation self.assertTrue('target1' in e) self.assertFalse('target2' in e) # Setting and retrieving a 'virtual' target user_type = ContentType.objects.get_for_model(User) e.set('virtual', (user_type, 10000)) self.assertEqual(e['virtual'], None) self.assertEqual(e.get('virtual', 'a-default-value'), None)
def log_addition(self, request, object, message=None): if message is not None: super(AdminEventLoggerMixin, self).log_addition(request, object, message) try: message = json.loads(message) except ValueError: pass else: super(AdminEventLoggerMixin, self).log_addition(request, object) fields = self._record_changes(object)['fields'] return papertrail.log( 'admin-edit', 'Created object', data={ 'action': 'add', 'fields': fields, 'message': message, }, targets={ 'acting_user': request.user, 'instance': self._resolve_pt_object(object), }, )
def test_change_related_object(self): user1 = User.objects.create_user('testuser1', '*****@*****.**') user2 = User.objects.create_user('testuser2', '*****@*****.**') Entry.objects.all().delete() log('test-entry', 'This is a test entry', targets={'user': user1}) log('test-entry', 'This is a test entry', targets={'user': user2}) qs = Entry.objects.all() self.assertEqual(qs.related_to(user1).count(), 1) self.assertEqual(qs.related_to(user2).count(), 1) replace_object_in_papertrail(user1, user2) qs = Entry.objects.all() self.assertEqual(qs.related_to(user1).count(), 0) self.assertEqual(qs.related_to(user2).count(), 2)
def log_deletion(self, request, object, object_repr): super(AdminEventLoggerMixin, self).log_deletion(request, object, object_repr) fields = self._record_changes(object)['fields'] return papertrail.log('admin-edit', 'Deleted object', data={'action': 'add', 'fields': fields}, targets={ 'acting_user': request.user, 'instance': object })
def insert(self, request, user=None, provider="Desktop", **extra_fields): """Docstring.""" try: g = GeoIP() ip = get_client_ip(request) if not user: user = request.user login = self.model( user=user, ip=ip, provider=provider, country=g.country(ip), city=g.city(ip), **extra_fields ) login.save(using=self._db) return login except Exception as e: print colored("###" * 27, "white", "on_red") print colored("### EXCEPTION @ `{module}`: {msg}".format( module=inspect.stack()[0][3], msg=str(e), ), "white", "on_red") # ----------------------------------------------------------------- # --- Save the Log. papertrail.log( event_type="exception-insert-user-login", message="Exception: Insert User Login Entry", data={ "user": user if user else request.user.email, "message": str(e), }, # timestamp=timezone.now(), targets={ "user": user if user else request.user, }, )
def wrapper(*args, **kwargs): try: return func(*args, **kwargs) except Exception as e: # ----------------------------------------------------------------- # --- Save the Log papertrail.log( event_type="runtime-exception", message="There was an exception in " + func.__name__, data={ "success": False, "origin": func.__name__, "response": str(e), }, # timestamp=timezone.now(), targets={}, ) # ----------------------------------------------------------------- # --- Re-raise the Exception raise
def log_change(self, request, object, message): super(AdminEventLoggerMixin, self).log_change(request, object, message) # construct_change_message() creates a JSON message that we load and # store here. (In case we don't get JSON back for some reason, still # store the message) try: data = {'changes': json.loads(message)} except ValueError: data = {'message': message} return papertrail.log('admin-edit', 'Updated object', data=data, targets={ 'acting_user': request.user, 'instance': object })
def log_deletion(self, request, object, object_repr): super(AdminEventLoggerMixin, self).log_deletion(request, object, object_repr) fields = self._record_changes(object)['fields'] return papertrail.log( 'admin-edit', 'Deleted object', data={ 'action': 'delete', 'fields': fields, }, targets={ 'acting_user': request.user, 'instance': self._resolve_pt_object(object), }, )
def log_change(self, request, object, message): super(AdminEventLoggerMixin, self).log_change(request, object, message) # construct_change_message() creates a JSON message that we load and # store here. (In case we don't get JSON back for some reason, still # store the message) try: data = {'changes': json.loads(message), 'action': 'change'} except ValueError: data = {'message': message, 'action': 'change'} return papertrail.log( 'admin-edit', 'Updated object', data=data, targets={ 'acting_user': request.user, 'instance': self._resolve_pt_object(object), }, )
def test_objects_represented(self): user1 = User.objects.create_user('testuser1', '*****@*****.**') user2 = User.objects.create_user('testuser2', '*****@*****.**') user3 = User.objects.create_user('testuser3', '*****@*****.**') some_group = Group.objects.create(name='some group') some_group2 = Group.objects.create(name='some group 2') some_group3 = Group.objects.create(name='some group 3') log('test-entry', 'Test 1', targets={'user': user1, 'group': some_group}) log('test-entry', 'Test 2', targets={'user': user2, 'group': some_group}) log('test-entry', 'Test 3', targets={'user': user2, 'group': some_group2}) log('test-entry', 'Test 4', targets={'blah': user1, 'group': some_group3}) all_users = User.objects.all() self.assertEqual( set(Entry.objects.filter(type='test-entry').objects_represented(all_users, 'user')), set([user1, user2]) ) self.assertEqual( set(Entry.objects.filter(type='test-entry').related_to(group=some_group).objects_represented(all_users, 'user')), set([user1, user2]), ) self.assertEqual( Entry.objects.filter(type='test-entry').related_to(group=some_group2).objects_represented(all_users, 'user').get(), user2, ) self.assertTrue( Entry.objects.filter(type='test-entry').related_to(group=some_group3).exists(), ) self.assertFalse( Entry.objects.filter(type='test-entry').related_to(group=some_group3).objects_represented(all_users, 'user').exists(), ) self.assertEqual( Entry.objects.filter(type='test-entry').objects_not_represented(all_users, 'user').get(), user3 )
def rebuild_search_indexes(): """Rebuild/update Search Indexes. https://stackoverflow.com/questions/4358771/updating-a-haystack-search-index-with-django-celery """ print colored("***" * 27, "green") print colored("*** INSIDE `%s`" % inspect.stack()[0][3], "green") print colored("[--- LOG ---] Going to rebuild Search Indexes...", "green") try: rebuild_index.Command().handle(age=4, batchsize=1000, workers=0, max_retries=5, interactive=False, remove=True, verbosity=2, using=[ "default", ]) """ update_index.Command().handle( age=4, interactive=False, remove=True, verbosity=2, using=["default", ]) """ # --------------------------------------------------------------------- # --- Save the Log papertrail.log( event_type="periodic-task-ran", message="Periodic Task `%s` executed" % inspect.stack()[0][3], data={ "success": True, }, # timestamp=timezone.now(), targets={}, ) except Exception as e: print colored("###" * 27, "white", "on_red") print colored( "### EXCEPTION @ `{module}`: {msg}".format( module=inspect.stack()[0][3], msg=str(e), ), "white", "on_red") # --------------------------------------------------------------------- # --- Save the Log papertrail.log( event_type="periodic-task-failed", message="Periodic Task `%s` failed" % inspect.stack()[0][3], data={ "success": False, "response": str(e), }, # timestamp=timezone.now(), targets={}, ) return True
def test_entry_logging(self): log('test', 'Testing entry') user = User.objects.create_user('testuser', '*****@*****.**') log('test-user-created', 'User created', targets={'user': user}) group = Group.objects.create(name='Test Group') log('test-group-created', 'Group created', targets={'group': group}) group.user_set.add(user) log('test-group-added-user', 'User added to group', targets={'user': user, 'group': group}) log('test-extra-data', 'Testing extra data', data={'key': 'value'}) tznow = timezone.now() overridden_timestamp_entry = log( 'test-overridden-timestamp', 'Testing overriding a timestamp for operations like importing', timestamp=tznow, ) self.assertEqual(tznow, overridden_timestamp_entry.timestamp) qs = Entry.objects.filter(type__startswith='test') self.assertEqual(qs.count(), 6) self.assertEqual(qs.related_to(user).count(), 2) self.assertEqual(qs.related_to(group).count(), 2) self.assertEqual(qs.related_to(user=user).count(), 2) self.assertEqual(qs.related_to(group=group).count(), 2) self.assertEqual(qs.related_to(user=group).count(), 0) self.assertEqual(qs.related_to(group=user).count(), 0) self.assertEqual(qs.related_to(user, group).count(), 1) self.assertEqual(qs.related_to(user=user, group=group).count(), 1) # test chaining and equivalence self.assertEqual(set(qs.related_to(user=user) .related_to(group=group) .values_list('id', flat=True)), set(qs.related_to(user=user, group=group) .values_list('id', flat=True))) # test related_to Q object self.assertEqual(set(qs.related_to(user, group) .values_list('id', flat=True)), set(qs.filter(related_to_q(user)) .filter(related_to_q(group)) .values_list('id', flat=True))) self.assertEqual(qs.filter(related_to_q(user) | related_to_q(group)) .distinct().count(), 3)
def post(self, request, invite_id): """POST: Invite create. Receive: organization_id :uint: group_name :str: group_description :str: Return: status 200/400/404/500 Example Payload: { "group_name": "Name", "group_description": "Description" } """ print colored("***" * 27, "green") print colored( "*** INSIDE `%s.%s`" % (self.__class__.__name__, inspect.stack()[0][3]), "green") # --------------------------------------------------------------------- # --- Retrieve Data from the Request. # --------------------------------------------------------------------- print colored("[--- DUMP ---] INVITE ID : %s" % invite_id, "yellow") # --------------------------------------------------------------------- # --- Handle Errors. # --------------------------------------------------------------------- if not invite_id: return Response({ "message": _("No Invite ID provided."), }, status=status.HTTP_400_BAD_REQUEST) # --------------------------------------------------------------------- # --- Retrieve the Invite. # --------------------------------------------------------------------- invite = get_object_or_None( Invite, id=invite_id, inviter=request.user, ) if not invite: return Response({ "message": _("Invite not found."), }, status=status.HTTP_404_NOT_FOUND) if invite.status != INVITE_STATUS.NEW: return Response( { "message": _("Invite Status has been changed already."), }, status=status.HTTP_400_BAD_REQUEST) invite.status = INVITE_STATUS.REVOKED invite.date_revoked = datetime.datetime.now() invite.save() # --------------------------------------------------------------------- # --- Send Email Notifications. # --------------------------------------------------------------------- invite.email_notify_invitee_inv_revoked(request) invite.email_notify_inviter_inv_revoked(request) # --------------------------------------------------------------------- # --- Save the Log. # --------------------------------------------------------------------- papertrail.log( event_type="invite-revoked", message="Invite was revoked", data={ "inviter": invite.inviter.email, "invitee": invite.invitee.email, "object": invite.content_object.name, }, # timestamp=timezone.now(), targets={ "inviter": invite.inviter, "invitee": invite.invitee, "object": invite.content_object, }, ) return Response( { "message": _("Successfully revoked the Invitation."), }, status=status.HTTP_200_OK)
def post(self, request): """POST: Invite create. Invite to the Challenge, Organization Staff or Group with Challenge and Organization Privacy Settings. Receive: invitee_id :uint: challenge_id :uint: organization_id :uint: org_group_id :uint: invitation_text :str: Return: status 200/400/404/500 Example Payload: { "invitee_id": 1, "organization_id": 100, "invitation_text": "Invitation Text" } """ print colored("***" * 27, "green") print colored( "*** INSIDE `%s.%s`" % (self.__class__.__name__, inspect.stack()[0][3]), "green") # --------------------------------------------------------------------- # --- Retrieve Data from the Request. # --------------------------------------------------------------------- invitee_id = request.data.get("invitee_id", "") challenge_id = request.data.get("challenge_id", "") organization_id = request.data.get("organization_id", "") org_group_id = request.data.get("org_group_id", "") invitation_text = request.data.get("invitation_text", "") print colored("[--- DUMP ---] INVITEE ID : %s" % invitee_id, "yellow") print colored("[--- DUMP ---] CHALLENGE ID : %s" % challenge_id, "yellow") print colored( "[--- DUMP ---] ORGANIZATION ID : %s" % organization_id, "yellow") print colored("[--- DUMP ---] ORG GROUP ID : %s" % org_group_id, "yellow") print colored( "[--- DUMP ---] INVITATION TEXT : %s" % invitation_text, "yellow") # --------------------------------------------------------------------- # --- Handle Errors. # --------------------------------------------------------------------- if not invitee_id: return Response({ "message": _("No Invitee ID provided."), }, status=status.HTTP_400_BAD_REQUEST) if not challenge_id and not organization_id and not org_group_id: return Response( { "message": _("Neither Challenge, nor Organization, nor Organization Group ID provided." ), }, status=status.HTTP_400_BAD_REQUEST) if not invitation_text: return Response({ "message": _("No Invitation Text provided."), }, status=status.HTTP_400_BAD_REQUEST) # --------------------------------------------------------------------- # --- Retrieve the Invitee. # --------------------------------------------------------------------- invitee = get_object_or_None( User, id=invitee_id, ) if not invitee: return Response({ "message": _("Invitee not found."), }, status=status.HTTP_404_NOT_FOUND) print colored("[--- INFO ---] FOUND INVITEE : %s" % invitee, "cyan") # --------------------------------------------------------------------- # --- Retrieve the Challenge. # --------------------------------------------------------------------- if challenge_id: print colored("[--- LOG ---] Going to retrieve the Challenge", "green") challenge = get_object_or_None( Challenge, Q(Q(organization=None) & Q(author=request.user), ) | Q( Q(organization__pk__in=OrganizationStaff.objects.filter( member=request.user, ).values_list("organization_id", flat=True)), ), id=challenge_id, ) if not challenge: return Response({ "message": _("Challenge not found."), }, status=status.HTTP_404_NOT_FOUND) content_type = ContentType.objects.get_for_model(challenge) object_id = challenge.id print colored("[--- INFO ---] FOUND CHALLENGE : %s" % challenge, "cyan") # --------------------------------------------------------------------- # --- Retrieve the Organization. # --------------------------------------------------------------------- if organization_id: print colored( "[--- LOG ---] Going to retrieve the Organization", "green") vals = OrganizationStaff.objects.filter( member=request.user, ).values_list("organization_id", flat=True) print colored("[--- DUMP ---] %s" % vals, "yellow") organization = get_object_or_None( Organization, Q(author=request.user) | Q(pk__in=OrganizationStaff.objects.filter( member=request.user, ).values_list("organization_id", flat=True)), id=organization_id, is_deleted=False, ) if not organization: return Response({ "message": _("Organization not found."), }, status=status.HTTP_404_NOT_FOUND) content_type = ContentType.objects.get_for_model(organization) object_id = organization.id print colored( "[--- INFO ---] FOUND ORGANIZATION : %s" % organization, "cyan") # --------------------------------------------------------------------- # --- Retrieve the Organization Group. # --------------------------------------------------------------------- if org_group_id: print colored("[--- LOG ---] Going to retrieve the Org Group", "green") org_group = get_object_or_None( OrganizationGroup, id=org_group_id, organization=organization, ) if not org_group: return Response( { "message": _("Organization Group not found."), }, status=status.HTTP_404_NOT_FOUND) content_type = ContentType.objects.get_for_model(org_group) object_id = org_group.id print colored("[--- INFO ---] FOUND ORG GROUP : %s" % org_group, "cyan") # --------------------------------------------------------------------- # --- Create/retrieve the Invite. # --------------------------------------------------------------------- invite, created = Invite.objects.get_or_create( inviter=request.user, invitee=invitee, content_type=content_type, object_id=object_id) invite.status = INVITE_STATUS.NEW invite.invitation_text = invitation_text invite.save() # --------------------------------------------------------------------- # --- Send Email Notifications. # --------------------------------------------------------------------- invite.email_notify_invitee_inv_created(request) invite.email_notify_inviter_inv_created(request) # --------------------------------------------------------------------- # --- Save the Log. # --------------------------------------------------------------------- papertrail.log( event_type="invite-created", message="Invite was created", data={ "inviter": request.user.email, "invitee": invitee.email, "object": invite.content_object.name, }, # timestamp=timezone.now(), targets={ "inviter": request.user, "invitee": invitee, "object": invite.content_object, }, ) return Response({ "message": _("Successfully sent the Invitation."), }, status=status.HTTP_200_OK)
def audit_log(*args, **kwargs): if settings.AUDIT: papertrail.log(*args, **kwargs)
def post(self, request, invite_id): """POST: Invite create. Receive: invite_id :uint: Return: status 200/400/404/500 Example Payload: { "invite_id": 100, } """ print colored("***" * 27, "green") print colored( "*** INSIDE `%s.%s`" % (self.__class__.__name__, inspect.stack()[0][3]), "green") # --------------------------------------------------------------------- # --- Retrieve Data from the Request. # --------------------------------------------------------------------- print colored("[--- DUMP ---] INVITE ID : %s" % invite_id, "yellow") # --------------------------------------------------------------------- # --- Handle Errors. # --------------------------------------------------------------------- if not invite_id: return Response({ "message": _("No Invite ID provided."), }, status=status.HTTP_400_BAD_REQUEST) # --------------------------------------------------------------------- # --- Retrieve the Invite. # --------------------------------------------------------------------- invite = get_object_or_None( Invite, id=invite_id, invitee=request.user, ) if not invite: return Response({ "message": _("Invite not found."), }, status=status.HTTP_404_NOT_FOUND) if invite.status != INVITE_STATUS.NEW: return Response( { "message": _("Invite Status has been changed already."), }, status=status.HTTP_400_BAD_REQUEST) invite.status = INVITE_STATUS.ACCEPTED invite.date_accepted = datetime.datetime.now() invite.save() # --------------------------------------------------------------------- # --- Make the Invitee a Challenge Participant. if invite.content_type.name == "challenge": # ----------------------------------------------------------------- # --- Create a Participation. participation, created = Participation.objects.get_or_create( user=invite.invitee, challenge=invite.content_object, ) participation.application_text =\ "Joined by Invitation from " + invite.inviter.get_full_name() participation.date_created = datetime.datetime.now() participation.status = PARTICIPATION_STATUS.CONFIRMED participation.date_accepted = datetime.datetime.now() participation.save() # --------------------------------------------------------------------- # --- Make the Invitee an Organization Staff Member. elif invite.content_type.name == "organization": org_staff_member, created =\ OrganizationStaff.objects.get_or_create( author=invite.inviter, organization=invite.content_object, member=invite.invitee, ) invite.content_object.subscribers.add(invite.invitee) invite.content_object.save() # --------------------------------------------------------------------- # --- Make the Invitee an Organization Group Member. elif invite.content_type.name == "organization group": invite.content_object.members.add(invite.invitee) invite.content_object.save() # --------------------------------------------------------------------- # --- Send Email Notifications. # --------------------------------------------------------------------- invite.email_notify_invitee_inv_accepted(request) invite.email_notify_inviter_inv_accepted(request) # --------------------------------------------------------------------- # --- Save the Log. # --------------------------------------------------------------------- papertrail.log( event_type="invite-accepted", message="Invite was accepted", data={ "inviter": invite.inviter.email, "invitee": invite.invitee.email, "object": invite.content_object.name, }, # timestamp=timezone.now(), targets={ "inviter": invite.inviter, "invitee": invite.invitee, "object": invite.content_object, }, ) return Response( { "message": _("Successfully accepted the Invitation."), }, status=status.HTTP_200_OK)
def post(self, request): """POST: Forgot Password notify. Receive: email :str: Return: status 200/400/404/500 Example Payload: { "email": "*****@*****.**", } """ print colored("***" * 27, "green") print colored( "*** INSIDE `%s.%s`" % (self.__class__.__name__, inspect.stack()[0][3]), "green") # --------------------------------------------------------------------- # --- Retrieve Data from the Request # --------------------------------------------------------------------- email = request.data.get("email", "") print colored("[--- DUMP ---] EMAIL : %s" % email, "yellow") # --------------------------------------------------------------------- # --- Handle Errors # --------------------------------------------------------------------- if not email: return Response({ "message": _("No Email provided."), }, status=status.HTTP_400_BAD_REQUEST) # --------------------------------------------------------------------- # --- Retrieve the User # --------------------------------------------------------------------- try: user = get_object_or_None( User, email=email, ) except Exception as e: print colored("###" * 27, "white", "on_red") print colored( "### EXCEPTION @ `{module}`: {msg}".format( module=inspect.stack()[0][3], msg=str(e), ), "white", "on_red") return Response( { "message": _("Failed to send the Password Renewal Link."), }, status=status.HTTP_400_BAD_REQUEST) if not user: return Response({ "message": _("User not found."), }, status=status.HTTP_404_NOT_FOUND) print colored("[--- INFO ---] FOUND USER : %s" % user, "cyan") # --------------------------------------------------------------------- # --- Send the Password Renewal Link # --------------------------------------------------------------------- try: uidb36 = int_to_base36(user.id) token = token_generator.make_token(user) DOMAIN_NAME = request.get_host() url = reverse("password-renew", kwargs={ "uidb36": uidb36, "token": token, }) confirmation_link = "http://{domain}{url}".format( domain=DOMAIN_NAME, url=url, ) # ----------------------------------------------------------------- # --- Send Email Notification(s) user.profile.email_notify_password_reset(request=request, url=confirmation_link) except Exception as e: print colored("###" * 27, "white", "on_red") print colored( "### EXCEPTION @ `{module}`: {msg}".format( module=inspect.stack()[0][3], msg=str(e), ), "white", "on_red") # ----------------------------------------------------------------- # --- Save the Log papertrail.log( event_type="exception-forgot-password-notify", message="Exception: Forgot Password notify", data={ "user": user if user else request.user.email, "message": str(e), }, # timestamp=timezone.now(), targets={ "user": user if user else request.user, }, ) return Response( { "message": _("Failed to send the Password Renewal Link."), }, status=status.HTTP_400_BAD_REQUEST) return Response( { "message": _("Successfully sent the Password Renewal Link."), }, status=status.HTTP_200_OK)
def send_templated_email( to, template_subj, template_text, template_html=None, template_id=None, substitutions={}, from_email=settings.EMAIL_SENDER, headers={}, cc=[], bcc=[]): """Send templated Email. This is new Version, which uses SendGrid HTML Template to be sent. """ print colored("***" * 27, "green") print colored("*** INSIDE `%s`" % inspect.stack()[0][3], "green") try: # --------------------------------------------------------------------- # Prepare Email to be sent subj_content = render_to_string( template_subj["name"], template_subj["context"], ) subj_content = "".join(subj_content.splitlines()) text_content = render_to_string( template_text["name"], template_text["context"], ) mail = EmailMultiAlternatives( subject=subj_content, body=text_content, from_email=from_email, to=to, cc=cc, bcc=bcc, headers=headers, ) # --------------------------------------------------------------------- # --- 1. Add Template ID # --- 2. Replace Substitutions in SendGrid Template if template_id: mail.template_id = template_id mail.substitutions = substitutions # --------------------------------------------------------------------- # --- Attach Alternative if template_html: html_content = render_to_string( template_html["name"], template_html["context"], ) mail.attach_alternative(html_content, "text/html") # --------------------------------------------------------------------- # --- Send Email mail.send() return True except Exception as e: print colored("###" * 27, "white", "on_red") print colored("### EXCEPTION @ `{module}`: {msg}".format( module=inspect.stack()[0][3], msg=str(e), ), "white", "on_red") # --------------------------------------------------------------------- # --- Save the Log papertrail.log( event_type="exception-send-templated-email", message="Exception: Send templated Email", data={ "to": to, "from": from_email, "message": str(e), }, # timestamp=timezone.now(), targets={}, ) return False
def test_entry_logging(self): log('test', 'Testing entry') user = User.objects.create_user('testuser', '*****@*****.**') log('test-user-created', 'User created', targets={'user': user}) group = Group.objects.create(name='Test Group') log('test-group-created', 'Group created', targets={'group': group}) group.user_set.add(user) log('test-group-added-user', 'User added to group', targets={ 'user': user, 'group': group }) log('test-extra-data', 'Testing extra data', data={'key': 'value'}) tznow = timezone.now() overridden_timestamp_entry = log( 'test-overridden-timestamp', 'Testing overriding a timestamp for operations like importing', timestamp=tznow, ) self.assertEqual(tznow, overridden_timestamp_entry.timestamp) qs = Entry.objects.filter(type__startswith='test') self.assertEqual(qs.count(), 6) self.assertEqual(qs.related_to(user).count(), 2) self.assertEqual(qs.related_to(group).count(), 2) self.assertEqual(qs.related_to(user=user).count(), 2) self.assertEqual(qs.related_to(group=group).count(), 2) self.assertEqual(qs.related_to(user=group).count(), 0) self.assertEqual(qs.related_to(group=user).count(), 0) self.assertEqual(qs.related_to(user, group).count(), 1) self.assertEqual(qs.related_to(user=user, group=group).count(), 1) # test chaining and equivalence self.assertEqual( set( qs.related_to(user=user).related_to(group=group).values_list( 'id', flat=True)), set( qs.related_to(user=user, group=group).values_list('id', flat=True))) # test related_to Q object self.assertEqual( set(qs.related_to(user, group).values_list('id', flat=True)), set( qs.filter(related_to_q(user)).filter( related_to_q(group)).values_list('id', flat=True))) self.assertEqual( qs.filter(related_to_q(user) | related_to_q(group)).distinct().count(), 3)
def test_json_field_filtering(self): log('test', 'test', data={ 'field': 'value', }) self.assertTrue(Entry.objects.filter(data__field='value').exists())
def post(self, request): """POST: Email Update. Receive: email :str: Return: status 200/400/404/500 Example Payload: { "email": "*****@*****.**", } """ print colored("***" * 27, "green") print colored( "*** INSIDE `%s.%s`" % (self.__class__.__name__, inspect.stack()[0][3]), "green") # --------------------------------------------------------------------- # --- Retrieve Data from the Request # --------------------------------------------------------------------- email = request.data.get("email", "") print colored("[--- DUMP ---] EMAIL : %s" % email, "yellow") # --------------------------------------------------------------------- # --- Handle Errors # --------------------------------------------------------------------- if not email: return Response({ "message": _("No Email provided."), }, status=status.HTTP_400_BAD_REQUEST) # --------------------------------------------------------------------- # --- TODO : Validate Email # --------------------------------------------------------------------- # --------------------------------------------------------------------- # --- Update Email # --------------------------------------------------------------------- try: request.user.email = email request.user.save() # ----------------------------------------------------------------- # --- Send Email Notification(s) except Exception as e: print colored("###" * 27, "white", "on_red") print colored( "### EXCEPTION @ `{module}`: {msg}".format( module=inspect.stack()[0][3], msg=str(e), ), "white", "on_red") # ----------------------------------------------------------------- # --- Failed to update the Email # --- Save the Log papertrail.log( event_type="email-update-failed", message="email update failed", data={ "email": email, }, # timestamp=timezone.now(), targets={ "user": request.user, }, ) return Response({ "message": _("Failed to update the Email."), }, status=status.HTTP_400_BAD_REQUEST) return Response({ "message": _("Successfully updated the Email."), }, status=status.HTTP_200_OK)
def save_profile(strategy, backend, uid, response, details, user, social, request, is_new=False, *args, **kwargs): """Docstring.""" print colored("***" * 27, "green") print colored("*** INSIDE `%s`" % inspect.stack()[0][3], "green") print colored("[--- DUMP ---] STRATEGY : %s" % strategy, "yellow") print colored("[--- DUMP ---] BACKEND : %s" % backend, "yellow") print colored("[--- DUMP ---] UID : %s" % uid, "yellow") print colored("[--- DUMP ---] RESPONSE : %s" % response, "yellow") print colored("[--- DUMP ---] DETAILS : %s" % details, "yellow") print colored("[--- DUMP ---] USER : %s" % user, "yellow") print colored("[--- DUMP ---] SOCIAL : %s" % social, "yellow") avatar_url = "" try: profile = user.profile except Exception as e: print colored("###" * 27, "white", "on_red") print colored( "### EXCEPTION @ `{module}`: {msg}".format( module=inspect.stack()[0][3], msg=str(e), ), "white", "on_red") profile = UserProfile.objects.create(user=user) # ------------------------------------------------------------------------- # --- FACEBOOK. # ------------------------------------------------------------------------- if is_new and backend.name == "facebook": # profile.gender = response.get("gender").capitalize() profile.fb_profile = response.get("link") avatar_url =\ "http://graph.facebook.com/{id}/picture?type=large".format( id=response.get("id"),) # ------------------------------------------------------------------------- # --- LINKEDIN. # ------------------------------------------------------------------------- if backend.name == "linkedin": pass # ------------------------------------------------------------------------- # --- GOOGLE-PLUS. # ------------------------------------------------------------------------- if backend.name == "google-oauth2": if response.get("image") and response["image"].get("url"): avatar_url = response["image"].get("url") # ------------------------------------------------------------------------- # --- Import social Profile Avatar. # ------------------------------------------------------------------------- if (avatar_url and (is_new or not profile.avatar)): try: response = requests.get(avatar_url) response.raise_for_status() except HTTPError: pass else: profile.avatar.save( "{username}_social.jpg".format(username=user.username, ), ContentFile(response.content)) else: # --------------------------------------------------------------------- # --- If existing Avatar, stick with it. pass profile.save() # ------------------------------------------------------------------------- # --- Track IP. # ------------------------------------------------------------------------- UserLogin.objects.insert( request=strategy.request, user=user, provider=backend.name, ) # ------------------------------------------------------------------------- # --- Save the Log. papertrail.log( event_type="user-logged-in-social", message="User logged in through social Network", data={ "backend": backend.name, "details": details, "user": user if user else request.user.email, "is_new": is_new, }, # timestamp=timezone.now(), targets={ "user": user if user else request.user, }, )
def post(self, request, organization_id): """POST: Organization Group remove. Receive: organization_id :uint: group_id :uint: reason :str: Return: status 200/400/404/500 Example Payload: { "group_id": 1, "reason": "Reason", } """ print colored("***" * 27, "green") print colored( "*** INSIDE `%s.%s`" % (self.__class__.__name__, inspect.stack()[0][3]), "green") # --------------------------------------------------------------------- # --- Retrieve Data from the Request # --------------------------------------------------------------------- group_id = request.data.get("group_id", "") reason = request.data.get("reason", "") print colored( "[--- DUMP ---] ORGANIZATION ID : %s" % organization_id, "yellow") print colored("[--- DUMP ---] GROUP ID : %s" % group_id, "yellow") print colored("[--- DUMP ---] REASON : %s" % reason, "yellow") # --------------------------------------------------------------------- # --- Handle Errors # --------------------------------------------------------------------- if not organization_id or not group_id: return Response( { "message": _("No Organization/Group ID provided."), }, status=status.HTTP_400_BAD_REQUEST) if not reason: return Response({ "message": _("No Payload provided."), }, status=status.HTTP_400_BAD_REQUEST) # --------------------------------------------------------------------- # --- Check the Rights # --------------------------------------------------------------------- if not organization_staff_member_required(request, organization_id): return Response( { "message": _("You don't have Permissions to perform the Action."), }, status=status.HTTP_400_BAD_REQUEST) # --------------------------------------------------------------------- # --- Retrieve and update the Organization Group Members # --------------------------------------------------------------------- organization_group = get_object_or_None( OrganizationGroup, pk=group_id, organization_id=organization_id, ) if not organization_group: return Response({ "message": _("Organization Group not found."), }, status=status.HTTP_404_NOT_FOUND) organization_group.delete() # --------------------------------------------------------------------- # --- Send Email Notification(s) # --------------------------------------------------------------------- # --------------------------------------------------------------------- # --- Save the Log # --------------------------------------------------------------------- papertrail.log( event_type="organization-group-removed", message="Organization Group was removed", data={ "admin": request.user.email, "name": organization_group.name, "reason": reason, }, # timestamp=timezone.now(), targets={ "admin": request.user, "organization": organization_group.organization, }, ) return Response({ "message": _("Successfully removed the Group."), }, status=status.HTTP_200_OK)
def post_create(request): """Create the Post.""" print colored("***" * 27, "green") print colored("*** INSIDE `%s`" % inspect.stack()[0][3], "green") # ------------------------------------------------------------------------- # --- Prepare Form(s) # ------------------------------------------------------------------------- form = CreateEditPostForm( request.POST or None, request.FILES or None, user=request.user) if request.method == "POST": if form.is_valid(): post = form.save(commit=False) post.save() form.save_m2m() # ----------------------------------------------------------------- # --- Render HTML Email Content if "post-draft" in request.POST: post.status = POST_STATUS.DRAFT # ------------------------------------------------------------- # --- TODO: Send confirmation Email else: post.status = POST_STATUS.VISIBLE # ------------------------------------------------------------- # --- TODO: Send confirmation Email post.save() # ----------------------------------------------------------------- # --- Save the Log papertrail.log( event_type="new-post-created", message="New Post created", data={ "author": post.author.email, "title": post.title, "status": post.status, }, # timestamp=timezone.now(), targets={ "author": post.author, "post": post, }, ) return redirect("post-list") # --------------------------------------------------------------------- # --- Failed to create the Post # --- Save the Log papertrail.log( event_type="post-create-failed", message="Post create failed", data={ "form": form_field_error_list(form), }, # timestamp=timezone.now(), targets={ "user": request.user, }, ) return render( request, "blog/post-create.html", { "form": form, })
def post(self, request): """POST: Complaint create. Receive: account_id :uint: challenge_id :uint: organization_id :uint: post_id :uint: complaint_text :str: Return: status 200/400/404/500 Example Payload: { "challenge_id": 1, "complaint_text": "Complaint Text" } """ print colored("***" * 27, "green") print colored( "*** INSIDE `%s.%s`" % (self.__class__.__name__, inspect.stack()[0][3]), "green") # --------------------------------------------------------------------- # --- Retrieve Data from the Request # --------------------------------------------------------------------- account_id = request.data.get("account_id", "") challenge_id = request.data.get("challenge_id", "") organization_id = request.data.get("organization_id", "") complaint_text = request.data.get("complaint_text", "") print colored("[--- DUMP ---] ACCOUNT ID : %s" % account_id, "yellow") print colored("[--- DUMP ---] CHALLENGE ID : %s" % challenge_id, "yellow") print colored( "[--- DUMP ---] ORGANIZATION ID : %s" % organization_id, "yellow") print colored( "[--- DUMP ---] COMPLAINT TEXT : %s" % complaint_text, "yellow") # --------------------------------------------------------------------- # --- Handle Errors # --------------------------------------------------------------------- if not account_id and not challenge_id and not organization_id: return Response( { "message": _("Neither Account, nor Challenge, nor Organization, ID provided." ), }, status=status.HTTP_400_BAD_REQUEST) if not complaint_text: return Response({ "message": _("No Complaint Text provided."), }, status=status.HTTP_400_BAD_REQUEST) # --------------------------------------------------------------------- # --- Retrieve the Account # --------------------------------------------------------------------- if account_id: account = get_object_or_None( User, id=account_id, ) if not account: return Response({ "message": _("Member not found."), }, status=status.HTTP_404_NOT_FOUND) # ----------------------------------------------------------------- # --- Check, if the User has already complained to the Account is_complained = account.profile.is_complained_by_user(request.user) if is_complained: return Response( { "message": _("You already complained on the Member."), }, status=status.HTTP_400_BAD_REQUEST) # ----------------------------------------------------------------- # --- Check, if the registered User participated in the same # Challenge(s), as the Account. if len(get_participations_intersection(request.user, account)) <= 0: return Response( { "message": _("You don't have Permissions to perform the Action."), }, status=status.HTTP_400_BAD_REQUEST) content_type = ContentType.objects.get_for_model(account.profile) object_id = account.profile.id # --------------------------------------------------------------------- # --- Retrieve the Challenge # --------------------------------------------------------------------- if challenge_id: challenge = get_object_or_None( Challenge, id=challenge_id, ) if not challenge: return Response({ "message": _("Challenge not found."), }, status=status.HTTP_404_NOT_FOUND) # ----------------------------------------------------------------- # --- Check, if the User has already complained to the Account is_complained = challenge.is_complained_by_user(request.user) if is_complained: return Response( { "message": _("You already complained on the Challenge."), }, status=status.HTTP_400_BAD_REQUEST) # ----------------------------------------------------------------- # --- Check, if the registered User participated in the Challenge. participation = get_object_or_None( Participation, user=request.user, challenge=challenge, ) if not participation: return Response( { "message": _("You don't have Permissions to perform the Action."), }, status=status.HTTP_400_BAD_REQUEST) if (not participation.is_waiting_for_selfreflection and not participation.is_waiting_for_acknowledgement and not participation.is_acknowledged): return Response( { "message": _("You don't have Permissions to perform the Action."), }, status=status.HTTP_400_BAD_REQUEST) content_type = ContentType.objects.get_for_model(challenge) object_id = challenge.id # --------------------------------------------------------------------- # --- Retrieve the Organization # --------------------------------------------------------------------- if organization_id: organization = get_object_or_None( Organization, id=organization_id, ) if not organization: return Response({ "message": _("Organization not found."), }, status=status.HTTP_404_NOT_FOUND) # ----------------------------------------------------------------- # --- Check, if the User has already complained to the Organization. is_complained = organization.is_complained_by_user(request.user) if is_complained: return Response( { "message": _("You already complained on the Organization."), }, status=status.HTTP_400_BAD_REQUEST) # ----------------------------------------------------------------- # --- Retrieve User's Participations to the Organization's # Challenges. completed_challenges = Challenge.objects.filter( organization=organization, status=CHALLENGE_STATUS.COMPLETE, ) challenge_ids = completed_challenges.values_list("pk", flat=True) try: participation = Participation.objects.filter( user=request.user, challenge__pk__in=challenge_ids, status__in=[ PARTICIPATION_STATUS.WAITING_FOR_SELFREFLECTION, PARTICIPATION_STATUS.ACKNOWLEDGED, PARTICIPATION_STATUS.WAITING_FOR_ACKNOWLEDGEMENT ]).latest("pk") if not participation: return Response( { "message": _("You don't have Permissions to perform the Action." ), }, status=status.HTTP_400_BAD_REQUEST) except Participation.DoesNotExist: print colored("[--- WARNING ---] Entry does not exist", "yellow") return Response( { "message": _("You don't have Permissions to perform the Action."), }, status=status.HTTP_400_BAD_REQUEST) content_type = ContentType.objects.get_for_model(organization) object_id = organization.id # --------------------------------------------------------------------- # --- Create Complaint # --------------------------------------------------------------------- complaint = Complaint.objects.create( user=request.user, text=complaint_text, content_type=content_type, object_id=object_id, ) complaint.save() # --------------------------------------------------------------------- # --- Send Email Notifications # --------------------------------------------------------------------- complaint.email_notify_admins_complaint_created(request) # --------------------------------------------------------------------- # --- Save the Log # --------------------------------------------------------------------- papertrail.log( event_type="complaint-created", message="Complaint was created", data={ "reporter": request.user.email, "object": complaint.content_object.name, }, # timestamp=timezone.now(), targets={ "reporter": request.user, "object": complaint.content_object, }, ) return Response({ "message": _("Successfully added the Complaint."), }, status=status.HTTP_200_OK)
def post_edit(request, slug): """Edit the Post.""" print colored("***" * 27, "green") print colored("*** INSIDE `%s`" % inspect.stack()[0][3], "green") # ------------------------------------------------------------------------- # --- Retrieve Blog Post # ------------------------------------------------------------------------- post = get_object_or_404( Post, slug=slug, ) if post.is_closed: raise Http404 form = CreateEditPostForm( request.POST or None, request.FILES or None, user=request.user, instance=post) if request.method == "POST": if form.is_valid(): post = form.save(commit=False) post.save() form.save_m2m() # ----------------------------------------------------------------- # --- TODO: Send confirmation Email # ----------------------------------------------------------------- # --- Save the Log papertrail.log( event_type="post-edited", message="Post was edited", data={ "user": request.user.email, "author": post.author.email, "title": post.title, "status": post.status, }, # timestamp=timezone.now(), targets={ "user": request.user, "author": post.author, "post": post, }, ) return HttpResponseRedirect( reverse("post-details", kwargs={ "slug": post.slug, })) # --------------------------------------------------------------------- # --- Failed to save the Post # --- Save the Log papertrail.log( event_type="post-save-failed", message="Post save failed", data={ "form": form_field_error_list(form), }, # timestamp=timezone.now(), targets={ "user": request.user, "post": post, }, ) return render( request, "blog/post-edit.html", { "form": form, "post": post, })
def post(self, request, forum_id): """POST: Forum remove. Receive: forum_id :uint: cancellation_text :str: Return: status 200/400/404/500 Example Payload: { "cancellation_text": "Reason for removal", } """ print colored("***" * 27, "green") print colored( "*** INSIDE `%s.%s`" % (self.__class__.__name__, inspect.stack()[0][3]), "green") # --------------------------------------------------------------------- # --- Retrieve Data from the Request # --------------------------------------------------------------------- cancellation_text = request.data.get("cancellation_text", "") print colored("[--- DUMP ---] FORUM ID : %s" % forum_id, "yellow") print colored( "[--- DUMP ---] CANCELLATION TEXT : %s" % cancellation_text, "yellow") # --------------------------------------------------------------------- # --- Handle Errors # --------------------------------------------------------------------- if not forum_id: return Response({ "message": _("No Forum ID provided."), }, status=status.HTTP_400_BAD_REQUEST) # --------------------------------------------------------------------- # --- Retrieve the Forum # --------------------------------------------------------------------- forum = get_object_or_None( Forum, id=forum_id, ) if not forum: return Response({ "message": _("Forum not found."), }, status=status.HTTP_404_NOT_FOUND) forum.delete() # --------------------------------------------------------------------- # --- Render HTML Email Content # --------------------------------------------------------------------- # --------------------------------------------------------------------- # --- Send Notification to the Admin # --------------------------------------------------------------------- # --------------------------------------------------------------------- # --- Save the Log # --------------------------------------------------------------------- papertrail.log( event_type="forum-removed", message="Forum was removed", data={ "user": request.user.email, "title": forum.title, }, # timestamp=timezone.now(), targets={ "user": request.user, }, ) return Response({ "message": _("Successfully removed the Forum."), }, status=status.HTTP_200_OK)