Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPawel Chojnacki <pawel@chojnacki.ws>2017-02-20 17:09:05 +0300
committerPawel Chojnacki <pawel@chojnacki.ws>2017-03-06 17:41:25 +0300
commit0ef8a643489ad1a3da4431155326f0a6e206d870 (patch)
treebeb7bceb362f627e4864075e76d05e81f9b743da
parent9cc0ff8f468c54e23172492d97f6d9b428d3ad2e (diff)
Remove unecessary calls to limit_user!, UniqueIps Middleware, and address MR review
- cleanup formating in haml - clarify time window is in seconds - cleanup straneous chunks in db/schema - rename count_uniqe_ips to update_and_return_ips_count - other
-rw-r--r--app/controllers/application_controller.rb4
-rw-r--r--app/controllers/sessions_controller.rb10
-rw-r--r--app/views/admin/application_settings/_form.html.haml5
-rw-r--r--config/application.rb4
-rw-r--r--config/initializers/doorkeeper.rb6
-rw-r--r--db/migrate/20170210131347_add_unique_ips_limit_to_application_settings.rb12
-rw-r--r--db/schema.rb2
-rw-r--r--lib/gitlab/auth.rb3
-rw-r--r--lib/gitlab/auth/too_many_ips.rb17
-rw-r--r--lib/gitlab/auth/unique_ips_limiter.rb34
-rw-r--r--lib/gitlab/request_context.rb1
-rw-r--r--spec/controllers/sessions_controller_spec.rb1
-rw-r--r--spec/lib/gitlab/auth/unique_ips_limiter_spec.rb35
-rw-r--r--spec/lib/gitlab/auth_spec.rb2
-rw-r--r--spec/lib/gitlab/request_context_spec.rb10
15 files changed, 60 insertions, 86 deletions
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index cc7b7f247e8..0d3ee4f4c1f 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -40,6 +40,10 @@ class ApplicationController < ActionController::Base
render_403
end
+ rescue_from Gitlab::Auth::TooManyIps do |e|
+ head :forbidden, retry_after: UniqueIpsLimiter.config.unique_ips_limit_time_window
+ end
+
def redirect_back_or_default(default: root_path, options: {})
redirect_to request.referer.present? ? :back : default, options
end
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 3f5b92d9a99..7d81c96262f 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -67,12 +67,10 @@ class SessionsController < Devise::SessionsController
end
def find_user
- Gitlab::Auth::UniqueIpsLimiter.limit_user! do
- if session[:otp_user_id]
- User.find(session[:otp_user_id])
- elsif user_params[:login]
- User.by_login(user_params[:login])
- end
+ if session[:otp_user_id]
+ User.find(session[:otp_user_id])
+ elsif user_params[:login]
+ User.by_login(user_params[:login])
end
end
diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml
index 7f25f76d0cb..00366b0a8c9 100644
--- a/app/views/admin/application_settings/_form.html.haml
+++ b/app/views/admin/application_settings/_form.html.haml
@@ -366,7 +366,8 @@
= f.label :unique_ips_limit_enabled do
= f.check_box :unique_ips_limit_enabled
Limit sign in from multiple ips
- %span.help-block#recaptcha_help_block Helps prevent malicious users hide their activity
+ %span.help-block#unique_ip_help_block
+ Helps prevent malicious users hide their activity
.form-group
= f.label :unique_ips_limit_per_user, 'IPs per user', class: 'control-label col-sm-2'
@@ -380,7 +381,7 @@
.col-sm-10
= f.number_field :unique_ips_limit_time_window, class: 'form-control'
.help-block
- How long an IP will be counted towards the limit
+ How many seconds an IP will be counted towards the limit
%fieldset
%legend Abuse reports
diff --git a/config/application.rb b/config/application.rb
index c4dea9e92b0..8003c055b27 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -8,8 +8,6 @@ module Gitlab
class Application < Rails::Application
require_dependency Rails.root.join('lib/gitlab/redis')
require_dependency Rails.root.join('lib/gitlab/request_context')
- require_dependency Rails.root.join('lib/gitlab/auth')
- require_dependency Rails.root.join('lib/gitlab/auth/unique_ips_limiter')
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
@@ -114,8 +112,6 @@ module Gitlab
config.middleware.insert_before Warden::Manager, Rack::Attack
- config.middleware.insert_before Warden::Manager, Gitlab::Auth::UniqueIpsLimiter
-
# Allow access to GitLab API from other domains
config.middleware.insert_before Warden::Manager, Rack::Cors do
allow do
diff --git a/config/initializers/doorkeeper.rb b/config/initializers/doorkeeper.rb
index 44b658e5872..88cd0f5f652 100644
--- a/config/initializers/doorkeeper.rb
+++ b/config/initializers/doorkeeper.rb
@@ -12,10 +12,8 @@ Doorkeeper.configure do
end
resource_owner_from_credentials do |routes|
- Gitlab::Auth::UniqueIpsLimiter.limit_user! do
- user = Gitlab::Auth.find_with_user_password(params[:username], params[:password])
- user unless user.try(:two_factor_enabled?)
- end
+ user = Gitlab::Auth.find_with_user_password(params[:username], params[:password])
+ user unless user.try(:two_factor_enabled?)
end
# If you want to restrict access to the web interface for adding oauth authorized applications, you need to declare the block below.
diff --git a/db/migrate/20170210131347_add_unique_ips_limit_to_application_settings.rb b/db/migrate/20170210131347_add_unique_ips_limit_to_application_settings.rb
index 2aa305f6b58..cbcf9a30b3c 100644
--- a/db/migrate/20170210131347_add_unique_ips_limit_to_application_settings.rb
+++ b/db/migrate/20170210131347_add_unique_ips_limit_to_application_settings.rb
@@ -4,14 +4,14 @@ class AddUniqueIpsLimitToApplicationSettings < ActiveRecord::Migration
disable_ddl_transaction!
def up
- add_column_with_default(:application_settings, :unique_ips_limit_per_user, :integer, default: 10)
- add_column_with_default(:application_settings, :unique_ips_limit_time_window, :integer, default: 3600)
- add_column_with_default(:application_settings, :unique_ips_limit_enabled, :boolean, default: false)
+ add_column_with_default :application_settings, :unique_ips_limit_per_user, :integer, default: 10
+ add_column_with_default :application_settings, :unique_ips_limit_time_window, :integer, default: 3600
+ add_column_with_default :application_settings, :unique_ips_limit_enabled, :boolean, default: false
end
def down
- remove_column(:application_settings, :unique_ips_limit_per_user)
- remove_column(:application_settings, :unique_ips_limit_time_window)
- remove_column(:application_settings, :unique_ips_limit_enabled)
+ remove_column :application_settings, :unique_ips_limit_per_user
+ remove_column :application_settings, :unique_ips_limit_time_window
+ remove_column :application_settings, :unique_ips_limit_enabled
end
end
diff --git a/db/schema.rb b/db/schema.rb
index 8aed4e13b28..be54b177fa6 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -586,9 +586,9 @@ ActiveRecord::Schema.define(version: 20170305203726) do
end
add_index "labels", ["group_id", "project_id", "title"], name: "index_labels_on_group_id_and_project_id_and_title", unique: true, using: :btree
+ add_index "labels", ["type", "project_id"], name: "index_labels_on_type_and_project_id", using: :btree
add_index "labels", ["project_id"], name: "index_labels_on_project_id", using: :btree
add_index "labels", ["title"], name: "index_labels_on_title", using: :btree
- add_index "labels", ["type", "project_id"], name: "index_labels_on_type_and_project_id", using: :btree
create_table "lfs_objects", force: :cascade do |t|
t.string "oid", null: false
diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb
index 8e2aee2d7a0..0a0bd0e781c 100644
--- a/lib/gitlab/auth.rb
+++ b/lib/gitlab/auth.rb
@@ -22,9 +22,8 @@ module Gitlab
user_with_password_for_git(login, password) ||
Gitlab::Auth::Result.new
- Gitlab::Auth::UniqueIpsLimiter.limit_user!(result.actor)
-
rate_limit!(ip, success: result.success?, login: login)
+ Gitlab::Auth::UniqueIpsLimiter.limit_user!(result.actor)
result
end
diff --git a/lib/gitlab/auth/too_many_ips.rb b/lib/gitlab/auth/too_many_ips.rb
new file mode 100644
index 00000000000..ed862791551
--- /dev/null
+++ b/lib/gitlab/auth/too_many_ips.rb
@@ -0,0 +1,17 @@
+module Gitlab
+ module Auth
+ class TooManyIps < StandardError
+ attr_reader :user_id, :ip, :unique_ips_count
+
+ def initialize(user_id, ip, unique_ips_count)
+ @user_id = user_id
+ @ip = ip
+ @unique_ips_count = unique_ips_count
+ end
+
+ def message
+ "User #{user_id} from IP: #{ip} tried logging from too many ips: #{unique_ips_count}"
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/auth/unique_ips_limiter.rb b/lib/gitlab/auth/unique_ips_limiter.rb
index 4b2b758be8a..7b1aa736769 100644
--- a/lib/gitlab/auth/unique_ips_limiter.rb
+++ b/lib/gitlab/auth/unique_ips_limiter.rb
@@ -1,19 +1,5 @@
module Gitlab
module Auth
- class TooManyIps < StandardError
- attr_reader :user_id, :ip, :unique_ips_count
-
- def initialize(user_id, ip, unique_ips_count)
- @user_id = user_id
- @ip = ip
- @unique_ips_count = unique_ips_count
- end
-
- def message
- "User #{user_id} from IP: #{ip} tried logging from too many ips: #{unique_ips_count}"
- end
- end
-
class UniqueIpsLimiter
USER_UNIQUE_IPS_PREFIX = 'user_unique_ips'
@@ -21,7 +7,7 @@ module Gitlab
def limit_user_id!(user_id)
if config.unique_ips_limit_enabled
ip = RequestContext.client_ip
- unique_ips = count_unique_ips(user_id, ip)
+ unique_ips = update_and_return_ips_count(user_id, ip)
raise TooManyIps.new(user_id, ip, unique_ips) if unique_ips > config.unique_ips_limit_per_user
end
end
@@ -36,8 +22,8 @@ module Gitlab
Gitlab::CurrentSettings.current_application_settings
end
- def count_unique_ips(user_id, ip)
- time = Time.now.to_i
+ def update_and_return_ips_count(user_id, ip)
+ time = Time.now.utc.to_i
key = "#{USER_UNIQUE_IPS_PREFIX}:#{user_id}"
Gitlab::Redis.with do |redis|
@@ -51,20 +37,6 @@ module Gitlab
end
end
end
-
- def initialize(app)
- @app = app
- end
-
- def call(env)
- begin
- @app.call(env)
- rescue TooManyIps => ex
-
- Rails.logger.info ex.message
- [403, { 'Content-Type' => 'text/plain', 'Retry-After' => UniqueIpsLimiter.config.unique_ips_limit_time_window }, ["Too many logins from different IPs\n"]]
- end
- end
end
end
end
diff --git a/lib/gitlab/request_context.rb b/lib/gitlab/request_context.rb
index 36a5d94d98a..548adf4775a 100644
--- a/lib/gitlab/request_context.rb
+++ b/lib/gitlab/request_context.rb
@@ -14,7 +14,6 @@ module Gitlab
end
def call(env)
- raise RequestStoreNotActive.new unless RequestStore.active?
req = Rack::Request.new(env)
RequestStore[:client_ip] = req.ip
diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb
index 56ed11737ad..fe11bdf4a78 100644
--- a/spec/controllers/sessions_controller_spec.rb
+++ b/spec/controllers/sessions_controller_spec.rb
@@ -33,6 +33,7 @@ describe SessionsController do
include_examples 'user login operation with unique ip limit' do
def operation
post(:create, user: { login: user.username, password: user.password })
+
expect(subject.current_user).to eq user
end
end
diff --git a/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb b/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb
index 2b21a76c59d..3214786d172 100644
--- a/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb
+++ b/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb
@@ -7,36 +7,35 @@ describe Gitlab::Auth::UniqueIpsLimiter, :redis, lib: true do
describe '#count_unique_ips' do
context 'non unique IPs' do
it 'properly counts them' do
- expect(Gitlab::Auth::UniqueIpsLimiter.count_unique_ips(user.id, 'ip1')).to eq(1)
- expect(Gitlab::Auth::UniqueIpsLimiter.count_unique_ips(user.id, 'ip1')).to eq(1)
+ expect(described_class.update_and_return_ips_count(user.id, 'ip1')).to eq(1)
+ expect(described_class.update_and_return_ips_count(user.id, 'ip1')).to eq(1)
end
end
context 'unique IPs' do
it 'properly counts them' do
- expect(Gitlab::Auth::UniqueIpsLimiter.count_unique_ips(user.id, 'ip2')).to eq(1)
- expect(Gitlab::Auth::UniqueIpsLimiter.count_unique_ips(user.id, 'ip3')).to eq(2)
+ expect(described_class.update_and_return_ips_count(user.id, 'ip2')).to eq(1)
+ expect(described_class.update_and_return_ips_count(user.id, 'ip3')).to eq(2)
end
end
it 'resets count after specified time window' do
- cur_time = Time.now
- allow(Time).to receive(:now).and_return(cur_time)
-
- expect(Gitlab::Auth::UniqueIpsLimiter.count_unique_ips(user.id, 'ip2')).to eq(1)
- expect(Gitlab::Auth::UniqueIpsLimiter.count_unique_ips(user.id, 'ip3')).to eq(2)
-
- allow(Time).to receive(:now).and_return(cur_time + Gitlab::Auth::UniqueIpsLimiter.config.unique_ips_limit_time_window)
-
- expect(Gitlab::Auth::UniqueIpsLimiter.count_unique_ips(user.id, 'ip4')).to eq(1)
- expect(Gitlab::Auth::UniqueIpsLimiter.count_unique_ips(user.id, 'ip5')).to eq(2)
+ Timecop.freeze do
+ expect(described_class.update_and_return_ips_count(user.id, 'ip2')).to eq(1)
+ expect(described_class.update_and_return_ips_count(user.id, 'ip3')).to eq(2)
+
+ Timecop.travel(Time.now.utc + described_class.config.unique_ips_limit_time_window) do
+ expect(described_class.update_and_return_ips_count(user.id, 'ip4')).to eq(1)
+ expect(described_class.update_and_return_ips_count(user.id, 'ip5')).to eq(2)
+ end
+ end
end
end
describe '#limit_user!' do
include_examples 'user login operation with unique ip limit' do
def operation
- Gitlab::Auth::UniqueIpsLimiter.limit_user! { user }
+ described_class.limit_user! { user }
end
end
@@ -45,13 +44,13 @@ describe Gitlab::Auth::UniqueIpsLimiter, :redis, lib: true do
it 'blocks user trying to login from third ip' do
change_ip('ip1')
- expect(Gitlab::Auth::UniqueIpsLimiter.limit_user! { user }).to eq(user)
+ expect(described_class.limit_user! { user }).to eq(user)
change_ip('ip2')
- expect(Gitlab::Auth::UniqueIpsLimiter.limit_user! { user }).to eq(user)
+ expect(described_class.limit_user! { user }).to eq(user)
change_ip('ip3')
- expect { Gitlab::Auth::UniqueIpsLimiter.limit_user! { user } }.to raise_error(Gitlab::Auth::TooManyIps)
+ expect { described_class.limit_user! { user } }.to raise_error(Gitlab::Auth::TooManyIps)
end
end
end
diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb
index 860189dcf3c..daf8f5c1d6c 100644
--- a/spec/lib/gitlab/auth_spec.rb
+++ b/spec/lib/gitlab/auth_spec.rb
@@ -206,7 +206,7 @@ describe Gitlab::Auth, lib: true do
include_examples 'user login operation with unique ip limit' do
def operation
- expect(gl_auth.find_with_user_password(username, password)).to eql user
+ expect(gl_auth.find_with_user_password(username, password)).to eq(user)
end
end
diff --git a/spec/lib/gitlab/request_context_spec.rb b/spec/lib/gitlab/request_context_spec.rb
index 69c5549c39c..b2828f7e5e0 100644
--- a/spec/lib/gitlab/request_context_spec.rb
+++ b/spec/lib/gitlab/request_context_spec.rb
@@ -26,15 +26,5 @@ describe Gitlab::RequestContext, lib: true do
it { is_expected.to be_nil }
end
end
-
- context 'RequestStore is not active' do
- it { is_expected.to be_nil }
-
- context 'when RequestContext mw is run' do
- subject { -> { Gitlab::RequestContext.new(app).call(env) } }
-
- it { is_expected.to raise_error(Gitlab::RequestStoreNotActive) }
- end
- end
end
end