Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions app/assets/javascripts/audit_logs.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('.js-log-type-select, .js-event-type-select').forEach((el) => {
$(el).select2();
});
document
.querySelectorAll(['.js-log-type-select', '.js-event-type-select', '.js-community-select'].join(', '))
.forEach((el) => {
$(el).select2();
});
});
13 changes: 13 additions & 0 deletions app/controllers/admin_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ class AdminController < ApplicationController
before_action :verify_global_admin, only: [:admin_email, :send_admin_email, :new_site, :create_site, :setup,
:setup_save, :failban, :all_email, :send_all_email]
before_action :verify_developer, only: [:change_users, :impersonate]
before_action :set_communities, only: [:audit_logs]
before_action :set_user, only: [:change_users, :failban, :impersonate]

skip_before_action :check_if_warning_or_suspension_pending, only: [:change_back, :verify_elevation]
Expand Down Expand Up @@ -122,6 +123,10 @@ def audit_logs
end
end

if params[:community].present?
@logs = @logs.where(community_id: params[:community])
end

if params[:from].present?
@logs = @logs.where('date(created_at) >= ?', params[:from])
end
Expand Down Expand Up @@ -274,6 +279,14 @@ def do_email_query

private

def set_communities
@communities = if current_user&.global_admin?
Community.unscoped.order(name: :asc)
else
Community.none
Comment thread
Oaphi marked this conversation as resolved.
end
end

def set_user
@user = User.find(params[:id])
end
Expand Down
22 changes: 16 additions & 6 deletions app/helpers/uri_helper.rb
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
module UriHelper
[:http, :https].each do |method|
# Does a given URI have the relevant scheme?
# @param {String} uri URI to check
# @return {Boolean} check result
# @param uri [String] URI to check
# @return [Boolean] check result
define_method "#{method}_uri?" do |uri|
URI(uri).scheme.casecmp(method.to_s).zero?
end
end

# Forces a given URI to be a safe one
# @para uri [String] URI to fixup
# @param scheme [Symbol] scheme to use if the URI is unsafe
# @return [String] safe URI
def force_safe_uri(uri, scheme = :http)
return uri if safe_uri?(uri)

safe_uri?(uri) ? uri : "#{scheme}://#{uri}"
end

# Is a given URI a relative one?
# @param {String} uri URI to check
# @return {Boolean} check result
# @param uri [String] URI to check
# @return [Boolean] check result
def relative_uri?(uri)
URI(uri).relative?
end

# Is a given URI a safe one (absolute http://, https://, or relative)?
# @param {String} uri URI to check
# @return {Boolean} check result
# @param uri [String] URI to check
# @return [Boolean] check result
def safe_uri?(uri)
relative_uri?(uri) || http_uri?(uri) || https_uri?(uri)
end
Expand Down
3 changes: 3 additions & 0 deletions app/views/admin/_audit_log.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
<strong><%= t('g.type').capitalize %>:</strong>
<%= log.log_type.humanize %><br/>

<strong><%= t('g.community').capitalize %></strong>
Comment thread
Oaphi marked this conversation as resolved.
<%= link_to log.community.name, force_safe_uri(log.community.host) %><br/>

<strong><%= t('g.user').capitalize %>:</strong>
<%= user_link(log.user) %><br/>

Expand Down
29 changes: 23 additions & 6 deletions app/views/admin/audit_logs.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,33 @@
<%= form_tag audit_logs_path, method: :get, class: 'form-inline audit-log-filters' do %>
<div class="form-group-horizontal">
<div class="form-group">
<%= label_tag :log_type, 'Log category', class: 'form-element' %>
<%= select_tag :log_type, options_for_select(@log_types.map { |lt| [lt, lt] }, selected: params[:log_type]),
include_blank: true, class: 'form-element js-log-type-select' %>
<%= label_tag :log_type, 'Type', class: 'form-element' %>
<%= select_tag :log_type,
options_for_select(@log_types.map { |lt| [lt, lt] },
selected: params[:log_type]),
include_blank: true,
class: 'form-element js-log-type-select' %>
</div>
<div class="form-group">
<%= label_tag :event_type, 'Event', class: 'form-element' %>
<%= select_tag :event_type, options_for_select(@event_types.map { |et| [et, et] },
selected: params[:event_type]),
include_blank: true, class: 'form-element js-event-type-select' %>
<%= select_tag :event_type,
options_for_select(@event_types.map { |et| [et, et] },
selected: params[:event_type]),
include_blank: true,
class: 'form-element js-event-type-select' %>
</div>

<% if current_user&.global_admin? %>
<div class="form-group">
<%= label_tag :community, 'Community', class: 'form-element' %>
<%= select_tag :community,
options_for_select(@communities.map { |c| [c.name, c.id] },
selected: params[:community]),
include_blank: true,
class: 'form-element js-community-select' %>
</div>
<% end %>

<div class="form-group">
<%= label_tag :from, 'From date', class: 'form-element' %>
<%= date_field_tag :from, params[:from], class: 'form-element' %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/users/mod_privileges.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
<p class="h-m-0 form-caption">Administrators can edit site settings and user roles.</p>
</div>
<div class="grid--cell">
<% if @user.global_moderator? %>
<% if @user.admin? %>
<button class="button is-filled js-role-grant-btn" data-role="admin" data-user="<%= @user.id %>">
revoke
</button>
Expand Down
39 changes: 39 additions & 0 deletions test/controllers/admin_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,45 @@ class AdminControllerTest < ActionController::TestCase
assert_not_nil assigns(:logs)
end

test ':audit_logs should correctly check community access' do
first_comm = communities(:sample)
second_comm = communities(:second)

expected = [
[:admin, false],
[:global_admin, true]
]

expected.each do |test_case|
user = users(test_case.first)
is_unscoped = test_case.second

sign_in(user)

get :audit_logs, params: { community: first_comm.id }
assert_response(:success)
@logs = assigns(:logs)
assert_not_nil(@logs)

assert @logs.any?
assert(@logs.all? { |l| l.community.id == first_comm.id })

get :audit_logs, params: { community: second_comm.id }
assert_response(:success)
@logs = assigns(:logs)
assert_not_nil(@logs)

if is_unscoped
assert @logs.any?
assert(@logs.all? { |l| l.community.id == second_comm.id })
else
assert @logs.none?
end

sign_out(user)
end
end

test 'should do email query' do
sign_in users(:admin)
post :do_email_query, params: { email: users(:standard_user).email }
Expand Down
8 changes: 8 additions & 0 deletions test/fixtures/audit_logs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,11 @@ vote_rate_limit_log:
comment: >
limit: 10
vote: 1

second_community_log:
community: second
log_type: admin_audit
event_type: impersonation_end
related_type: User
related: moderator
user: admin
19 changes: 19 additions & 0 deletions test/helpers/uri_helper_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
require 'test_helper'

class UriHelperTest < ActionView::TestCase
include Devise::Test::ControllerHelpers

test ':force_safe_uri should correctly handle URIs' do
expected = [
['/relative', '/relative'],
['http://example.com', 'http://example.com'],
['https://example.com', 'https://example.com'],
['localhost:3000', 'http://localhost:3000']
]

expected.each do |input, expected|
actual = force_safe_uri(input)
assert_equal expected, actual
end
end
end
Loading