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
0a280158
Commit
0a280158
authored
Apr 15, 2016
by
Timothy Andrew
Committed by
Kamil Trzcinski
Apr 29, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Eager load `lib/api`
- So that the server doesn't have to be restarted for every change in dev.
parent
5fc310b4
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
141 additions
and
140 deletions
+141
-140
config/application.rb
config/application.rb
+2
-0
config/routes.rb
config/routes.rb
+0
-1
lib/api/api.rb
lib/api/api.rb
+1
-3
lib/api/api_guard.rb
lib/api/api_guard.rb
+137
-135
lib/ci/api/api.rb
lib/ci/api/api.rb
+1
-1
No files found.
config/application.rb
View file @
0a280158
...
@@ -79,6 +79,8 @@ module Gitlab
...
@@ -79,6 +79,8 @@ module Gitlab
# This is needed for gitlab-shell
# This is needed for gitlab-shell
ENV
[
'GITLAB_PATH_OUTSIDE_HOOK'
]
=
ENV
[
'PATH'
]
ENV
[
'GITLAB_PATH_OUTSIDE_HOOK'
]
=
ENV
[
'PATH'
]
config
.
eager_load_paths
+=
[
"
#{
Rails
.
root
}
/lib"
]
config
.
generators
do
|
g
|
config
.
generators
do
|
g
|
g
.
factory_girl
false
g
.
factory_girl
false
end
end
...
...
config/routes.rb
View file @
0a280158
require
'sidekiq/web'
require
'sidekiq/web'
require
'sidekiq/cron/web'
require
'sidekiq/cron/web'
require
'api/api'
Rails
.
application
.
routes
.
draw
do
Rails
.
application
.
routes
.
draw
do
if
Gitlab
::
Sherlock
.
enabled?
if
Gitlab
::
Sherlock
.
enabled?
...
...
lib/api/api.rb
View file @
0a280158
Dir
[
"
#{
Rails
.
root
}
/lib/api/*.rb"
].
each
{
|
file
|
require
file
}
module
API
module
API
class
API
<
Grape
::
API
class
API
<
Grape
::
API
include
APIGuard
include
::
API
::
APIGuard
version
'v3'
,
using: :path
version
'v3'
,
using: :path
rescue_from
ActiveRecord
::
RecordNotFound
do
rescue_from
ActiveRecord
::
RecordNotFound
do
...
...
lib/api/api_guard.rb
View file @
0a280158
...
@@ -2,171 +2,173 @@
...
@@ -2,171 +2,173 @@
require
'rack/oauth2'
require
'rack/oauth2'
module
APIGuard
module
API
extend
ActiveSupport
::
Concern
module
APIGuard
extend
ActiveSupport
::
Concern
included
do
|
base
|
included
do
|
base
|
# OAuth2 Resource Server Authentication
# OAuth2 Resource Server Authentication
use
Rack
::
OAuth2
::
Server
::
Resource
::
Bearer
,
'The API'
do
|
request
|
use
Rack
::
OAuth2
::
Server
::
Resource
::
Bearer
,
'The API'
do
|
request
|
# The authenticator only fetches the raw token string
# The authenticator only fetches the raw token string
# Must yield access token to store it in the env
# Must yield access token to store it in the env
request
.
access_token
request
.
access_token
end
end
helpers
HelperMethods
helpers
HelperMethods
install_error_responders
(
base
)
install_error_responders
(
base
)
end
end
# Helper Methods for Grape Endpoint
# Helper Methods for Grape Endpoint
module
HelperMethods
module
HelperMethods
# Invokes the doorkeeper guard.
# Invokes the doorkeeper guard.
#
#
# If token is presented and valid, then it sets @current_user.
# If token is presented and valid, then it sets @current_user.
#
#
# If the token does not have sufficient scopes to cover the requred scopes,
# If the token does not have sufficient scopes to cover the requred scopes,
# then it raises InsufficientScopeError.
# then it raises InsufficientScopeError.
#
#
# If the token is expired, then it raises ExpiredError.
# If the token is expired, then it raises ExpiredError.
#
#
# If the token is revoked, then it raises RevokedError.
# If the token is revoked, then it raises RevokedError.
#
#
# If the token is not found (nil), then it raises TokenNotFoundError.
# If the token is not found (nil), then it raises TokenNotFoundError.
#
#
# Arguments:
# Arguments:
#
#
# scopes: (optional) scopes required for this guard.
# scopes: (optional) scopes required for this guard.
# Defaults to empty array.
# Defaults to empty array.
#
#
def
doorkeeper_guard!
(
scopes:
[])
def
doorkeeper_guard!
(
scopes:
[])
if
(
access_token
=
find_access_token
).
nil?
if
(
access_token
=
find_access_token
).
nil?
raise
TokenNotFoundError
raise
TokenNotFoundError
else
else
case
validate_access_token
(
access_token
,
scopes
)
case
validate_access_token
(
access_token
,
scopes
)
when
Oauth2
::
AccessTokenValidationService
::
INSUFFICIENT_SCOPE
when
Oauth2
::
AccessTokenValidationService
::
INSUFFICIENT_SCOPE
raise
InsufficientScopeError
.
new
(
scopes
)
raise
InsufficientScopeError
.
new
(
scopes
)
when
Oauth2
::
AccessTokenValidationService
::
EXPIRED
when
Oauth2
::
AccessTokenValidationService
::
EXPIRED
raise
ExpiredError
raise
ExpiredError
when
Oauth2
::
AccessTokenValidationService
::
REVOKED
when
Oauth2
::
AccessTokenValidationService
::
REVOKED
raise
RevokedError
raise
RevokedError
when
Oauth2
::
AccessTokenValidationService
::
VALID
when
Oauth2
::
AccessTokenValidationService
::
VALID
@current_user
=
User
.
find
(
access_token
.
resource_owner_id
)
@current_user
=
User
.
find
(
access_token
.
resource_owner_id
)
end
end
end
end
end
end
def
doorkeeper_guard
(
scopes:
[])
def
doorkeeper_guard
(
scopes:
[])
if
access_token
=
find_access_token
if
access_token
=
find_access_token
case
validate_access_token
(
access_token
,
scopes
)
case
validate_access_token
(
access_token
,
scopes
)
when
Oauth2
::
AccessTokenValidationService
::
INSUFFICIENT_SCOPE
when
Oauth2
::
AccessTokenValidationService
::
INSUFFICIENT_SCOPE
raise
InsufficientScopeError
.
new
(
scopes
)
raise
InsufficientScopeError
.
new
(
scopes
)
when
Oauth2
::
AccessTokenValidationService
::
EXPIRED
when
Oauth2
::
AccessTokenValidationService
::
EXPIRED
raise
ExpiredError
raise
ExpiredError
when
Oauth2
::
AccessTokenValidationService
::
REVOKED
when
Oauth2
::
AccessTokenValidationService
::
REVOKED
raise
RevokedError
raise
RevokedError
when
Oauth2
::
AccessTokenValidationService
::
VALID
when
Oauth2
::
AccessTokenValidationService
::
VALID
@current_user
=
User
.
find
(
access_token
.
resource_owner_id
)
@current_user
=
User
.
find
(
access_token
.
resource_owner_id
)
end
end
end
end
end
end
def
current_user
@current_user
end
private
def
current_user
def
find_access_token
@current_user
@access_token
||=
Doorkeeper
.
authenticate
(
doorkeeper_request
,
Doorkeeper
.
configuration
.
access_token_methods
)
end
end
def
doorkeeper_request
private
@doorkeeper_request
||=
ActionDispatch
::
Request
.
new
(
env
)
def
find_access_token
end
@access_token
||=
Doorkeeper
.
authenticate
(
doorkeeper_request
,
Doorkeeper
.
configuration
.
access_token_methods
)
end
def
validate_access_token
(
access_token
,
scopes
)
def
doorkeeper_request
Oauth2
::
AccessTokenValidationService
.
validate
(
access_token
,
scopes:
scopes
)
@doorkeeper_request
||=
ActionDispatch
::
Request
.
new
(
env
)
end
end
end
module
ClassMethods
def
validate_access_token
(
access_token
,
scopes
)
# Installs the doorkeeper guard on the whole Grape API endpoint.
Oauth2
::
AccessTokenValidationService
.
validate
(
access_token
,
scopes:
scopes
)
#
# Arguments:
#
# scopes: (optional) scopes required for this guard.
# Defaults to empty array.
#
def
guard_all!
(
scopes:
[])
before
do
guard!
scopes:
scopes
end
end
end
end
private
module
ClassMethods
def
install_error_responders
(
base
)
# Installs the doorkeeper guard on the whole Grape API endpoint.
error_classes
=
[
MissingTokenError
,
TokenNotFoundError
,
#
ExpiredError
,
RevokedError
,
InsufficientScopeError
]
# Arguments:
#
# scopes: (optional) scopes required for this guard.
# Defaults to empty array.
#
def
guard_all!
(
scopes:
[])
before
do
guard!
scopes:
scopes
end
end
base
.
send
:rescue_from
,
*
error_classes
,
oauth2_bearer_token_error_handler
private
end
def
install_error_responders
(
base
)
error_classes
=
[
MissingTokenError
,
TokenNotFoundError
,
ExpiredError
,
RevokedError
,
InsufficientScopeError
]
def
oauth2_bearer_token_error_handler
base
.
send
:rescue_from
,
*
error_classes
,
oauth2_bearer_token_error_handler
Proc
.
new
do
|
e
|
end
response
=
case
e
when
MissingTokenError
Rack
::
OAuth2
::
Server
::
Resource
::
Bearer
::
Unauthorized
.
new
when
TokenNotFoundError
Rack
::
OAuth2
::
Server
::
Resource
::
Bearer
::
Unauthorized
.
new
(
:invalid_token
,
"Bad Access Token."
)
when
ExpiredError
Rack
::
OAuth2
::
Server
::
Resource
::
Bearer
::
Unauthorized
.
new
(
:invalid_token
,
"Token is expired. You can either do re-authorization or token refresh."
)
when
RevokedError
Rack
::
OAuth2
::
Server
::
Resource
::
Bearer
::
Unauthorized
.
new
(
:invalid_token
,
"Token was revoked. You have to re-authorize from the user."
)
when
InsufficientScopeError
# FIXME: ForbiddenError (inherited from Bearer::Forbidden of Rack::Oauth2)
# does not include WWW-Authenticate header, which breaks the standard.
Rack
::
OAuth2
::
Server
::
Resource
::
Bearer
::
Forbidden
.
new
(
:insufficient_scope
,
Rack
::
OAuth2
::
Server
::
Resource
::
ErrorMethods
::
DEFAULT_DESCRIPTION
[
:insufficient_scope
],
{
scope:
e
.
scopes
})
end
response
.
finish
def
oauth2_bearer_token_error_handler
Proc
.
new
do
|
e
|
response
=
case
e
when
MissingTokenError
Rack
::
OAuth2
::
Server
::
Resource
::
Bearer
::
Unauthorized
.
new
when
TokenNotFoundError
Rack
::
OAuth2
::
Server
::
Resource
::
Bearer
::
Unauthorized
.
new
(
:invalid_token
,
"Bad Access Token."
)
when
ExpiredError
Rack
::
OAuth2
::
Server
::
Resource
::
Bearer
::
Unauthorized
.
new
(
:invalid_token
,
"Token is expired. You can either do re-authorization or token refresh."
)
when
RevokedError
Rack
::
OAuth2
::
Server
::
Resource
::
Bearer
::
Unauthorized
.
new
(
:invalid_token
,
"Token was revoked. You have to re-authorize from the user."
)
when
InsufficientScopeError
# FIXME: ForbiddenError (inherited from Bearer::Forbidden of Rack::Oauth2)
# does not include WWW-Authenticate header, which breaks the standard.
Rack
::
OAuth2
::
Server
::
Resource
::
Bearer
::
Forbidden
.
new
(
:insufficient_scope
,
Rack
::
OAuth2
::
Server
::
Resource
::
ErrorMethods
::
DEFAULT_DESCRIPTION
[
:insufficient_scope
],
{
scope:
e
.
scopes
})
end
response
.
finish
end
end
end
end
end
end
#
#
# Exceptions
# Exceptions
#
#
class
MissingTokenError
<
StandardError
;
end
class
MissingTokenError
<
StandardError
;
end
class
TokenNotFoundError
<
StandardError
;
end
class
TokenNotFoundError
<
StandardError
;
end
class
ExpiredError
<
StandardError
;
end
class
ExpiredError
<
StandardError
;
end
class
RevokedError
<
StandardError
;
end
class
RevokedError
<
StandardError
;
end
class
InsufficientScopeError
<
StandardError
class
InsufficientScopeError
<
StandardError
attr_reader
:scopes
attr_reader
:scopes
def
initialize
(
scopes
)
def
initialize
(
scopes
)
@scopes
=
scopes
@scopes
=
scopes
end
end
end
end
end
end
end
\ No newline at end of file
lib/ci/api/api.rb
View file @
0a280158
...
@@ -3,7 +3,7 @@ Dir["#{Rails.root}/lib/ci/api/*.rb"].each {|file| require file}
...
@@ -3,7 +3,7 @@ Dir["#{Rails.root}/lib/ci/api/*.rb"].each {|file| require file}
module
Ci
module
Ci
module
API
module
API
class
API
<
Grape
::
API
class
API
<
Grape
::
API
include
APIGuard
include
::
API
::
APIGuard
version
'v1'
,
using: :path
version
'v1'
,
using: :path
rescue_from
ActiveRecord
::
RecordNotFound
do
rescue_from
ActiveRecord
::
RecordNotFound
do
...
...
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