Skip to content

Commit 7ec69c6

Browse files
Add support for admin and owner view logging; update tests and views (#3953)
* Add support for admin and owner view logging; update tests and views * Sign out user in tests to ensure views count as regular views * Clarify comment in log_view method to emphasize admin view precedence over owner views * Add tests for log_view method to create owner_view and admin_view audit logs
1 parent 65b4fbf commit 7ec69c6

File tree

12 files changed

+554
-13
lines changed

12 files changed

+554
-13
lines changed

app/controllers/concerns/log_events.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,16 @@ module LogEvents
33
# log_view
44
#
55
# Record that a view is being made for a push
6+
# If the viewer is the owner or an admin, it won't count towards view limits
67
#
78
def log_view(push)
89
if push.expired
910
log_event(push, :failed_view)
11+
elsif user_signed_in? && current_user.admin?
12+
# Admin views take precedence over owner views
13+
log_event(push, :admin_view)
14+
elsif user_signed_in? && push.user_id == current_user.id
15+
log_event(push, :owner_view)
1016
else
1117
log_event(push, :view)
1218
end

app/models/audit_log.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# frozen_string_literal: true
22

33
class AuditLog < ApplicationRecord
4-
enum :kind, [:creation, :view, :failed_view, :expire, :failed_passphrase], validate: true
4+
enum :kind, [:creation, :view, :failed_view, :expire, :failed_passphrase, :admin_view, :owner_view], validate: true
55

66
belongs_to :push
77
belongs_to :user, optional: true
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<div class="list-group-item list-group-item-action list-group-item-info">
2+
<em class="bi bi-shield-check"></em>
3+
<%= _('Admin view on %{date} by %{user}') % {
4+
date: I18n.l(audit_log.created_at.in_time_zone(Settings.timezone)),
5+
user: audit_log.subject_name
6+
} %>
7+
<span class="badge bg-info"><%= _('Does not count towards view limit') %></span>
8+
<br>
9+
<%= _('IP Address:') %> <code><%= render 'application/ip_address', ip: audit_log.ip %></code>
10+
<br>
11+
<%= _('User Agent:') %> <code><%= audit_log.user_agent.blank? ? _('None') : audit_log.user_agent %></code>
12+
<br>
13+
<%= _('Referrer:') %> <code><%= audit_log.referrer.blank? ? _('None') : audit_log.referrer %></code>
14+
</div>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<div class="list-group-item list-group-item-action list-group-item-info">
2+
<em class="bi bi-person-check"></em>
3+
<%= _('Owner view on %{date} by %{user}') % {
4+
date: I18n.l(audit_log.created_at.in_time_zone(Settings.timezone)),
5+
user: audit_log.subject_name
6+
} %>
7+
<span class="badge bg-info"><%= _('Does not count towards view limit') %></span>
8+
<br>
9+
<%= _('IP Address:') %> <code><%= render 'application/ip_address', ip: audit_log.ip %></code>
10+
<br>
11+
<%= _('User Agent:') %> <code><%= audit_log.user_agent.blank? ? _('None') : audit_log.user_agent %></code>
12+
<br>
13+
<%= _('Referrer:') %> <code><%= audit_log.referrer.blank? ? _('None') : audit_log.referrer %></code>
14+
</div>

test/controllers/concerns/log_events_test.rb

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,71 @@ class LogEventsTest < ActionController::TestCase
6060
assert_equal @push, result
6161
end
6262

63+
test "log_view creates owner_view audit log when current_user is push owner" do
64+
@push.update(expired: false, user: @user)
65+
sign_in @user
66+
67+
@request.env["REMOTE_ADDR"] = "192.168.1.1"
68+
@request.env["HTTP_USER_AGENT"] = "Mozilla/5.0"
69+
@request.env["HTTP_REFERER"] = "https://example.com"
70+
71+
result = @controller.log_view(@push)
72+
73+
assert_equal @push, result
74+
assert_equal 1, AuditLog.count
75+
log = AuditLog.last
76+
assert_equal :owner_view, log.kind.to_sym
77+
assert_equal @push, log.push
78+
assert_equal @user, log.user
79+
assert_equal "192.168.1.1", log.ip
80+
assert_equal "Mozilla/5.0", log.user_agent
81+
assert_equal "https://example.com", log.referrer
82+
end
83+
84+
test "log_view creates admin_view audit log when current_user is admin but not owner" do
85+
admin = users(:mr_admin)
86+
@push.update(expired: false, user: @user)
87+
sign_in admin
88+
89+
@request.env["REMOTE_ADDR"] = "10.0.0.5"
90+
@request.env["HTTP_USER_AGENT"] = "AdminBrowser/1.0"
91+
@request.env["HTTP_REFERER"] = "https://admin.com"
92+
93+
result = @controller.log_view(@push)
94+
95+
assert_equal @push, result
96+
assert_equal 1, AuditLog.count
97+
log = AuditLog.last
98+
assert_equal :admin_view, log.kind.to_sym
99+
assert_equal @push, log.push
100+
assert_equal admin, log.user
101+
assert_equal "10.0.0.5", log.ip
102+
assert_equal "AdminBrowser/1.0", log.user_agent
103+
assert_equal "https://admin.com", log.referrer
104+
end
105+
106+
test "log_view creates regular view audit log when signed in user is neither owner nor admin" do
107+
other_user = users(:one)
108+
@push.update(expired: false, user: @user)
109+
sign_in other_user
110+
111+
@request.env["REMOTE_ADDR"] = "172.16.0.10"
112+
@request.env["HTTP_USER_AGENT"] = "UserBrowser/2.0"
113+
@request.env["HTTP_REFERER"] = "https://user.com"
114+
115+
result = @controller.log_view(@push)
116+
117+
assert_equal @push, result
118+
assert_equal 1, AuditLog.count
119+
log = AuditLog.last
120+
assert_equal :view, log.kind.to_sym
121+
assert_equal @push, log.push
122+
assert_equal other_user, log.user
123+
assert_equal "172.16.0.10", log.ip
124+
assert_equal "UserBrowser/2.0", log.user_agent
125+
assert_equal "https://user.com", log.referrer
126+
end
127+
63128
# Test log_creation method
64129
test "log_creation creates creation audit log" do
65130
@request.env["REMOTE_ADDR"] = "172.16.0.1"
@@ -247,7 +312,7 @@ class LogEventsTest < ActionController::TestCase
247312

248313
# Test edge cases
249314
test "log_event handles all valid audit log kinds" do
250-
kinds = [:creation, :view, :failed_view, :expire, :failed_passphrase]
315+
kinds = [:creation, :view, :failed_view, :expire, :failed_passphrase, :owner_view, :admin_view]
251316

252317
kinds.each do |kind|
253318
AuditLog.delete_all
@@ -274,6 +339,18 @@ class LogEventsTest < ActionController::TestCase
274339
when :failed_view
275340
push.update(expired: true)
276341
@controller.log_view(push)
342+
when :owner_view
343+
owner = users(:luca)
344+
push.update(user: owner)
345+
sign_in owner
346+
@controller.log_view(push)
347+
sign_out owner
348+
when :admin_view
349+
admin = users(:mr_admin)
350+
push.update(user: users(:one))
351+
sign_in admin
352+
@controller.log_view(push)
353+
sign_out admin
277354
end
278355

279356
assert_equal 1, AuditLog.count, "Expected 1 audit log for kind: #{kind}"

0 commit comments

Comments
 (0)