Commit a1b17f13 authored by Gabriel Mazetto's avatar Gabriel Mazetto

Gitlab Geo force authentication with primary node

parent 5ab12ad0
......@@ -4,6 +4,7 @@ class SessionsController < Devise::SessionsController
prepend_before_action :authenticate_with_two_factor, only: [:create]
prepend_before_action :store_redirect_path, only: [:new]
prepend_before_action :gitlab_geo_auth, only: [:new]
before_action :auto_sign_in_with_provider, only: [:new]
before_action :load_recaptcha
......@@ -52,6 +53,8 @@ class SessionsController < Devise::SessionsController
else
request.fullpath
end
elsif session[:geo_redirect].present? && (params['redirect_to_referer'] == 'yes')
stored_location_for(:geo_redirect)
else
request.fullpath
end
......@@ -85,6 +88,16 @@ class SessionsController < Devise::SessionsController
end
end
def gitlab_geo_auth
if !signed_in? && Gitlab::Geo.enabled? && Gitlab::Geo.readonly?
# reuse location from :store_redirect_path to share with primary node by shared session
store_location_for(:geo_redirect, stored_location_for(:redirect))
login_uri = URI.join(Gitlab::Geo.primary_node.uri, new_session_path(:user, redirect_to_referer: 'yes'))
redirect_to login_uri.to_s
end
end
def auto_sign_in_with_provider
provider = Gitlab.config.omniauth.auto_sign_in_with_provider
return unless provider.present?
......
......@@ -3,15 +3,24 @@
# Table name: geo_nodes
#
# id :integer not null, primary key
# schema :string
# host :string
# port :integer
# relative_url_root :string
# primary :boolean
#
class GeoNode < ActiveRecord::Base
default_value_for :primary, false
default_value_for :schema, 'http'
default_value_for :port, 80
default_value_for :relative_url_root, ''
default_value_for :primary, false
validates :host, hostname: true, presence: true, uniqueness: { case_sensitive: false }
validates :host, host: true, presence: true, uniqueness: { case_sensitive: false, scope: :port }
validates :primary, uniqueness: { message: 'primary node already exists' }, if: :primary
validates :schema, inclusion: %w(http https)
def uri
URI.parse("#{schema}://#{host}:#{port}/#{relative_url_root}")
end
end
# HostnameValidator
#
# Custom validator for Hostnames.
# Custom validator for Hosts.
#
# This is similar to an URI validator, but will make sure no schema or
# path is present, only the domain part.
#
class HostnameValidator < ActiveModel::EachValidator
class HostValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
unless valid_hostname?(value)
record.errors.add(attribute, 'must be a valid host')
unless valid_host?(value)
record.errors.add(attribute, 'must be a valid hostname!')
end
end
private
def valid_hostname?(value)
URI.parse("fake://#{value}").hostname == value
def valid_host?(value)
URI.parse("http://#{value}").host == value
rescue URI::InvalidURIError => e
false
end
end
class CreateGeoNodes < ActiveRecord::Migration
def change
create_table :geo_nodes do |t|
t.string :host
t.string :schema
t.string :host, index: true
t.integer :port
t.string :relative_url_root
t.boolean :primary
t.boolean :primary, index: true
end
end
end
......@@ -401,11 +401,15 @@ ActiveRecord::Schema.define(version: 20160119170055) do
add_index "forked_project_links", ["forked_to_project_id"], name: "index_forked_project_links_on_forked_to_project_id", unique: true, using: :btree
create_table "geo_nodes", force: :cascade do |t|
t.string "schema"
t.string "host"
t.integer "port"
t.string "relative_url_root"
t.boolean "primary"
end
add_index "geo_nodes", ["host"], name: "index_geo_nodes_on_host", using: :btree
add_index "geo_nodes", ["primary"], name: "index_geo_nodes_on_primary", using: :btree
create_table "git_hooks", force: :cascade do |t|
t.string "force_push_regex"
t.string "delete_branch_regex"
......
module Gitlab
module Geo
def self.current_node
GeoNode.find_by(host: Gitlab.config.gitlab.host,
port: Gitlab.config.gitlab.port,
relative_url_root: Gitlab.config.gitlab.relative_url_root)
end
def self.primary_node
GeoNode.find_by(primary: true)
end
def self.enabled?
GeoNode.exists?
end
def self.current_node
GeoNode.find_by(host: Gitlab.config.gitlab.host, relative_url_root: Gitlab.config.gitlab.relative_url_root)
def self.readonly?
self.enabled? && !self.current_node.primary?
end
end
end
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