Commit 516b4c12 authored by Robert Speicher's avatar Robert Speicher

Allow Admin to filter users by 2FA status

parent e13b523c
...@@ -198,6 +198,8 @@ class User < ActiveRecord::Base ...@@ -198,6 +198,8 @@ class User < ActiveRecord::Base
scope :active, -> { with_state(:active) } scope :active, -> { with_state(:active) }
scope :not_in_project, ->(project) { project.users.present? ? where("id not in (:ids)", ids: project.users.map(&:id) ) : all } scope :not_in_project, ->(project) { project.users.present? ? where("id not in (:ids)", ids: project.users.map(&:id) ) : all }
scope :without_projects, -> { where('id NOT IN (SELECT DISTINCT(user_id) FROM members)') } scope :without_projects, -> { where('id NOT IN (SELECT DISTINCT(user_id) FROM members)') }
scope :with_two_factor, -> { where('otp_required_for_login IS true') }
scope :without_two_factor, -> { where('otp_required_for_login IS NOT true') }
# #
# Class methods # Class methods
...@@ -231,9 +233,16 @@ class User < ActiveRecord::Base ...@@ -231,9 +233,16 @@ class User < ActiveRecord::Base
def filter(filter_name) def filter(filter_name)
case filter_name case filter_name
when "admins"; self.admins when 'admins'
when "blocked"; self.blocked self.admins
when "wop"; self.without_projects when 'blocked'
self.blocked
when 'two_factor_disabled'
self.without_two_factor
when 'two_factor_enabled'
self.with_two_factor
when 'wop'
self.without_projects
else else
self.active self.active
end end
......
...@@ -13,6 +13,14 @@ ...@@ -13,6 +13,14 @@
= link_to admin_users_path(filter: "admins") do = link_to admin_users_path(filter: "admins") do
Admins Admins
%small.pull-right= User.admins.count %small.pull-right= User.admins.count
%li.filter-two-factor-enabled{class: "#{'active' if params[:filter] == 'two_factor_enabled'}"}
= link_to admin_users_path(filter: 'two_factor_enabled') do
2FA Enabled
%small.pull-right= User.with_two_factor.count
%li.filter-two-factor-disabled{class: "#{'active' if params[:filter] == 'two_factor_disabled'}"}
= link_to admin_users_path(filter: 'two_factor_disabled') do
2FA Disabled
%small.pull-right= User.without_two_factor.count
%li{class: "#{'active' if params[:filter] == "blocked"}"} %li{class: "#{'active' if params[:filter] == "blocked"}"}
= link_to admin_users_path(filter: "blocked") do = link_to admin_users_path(filter: "blocked") do
Blocked Blocked
......
...@@ -16,6 +16,46 @@ describe "Admin::Users", feature: true do ...@@ -16,6 +16,46 @@ describe "Admin::Users", feature: true do
expect(page).to have_content(@user.email) expect(page).to have_content(@user.email)
expect(page).to have_content(@user.name) expect(page).to have_content(@user.name)
end end
describe 'Two-factor Authentication filters' do
it 'counts users who have enabled 2FA' do
create(:user, two_factor_enabled: true)
visit admin_users_path
page.within('.filter-two-factor-enabled small') do
expect(page).to have_content('1')
end
end
it 'filters by users who have enabled 2FA' do
user = create(:user, two_factor_enabled: true)
visit admin_users_path
click_link '2FA Enabled'
expect(page).to have_content(user.email)
end
it 'counts users who have not enabled 2FA' do
create(:user, two_factor_enabled: false)
visit admin_users_path
page.within('.filter-two-factor-disabled small') do
expect(page).to have_content('2') # Including admin
end
end
it 'filters by users who have not enabled 2FA' do
user = create(:user, two_factor_enabled: false)
visit admin_users_path
click_link '2FA Disabled'
expect(page).to have_content(user.email)
end
end
end end
describe "GET /admin/users/new" do describe "GET /admin/users/new" do
......
...@@ -308,18 +308,44 @@ describe User do ...@@ -308,18 +308,44 @@ describe User do
end end
end end
describe 'filter' do describe '.filter' do
before do let(:user) { double }
User.delete_all
@user = create :user it 'filters by active users by default' do
@admin = create :user, admin: true expect(User).to receive(:active).and_return([user])
@blocked = create :user, state: :blocked
expect(User.filter(nil)).to include user
end end
it { expect(User.filter("admins")).to eq([@admin]) } it 'filters by admins' do
it { expect(User.filter("blocked")).to eq([@blocked]) } expect(User).to receive(:admins).and_return([user])
it { expect(User.filter("wop")).to include(@user, @admin, @blocked) }
it { expect(User.filter(nil)).to include(@user, @admin) } expect(User.filter('admins')).to include user
end
it 'filters by blocked' do
expect(User).to receive(:blocked).and_return([user])
expect(User.filter('blocked')).to include user
end
it 'filters by two_factor_disabled' do
expect(User).to receive(:without_two_factor).and_return([user])
expect(User.filter('two_factor_disabled')).to include user
end
it 'filters by two_factor_enabled' do
expect(User).to receive(:with_two_factor).and_return([user])
expect(User.filter('two_factor_enabled')).to include user
end
it 'filters by wop' do
expect(User).to receive(:without_projects).and_return([user])
expect(User.filter('wop')).to include user
end
end end
describe :not_in_project do describe :not_in_project do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment