Commit e7df3f51 authored by Jacob Vosmaer's avatar Jacob Vosmaer

Move method to User

parent 0223b58f
...@@ -246,7 +246,7 @@ class ApplicationController < ActionController::Base ...@@ -246,7 +246,7 @@ class ApplicationController < ActionController::Base
def ldap_security_check def ldap_security_check
if current_user && current_user.requires_ldap_check? if current_user && current_user.requires_ldap_check?
return unless Gitlab::LDAP::Access.try_lock_user(current_user) return unless current_user.try_obtain_ldap_lease
unless Gitlab::LDAP::Access.allowed?(current_user) unless Gitlab::LDAP::Access.allowed?(current_user)
sign_out current_user sign_out current_user
......
...@@ -612,6 +612,13 @@ class User < ActiveRecord::Base ...@@ -612,6 +612,13 @@ class User < ActiveRecord::Base
end end
end end
def try_obtain_ldap_lease
# After obtaining this lease LDAP checks will be blocked for 600 seconds
# (10 minutes) for this user.
lease = Gitlab::ExclusiveLease.new("user_ldap_check:#{id}", timeout: 600)
lease.try_obtain
end
def solo_owned_groups def solo_owned_groups
@solo_owned_groups ||= owned_groups.select do |group| @solo_owned_groups ||= owned_groups.select do |group|
group.owners == [self] group.owners == [self]
......
...@@ -8,14 +8,25 @@ module Gitlab ...@@ -8,14 +8,25 @@ module Gitlab
# servers. It is a 'cheap' alternative to using SQL queries and updates: # servers. It is a 'cheap' alternative to using SQL queries and updates:
# you do not need to change the SQL schema to start using # you do not need to change the SQL schema to start using
# ExclusiveLease. # ExclusiveLease.
#
# It is important to choose the timeout wisely. If the timeout is very
# high (1 hour) then the throughput of your operation gets very low (at
# most once an hour). If the timeout is lower than how long your
# operation may take then you cannot count on exclusivity. For example,
# if the timeout is 10 seconds and you do an operation which may take 20
# seconds then two overlapping operations may hold a lease at the
# same time.
#
class ExclusiveLease class ExclusiveLease
def initialize(key, timeout) def initialize(key, timeout:)
@key, @timeout = key, timeout @key, @timeout = key, timeout
end end
# Try to obtain the lease. Return true on succes, # Try to obtain the lease. Return true on succes,
# false if the lease is already taken. # false if the lease is already taken.
def try_obtain def try_obtain
# This is expected to be atomic because we are talking to a
# single-threaded Redis server.
!!redis.set(redis_key, redis_value, nx: true, ex: @timeout) !!redis.set(redis_key, redis_value, nx: true, ex: @timeout)
end end
......
...@@ -7,16 +7,6 @@ module Gitlab ...@@ -7,16 +7,6 @@ module Gitlab
class Access class Access
attr_reader :provider, :user attr_reader :provider, :user
# This timeout acts as a throttle on LDAP user checks. Its value of 600
# seconds (10 minutes) means that after calling try_lock_user for user
# janedoe, no new LDAP checks can start for that user for the next 10
# minutes.
LEASE_TIMEOUT = 600
def self.try_lock_user(user)
Gitlab::ExclusiveLease.new("user_ldap_check:#{user.id}", LEASE_TIMEOUT).try_obtain
end
def self.open(user, &block) def self.open(user, &block)
Gitlab::LDAP::Adapter.open(user.ldap_identity.provider) do |adapter| Gitlab::LDAP::Adapter.open(user.ldap_identity.provider) do |adapter|
block.call(self.new(user, adapter)) block.call(self.new(user, adapter))
......
...@@ -3,9 +3,8 @@ module Gitlab ...@@ -3,9 +3,8 @@ module Gitlab
def self.allowed?(user) def self.allowed?(user)
return false if user.blocked? return false if user.blocked?
if user.requires_ldap_check? && Gitlab::LDAP::Access.try_lock_user(user) if user.requires_ldap_check? && user.try_obtain_ldap_lease
return Gitlab::LDAP::Access.allowed?(user) return false unless Gitlab::LDAP::Access.allowed?(user)
end
end end
true true
......
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