diff --git a/app/assets/javascripts/admin/routes/admin-logs-staff-action-logs.js.es6 b/app/assets/javascripts/admin/routes/admin-logs-staff-action-logs.js.es6 index 48d04abc5f7..b7b855ba5f9 100644 --- a/app/assets/javascripts/admin/routes/admin-logs-staff-action-logs.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-logs-staff-action-logs.js.es6 @@ -8,7 +8,6 @@ export default Discourse.Route.extend({ setupController: function(controller) { controller.resetFilters(); - controller.refresh(); }, actions: { diff --git a/app/assets/javascripts/admin/routes/admin-user-index.js.es6 b/app/assets/javascripts/admin/routes/admin-user-index.js.es6 index c10e5957d5a..05444f29208 100644 --- a/app/assets/javascripts/admin/routes/admin-user-index.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-user-index.js.es6 @@ -28,6 +28,13 @@ export default Discourse.Route.extend({ showSuspendModal(model) { showModal('admin-suspend-user', { model, admin: true }); this.controllerFor('modal').set('modalClass', 'suspend-user-modal'); + }, + + viewActionLogs(username) { + const controller = this.controllerFor('adminLogs.staffActionLogs') + this.transitionTo('adminLogs.staffActionLogs').then(() => { + controller._changeFilters({ acting_user: username }); + }); } } }); diff --git a/app/assets/javascripts/admin/templates/user-index.hbs b/app/assets/javascripts/admin/templates/user-index.hbs index 9cc35a3dce3..923fb1c09b9 100644 --- a/app/assets/javascripts/admin/templates/user-index.hbs +++ b/app/assets/javascripts/admin/templates/user-index.hbs @@ -7,6 +7,9 @@ {{i18n 'admin.user.show_public_profile'}} {{/link-to}} {{/if}} + {{#if model.can_view_action_logs}} + {{d-button action="viewActionLogs" actionParam=model.username icon="list-alt" label="admin.user.action_logs"}} + {{/if}} {{#if model.active}} {{#if model.can_impersonate}} {{d-button class="btn-danger" action="impersonate" icon="crosshairs" label="admin.impersonate.title" title="admin.impersonate.help"}} diff --git a/app/serializers/admin_detailed_user_serializer.rb b/app/serializers/admin_detailed_user_serializer.rb index b6a2072f97c..563ae1821e1 100644 --- a/app/serializers/admin_detailed_user_serializer.rb +++ b/app/serializers/admin_detailed_user_serializer.rb @@ -22,7 +22,8 @@ class AdminDetailedUserSerializer < AdminUserSerializer :warnings_received_count, :user_fields, :bounce_score, - :reset_bounce_score_after + :reset_bounce_score_after, + :can_view_action_logs has_one :approved_by, serializer: BasicUserSerializer, embed: :objects has_one :api_key, serializer: ApiKeySerializer, embed: :objects @@ -86,4 +87,8 @@ class AdminDetailedUserSerializer < AdminUserSerializer object.user_stat.reset_bounce_score_after end + def can_view_action_logs + scope.can_view_action_logs?(object) + end + end diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index b00207e7a9c..62c23e88cf4 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -3053,6 +3053,7 @@ en: refresh_browsers_message: "Message sent to all clients!" show_public_profile: "Show Public Profile" impersonate: 'Impersonate' + action_logs: "Action Logs" ip_lookup: "IP Lookup" log_out: "Log Out" logged_out: "User was logged out on all devices" diff --git a/lib/guardian.rb b/lib/guardian.rb index 9f479154909..48e0eda3983 100644 --- a/lib/guardian.rb +++ b/lib/guardian.rb @@ -158,6 +158,10 @@ class Guardian # make it impossible to be the same user. end + def can_view_action_logs?(target) + is_staff? && target && target.staff? + end + # Can we approve it? def can_approve?(target) is_staff? && target && not(target.approved?) diff --git a/spec/components/guardian_spec.rb b/spec/components/guardian_spec.rb index e0ce2a29a4a..dc4b640f7ad 100644 --- a/spec/components/guardian_spec.rb +++ b/spec/components/guardian_spec.rb @@ -281,6 +281,24 @@ describe Guardian do end end + describe "can_view_action_logs?" do + it 'is false for non-staff acting user' do + expect(Guardian.new(user).can_view_action_logs?(moderator)).to be_falsey + end + + it 'is false without a target user' do + expect(Guardian.new(moderator).can_view_action_logs?(nil)).to be_falsey + end + + it 'is false for non-staff target user' do + expect(Guardian.new(moderator).can_view_action_logs?(user)).to be_falsey + end + + it 'is true for staff target user' do + expect(Guardian.new(moderator).can_view_action_logs?(admin)).to be_truthy + end + end + describe 'can_invite_to_forum?' do let(:user) { Fabricate.build(:user) } let(:moderator) { Fabricate.build(:moderator) }