mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-22 10:15:35 +01:00
Merge pull request #2158 from ywk253100/170427_pm
Implement security context for secret
This commit is contained in:
commit
80d83d97bd
48
src/common/secret/store.go
Normal file
48
src/common/secret/store.go
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package secret
|
||||
|
||||
const (
|
||||
// AdminserverUser is the name of adminserver user
|
||||
AdminserverUser = "harbor-adminserver"
|
||||
// JobserviceUser is the name of jobservice user
|
||||
JobserviceUser = "harbor-jobservice"
|
||||
// UIUser is the name of ui user
|
||||
UIUser = "harbor-ui"
|
||||
)
|
||||
|
||||
// Store the secrets and provides methods to validate secrets
|
||||
type Store struct {
|
||||
// the key is secret
|
||||
// the value is username
|
||||
secrets map[string]string
|
||||
}
|
||||
|
||||
// NewStore ...
|
||||
func NewStore(secrets map[string]string) *Store {
|
||||
return &Store{
|
||||
secrets: secrets,
|
||||
}
|
||||
}
|
||||
|
||||
// IsValid returns whether the secret is valid
|
||||
func (s *Store) IsValid(secret string) bool {
|
||||
return len(s.GetUsername(secret)) != 0
|
||||
}
|
||||
|
||||
// GetUsername returns the corresponding username of the secret
|
||||
func (s *Store) GetUsername(secret string) string {
|
||||
return s.secrets[secret]
|
||||
}
|
39
src/common/secret/store_test.go
Normal file
39
src/common/secret/store_test.go
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package secret
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestIsValid(t *testing.T) {
|
||||
store := NewStore(map[string]string{
|
||||
"secret1": "username1",
|
||||
})
|
||||
|
||||
assert.False(t, store.IsValid("invalid_secret"))
|
||||
assert.True(t, store.IsValid("secret1"))
|
||||
}
|
||||
|
||||
func TestGetUsername(t *testing.T) {
|
||||
store := NewStore(map[string]string{
|
||||
"secret1": "username1",
|
||||
})
|
||||
|
||||
assert.Equal(t, "", store.GetUsername("invalid_secret"))
|
||||
assert.Equal(t, "username1", store.GetUsername("secret1"))
|
||||
}
|
@ -18,15 +18,14 @@ package security
|
||||
type Context interface {
|
||||
// IsAuthenticated returns whether the context has been authenticated or not
|
||||
IsAuthenticated() bool
|
||||
// GetUsername returns the username of user related to the context
|
||||
GetUsername() string
|
||||
// IsSysAdmin returns whether the user is system admin
|
||||
IsSysAdmin() bool
|
||||
// HasReadPerm returns whether the user has read permission to the project
|
||||
// whose ID is projectID
|
||||
HasReadPerm(projectID int64) bool
|
||||
HasReadPerm(projectIDOrName interface{}) bool
|
||||
// HasWritePerm returns whether the user has write permission to the project
|
||||
// whose ID is projectID
|
||||
HasWritePerm(projectID int64) bool
|
||||
HasWritePerm(projectIDOrName interface{}) bool
|
||||
// HasAllPerm returns whether the user has all permissions to the project
|
||||
// whose ID is projectID
|
||||
HasAllPerm(projectID int64) bool
|
||||
HasAllPerm(projectIDOrName interface{}) bool
|
||||
}
|
74
src/common/security/secret/context.go
Normal file
74
src/common/security/secret/context.go
Normal file
@ -0,0 +1,74 @@
|
||||
// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package secret
|
||||
|
||||
import (
|
||||
"github.com/vmware/harbor/src/common/secret"
|
||||
)
|
||||
|
||||
// SecurityContext implements security.Context interface based on secret store
|
||||
type SecurityContext struct {
|
||||
secret string
|
||||
store *secret.Store
|
||||
}
|
||||
|
||||
// NewSecurityContext ...
|
||||
func NewSecurityContext(secret string, store *secret.Store) *SecurityContext {
|
||||
return &SecurityContext{
|
||||
secret: secret,
|
||||
store: store,
|
||||
}
|
||||
}
|
||||
|
||||
// IsAuthenticated returns true if the secret is valid
|
||||
func (s *SecurityContext) IsAuthenticated() bool {
|
||||
if s.store == nil {
|
||||
return false
|
||||
}
|
||||
return s.store.IsValid(s.secret)
|
||||
}
|
||||
|
||||
// GetUsername returns the corresponding username of the secret
|
||||
// or null if the secret is invalid
|
||||
func (s *SecurityContext) GetUsername() string {
|
||||
if s.store == nil {
|
||||
return ""
|
||||
}
|
||||
return s.store.GetUsername(s.secret)
|
||||
}
|
||||
|
||||
// IsSysAdmin always returns false
|
||||
func (s *SecurityContext) IsSysAdmin() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// HasReadPerm returns true if the corresponding user of the secret
|
||||
// is jobservice, otherwise returns false
|
||||
func (s *SecurityContext) HasReadPerm(projectIDOrName interface{}) bool {
|
||||
if s.store == nil {
|
||||
return false
|
||||
}
|
||||
return s.store.GetUsername(s.secret) == secret.JobserviceUser
|
||||
}
|
||||
|
||||
// HasWritePerm always returns false
|
||||
func (s *SecurityContext) HasWritePerm(projectIDOrName interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// HasAllPerm always returns false
|
||||
func (s *SecurityContext) HasAllPerm(projectIDOrName interface{}) bool {
|
||||
return false
|
||||
}
|
134
src/common/security/secret/context_test.go
Normal file
134
src/common/security/secret/context_test.go
Normal file
@ -0,0 +1,134 @@
|
||||
// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package secret
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/vmware/harbor/src/common/secret"
|
||||
)
|
||||
|
||||
func TestIsAuthenticated(t *testing.T) {
|
||||
// secret store is null
|
||||
context := NewSecurityContext("", nil)
|
||||
isAuthenticated := context.IsAuthenticated()
|
||||
assert.False(t, isAuthenticated)
|
||||
|
||||
//invalid secret
|
||||
context = NewSecurityContext("invalid_secret",
|
||||
secret.NewStore(map[string]string{
|
||||
"secret": "username",
|
||||
}))
|
||||
isAuthenticated = context.IsAuthenticated()
|
||||
assert.False(t, isAuthenticated)
|
||||
|
||||
//valid secret
|
||||
context = NewSecurityContext("secret",
|
||||
secret.NewStore(map[string]string{
|
||||
"secret": "username",
|
||||
}))
|
||||
isAuthenticated = context.IsAuthenticated()
|
||||
assert.True(t, isAuthenticated)
|
||||
}
|
||||
|
||||
func TestGetUsername(t *testing.T) {
|
||||
// secret store is null
|
||||
context := NewSecurityContext("", nil)
|
||||
username := context.GetUsername()
|
||||
assert.Equal(t, "", username)
|
||||
|
||||
//invalid secret
|
||||
context = NewSecurityContext("invalid_secret",
|
||||
secret.NewStore(map[string]string{
|
||||
"secret": "username",
|
||||
}))
|
||||
username = context.GetUsername()
|
||||
assert.Equal(t, "", username)
|
||||
|
||||
//valid secret
|
||||
context = NewSecurityContext("secret",
|
||||
secret.NewStore(map[string]string{
|
||||
"secret": "username",
|
||||
}))
|
||||
username = context.GetUsername()
|
||||
assert.Equal(t, "username", username)
|
||||
}
|
||||
|
||||
func TestIsSysAdmin(t *testing.T) {
|
||||
context := NewSecurityContext("secret",
|
||||
secret.NewStore(map[string]string{
|
||||
"secret": "username",
|
||||
}))
|
||||
isSysAdmin := context.IsSysAdmin()
|
||||
assert.False(t, isSysAdmin)
|
||||
}
|
||||
|
||||
func TestHasReadPerm(t *testing.T) {
|
||||
// secret store is null
|
||||
context := NewSecurityContext("", nil)
|
||||
hasReadPerm := context.HasReadPerm("project_name")
|
||||
assert.False(t, hasReadPerm)
|
||||
|
||||
//invalid secret
|
||||
context = NewSecurityContext("invalid_secret",
|
||||
secret.NewStore(map[string]string{
|
||||
"jobservice_secret": secret.JobserviceUser,
|
||||
}))
|
||||
hasReadPerm = context.HasReadPerm("project_name")
|
||||
assert.False(t, hasReadPerm)
|
||||
|
||||
//valid secret, project name
|
||||
context = NewSecurityContext("jobservice_secret",
|
||||
secret.NewStore(map[string]string{
|
||||
"jobservice_secret": secret.JobserviceUser,
|
||||
}))
|
||||
hasReadPerm = context.HasReadPerm("project_name")
|
||||
assert.True(t, hasReadPerm)
|
||||
|
||||
//valid secret, project ID
|
||||
hasReadPerm = context.HasReadPerm(1)
|
||||
assert.True(t, hasReadPerm)
|
||||
}
|
||||
|
||||
func TestHasWritePerm(t *testing.T) {
|
||||
context := NewSecurityContext("secret",
|
||||
secret.NewStore(map[string]string{
|
||||
"secret": "username",
|
||||
}))
|
||||
|
||||
// project name
|
||||
hasWritePerm := context.HasWritePerm("project_name")
|
||||
assert.False(t, hasWritePerm)
|
||||
|
||||
// project ID
|
||||
hasWritePerm = context.HasWritePerm(1)
|
||||
assert.False(t, hasWritePerm)
|
||||
}
|
||||
|
||||
func TestHasAllPerm(t *testing.T) {
|
||||
context := NewSecurityContext("secret",
|
||||
secret.NewStore(map[string]string{
|
||||
"secret": "username",
|
||||
}))
|
||||
|
||||
// project name
|
||||
hasAllPerm := context.HasAllPerm("project_name")
|
||||
assert.False(t, hasAllPerm)
|
||||
|
||||
// project ID
|
||||
hasAllPerm = context.HasAllPerm(1)
|
||||
assert.False(t, hasAllPerm)
|
||||
}
|
@ -19,8 +19,8 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/astaxie/beego/context"
|
||||
"github.com/vmware/harbor/src/common/security"
|
||||
"github.com/vmware/harbor/src/common/utils/log"
|
||||
"github.com/vmware/harbor/src/ui/security"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -12,4 +12,4 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package secret
|
||||
package db
|
20
src/ui/pms/service.go
Normal file
20
src/ui/pms/service.go
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package project
|
||||
|
||||
// PMS is the project mamagement service which abstracts
|
||||
// the operations related to projects
|
||||
type PMS interface {
|
||||
}
|
Loading…
Reference in New Issue
Block a user