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
1
Merge Requests
1
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
nexedi
gitlab-ce
Commits
5269058d
Commit
5269058d
authored
Jan 28, 2016
by
Achilleas Pipinellis
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into es_docs
parents
130dfd7c
27e2d103
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
216 additions
and
12 deletions
+216
-12
app/controllers/application_controller.rb
app/controllers/application_controller.rb
+6
-2
app/controllers/sessions_controller.rb
app/controllers/sessions_controller.rb
+24
-10
app/models/geo_node.rb
app/models/geo_node.rb
+30
-0
app/validators/host_validator.rb
app/validators/host_validator.rb
+22
-0
db/migrate/20160112174440_create_geo_nodes.rb
db/migrate/20160112174440_create_geo_nodes.rb
+11
-0
db/schema.rb
db/schema.rb
+10
-0
lib/gitlab/geo.rb
lib/gitlab/geo.rb
+27
-0
spec/factories.rb
spec/factories.rb
+10
-0
spec/lib/gitlab/geo_spec.rb
spec/lib/gitlab/geo_spec.rb
+71
-0
spec/support/request_store.rb
spec/support/request_store.rb
+5
-0
No files found.
app/controllers/application_controller.rb
View file @
5269058d
...
@@ -100,12 +100,16 @@ class ApplicationController < ActionController::Base
...
@@ -100,12 +100,16 @@ class ApplicationController < ActionController::Base
flash
[
:alert
]
=
"Your account is blocked. Retry when an admin has unblocked it."
flash
[
:alert
]
=
"Your account is blocked. Retry when an admin has unblocked it."
new_user_session_path
new_user_session_path
else
else
stored_location_for
(
:redirect
)
||
stored_location_for
(
resource
)
||
root_path
stored_location_for
(
:
geo_node
)
||
stored_location_for
(
:
redirect
)
||
stored_location_for
(
resource
)
||
root_path
end
end
end
end
def
after_sign_out_path_for
(
resource
)
def
after_sign_out_path_for
(
resource
)
current_application_settings
.
after_sign_out_path
||
new_user_session_path
if
Gitlab
::
Geo
.
readonly?
Gitlab
::
Geo
.
primary_node
.
url
else
current_application_settings
.
after_sign_out_path
||
new_user_session_path
end
end
end
def
abilities
def
abilities
...
...
app/controllers/sessions_controller.rb
View file @
5269058d
...
@@ -4,6 +4,7 @@ class SessionsController < Devise::SessionsController
...
@@ -4,6 +4,7 @@ class SessionsController < Devise::SessionsController
prepend_before_action
:authenticate_with_two_factor
,
only:
[
:create
]
prepend_before_action
:authenticate_with_two_factor
,
only:
[
:create
]
prepend_before_action
:store_redirect_path
,
only:
[
:new
]
prepend_before_action
:store_redirect_path
,
only:
[
:new
]
before_action
:gitlab_geo_login
,
only:
[
:new
]
before_action
:auto_sign_in_with_provider
,
only:
[
:new
]
before_action
:auto_sign_in_with_provider
,
only:
[
:new
]
before_action
:load_recaptcha
before_action
:load_recaptcha
...
@@ -44,23 +45,25 @@ class SessionsController < Devise::SessionsController
...
@@ -44,23 +45,25 @@ class SessionsController < Devise::SessionsController
end
end
def
store_redirect_path
def
store_redirect_path
redirect_
path
=
redirect_
uri
=
if
request
.
referer
.
present?
&&
(
params
[
'redirect_to_referer'
]
==
'yes'
)
if
request
.
referer
.
present?
&&
(
params
[
'redirect_to_referer'
]
==
'yes'
)
referer_uri
=
URI
(
request
.
referer
)
URI
(
request
.
referer
)
if
referer_uri
.
host
==
Gitlab
.
config
.
gitlab
.
host
referer_uri
.
path
else
request
.
fullpath
end
else
else
request
.
fullpath
URI
(
request
.
url
)
end
end
# Prevent a 'you are already signed in' message directly after signing:
# Prevent a 'you are already signed in' message directly after signing:
# we should never redirect to '/users/sign_in' after signing in successfully.
# we should never redirect to '/users/sign_in' after signing in successfully.
unless
redirect_path
==
new_user_session_path
if
redirect_uri
.
path
==
new_user_session_path
store_location_for
(
:redirect
,
redirect_path
)
return
true
elsif
redirect_uri
.
host
==
Gitlab
.
config
.
gitlab
.
host
&&
redirect_uri
.
port
==
Gitlab
.
config
.
gitlab
.
port
redirect_to
=
redirect_uri
.
to_s
elsif
Gitlab
::
Geo
.
geo_node?
(
host:
redirect_uri
.
host
,
port:
redirect_uri
.
port
)
redirect_to
=
redirect_uri
.
to_s
end
end
@redirect_to
=
redirect_to
store_location_for
(
:redirect
,
redirect_to
)
end
end
def
authenticate_with_two_factor
def
authenticate_with_two_factor
...
@@ -85,6 +88,17 @@ class SessionsController < Devise::SessionsController
...
@@ -85,6 +88,17 @@ class SessionsController < Devise::SessionsController
end
end
end
end
def
gitlab_geo_login
if
!
signed_in?
&&
Gitlab
::
Geo
.
enabled?
&&
Gitlab
::
Geo
.
readonly?
# share full url with primary node by shared session
user_return_to
=
URI
.
join
(
root_url
,
session
[
:user_return_to
]).
to_s
session
[
:geo_node_return_to
]
=
@redirect_to
||
user_return_to
login_uri
=
URI
.
join
(
Gitlab
::
Geo
.
primary_node
.
url
,
new_session_path
(
:user
)).
to_s
redirect_to
login_uri
end
end
def
auto_sign_in_with_provider
def
auto_sign_in_with_provider
provider
=
Gitlab
.
config
.
omniauth
.
auto_sign_in_with_provider
provider
=
Gitlab
.
config
.
omniauth
.
auto_sign_in_with_provider
return
unless
provider
.
present?
return
unless
provider
.
present?
...
...
app/models/geo_node.rb
0 → 100644
View file @
5269058d
# == Schema Information
#
# 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
:schema
,
'http'
default_value_for
:port
,
80
default_value_for
:relative_url_root
,
''
default_value_for
:primary
,
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
def
url
uri
.
to_s
end
end
app/validators/host_validator.rb
0 → 100644
View file @
5269058d
# HostnameValidator
#
# 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
HostValidator
<
ActiveModel
::
EachValidator
def
validate_each
(
record
,
attribute
,
value
)
unless
valid_host?
(
value
)
record
.
errors
.
add
(
attribute
,
'must be a valid hostname!'
)
end
end
private
def
valid_host?
(
value
)
URI
.
parse
(
"http://
#{
value
}
"
).
host
==
value
rescue
URI
::
InvalidURIError
false
end
end
db/migrate/20160112174440_create_geo_nodes.rb
0 → 100644
View file @
5269058d
class
CreateGeoNodes
<
ActiveRecord
::
Migration
def
change
create_table
:geo_nodes
do
|
t
|
t
.
string
:schema
t
.
string
:host
,
index:
true
t
.
integer
:port
t
.
string
:relative_url_root
t
.
boolean
:primary
,
index:
true
end
end
end
db/schema.rb
View file @
5269058d
...
@@ -404,6 +404,16 @@ ActiveRecord::Schema.define(version: 20160120172143) do
...
@@ -404,6 +404,16 @@ ActiveRecord::Schema.define(version: 20160120172143) do
add_index
"forked_project_links"
,
[
"forked_to_project_id"
],
name:
"index_forked_project_links_on_forked_to_project_id"
,
unique:
true
,
using: :btree
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
|
create_table
"git_hooks"
,
force: :cascade
do
|
t
|
t
.
string
"force_push_regex"
t
.
string
"force_push_regex"
t
.
string
"delete_branch_regex"
t
.
string
"delete_branch_regex"
...
...
lib/gitlab/geo.rb
0 → 100644
View file @
5269058d
module
Gitlab
module
Geo
def
self
.
current_node
RequestStore
.
store
[
:geo_node_current
]
||=
begin
GeoNode
.
find_by
(
host:
Gitlab
.
config
.
gitlab
.
host
,
port:
Gitlab
.
config
.
gitlab
.
port
,
relative_url_root:
Gitlab
.
config
.
gitlab
.
relative_url_root
)
end
end
def
self
.
primary_node
RequestStore
.
store
[
:geo_node_primary
]
||=
GeoNode
.
find_by
(
primary:
true
)
end
def
self
.
enabled?
RequestStore
.
store
[
:geo_node_enabled
]
||=
GeoNode
.
exists?
end
def
self
.
readonly?
RequestStore
.
store
[
:geo_node_readonly
]
||=
self
.
enabled?
&&
!
self
.
current_node
.
primary?
end
def
self
.
geo_node?
(
host
:,
port
:)
GeoNode
.
where
(
host:
host
,
port:
port
).
exists?
end
end
end
spec/factories.rb
View file @
5269058d
...
@@ -244,4 +244,14 @@ FactoryGirl.define do
...
@@ -244,4 +244,14 @@ FactoryGirl.define do
factory
:license
do
factory
:license
do
data
{
build
(
:gitlab_license
).
export
}
data
{
build
(
:gitlab_license
).
export
}
end
end
factory
:geo_node
do
host
{
Gitlab
.
config
.
gitlab
.
host
}
sequence
(
:port
)
{
|
n
|
n
}
trait
:primary
do
primary
true
port
{
Gitlab
.
config
.
gitlab
.
port
}
end
end
end
end
spec/lib/gitlab/geo_spec.rb
0 → 100644
View file @
5269058d
require
'spec_helper'
describe
Gitlab
::
Geo
,
lib:
true
do
let
(
:primary_node
)
{
FactoryGirl
.
create
(
:geo_node
,
:primary
)
}
let
(
:secondary_node
)
{
FactoryGirl
.
create
(
:geo_node
)
}
describe
'current_node'
do
before
(
:each
)
{
primary_node
}
it
'returns a GeoNode instance'
do
expect
(
described_class
.
current_node
).
to
eq
(
primary_node
)
end
end
describe
'primary_node'
do
before
(
:each
)
do
primary_node
secondary_node
end
it
'returns a GeoNode primary instance'
do
expect
(
described_class
.
current_node
).
to
eq
(
primary_node
)
end
end
describe
'enabled?'
do
context
'when any GeoNode exists'
do
before
(
:each
)
{
secondary_node
}
it
'returns true'
do
expect
(
described_class
.
enabled?
).
to
be_truthy
end
end
context
'when no GeoNode exists'
do
it
'returns false'
do
expect
(
described_class
.
enabled?
).
to
be_falsey
end
end
end
describe
'readonly?'
do
context
'when current node is secondary'
do
before
(
:each
)
{
secondary_node
}
it
'returns true'
do
expect
(
described_class
).
to
receive
(
:current_node
)
{
secondary_node
}
expect
(
described_class
.
readonly?
).
to
be_truthy
end
end
context
'current node is primary'
do
before
(
:each
)
{
primary_node
}
it
'returns false when '
do
expect
(
described_class
).
to
receive
(
:current_node
)
{
primary_node
}
expect
(
described_class
.
readonly?
).
to
be_falsey
end
end
end
describe
'geo_node?'
do
it
'returns true if a node with specific host and port exists'
do
expect
(
described_class
.
geo_node?
(
host:
primary_node
.
host
,
port:
primary_node
.
port
)).
to
be_truthy
end
it
'returns false if specified host and port doesnt match any existing node'
do
expect
(
described_class
.
geo_node?
(
host:
'inexistent'
,
port:
1234
)).
to
be_falsey
end
end
end
spec/support/request_store.rb
0 → 100644
View file @
5269058d
RSpec
.
configure
do
|
config
|
config
.
before
(
:each
)
do
RequestStore
.
clear!
end
end
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