Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
小 白蛋
Harbor
Commits
4a3dc9ae
Unverified
Commit
4a3dc9ae
authored
5 years ago
by
Wang Yan
Committed by
GitHub
5 years ago
Browse files
Options
Download
Email Patches
Plain Diff
Revert "Enable robot account to support scan pull case"
parent
d18678a4
Changes
24
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
src/common/rbac/const.go
+1
-2
src/common/rbac/const.go
src/common/security/robot/robot.go
+6
-12
src/common/security/robot/robot.go
src/common/security/robot/robot_test.go
+1
-2
src/common/security/robot/robot_test.go
src/common/token/claims.go
+4
-4
src/common/token/claims.go
src/common/token/claims_test.go
+5
-5
src/common/token/claims_test.go
src/common/token/htoken.go
+87
-0
src/common/token/htoken.go
src/common/token/htoken_test.go
+4
-22
src/common/token/htoken_test.go
src/common/token/options.go
+20
-20
src/common/token/options.go
src/common/token/options_test.go
+3
-3
src/common/token/options_test.go
src/common/utils/oidc/helper.go
+3
-3
src/common/utils/oidc/helper.go
src/core/filter/security.go
+5
-7
src/core/filter/security.go
src/core/middlewares/chain.go
+0
-2
src/core/middlewares/chain.go
src/core/middlewares/config.go
+1
-2
src/core/middlewares/config.go
src/core/middlewares/contenttrust/handler.go
+0
-4
src/core/middlewares/contenttrust/handler.go
src/core/middlewares/regtoken/handler.go
+0
-71
src/core/middlewares/regtoken/handler.go
src/core/middlewares/regtoken/handler_test.go
+0
-55
src/core/middlewares/regtoken/handler_test.go
src/core/middlewares/util/util.go
+0
-13
src/core/middlewares/util/util.go
src/core/middlewares/vulnerable/handler.go
+2
-7
src/core/middlewares/vulnerable/handler.go
src/core/service/token/authutils.go
+0
-3
src/core/service/token/authutils.go
src/core/service/token/creator.go
+0
-2
src/core/service/token/creator.go
with
142 additions
and
239 deletions
+142
-239
src/common/rbac/const.go
+
1
-
2
View file @
4a3dc9ae
...
...
@@ -28,8 +28,7 @@ const (
ActionDelete
=
Action
(
"delete"
)
ActionList
=
Action
(
"list"
)
ActionOperate
=
Action
(
"operate"
)
ActionScannerPull
=
Action
(
"scanner-pull"
)
// for robot account created by scanner to pull image, bypass the policy check
ActionOperate
=
Action
(
"operate"
)
)
// const resource variables
...
...
This diff is collapsed.
Click to expand it.
src/common/security/robot/robot.go
+
6
-
12
View file @
4a3dc9ae
...
...
@@ -47,22 +47,16 @@ func filterPolicies(namespace rbac.Namespace, policies []*rbac.Policy) []*rbac.P
return
results
}
mp
:=
getAllPolicies
(
namespace
)
mp
:=
map
[
string
]
bool
{}
for
_
,
policy
:=
range
project
.
GetAllPolicies
(
namespace
)
{
mp
[
policy
.
String
()]
=
true
}
for
_
,
policy
:=
range
policies
{
if
mp
[
policy
.
String
()]
{
results
=
append
(
results
,
policy
)
}
}
return
results
}
// getAllPolicies gets all of supported policies supported in project and external policies supported for robot account
func
getAllPolicies
(
namespace
rbac
.
Namespace
)
map
[
string
]
bool
{
mp
:=
map
[
string
]
bool
{}
for
_
,
policy
:=
range
project
.
GetAllPolicies
(
namespace
)
{
mp
[
policy
.
String
()]
=
true
}
scannerPull
:=
&
rbac
.
Policy
{
Resource
:
namespace
.
Resource
(
rbac
.
ResourceRepository
),
Action
:
rbac
.
ActionScannerPull
}
mp
[
scannerPull
.
String
()]
=
true
return
mp
return
results
}
This diff is collapsed.
Click to expand it.
src/common/security/robot/robot_test.go
+
1
-
2
View file @
4a3dc9ae
...
...
@@ -44,11 +44,10 @@ func TestGetPolicies(t *testing.T) {
func
TestNewRobot
(
t
*
testing
.
T
)
{
policies
:=
[]
*
rbac
.
Policy
{
{
Resource
:
"/project/1/repository"
,
Action
:
"pull"
},
{
Resource
:
"/project/1/repository"
,
Action
:
"scanner-pull"
},
{
Resource
:
"/project/library/repository"
,
Action
:
"pull"
},
{
Resource
:
"/project/library/repository"
,
Action
:
"push"
},
}
robot
:=
NewRobot
(
"test"
,
rbac
.
NewProjectNamespace
(
1
,
false
),
policies
)
assert
.
Len
(
t
,
robot
.
GetPolicies
(),
2
)
assert
.
Len
(
t
,
robot
.
GetPolicies
(),
1
)
}
This diff is collapsed.
Click to expand it.
src/
pkg
/token/claims
/robot/robot
.go
→
src/
common
/token/claims.go
+
4
-
4
View file @
4a3dc9ae
package
robot
package
token
import
(
"errors"
...
...
@@ -6,8 +6,8 @@ import (
"github.com/goharbor/harbor/src/common/rbac"
)
// Claim implements the interface of jwt.Claims
type
Claim
struct
{
//
Robot
Claim
s
implements the interface of jwt.Claims
type
Robot
Claim
s
struct
{
jwt
.
StandardClaims
TokenID
int64
`json:"id"`
ProjectID
int64
`json:"pid"`
...
...
@@ -15,7 +15,7 @@ type Claim struct {
}
// Valid valid the claims "tokenID, projectID and access".
func
(
rc
Claim
)
Valid
()
error
{
func
(
rc
Robot
Claim
s
)
Valid
()
error
{
if
rc
.
TokenID
<
0
{
return
errors
.
New
(
"Token id must an valid INT"
)
}
...
...
This diff is collapsed.
Click to expand it.
src/
pkg
/token/claims
/robot/robot
_test.go
→
src/
common
/token/claims_test.go
+
5
-
5
View file @
4a3dc9ae
package
robot
package
token
import
(
"github.com/goharbor/harbor/src/common/rbac"
...
...
@@ -15,7 +15,7 @@ func TestValid(t *testing.T) {
policies
:=
[]
*
rbac
.
Policy
{}
policies
=
append
(
policies
,
rbacPolicy
)
rClaims
:=
&
Claim
{
rClaims
:=
&
Robot
Claim
s
{
TokenID
:
1
,
ProjectID
:
2
,
Access
:
policies
,
...
...
@@ -32,7 +32,7 @@ func TestUnValidTokenID(t *testing.T) {
policies
:=
[]
*
rbac
.
Policy
{}
policies
=
append
(
policies
,
rbacPolicy
)
rClaims
:=
&
Claim
{
rClaims
:=
&
Robot
Claim
s
{
TokenID
:
-
1
,
ProjectID
:
2
,
Access
:
policies
,
...
...
@@ -49,7 +49,7 @@ func TestUnValidProjectID(t *testing.T) {
policies
:=
[]
*
rbac
.
Policy
{}
policies
=
append
(
policies
,
rbacPolicy
)
rClaims
:=
&
Claim
{
rClaims
:=
&
Robot
Claim
s
{
TokenID
:
1
,
ProjectID
:
-
2
,
Access
:
policies
,
...
...
@@ -59,7 +59,7 @@ func TestUnValidProjectID(t *testing.T) {
func
TestUnValidPolicy
(
t
*
testing
.
T
)
{
rClaims
:=
&
Claim
{
rClaims
:=
&
Robot
Claim
s
{
TokenID
:
1
,
ProjectID
:
2
,
Access
:
nil
,
...
...
This diff is collapsed.
Click to expand it.
src/
pkg
/token/token.go
→
src/
common
/token/
h
token.go
+
87
-
0
View file @
4a3dc9ae
...
...
@@ -6,36 +6,46 @@ import (
"errors"
"fmt"
"github.com/dgrijalva/jwt-go"
"github.com/goharbor/harbor/src/common/rbac"
"github.com/goharbor/harbor/src/common/utils/log"
"time"
)
// Token is a jwt token for harbor robot account,
type
Token
struct
{
// HToken htoken is a jwt token for harbor robot account,
// which contains the robot ID, project ID and the access permission for the project.
// It used for authn/authz for robot account in Harbor.
type
HToken
struct
{
jwt
.
Token
Opt
*
Options
Claim
jwt
.
Claims
}
// New ...
func
New
(
opt
*
Options
,
claims
jwt
.
Claims
)
(
*
Token
,
error
)
{
err
:=
claims
.
Valid
()
func
New
(
tokenID
,
projectID
,
expiresAt
int64
,
access
[]
*
rbac
.
Policy
)
(
*
HToken
,
error
)
{
rClaims
:=
&
RobotClaims
{
TokenID
:
tokenID
,
ProjectID
:
projectID
,
Access
:
access
,
StandardClaims
:
jwt
.
StandardClaims
{
IssuedAt
:
time
.
Now
()
.
UTC
()
.
Unix
(),
ExpiresAt
:
expiresAt
,
Issuer
:
DefaultOptions
()
.
Issuer
,
},
}
err
:=
rClaims
.
Valid
()
if
err
!=
nil
{
return
nil
,
err
}
return
&
Token
{
Token
:
*
jwt
.
NewWithClaims
(
opt
.
SignMethod
,
claims
),
Opt
:
opt
,
Claim
:
claims
,
return
&
HToken
{
Token
:
*
jwt
.
NewWithClaims
(
DefaultOptions
()
.
SignMethod
,
rClaims
),
},
nil
}
// Raw get the Raw string of token
func
(
tk
*
Token
)
Raw
()
(
string
,
error
)
{
key
,
err
:=
tk
.
Opt
.
GetKey
()
func
(
h
tk
*
H
Token
)
Raw
()
(
string
,
error
)
{
key
,
err
:=
DefaultOptions
()
.
GetKey
()
if
err
!=
nil
{
return
""
,
nil
}
raw
,
err
:=
tk
.
Token
.
SignedString
(
key
)
raw
,
err
:=
h
tk
.
Token
.
SignedString
(
key
)
if
err
!=
nil
{
log
.
Debugf
(
fmt
.
Sprintf
(
"failed to issue token %v"
,
err
))
return
""
,
err
...
...
@@ -43,14 +53,14 @@ func (tk *Token) Raw() (string, error) {
return
raw
,
err
}
// Parse ...
func
Parse
(
opt
*
Options
,
rawToken
string
,
claims
jwt
.
Claims
)
(
*
Token
,
error
)
{
key
,
err
:=
opt
.
GetKey
()
// Parse
WithClaims
...
func
Parse
WithClaims
(
rawToken
string
,
claims
jwt
.
Claims
)
(
*
H
Token
,
error
)
{
key
,
err
:=
DefaultOptions
()
.
GetKey
()
if
err
!=
nil
{
return
nil
,
err
}
token
,
err
:=
jwt
.
ParseWithClaims
(
rawToken
,
claims
,
func
(
token
*
jwt
.
Token
)
(
interface
{},
error
)
{
if
token
.
Method
.
Alg
()
!=
opt
.
SignMethod
.
Alg
()
{
if
token
.
Method
.
Alg
()
!=
DefaultOptions
()
.
SignMethod
.
Alg
()
{
return
nil
,
errors
.
New
(
"invalid signing method"
)
}
switch
k
:=
key
.
(
type
)
{
...
...
@@ -71,7 +81,7 @@ func Parse(opt *Options, rawToken string, claims jwt.Claims) (*Token, error) {
log
.
Errorf
(
fmt
.
Sprintf
(
"invalid jwt token, %v"
,
token
))
return
nil
,
errors
.
New
(
"invalid jwt token"
)
}
return
&
Token
{
return
&
H
Token
{
Token
:
*
token
,
},
nil
}
This diff is collapsed.
Click to expand it.
src/
pkg
/token/token_test.go
→
src/
common
/token/
h
token_test.go
+
4
-
22
View file @
4a3dc9ae
...
...
@@ -5,10 +5,8 @@ import (
"testing"
"time"
"github.com/dgrijalva/jwt-go"
"github.com/goharbor/harbor/src/common/rbac"
"github.com/goharbor/harbor/src/core/config"
robot_claim
"github.com/goharbor/harbor/src/pkg/token/claims/robot"
"github.com/stretchr/testify/assert"
)
...
...
@@ -35,15 +33,7 @@ func TestNew(t *testing.T) {
projectID
:=
int64
(
321
)
tokenExpiration
:=
time
.
Duration
(
10
)
*
24
*
time
.
Hour
expiresAt
:=
time
.
Now
()
.
UTC
()
.
Add
(
tokenExpiration
)
.
Unix
()
robot
:=
robot_claim
.
Claim
{
TokenID
:
tokenID
,
ProjectID
:
projectID
,
Access
:
policies
,
StandardClaims
:
jwt
.
StandardClaims
{
ExpiresAt
:
expiresAt
,
},
}
token
,
err
:=
New
(
DefaultTokenOptions
(),
robot
)
token
,
err
:=
New
(
tokenID
,
projectID
,
expiresAt
,
policies
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
token
.
Header
[
"alg"
],
"RS256"
)
...
...
@@ -64,15 +54,7 @@ func TestRaw(t *testing.T) {
tokenExpiration
:=
time
.
Duration
(
10
)
*
24
*
time
.
Hour
expiresAt
:=
time
.
Now
()
.
UTC
()
.
Add
(
tokenExpiration
)
.
Unix
()
robot
:=
robot_claim
.
Claim
{
TokenID
:
tokenID
,
ProjectID
:
projectID
,
Access
:
policies
,
StandardClaims
:
jwt
.
StandardClaims
{
ExpiresAt
:
expiresAt
,
},
}
token
,
err
:=
New
(
DefaultTokenOptions
(),
robot
)
token
,
err
:=
New
(
tokenID
,
projectID
,
expiresAt
,
policies
)
assert
.
Nil
(
t
,
err
)
rawTk
,
err
:=
token
.
Raw
()
...
...
@@ -82,8 +64,8 @@ func TestRaw(t *testing.T) {
func
TestParseWithClaims
(
t
*
testing
.
T
)
{
rawTk
:=
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJJRCI6MTIzLCJQcm9qZWN0SUQiOjAsIkFjY2VzcyI6W3siUmVzb3VyY2UiOiIvcHJvamVjdC9saWJyYXkvcmVwb3NpdG9yeSIsIkFjdGlvbiI6InB1bGwiLCJFZmZlY3QiOiIifV0sIlN0YW5kYXJkQ2xhaW1zIjp7ImV4cCI6MTU0ODE0MDIyOSwiaXNzIjoiaGFyYm9yLXRva2VuLWlzc3VlciJ9fQ.Jc3qSKN4SJVUzAvBvemVpRcSOZaHlu0Avqms04qzPm4ru9-r9IRIl3mnSkI6m9XkzLUeJ7Kiwyw63ghngnVKw_PupeclOGC6s3TK5Cfmo4h-lflecXjZWwyy-dtH_e7Us_ItS-R3nXDJtzSLEpsGHCcAj-1X2s93RB2qD8LNSylvYeDezVkTzqRzzfawPJheKKh9JTrz-3eUxCwQard9-xjlwvfUYULoHTn9npNAUq4-jqhipW4uE8HL-ym33AGF57la8U0RO11hmDM5K8-PiYknbqJ_oONeS3HBNym2pEFeGjtTv2co213wl4T5lemlg4SGolMBuJ03L7_beVZ0o-MKTkKDqDwJalb6_PM-7u3RbxC9IzJMiwZKIPnD3FvV10iPxUUQHaH8Jz5UZ2pFIhi_8BNnlBfT0JOPFVYATtLjHMczZelj2YvAeR1UHBzq3E0jPpjjwlqIFgaHCaN_KMwEvadTo_Fi2sEH4pNGP7M3yehU_72oLJQgF4paJarsmEoij6ZtPs6xekBz1fccVitq_8WNIz9aeCUdkUBRwI5QKw1RdW4ua-w74ld5MZStWJA8veyoLkEb_Q9eq2oAj5KWFjJbW5-ltiIfM8gxKflsrkWAidYGcEIYcuXr7UdqEKXxtPiWM0xb3B91ovYvO5402bn3f9-UGtlcestxNHA"
rClaims
:=
&
r
obot
_claim
.
Claim
{}
_
,
_
=
Parse
(
DefaultTokenOptions
(),
rawTk
,
rClaims
)
rClaims
:=
&
R
obotClaim
s
{}
_
,
_
=
Parse
WithClaims
(
rawTk
,
rClaims
)
assert
.
Equal
(
t
,
int64
(
123
),
rClaims
.
TokenID
)
assert
.
Equal
(
t
,
int64
(
0
),
rClaims
.
ProjectID
)
assert
.
Equal
(
t
,
"/project/libray/repository"
,
rClaims
.
Access
[
0
]
.
Resource
.
String
())
...
...
This diff is collapsed.
Click to expand it.
src/
pkg
/token/options.go
→
src/
common
/token/options.go
+
20
-
20
View file @
4a3dc9ae
...
...
@@ -11,9 +11,9 @@ import (
)
const
(
defaultTTL
=
60
*
time
.
Minute
defaultI
ssuer
=
"harbor-token-
defaultI
ssuer"
defaultS
ignedMethod
=
"RS256"
ttl
=
60
*
time
.
Minute
i
ssuer
=
"harbor-token-
i
ssuer"
s
ignedMethod
=
"RS256"
)
// Options ...
...
...
@@ -25,6 +25,23 @@ type Options struct {
Issuer
string
}
// DefaultOptions ...
func
DefaultOptions
()
*
Options
{
privateKeyFile
:=
config
.
TokenPrivateKeyPath
()
privateKey
,
err
:=
ioutil
.
ReadFile
(
privateKeyFile
)
if
err
!=
nil
{
log
.
Errorf
(
fmt
.
Sprintf
(
"failed to read private key %v"
,
err
))
return
nil
}
opt
:=
&
Options
{
SignMethod
:
jwt
.
GetSigningMethod
(
signedMethod
),
PrivateKey
:
privateKey
,
Issuer
:
issuer
,
TTL
:
ttl
,
}
return
opt
}
// GetKey ...
func
(
o
*
Options
)
GetKey
()
(
interface
{},
error
)
{
var
err
error
...
...
@@ -59,20 +76,3 @@ func (o *Options) GetKey() (interface{}, error) {
return
nil
,
fmt
.
Errorf
(
fmt
.
Sprintf
(
"unsupported sign method, %s"
,
o
.
SignMethod
))
}
}
// DefaultTokenOptions ...
func
DefaultTokenOptions
()
*
Options
{
privateKeyFile
:=
config
.
TokenPrivateKeyPath
()
privateKey
,
err
:=
ioutil
.
ReadFile
(
privateKeyFile
)
if
err
!=
nil
{
log
.
Errorf
(
fmt
.
Sprintf
(
"failed to read private key %v"
,
err
))
return
nil
}
opt
:=
&
Options
{
SignMethod
:
jwt
.
GetSigningMethod
(
defaultSignedMethod
),
PrivateKey
:
privateKey
,
Issuer
:
defaultIssuer
,
TTL
:
defaultTTL
,
}
return
opt
}
This diff is collapsed.
Click to expand it.
src/
pkg
/token/option_test.go
→
src/
common
/token/option
s
_test.go
+
3
-
3
View file @
4a3dc9ae
...
...
@@ -8,15 +8,15 @@ import (
)
func
TestNewOptions
(
t
*
testing
.
T
)
{
defaultOpt
:=
Default
Token
Options
()
defaultOpt
:=
DefaultOptions
()
assert
.
NotNil
(
t
,
defaultOpt
)
assert
.
Equal
(
t
,
defaultOpt
.
SignMethod
,
jwt
.
GetSigningMethod
(
"RS256"
))
assert
.
Equal
(
t
,
defaultOpt
.
Issuer
,
"harbor-token-
defaultI
ssuer"
)
assert
.
Equal
(
t
,
defaultOpt
.
Issuer
,
"harbor-token-
i
ssuer"
)
assert
.
Equal
(
t
,
defaultOpt
.
TTL
,
60
*
time
.
Minute
)
}
func
TestGetKey
(
t
*
testing
.
T
)
{
defaultOpt
:=
Default
Token
Options
()
defaultOpt
:=
DefaultOptions
()
key
,
err
:=
defaultOpt
.
GetKey
()
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
key
)
...
...
This diff is collapsed.
Click to expand it.
src/common/utils/oidc/helper.go
+
3
-
3
View file @
4a3dc9ae
...
...
@@ -208,7 +208,7 @@ func RefreshToken(ctx context.Context, token *Token) (*Token, error) {
return
&
Token
{
Token
:
*
t
,
IDToken
:
it
},
nil
}
// GroupsFromToken returns the list of group name in the token, the claim
s
of the group list is set in OIDCSetting.
// GroupsFromToken returns the list of group name in the token, the claim of the group list is set in OIDCSetting.
// It's designed not to return errors, in case of unexpected situation it will log and return empty list.
func
GroupsFromToken
(
token
*
gooidc
.
IDToken
)
[]
string
{
if
token
==
nil
{
...
...
@@ -217,7 +217,7 @@ func GroupsFromToken(token *gooidc.IDToken) []string {
}
setting
:=
provider
.
setting
.
Load
()
.
(
models
.
OIDCSetting
)
if
len
(
setting
.
GroupsClaim
)
==
0
{
log
.
Warning
(
"Group claim
s
is not set in OIDC setting returning empty group list."
)
log
.
Warning
(
"Group claim is not set in OIDC setting returning empty group list."
)
return
[]
string
{}
}
var
c
map
[
string
]
interface
{}
...
...
@@ -233,7 +233,7 @@ func groupsFromClaim(claimMap map[string]interface{}, k string) []string {
var
res
[]
string
g
,
ok
:=
claimMap
[
k
]
.
([]
interface
{})
if
!
ok
{
log
.
Warningf
(
"Unable to get groups from claims, claims: %+v, groups claim
s
key: %s"
,
claimMap
,
k
)
log
.
Warningf
(
"Unable to get groups from claims, claims: %+v, groups claim key: %s"
,
claimMap
,
k
)
return
res
}
for
_
,
e
:=
range
g
{
...
...
This diff is collapsed.
Click to expand it.
src/core/filter/security.go
+
5
-
7
View file @
4a3dc9ae
...
...
@@ -34,6 +34,7 @@ import (
"github.com/goharbor/harbor/src/common/security/local"
robotCtx
"github.com/goharbor/harbor/src/common/security/robot"
"github.com/goharbor/harbor/src/common/security/secret"
"github.com/goharbor/harbor/src/common/token"
"github.com/goharbor/harbor/src/common/utils/log"
"github.com/goharbor/harbor/src/core/auth"
"github.com/goharbor/harbor/src/core/config"
...
...
@@ -43,8 +44,6 @@ import (
"github.com/goharbor/harbor/src/pkg/authproxy"
"github.com/goharbor/harbor/src/pkg/robot"
pkg_token
"github.com/goharbor/harbor/src/pkg/token"
robot_claim
"github.com/goharbor/harbor/src/pkg/token/claims/robot"
)
// ContextValueKey for content value
...
...
@@ -189,16 +188,15 @@ func (r *robotAuthReqCtxModifier) Modify(ctx *beegoctx.Context) bool {
if
!
strings
.
HasPrefix
(
robotName
,
common
.
RobotPrefix
)
{
return
false
}
rClaims
:=
&
robot_claim
.
Claim
{}
opt
:=
pkg_token
.
DefaultTokenOptions
()
rtk
,
err
:=
pkg_token
.
Parse
(
opt
,
robotTk
,
rClaims
)
rClaims
:=
&
token
.
RobotClaims
{}
htk
,
err
:=
token
.
ParseWithClaims
(
robotTk
,
rClaims
)
if
err
!=
nil
{
log
.
Errorf
(
"failed to decrypt robot token, %v"
,
err
)
return
false
}
// Do authn for robot account, as Harbor only stores the token ID, just validate the ID and disable.
ctr
:=
robot
.
RobotCtr
robot
,
err
:=
ctr
.
GetRobotAccount
(
r
tk
.
Claims
.
(
*
robot_claim
.
Claim
)
.
TokenID
)
robot
,
err
:=
ctr
.
GetRobotAccount
(
h
tk
.
Claims
.
(
*
token
.
Robot
Claim
s
)
.
TokenID
)
if
err
!=
nil
{
log
.
Errorf
(
"failed to get robot %s: %v"
,
robotName
,
err
)
return
false
...
...
@@ -217,7 +215,7 @@ func (r *robotAuthReqCtxModifier) Modify(ctx *beegoctx.Context) bool {
}
log
.
Debug
(
"creating robot account security context..."
)
pm
:=
config
.
GlobalProjectMgr
securCtx
:=
robotCtx
.
NewSecurityContext
(
robot
,
pm
,
r
tk
.
Claims
.
(
*
robot_claim
.
Claim
)
.
Access
)
securCtx
:=
robotCtx
.
NewSecurityContext
(
robot
,
pm
,
h
tk
.
Claims
.
(
*
token
.
Robot
Claim
s
)
.
Access
)
setSecurCtxAndPM
(
ctx
.
Request
,
securCtx
,
pm
)
return
true
}
...
...
This diff is collapsed.
Click to expand it.
src/core/middlewares/chain.go
+
0
-
2
View file @
4a3dc9ae
...
...
@@ -25,7 +25,6 @@ import (
"github.com/goharbor/harbor/src/core/middlewares/listrepo"
"github.com/goharbor/harbor/src/core/middlewares/multiplmanifest"
"github.com/goharbor/harbor/src/core/middlewares/readonly"
"github.com/goharbor/harbor/src/core/middlewares/regtoken"
"github.com/goharbor/harbor/src/core/middlewares/sizequota"
"github.com/goharbor/harbor/src/core/middlewares/url"
"github.com/goharbor/harbor/src/core/middlewares/vulnerable"
...
...
@@ -73,7 +72,6 @@ func (b *DefaultCreator) geMiddleware(mName string) alice.Constructor {
SIZEQUOTA
:
func
(
next
http
.
Handler
)
http
.
Handler
{
return
sizequota
.
New
(
next
)
},
COUNTQUOTA
:
func
(
next
http
.
Handler
)
http
.
Handler
{
return
countquota
.
New
(
next
)
},
IMMUTABLE
:
func
(
next
http
.
Handler
)
http
.
Handler
{
return
immutable
.
New
(
next
)
},
REGTOKEN
:
func
(
next
http
.
Handler
)
http
.
Handler
{
return
regtoken
.
New
(
next
)
},
}
return
middlewares
[
mName
]
}
This diff is collapsed.
Click to expand it.
src/core/middlewares/config.go
+
1
-
2
View file @
4a3dc9ae
...
...
@@ -26,14 +26,13 @@ const (
SIZEQUOTA
=
"sizequota"
COUNTQUOTA
=
"countquota"
IMMUTABLE
=
"immutable"
REGTOKEN
=
"regtoken"
)
// ChartMiddlewares middlewares for chart server
var
ChartMiddlewares
=
[]
string
{
CHART
}
// Middlewares with sequential organization
var
Middlewares
=
[]
string
{
READONLY
,
URL
,
REGTOKEN
,
MUITIPLEMANIFEST
,
LISTREPO
,
CONTENTTRUST
,
VULNERABLE
,
SIZEQUOTA
,
IMMUTABLE
,
COUNTQUOTA
}
var
Middlewares
=
[]
string
{
READONLY
,
URL
,
MUITIPLEMANIFEST
,
LISTREPO
,
CONTENTTRUST
,
VULNERABLE
,
SIZEQUOTA
,
IMMUTABLE
,
COUNTQUOTA
}
// MiddlewaresLocal ...
var
MiddlewaresLocal
=
[]
string
{
SIZEQUOTA
,
IMMUTABLE
,
COUNTQUOTA
}
This diff is collapsed.
Click to expand it.
src/core/middlewares/contenttrust/handler.go
+
0
-
4
View file @
4a3dc9ae
...
...
@@ -49,10 +49,6 @@ func (cth contentTrustHandler) ServeHTTP(rw http.ResponseWriter, req *http.Reque
cth
.
next
.
ServeHTTP
(
rw
,
req
)
return
}
if
scannerPull
,
ok
:=
util
.
ScannerPullFromContext
(
req
.
Context
());
ok
&&
scannerPull
{
cth
.
next
.
ServeHTTP
(
rw
,
req
)
return
}
if
!
util
.
GetPolicyChecker
()
.
ContentTrustEnabled
(
img
.
ProjectName
)
{
cth
.
next
.
ServeHTTP
(
rw
,
req
)
return
...
...
This diff is collapsed.
Click to expand it.
src/core/middlewares/regtoken/handler.go
deleted
100644 → 0
+
0
-
71
View file @
d18678a4
package
regtoken
import
(
"github.com/docker/distribution/registry/auth"
"github.com/goharbor/harbor/src/common/rbac"
"github.com/goharbor/harbor/src/common/utils/log"
"github.com/goharbor/harbor/src/core/middlewares/util"
pkg_token
"github.com/goharbor/harbor/src/pkg/token"
"github.com/goharbor/harbor/src/pkg/token/claims/registry"
"net/http"
"strings"
)
// regTokenHandler is responsible for decoding the registry token in the docker pull request header,
// as harbor adds customized claims action into registry auth token, the middlerware is for decode it and write it into
// request context, then for other middlerwares in chain to use it to bypass request validation.
type
regTokenHandler
struct
{
next
http
.
Handler
}
// New ...
func
New
(
next
http
.
Handler
)
http
.
Handler
{
return
&
regTokenHandler
{
next
:
next
,
}
}
// ServeHTTP ...
func
(
r
*
regTokenHandler
)
ServeHTTP
(
rw
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
imgRaw
:=
req
.
Context
()
.
Value
(
util
.
ImageInfoCtxKey
)
if
imgRaw
==
nil
{
r
.
next
.
ServeHTTP
(
rw
,
req
)
return
}
img
,
_
:=
req
.
Context
()
.
Value
(
util
.
ImageInfoCtxKey
)
.
(
util
.
ImageInfo
)
if
img
.
Digest
==
""
{
r
.
next
.
ServeHTTP
(
rw
,
req
)
return
}
parts
:=
strings
.
Split
(
req
.
Header
.
Get
(
"Authorization"
),
" "
)
if
len
(
parts
)
!=
2
||
strings
.
ToLower
(
parts
[
0
])
!=
"bearer"
{
r
.
next
.
ServeHTTP
(
rw
,
req
)
return
}
rawToken
:=
parts
[
1
]
opt
:=
pkg_token
.
DefaultTokenOptions
()
regTK
,
err
:=
pkg_token
.
Parse
(
opt
,
rawToken
,
&
registry
.
Claim
{})
if
err
!=
nil
{
log
.
Errorf
(
"failed to decode reg token: %v, the error is skipped and round the request to native registry."
,
err
)
r
.
next
.
ServeHTTP
(
rw
,
req
)
return
}
accessItems
:=
[]
auth
.
Access
{}
accessItems
=
append
(
accessItems
,
auth
.
Access
{
Resource
:
auth
.
Resource
{
Type
:
rbac
.
ResourceRepository
.
String
(),
Name
:
img
.
Repository
,
},
Action
:
rbac
.
ActionScannerPull
.
String
(),
})
accessSet
:=
regTK
.
Claims
.
(
*
registry
.
Claim
)
.
GetAccess
()
for
_
,
access
:=
range
accessItems
{
if
accessSet
.
Contains
(
access
)
{
*
req
=
*
(
req
.
WithContext
(
util
.
NewScannerPullContext
(
req
.
Context
(),
true
)))
}
}
r
.
next
.
ServeHTTP
(
rw
,
req
)
}
This diff is collapsed.
Click to expand it.
src/core/middlewares/regtoken/handler_test.go
deleted
100644 → 0
+
0
-
55
View file @
d18678a4
package
regtoken
import
(
"fmt"
"github.com/goharbor/harbor/src/core/middlewares/util"
"github.com/stretchr/testify/suite"
"net/http"
"net/http/httptest"
"os"
"testing"
)
type
HandlerSuite
struct
{
suite
.
Suite
}
func
doPullManifestRequest
(
projectName
,
name
,
tag
string
,
next
...
http
.
HandlerFunc
)
int
{
repository
:=
fmt
.
Sprintf
(
"%s/%s"
,
projectName
,
name
)
url
:=
fmt
.
Sprintf
(
"/v2/%s/manifests/%s"
,
repository
,
tag
)
req
,
_
:=
http
.
NewRequest
(
"GET"
,
url
,
nil
)
token
:=
"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IkNWUTc6REM3NTpHVEROOkxTTUs6VUFJTjpIUUVWOlZVSDQ6Q0lRRDpRV01COlM0Qzc6U0c0STpGRUhYIn0.eyJpc3MiOiJoYXJib3ItdG9rZW4taXNzdWVyIiwic3ViIjoicm9ib3QkZGVtbzExIiwiYXVkIjoiaGFyYm9yLXJlZ2lzdHJ5IiwiZXhwIjoxNTcxNzYzOTI2LCJuYmYiOjE1NzE3NjM4NjYsImlhdCI6MTU3MTc2Mzg2NiwianRpIjoiTnRaZWx4Z01KTUU1MXlEMCIsImFjY2VzcyI6W3sidHlwZSI6InJlcG9zaXRvcnkiLCJuYW1lIjoibGlicmFyeS9oZWxsby13b3JsZCIsImFjdGlvbnMiOlsicHVzaCIsIioiLCJwdWxsIiwic2Nhbm5lcnB1bGwiXX1dfQ.GlWuvtoxmChnpvbWaG5901Z9-g63DrzyNUREWlDbR5gnNeuOKjLNyE4QpogAQKx2yYtcGxbqNL3VfJkExJ_gMS0Qw8e10utGOawwqD4oqf_J06eKq4HzpZJengZfcjMA4g2RoeOlqdVdwimB_PdX9vkBO1od0wX0Cc2v0p2w5TkibcThKRoeLeVs2oRewkKLuVHNSM8wwRIlAvpWJuNnvRCFlHRkLcZM_KpGXqT7H-PZETTisWCi1pMxeYEwIsDFLlTKdV8LaiDeDmH-RaLOsuyAySYEW9Ynk5K3P_dUl2c_SYQXloPyi0MvXxSn6EWE4eHF2oQDM_SvIzR9sOVB8TtjMjKKMQ4yr_mqgMcfEpnInJATExBR56wmxNdLESncHl8rUYCe2jCjQFuR9NGQA1tGdjI4NoBN-OVD0dBs9rm_mkb2tgD-3gEhyzAw6hg0uzDsF7bj5Aq8scoi42UurhX2bZM89s4-TWBp4DWuBG0HDiwpOiBvB3RMm6MpQxsqrl0hQm_WH18L6QCknAW2e3d_6DJWJ0eBzISrhDr7LkqJKl1J8pv4zqoh_EUVeLyzTmjEULm-VbnpVF4wW5yTLF3S6F7Ox4vwWtVfi1XQNVOcJDB3VPUsRgiTTuCW-ZGcBLw-OdIcwaJ3T_QZkEjUw1f6i1JcGa0Mpgl83aLiSdQ 0xc0003c77c0 map[alg:RS256 kid:CVQ7:DC75:GTDN:LSMK:UAIN:HQEV:VUH4:CIQD:QWMB:S4C7:SG4I:FEHX typ:JWT] 0xc000496000 GlWuvtoxmChnpvbWaG5901Z9-g63DrzyNUREWlDbR5gnNeuOKjLNyE4QpogAQKx2yYtcGxbqNL3VfJkExJ_gMS0Qw8e10utGOawwqD4oqf_J06eKq4HzpZJengZfcjMA4g2RoeOlqdVdwimB_PdX9vkBO1od0wX0Cc2v0p2w5TkibcThKRoeLeVs2oRewkKLuVHNSM8wwRIlAvpWJuNnvRCFlHRkLcZM_KpGXqT7H-PZETTisWCi1pMxeYEwIsDFLlTKdV8LaiDeDmH-RaLOsuyAySYEW9Ynk5K3P_dUl2c_SYQXloPyi0MvXxSn6EWE4eHF2oQDM_SvIzR9sOVB8TtjMjKKMQ4yr_mqgMcfEpnInJATExBR56wmxNdLESncHl8rUYCe2jCjQFuR9NGQA1tGdjI4NoBN-OVD0dBs9rm_mkb2tgD-3gEhyzAw6hg0uzDsF7bj5Aq8scoi42UurhX2bZM89s4-TWBp4DWuBG0HDiwpOiBvB3RMm6MpQxsqrl0hQm_WH18L6QCknAW2e3d_6DJWJ0eBzISrhDr7LkqJKl1J8pv4zqoh_EUVeLyzTmjEULm-VbnpVF4wW5yTLF3S6F7Ox4vwWtVfi1XQNVOcJDB3VPUsRgiTTuCW-ZGcBLw-OdIcwaJ3T_QZkEjUw1f6i1JcGa0Mpgl83aLiSdQ"
req
.
Header
.
Set
(
"Authorization"
,
fmt
.
Sprintf
(
"Bearer %s"
,
token
))
rr
:=
httptest
.
NewRecorder
()
var
n
http
.
HandlerFunc
if
len
(
next
)
>
0
{
n
=
next
[
0
]
}
else
{
n
=
func
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
w
.
WriteHeader
(
http
.
StatusNotFound
)
}
}
h
:=
New
(
http
.
HandlerFunc
(
n
))
h
.
ServeHTTP
(
util
.
NewCustomResponseWriter
(
rr
),
req
)
return
rr
.
Code
}
func
(
suite
*
HandlerSuite
)
TestPullManifest
()
{
code1
:=
doPullManifestRequest
(
"library"
,
"photon"
,
"release-1.10"
)
suite
.
Equal
(
http
.
StatusNotFound
,
code1
)
}
func
TestMain
(
m
*
testing
.
M
)
{
if
result
:=
m
.
Run
();
result
!=
0
{
os
.
Exit
(
result
)
}
}
func
TestRunHandlerSuite
(
t
*
testing
.
T
)
{
suite
.
Run
(
t
,
new
(
HandlerSuite
))
}
This diff is collapsed.
Click to expand it.
src/core/middlewares/util/util.go
+
0
-
13
View file @
4a3dc9ae
...
...
@@ -49,8 +49,6 @@ type contextKey string
const
(
// ImageInfoCtxKey the context key for image information
ImageInfoCtxKey
=
contextKey
(
"ImageInfo"
)
// ScannerPullCtxKey the context key for robot account to bypass the pull policy check.
ScannerPullCtxKey
=
contextKey
(
"ScannerPullCheck"
)
// TokenUsername ...
// TODO: temp solution, remove after vmware/harbor#2242 is resolved.
TokenUsername
=
"harbor-core"
...
...
@@ -445,17 +443,6 @@ func ManifestInfoFromContext(ctx context.Context) (*ManifestInfo, bool) {
return
info
,
ok
}
// NewScannerPullContext returns context with policy check info
func
NewScannerPullContext
(
ctx
context
.
Context
,
scannerPull
bool
)
context
.
Context
{
return
context
.
WithValue
(
ctx
,
ScannerPullCtxKey
,
scannerPull
)
}
// ScannerPullFromContext returns whether to bypass policy check
func
ScannerPullFromContext
(
ctx
context
.
Context
)
(
bool
,
bool
)
{
info
,
ok
:=
ctx
.
Value
(
ScannerPullCtxKey
)
.
(
bool
)
return
info
,
ok
}
// NewBlobInfoContext returns context with blob info
func
NewBlobInfoContext
(
ctx
context
.
Context
,
info
*
BlobInfo
)
context
.
Context
{
return
context
.
WithValue
(
ctx
,
blobInfoKey
,
info
)
...
...
This diff is collapsed.
Click to expand it.
src/core/middlewares/vulnerable/handler.go
+
2
-
7
View file @
4a3dc9ae
...
...
@@ -52,11 +52,6 @@ func (vh vulnerableHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request)
return
}
if
scannerPull
,
ok
:=
util
.
ScannerPullFromContext
(
req
.
Context
());
ok
&&
scannerPull
{
vh
.
next
.
ServeHTTP
(
rw
,
req
)
return
}
// Is vulnerable policy set?
projectVulnerableEnabled
,
projectVulnerableSeverity
,
wl
:=
util
.
GetPolicyChecker
()
.
VulnerablePolicy
(
img
.
ProjectName
)
if
!
projectVulnerableEnabled
{
...
...
@@ -114,10 +109,10 @@ func (vh vulnerableHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request)
return
}
// Print
scannerPull
CVE list
// Print
bypass
CVE list
if
len
(
summary
.
CVEBypassed
)
>
0
{
for
_
,
cve
:=
range
summary
.
CVEBypassed
{
log
.
Infof
(
"Vulnerable policy check:
scannerPull
CVE %s"
,
cve
)
log
.
Infof
(
"Vulnerable policy check:
bypass
CVE %s"
,
cve
)
}
}
...
...
This diff is collapsed.
Click to expand it.
src/core/service/token/authutils.go
+
0
-
3
View file @
4a3dc9ae
...
...
@@ -133,9 +133,6 @@ func permToActions(p string) []string {
if
strings
.
Contains
(
p
,
"R"
)
{
res
=
append
(
res
,
"pull"
)
}
if
strings
.
Contains
(
p
,
"S"
)
{
res
=
append
(
res
,
"scanner-pull"
)
}
return
res
}
...
...
This diff is collapsed.
Click to expand it.
src/core/service/token/creator.go
+
0
-
2
View file @
4a3dc9ae
...
...
@@ -177,8 +177,6 @@ func (rep repositoryFilter) filter(ctx security.Context, pm promgr.ProjectManage
permission
=
"RWM"
}
else
if
ctx
.
Can
(
rbac
.
ActionPush
,
resource
)
{
permission
=
"RW"
}
else
if
ctx
.
Can
(
rbac
.
ActionScannerPull
,
resource
)
{
permission
=
"RS"
}
else
if
ctx
.
Can
(
rbac
.
ActionPull
,
resource
)
{
permission
=
"R"
}
...
...
This diff is collapsed.
Click to expand it.
Prev
1
2
Next
Write
Preview
Supports
Markdown
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
Menu
Projects
Groups
Snippets
Help