Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
李少辉-开发者
gitlab-foss
提交
b6c5a73c
G
gitlab-foss
项目概览
李少辉-开发者
/
gitlab-foss
通知
15
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
gitlab-foss
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
b6c5a73c
编写于
9月 27, 2017
作者:
D
Douwe Maan
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Make sure API responds with 401 when invalid authentication info is provided
上级
66068747
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
83 addition
and
54 deletion
+83
-54
changelogs/unreleased/dm-api-unauthorized.yml
changelogs/unreleased/dm-api-unauthorized.yml
+5
-0
lib/api/api_guard.rb
lib/api/api_guard.rb
+18
-6
lib/api/helpers.rb
lib/api/helpers.rb
+20
-10
spec/requests/api/helpers_spec.rb
spec/requests/api/helpers_spec.rb
+40
-38
未找到文件。
changelogs/unreleased/dm-api-unauthorized.yml
0 → 100644
浏览文件 @
b6c5a73c
---
title
:
Make sure API responds with 401 when invalid authentication info is provided
merge_request
:
author
:
type
:
fixed
lib/api/api_guard.rb
浏览文件 @
b6c5a73c
...
...
@@ -75,7 +75,7 @@ module API
raise
RevokedError
when
AccessTokenValidationService
::
VALID
@current_user
=
User
.
find
(
access_token
.
resource_owner_id
)
User
.
find
(
access_token
.
resource_owner_id
)
end
end
...
...
@@ -84,11 +84,13 @@ module API
return
nil
unless
token_string
.
present?
find_user_by_authentication_token
(
token_string
)
||
find_user_by_personal_access_token
(
token_string
,
scopes
)
end
user
=
find_user_by_authentication_token
(
token_string
)
||
find_user_by_personal_access_token
(
token_string
,
scopes
)
raise
UnauthorizedError
unless
user
def
current_user
@current_user
user
end
private
...
...
@@ -107,7 +109,16 @@ module API
end
def
find_access_token
@access_token
||=
Doorkeeper
.
authenticate
(
doorkeeper_request
,
Doorkeeper
.
configuration
.
access_token_methods
)
return
@access_token
if
defined?
(
@access_token
)
token
=
Doorkeeper
::
OAuth
::
Token
.
from_request
(
doorkeeper_request
,
*
Doorkeeper
.
configuration
.
access_token_methods
)
return
@access_token
=
nil
unless
token
@access_token
=
Doorkeeper
::
AccessToken
.
by_token
(
token
)
raise
UnauthorizedError
unless
@access_token
@access_token
.
revoke_previous_refresh_token!
@access_token
end
def
doorkeeper_request
...
...
@@ -169,6 +180,7 @@ module API
TokenNotFoundError
=
Class
.
new
(
StandardError
)
ExpiredError
=
Class
.
new
(
StandardError
)
RevokedError
=
Class
.
new
(
StandardError
)
UnauthorizedError
=
Class
.
new
(
StandardError
)
class
InsufficientScopeError
<
StandardError
attr_reader
:scopes
...
...
lib/api/helpers.rb
浏览文件 @
b6c5a73c
...
...
@@ -3,6 +3,8 @@ module API
include
Gitlab
::
Utils
include
Helpers
::
Pagination
UnauthorizedError
=
Class
.
new
(
StandardError
)
SUDO_HEADER
=
"HTTP_SUDO"
.
freeze
SUDO_PARAM
=
:sudo
...
...
@@ -139,7 +141,7 @@ module API
end
def
authenticate!
unauthorized!
unless
current_user
&&
can?
(
initial_current_user
,
:access_api
)
unauthorized!
unless
current_user
end
def
authenticate_non_get!
...
...
@@ -397,19 +399,27 @@ module API
def
initial_current_user
return
@initial_current_user
if
defined?
(
@initial_current_user
)
Gitlab
::
Auth
::
UniqueIpsLimiter
.
limit_user!
do
@initial_current_user
||=
find_user_by_private_token
(
scopes:
scopes_registered_for_endpoint
)
@initial_current_user
||=
doorkeeper_guard
(
scopes:
scopes_registered_for_endpoint
)
@initial_current_user
||=
find_user_from_warden
unless
@initial_current_user
&&
Gitlab
::
UserAccess
.
new
(
@initial_current_user
).
allowed?
@initial_current_user
=
nil
end
@initial_current_user
begin
@initial_current_user
=
Gitlab
::
Auth
::
UniqueIpsLimiter
.
limit_user!
{
find_current_user
}
rescue
APIGuard
::
UnauthorizedError
,
UnauthorizedError
unauthorized!
end
end
def
find_current_user
user
=
find_user_by_private_token
(
scopes:
scopes_registered_for_endpoint
)
||
doorkeeper_guard
(
scopes:
scopes_registered_for_endpoint
)
||
find_user_from_warden
return
nil
unless
user
raise
UnauthorizedError
unless
Gitlab
::
UserAccess
.
new
(
user
).
allowed?
&&
user
.
can?
(
:access_api
)
user
end
def
sudo!
return
unless
sudo_identifier
return
unless
initial_current_user
...
...
spec/requests/api/helpers_spec.rb
浏览文件 @
b6c5a73c
...
...
@@ -159,18 +159,25 @@ describe API::Helpers do
end
describe
"when authenticating using a user's private token"
do
it
"returns
nil
for an invalid token"
do
it
"returns
a 401 response
for an invalid token"
do
env
[
API
::
APIGuard
::
PRIVATE_TOKEN_HEADER
]
=
'invalid token'
allow_any_instance_of
(
self
.
class
).
to
receive
(
:doorkeeper_guard
)
{
false
}
expect
(
current_user
).
to
be_nil
expect
{
current_user
}.
to
raise_error
/401/
end
it
"returns
nil
for a user without access"
do
it
"returns
a 401 response
for a user without access"
do
env
[
API
::
APIGuard
::
PRIVATE_TOKEN_HEADER
]
=
user
.
private_token
allow_any_instance_of
(
Gitlab
::
UserAccess
).
to
receive
(
:allowed?
).
and_return
(
false
)
expect
(
current_user
).
to
be_nil
expect
{
current_user
}.
to
raise_error
/401/
end
it
'returns a 401 response for a user who is blocked'
do
user
.
block!
env
[
API
::
APIGuard
::
PRIVATE_TOKEN_HEADER
]
=
user
.
private_token
expect
{
current_user
}.
to
raise_error
/401/
end
it
"leaves user as is when sudo not specified"
do
...
...
@@ -193,24 +200,31 @@ describe API::Helpers do
allow_any_instance_of
(
self
.
class
).
to
receive
(
:doorkeeper_guard
)
{
false
}
end
it
"returns
nil
for an invalid token"
do
it
"returns
a 401 response
for an invalid token"
do
env
[
API
::
APIGuard
::
PRIVATE_TOKEN_HEADER
]
=
'invalid token'
expect
(
current_user
).
to
be_nil
expect
{
current_user
}.
to
raise_error
/401/
end
it
"returns
nil
for a user without access"
do
it
"returns
a 401 response
for a user without access"
do
env
[
API
::
APIGuard
::
PRIVATE_TOKEN_HEADER
]
=
personal_access_token
.
token
allow_any_instance_of
(
Gitlab
::
UserAccess
).
to
receive
(
:allowed?
).
and_return
(
false
)
expect
(
current_user
).
to
be_nil
expect
{
current_user
}.
to
raise_error
/401/
end
it
'returns a 401 response for a user who is blocked'
do
user
.
block!
env
[
API
::
APIGuard
::
PRIVATE_TOKEN_HEADER
]
=
personal_access_token
.
token
expect
{
current_user
}.
to
raise_error
/401/
end
it
"returns
nil
for a token without the appropriate scope"
do
it
"returns
a 401 response
for a token without the appropriate scope"
do
personal_access_token
=
create
(
:personal_access_token
,
user:
user
,
scopes:
[
'read_user'
])
env
[
API
::
APIGuard
::
PRIVATE_TOKEN_HEADER
]
=
personal_access_token
.
token
expect
(
current_user
).
to
be_nil
expect
{
current_user
}.
to
raise_error
/401/
end
it
"leaves user as is when sudo not specified"
do
...
...
@@ -226,14 +240,14 @@ describe API::Helpers do
personal_access_token
.
revoke!
env
[
API
::
APIGuard
::
PRIVATE_TOKEN_HEADER
]
=
personal_access_token
.
token
expect
(
current_user
).
to
be_nil
expect
{
current_user
}.
to
raise_error
/401/
end
it
'does not allow expired tokens'
do
personal_access_token
.
update_attributes!
(
expires_at:
1
.
day
.
ago
)
env
[
API
::
APIGuard
::
PRIVATE_TOKEN_HEADER
]
=
personal_access_token
.
token
expect
(
current_user
).
to
be_nil
expect
{
current_user
}.
to
raise_error
/401/
end
end
...
...
@@ -351,6 +365,18 @@ describe API::Helpers do
end
end
end
context
'when user is blocked'
do
before
do
user
.
block!
end
it
'changes current_user to sudo'
do
set_env
(
admin
,
user
.
id
)
expect
(
current_user
).
to
eq
(
user
)
end
end
end
context
'with regular user'
do
...
...
@@ -490,11 +516,10 @@ describe API::Helpers do
context
'current_user is nil'
do
before
do
expect_any_instance_of
(
self
.
class
).
to
receive
(
:current_user
).
and_return
(
nil
)
allow_any_instance_of
(
self
.
class
).
to
receive
(
:initial_current_user
).
and_return
(
nil
)
end
it
'returns a 401 response'
do
expect
{
authenticate!
}.
to
raise_error
'401 - {"message"=>"401 Unauthorized"}'
expect
{
authenticate!
}.
to
raise_error
/401/
end
end
...
...
@@ -502,35 +527,12 @@ describe API::Helpers do
let
(
:user
)
{
build
(
:user
)
}
before
do
expect_any_instance_of
(
self
.
class
).
to
receive
(
:current_user
).
at_least
(
:once
).
and_return
(
user
)
expect_any_instance_of
(
self
.
class
).
to
receive
(
:initial_current_user
).
and_return
(
user
)
expect_any_instance_of
(
self
.
class
).
to
receive
(
:current_user
).
and_return
(
user
)
end
it
'does not raise an error'
do
expect
{
authenticate!
}.
not_to
raise_error
end
end
context
'current_user is blocked'
do
let
(
:user
)
{
build
(
:user
,
:blocked
)
}
before
do
expect_any_instance_of
(
self
.
class
).
to
receive
(
:current_user
).
at_least
(
:once
).
and_return
(
user
)
end
it
'raises an error'
do
expect_any_instance_of
(
self
.
class
).
to
receive
(
:initial_current_user
).
and_return
(
user
)
expect
{
authenticate!
}.
to
raise_error
'401 - {"message"=>"401 Unauthorized"}'
end
it
"doesn't raise an error if an admin user is impersonating a blocked user (via sudo)"
do
admin_user
=
build
(
:user
,
:admin
)
expect_any_instance_of
(
self
.
class
).
to
receive
(
:initial_current_user
).
and_return
(
admin_user
)
expect
{
authenticate!
}.
not_to
raise_error
end
end
end
end
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录