Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Léo-Paul Géneau
gitlab-ce
Commits
1a39d24d
Commit
1a39d24d
authored
Jul 20, 2018
by
Grzegorz Bizon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor blocked user tracker class
parent
33e11345
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
59 additions
and
35 deletions
+59
-35
config/initializers/warden.rb
config/initializers/warden.rb
+12
-11
lib/gitlab/auth/activity.rb
lib/gitlab/auth/activity.rb
+4
-1
lib/gitlab/auth/blocked_user_tracker.rb
lib/gitlab/auth/blocked_user_tracker.rb
+37
-19
spec/lib/gitlab/auth/blocked_user_tracker_spec.rb
spec/lib/gitlab/auth/blocked_user_tracker_spec.rb
+6
-4
No files found.
config/initializers/warden.rb
View file @
1a39d24d
...
@@ -4,30 +4,31 @@ Rails.application.configure do |config|
...
@@ -4,30 +4,31 @@ Rails.application.configure do |config|
end
end
Warden
::
Manager
.
before_failure
(
scope: :user
)
do
|
env
,
opts
|
Warden
::
Manager
.
before_failure
(
scope: :user
)
do
|
env
,
opts
|
Gitlab
::
Auth
::
BlockedUserTracker
.
log_if_user_blocked
(
env
)
Gitlab
::
Auth
::
BlockedUserTracker
.
new
(
env
).
tap
do
|
tracker
|
tracker
.
log_blocked_user_activity!
if
tracker
.
user_blocked?
Gitlab
::
Auth
::
Activity
.
new
(
opts
).
user_authentication_failed!
Gitlab
::
Auth
::
Activity
.
new
(
tracker
.
user
,
opts
).
user_authentication_failed!
end
end
end
Warden
::
Manager
.
after_authentication
(
scope: :user
)
do
|
user
,
auth
,
opts
|
Warden
::
Manager
.
after_authentication
(
scope: :user
)
do
|
user
,
auth
,
opts
|
ActiveSession
.
cleanup
(
user
)
ActiveSession
.
cleanup
(
user
)
Gitlab
::
Auth
::
Activity
.
new
(
user
,
opts
).
user_authenticated!
Gitlab
::
Auth
::
Activity
.
new
(
opts
).
user_authenticated!
end
end
Warden
::
Manager
.
after_set_user
(
scope: :user
,
only: :fetch
)
do
|
user
,
auth
,
opts
|
Warden
::
Manager
.
after_set_user
(
scope: :user
,
only: :fetch
)
do
|
user
,
auth
,
opts
|
ActiveSession
.
set
(
user
,
auth
.
request
)
ActiveSession
.
set
(
user
,
auth
.
request
)
Gitlab
::
Auth
::
Activity
.
new
(
user
,
opts
).
user_session_fetched!
Gitlab
::
Auth
::
Activity
.
new
(
opts
).
user_session_fetched!
end
end
Warden
::
Manager
.
after_set_user
(
scope: :user
,
only: :set_user
)
do
|
user
,
auth
,
opts
|
Warden
::
Manager
.
after_set_user
(
scope: :user
,
only: :set_user
)
do
|
user
,
auth
,
opts
|
Gitlab
::
Auth
::
Activity
.
new
(
opts
).
user_session_override!
Gitlab
::
Auth
::
Activity
.
new
(
user
,
opts
).
user_session_override!
end
end
Warden
::
Manager
.
before_logout
(
scope: :user
)
do
|
user
,
auth
,
opts
|
Warden
::
Manager
.
before_logout
(
scope: :user
)
do
|
warden_user
,
auth
,
opts
|
ActiveSession
.
destroy
(
user
||
auth
.
user
,
auth
.
request
.
session
.
id
)
(
warden_user
||
auth
.
user
).
tap
do
|
user
|
ActiveSession
.
destroy
(
user
,
auth
.
request
.
session
.
id
)
Gitlab
::
Auth
::
Activity
.
new
(
opts
).
user_signed_out!
Gitlab
::
Auth
::
Activity
.
new
(
user
,
opts
).
user_signed_out!
end
end
end
end
end
lib/gitlab/auth/activity.rb
View file @
1a39d24d
...
@@ -16,7 +16,8 @@ module Gitlab
...
@@ -16,7 +16,8 @@ module Gitlab
user_signed_out:
'Counter of total user sign out events'
user_signed_out:
'Counter of total user sign out events'
}.
freeze
}.
freeze
def
initialize
(
opts
)
def
initialize
(
user
,
opts
)
@user
=
user
@opts
=
opts
@opts
=
opts
end
end
...
@@ -29,6 +30,8 @@ module Gitlab
...
@@ -29,6 +30,8 @@ module Gitlab
when
:invalid
when
:invalid
self
.
class
.
user_password_invalid_counter
.
increment
self
.
class
.
user_password_invalid_counter
.
increment
end
end
# case blocked user
end
end
def
user_authenticated!
def
user_authenticated!
...
...
lib/gitlab/auth/blocked_user_tracker.rb
View file @
1a39d24d
...
@@ -2,34 +2,52 @@
...
@@ -2,34 +2,52 @@
module
Gitlab
module
Gitlab
module
Auth
module
Auth
class
BlockedUserTracker
class
BlockedUserTracker
include
Gitlab
::
Utils
::
StrongMemoize
ACTIVE_RECORD_REQUEST_PARAMS
=
'action_dispatch.request.request_parameters'
ACTIVE_RECORD_REQUEST_PARAMS
=
'action_dispatch.request.request_parameters'
def
self
.
log_if_user_blocked
(
env
)
def
initialize
(
env
)
message
=
env
.
dig
(
'warden.options'
,
:message
)
@env
=
env
end
# Devise calls User#active_for_authentication? on the User model and then
##
# throws an exception to Warden with User#inactive_message:
# Devise calls User#active_for_authentication? on the User model and then
# https://github.com/plataformatec/devise/blob/v4.2.1/lib/devise/hooks/activatable.rb#L8
# throws an exception to Warden with User#inactive_message:
#
# https://github.com/plataformatec/devise/blob/v4.2.1/lib/devise/hooks/activatable.rb#L8
# Since Warden doesn't pass the user record to the failure handler, we
#
# need to do a database lookup with the username. We can limit the
# Since Warden doesn't pass the user record to the failure handler, we
# lookups to happen when the user was blocked by checking the inactive
# need to do a database lookup with the username. We can limit the
# message passed along by Warden.
# lookups to happen when the user was blocked by checking the inactive
return
unless
message
==
User
::
BLOCKED_MESSAGE
# message passed along by Warden.
#
def
has_user_blocked_message?
strong_memoize
(
:user_blocked_message
)
do
message
=
@env
.
dig
(
'warden.options'
,
:message
)
message
==
User
::
BLOCKED_MESSAGE
end
end
# Check for either LDAP or regular GitLab account logins
def
user
login
=
env
.
dig
(
ACTIVE_RECORD_REQUEST_PARAMS
,
'username'
)
||
return
unless
has_user_blocked_message?
env
.
dig
(
ACTIVE_RECORD_REQUEST_PARAMS
,
'user'
,
'login'
)
return
unless
login
.
present?
strong_memoize
(
:user
)
do
# Check for either LDAP or regular GitLab account logins
login
=
@env
.
dig
(
ACTIVE_RECORD_REQUEST_PARAMS
,
'username'
)
||
@env
.
dig
(
ACTIVE_RECORD_REQUEST_PARAMS
,
'user'
,
'login'
)
user
=
User
.
by_login
(
login
)
User
.
by_login
(
login
)
if
login
.
present?
end
end
return
unless
user
&
.
blocked?
def
user_blocked?
user
&
.
blocked?
end
Gitlab
::
AppLogger
.
info
(
"Failed login for blocked user: user=
#{
user
.
username
}
ip=
#{
env
[
'REMOTE_ADDR'
]
}
"
)
def
log_blocked_user_activity!
SystemHooksService
.
new
.
execute_hooks_for
(
user
,
:failed_login
)
return
unless
user_blocked?
Gitlab
::
AppLogger
.
info
(
"Failed login for blocked user: user=
#{
user
.
username
}
ip=
#{
@env
[
'REMOTE_ADDR'
]
}
"
)
SystemHooksService
.
new
.
execute_hooks_for
(
user
,
:failed_login
)
true
true
rescue
TypeError
rescue
TypeError
end
end
...
...
spec/lib/gitlab/auth/blocked_user_tracker_spec.rb
View file @
1a39d24d
...
@@ -3,24 +3,26 @@ require 'spec_helper'
...
@@ -3,24 +3,26 @@ require 'spec_helper'
describe
Gitlab
::
Auth
::
BlockedUserTracker
do
describe
Gitlab
::
Auth
::
BlockedUserTracker
do
set
(
:user
)
{
create
(
:user
)
}
set
(
:user
)
{
create
(
:user
)
}
describe
'.log_if_user_blocked'
do
# TODO, add more specs
describe
'#log_blocked_user_activity!'
do
it
'does not log if user failed to login due to undefined reason'
do
it
'does not log if user failed to login due to undefined reason'
do
expect_any_instance_of
(
SystemHooksService
).
not_to
receive
(
:execute_hooks_for
)
expect_any_instance_of
(
SystemHooksService
).
not_to
receive
(
:execute_hooks_for
)
expect
(
described_class
.
log_if_user_blocked
({})
).
to
be_nil
expect
(
described_class
.
new
({}).
log_blocked_user_activity!
).
to
be_nil
end
end
it
'gracefully handles malformed environment variables'
do
it
'gracefully handles malformed environment variables'
do
env
=
{
'warden.options'
=>
'test'
}
env
=
{
'warden.options'
=>
'test'
}
expect
(
described_class
.
log_if_user_blocked
(
env
)
).
to
be_nil
expect
(
described_class
.
new
(
env
).
log_blocked_user_activity!
).
to
be_nil
end
end
context
'failed login due to blocked user'
do
context
'failed login due to blocked user'
do
let
(
:base_env
)
{
{
'warden.options'
=>
{
message:
User
::
BLOCKED_MESSAGE
}
}
}
let
(
:base_env
)
{
{
'warden.options'
=>
{
message:
User
::
BLOCKED_MESSAGE
}
}
}
let
(
:env
)
{
base_env
.
merge
(
request_env
)
}
let
(
:env
)
{
base_env
.
merge
(
request_env
)
}
subject
{
described_class
.
log_if_user_blocked
(
env
)
}
subject
{
described_class
.
new
(
env
).
log_blocked_user_activity!
}
before
do
before
do
expect_any_instance_of
(
SystemHooksService
).
to
receive
(
:execute_hooks_for
).
with
(
user
,
:failed_login
)
expect_any_instance_of
(
SystemHooksService
).
to
receive
(
:execute_hooks_for
).
with
(
user
,
:failed_login
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment