diff --git a/src/ui/filter/security.go b/src/ui/filter/security.go new file mode 100644 index 000000000..ff36cea76 --- /dev/null +++ b/src/ui/filter/security.go @@ -0,0 +1,59 @@ +// 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 filter + +import ( + "net/http" + "strings" + + "github.com/astaxie/beego/context" + "github.com/vmware/harbor/src/common/utils/log" + "github.com/vmware/harbor/src/ui/security" +) + +const ( + // HarborSecurityContext is the name of security context passed to handlers + HarborSecurityContext = "harbor_security_context" +) + +// SecurityFilter authenticates the request and passes a security context with it +// which can be used to do some authorization +func SecurityFilter(ctx *context.Context) { + if ctx == nil { + return + } + + req := ctx.Request + if req == nil { + return + } + + if !strings.HasPrefix(req.RequestURI, "/api/") && + !strings.HasPrefix(req.RequestURI, "/service/") { + return + } + + securityCtx, err := createSecurityContext(req) + if err != nil { + log.Warningf("failed to create security context: %v", err) + return + } + + ctx.Input.SetData(HarborSecurityContext, securityCtx) +} + +func createSecurityContext(req *http.Request) (security.Context, error) { + return nil, nil +} diff --git a/src/ui/filter/security_test.go b/src/ui/filter/security_test.go new file mode 100644 index 000000000..5365c9382 --- /dev/null +++ b/src/ui/filter/security_test.go @@ -0,0 +1,50 @@ +// 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 filter + +import ( + "net/http" + "testing" + + "github.com/astaxie/beego/context" + "github.com/stretchr/testify/assert" +) + +func TestSecurityFilter(t *testing.T) { + // nil request + ctx := &context.Context{ + Request: nil, + Input: context.NewInput(), + } + SecurityFilter(ctx) + securityContext := ctx.Input.GetData(HarborSecurityContext) + assert.Nil(t, securityContext) + + // the pattern of request does not need security check + req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1/static/index.html", nil) + if err != nil { + t.Fatalf("failed to create request: %v", req) + } + + ctx = &context.Context{ + Request: req, + Input: context.NewInput(), + } + SecurityFilter(ctx) + securityContext = ctx.Input.GetData(HarborSecurityContext) + assert.Nil(t, securityContext) + + //TODO add a case to test normal process +} diff --git a/src/ui/main.go b/src/ui/main.go index 8d756bd19..aa52fae8d 100644 --- a/src/ui/main.go +++ b/src/ui/main.go @@ -30,6 +30,7 @@ import ( _ "github.com/vmware/harbor/src/ui/auth/db" _ "github.com/vmware/harbor/src/ui/auth/ldap" "github.com/vmware/harbor/src/ui/config" + "github.com/vmware/harbor/src/ui/filter" "github.com/vmware/harbor/src/ui/service/token" ) @@ -95,6 +96,9 @@ func main() { if err := updateInitPassword(adminUserID, password); err != nil { log.Error(err) } + + beego.InsertFilter("/*", beego.BeforeRouter, filter.SecurityFilter) + initRouters() if err := api.SyncRegistry(); err != nil { log.Error(err) diff --git a/src/ui/security/context.go b/src/ui/security/context.go new file mode 100644 index 000000000..a112523f1 --- /dev/null +++ b/src/ui/security/context.go @@ -0,0 +1,32 @@ +// 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 security + +// Context abstracts the operations related with authN and authZ +type Context interface { + // IsAuthenticated returns whether the context has been authenticated or not + IsAuthenticated() bool + // 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 + // HasWritePerm returns whether the user has write permission to the project + // whose ID is projectID + HasWritePerm(projectID int64) bool + // HasAllPerm returns whether the user has all permissions to the project + // whose ID is projectID + HasAllPerm(projectID int64) bool +} diff --git a/src/ui/security/db/context.go b/src/ui/security/db/context.go new file mode 100644 index 000000000..0086c5d31 --- /dev/null +++ b/src/ui/security/db/context.go @@ -0,0 +1,15 @@ +// 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 db diff --git a/src/ui/security/rbac/context.go b/src/ui/security/rbac/context.go new file mode 100644 index 000000000..02d6c6ffc --- /dev/null +++ b/src/ui/security/rbac/context.go @@ -0,0 +1,15 @@ +// 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 rbac diff --git a/src/ui/security/secret/context.go b/src/ui/security/secret/context.go new file mode 100644 index 000000000..6561a2cde --- /dev/null +++ b/src/ui/security/secret/context.go @@ -0,0 +1,15 @@ +// 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