summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Speicher <rspeicher@gmail.com>2015-06-19 16:31:36 -0400
committerRobert Speicher <rspeicher@gmail.com>2015-06-19 16:35:53 -0400
commit516b4c124831296a9280b9f04abcd865492eea1e (patch)
tree300022679679440235dc36576656e22ff470137b
parente13b523c92d82d10c553a90dd0fb93b73dee3023 (diff)
downloadgitlab-ce-516b4c124831296a9280b9f04abcd865492eea1e.tar.gz
Allow Admin to filter users by 2FA status
-rw-r--r--app/models/user.rb17
-rw-r--r--app/views/admin/users/index.html.haml8
-rw-r--r--spec/features/admin/admin_users_spec.rb40
-rw-r--r--spec/models/user_spec.rb46
4 files changed, 97 insertions, 14 deletions
diff --git a/app/models/user.rb b/app/models/user.rb
index a2e2d220b3a..57a36a73ac5 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -193,11 +193,13 @@ class User < ActiveRecord::Base
mount_uploader :avatar, AvatarUploader
# Scopes
- scope :admins, -> { where(admin: true) }
+ scope :admins, -> { where(admin: true) }
scope :blocked, -> { with_state(:blocked) }
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 :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
@@ -231,9 +233,16 @@ class User < ActiveRecord::Base
def filter(filter_name)
case filter_name
- when "admins"; self.admins
- when "blocked"; self.blocked
- when "wop"; self.without_projects
+ when 'admins'
+ self.admins
+ 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
self.active
end
diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml
index 45dee86b017..9c1bec7c84d 100644
--- a/app/views/admin/users/index.html.haml
+++ b/app/views/admin/users/index.html.haml
@@ -13,6 +13,14 @@
= link_to admin_users_path(filter: "admins") do
Admins
%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"}"}
= link_to admin_users_path(filter: "blocked") do
Blocked
diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb
index 7f5cb30cb94..86717761582 100644
--- a/spec/features/admin/admin_users_spec.rb
+++ b/spec/features/admin/admin_users_spec.rb
@@ -16,6 +16,46 @@ describe "Admin::Users", feature: true do
expect(page).to have_content(@user.email)
expect(page).to have_content(@user.name)
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
describe "GET /admin/users/new" do
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index fa7680fbbec..d86401c9fbb 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -308,18 +308,44 @@ describe User do
end
end
- describe 'filter' do
- before do
- User.delete_all
- @user = create :user
- @admin = create :user, admin: true
- @blocked = create :user, state: :blocked
+ describe '.filter' do
+ let(:user) { double }
+
+ it 'filters by active users by default' do
+ expect(User).to receive(:active).and_return([user])
+
+ expect(User.filter(nil)).to include user
end
- it { expect(User.filter("admins")).to eq([@admin]) }
- it { expect(User.filter("blocked")).to eq([@blocked]) }
- it { expect(User.filter("wop")).to include(@user, @admin, @blocked) }
- it { expect(User.filter(nil)).to include(@user, @admin) }
+ it 'filters by admins' do
+ expect(User).to receive(:admins).and_return([user])
+
+ 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
describe :not_in_project do