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
55f5a68f
Commit
55f5a68f
authored
Mar 23, 2016
by
Jacob Vosmaer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Get Grack::Auth tests to pass
parent
19a5e7c9
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
191 additions
and
8 deletions
+191
-8
app/controllers/projects/application_controller.rb
app/controllers/projects/application_controller.rb
+17
-5
app/controllers/projects/git_http_controller.rb
app/controllers/projects/git_http_controller.rb
+167
-0
config/routes.rb
config/routes.rb
+7
-3
No files found.
app/controllers/projects/application_controller.rb
View file @
55f5a68f
...
...
@@ -10,9 +10,6 @@ class Projects::ApplicationController < ApplicationController
def
project
unless
@project
namespace
=
params
[
:namespace_id
]
id
=
params
[
:project_id
]
||
params
[
:id
]
# Redirect from
# localhost/group/project.git
# to
...
...
@@ -23,8 +20,7 @@ class Projects::ApplicationController < ApplicationController
return
end
project_path
=
"
#{
namespace
}
/
#{
id
}
"
@project
=
Project
.
find_with_namespace
(
project_path
)
@project
=
find_project
if
@project
&&
can?
(
current_user
,
:read_project
,
@project
)
if
@project
.
path_with_namespace
!=
project_path
...
...
@@ -44,6 +40,22 @@ class Projects::ApplicationController < ApplicationController
@project
end
def
id
params
[
:project_id
]
||
params
[
:id
]
end
def
namespace
params
[
:namespace_id
]
end
def
project_path
"
#{
namespace
}
/
#{
id
}
"
end
def
find_project
Project
.
find_with_namespace
(
project_path
)
end
def
repository
@repository
||=
project
.
repository
end
...
...
app/controllers/projects/git_http_controller.rb
0 → 100644
View file @
55f5a68f
class
Projects::GitHttpController
<
Projects
::
ApplicationController
skip_before_action
:repository
before_action
:authenticate_user
before_action
:project_found?
def
git_rpc
if
upload_pack?
&&
upload_pack_allowed?
render_ok
and
return
end
render_not_found
end
%i{info_refs git_receive_pack git_upload_pack}
.
each
do
|
method
|
alias_method
method
,
:git_rpc
end
private
def
authenticate_user
return
if
project
&&
project
.
public?
&&
upload_pack?
authenticate_or_request_with_http_basic
do
|
login
,
password
|
return
@ci
=
true
if
ci_request?
(
login
,
password
)
@user
=
Gitlab
::
Auth
.
new
.
find
(
login
,
password
)
@user
||=
oauth_access_token_check
(
login
,
password
)
rate_limit_ip!
(
login
,
@user
)
end
end
def
project_found?
render_not_found
if
project
.
nil?
end
def
ci_request?
(
login
,
password
)
matched_login
=
/(?<s>^[a-zA-Z]*-ci)-token$/
.
match
(
login
)
if
project
&&
matched_login
.
present?
&&
upload_pack?
underscored_service
=
matched_login
[
's'
].
underscore
if
underscored_service
==
'gitlab_ci'
return
project
&&
project
.
valid_build_token?
(
password
)
elsif
Service
.
available_services_names
.
include?
(
underscored_service
)
service_method
=
"
#{
underscored_service
}
_service"
service
=
project
.
send
(
service_method
)
return
service
&&
service
.
activated?
&&
service
.
valid_token?
(
password
)
end
end
false
end
def
oauth_access_token_check
(
login
,
password
)
if
login
==
"oauth2"
&&
upload_pack?
&&
password
.
present?
token
=
Doorkeeper
::
AccessToken
.
by_token
(
password
)
token
&&
token
.
accessible?
&&
User
.
find_by
(
id:
token
.
resource_owner_id
)
end
end
def
rate_limit_ip!
(
login
,
user
)
# If the user authenticated successfully, we reset the auth failure count
# from Rack::Attack for that IP. A client may attempt to authenticate
# with a username and blank password first, and only after it receives
# a 401 error does it present a password. Resetting the count prevents
# false positives from occurring.
#
# Otherwise, we let Rack::Attack know there was a failed authentication
# attempt from this IP. This information is stored in the Rails cache
# (Redis) and will be used by the Rack::Attack middleware to decide
# whether to block requests from this IP.
config
=
Gitlab
.
config
.
rack_attack
.
git_basic_auth
return
user
unless
config
.
enabled
if
user
# A successful login will reset the auth failure count from this IP
Rack
::
Attack
::
Allow2Ban
.
reset
(
request
.
ip
,
config
)
else
banned
=
Rack
::
Attack
::
Allow2Ban
.
filter
(
request
.
ip
,
config
)
do
# Unless the IP is whitelisted, return true so that Allow2Ban
# increments the counter (stored in Rails.cache) for the IP
if
config
.
ip_whitelist
.
include?
(
request
.
ip
)
false
else
true
end
end
if
banned
Rails
.
logger
.
info
"IP
#{
request
.
ip
}
failed to login "
\
"as
#{
login
}
but has been temporarily banned from Git auth"
end
end
user
end
def
project
return
@project
if
defined?
(
@project
)
@project
=
find_project
end
def
id
id
=
params
[
:project_id
]
return
if
id
.
nil?
if
id
.
end_with?
(
'.wiki.git'
)
id
.
slice
(
0
,
id
.
length
-
9
)
elsif
id
.
end_with?
(
'.git'
)
id
.
slice
(
0
,
id
.
length
-
4
)
end
end
def
repo_path
@repo_path
||=
begin
if
params
[
:project_id
].
end_with?
(
'.wiki.git'
)
project
.
wiki
.
wiki
.
path
else
repository
.
path_to_repo
end
end
end
def
upload_pack?
if
action_name
==
'info_refs'
params
[
:service
]
==
'git-upload-pack'
else
action_name
==
'git_upload_pack'
end
end
def
render_ok
render
json:
{
'GL_ID'
=>
Gitlab
::
ShellEnv
.
gl_id
(
@user
),
'RepoPath'
=>
repo_path
,
}
end
def
render_not_found
render
text:
'Not Found'
,
status: :not_found
end
def
ci?
!!
@ci
end
def
user
@user
end
def
upload_pack_allowed?
if
!
Gitlab
.
config
.
gitlab_shell
.
upload_pack
false
elsif
ci?
true
elsif
user
Gitlab
::
GitAccess
.
new
(
user
,
project
).
download_access_check
.
allowed?
elsif
project
.
public?
# Allow clone/fetch for public projects
true
else
false
end
end
end
config/routes.rb
View file @
55f5a68f
...
...
@@ -59,9 +59,6 @@ Rails.application.routes.draw do
mount
Sidekiq
::
Web
,
at:
'/admin/sidekiq'
,
as: :sidekiq
end
# Enable Grack support
mount
Grack
::
AuthSpawner
,
at:
'/'
,
constraints:
lambda
{
|
request
|
/[-\/\w\.]+\.git\//
.
match
(
request
.
path_info
)
},
via:
[
:get
,
:post
,
:put
]
# Help
get
'help'
=>
'help#index'
get
'help/:category/:file'
=>
'help#show'
,
as: :help_page
,
constraints:
{
category:
/.*/
,
file:
/[^\/\.]+/
}
...
...
@@ -426,6 +423,13 @@ Rails.application.routes.draw do
end
scope
module: :projects
do
# Git HTTP clients ('git clone' etc.)
scope
constraints:
{
format:
/(git|wiki\.git)/
}
do
get
'/info/refs'
,
to:
'git_http#info_refs'
,
only: :get
get
'/git-upload-pack'
,
to:
'git_http#git_upload_pack'
,
only: :post
get
'/git-receive-pack'
,
to:
'git_http#git_receive_pack'
,
only: :post
end
# Blob routes:
get
'/new/*id'
,
to:
'blob#new'
,
constraints:
{
id:
/.+/
},
as:
'new_blob'
post
'/create/*id'
,
to:
'blob#create'
,
constraints:
{
id:
/.+/
},
as:
'create_blob'
...
...
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