Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(655)

Unified Diff: server/config/access/access_test.go

Issue 2576993002: server/config: Service-side project access checks. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« server/config/access/access.go ('K') | « server/config/access/access.go ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: server/config/access/access_test.go
diff --git a/server/config/access/access_test.go b/server/config/access/access_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..f296dc6c90563ea45911ae310755a6be6d99de26
--- /dev/null
+++ b/server/config/access/access_test.go
@@ -0,0 +1,138 @@
+// Copyright 2016 The LUCI Authors. All rights reserved.
+// Use of this source code is governed under the Apache License, Version 2.0
+// that can be found in the LICENSE file.
+
+package access
+
+import (
+ "fmt"
+ "testing"
+
+ configPB "github.com/luci/luci-go/common/proto/config"
+ "github.com/luci/luci-go/server/auth"
+ "github.com/luci/luci-go/server/auth/authtest"
+ "github.com/luci/luci-go/server/auth/identity"
+ "github.com/luci/luci-go/server/config"
+
+ "github.com/golang/protobuf/proto"
+ "golang.org/x/net/context"
+
+ . "github.com/luci/luci-go/common/testing/assertions"
+ . "github.com/smartystreets/goconvey/convey"
+)
+
+type testingBackend struct {
+ config.Backend
+
+ item *config.Item
+}
+
+func (tb *testingBackend) Get(c context.Context, configSet, path string, p config.Params) (*config.Item, error) {
+ if tb.item == nil {
+ return nil, config.ErrNoConfig
+ }
+ clone := *tb.item
+ return &clone, nil
+}
+
+func tpb(msg proto.Message) string { return proto.MarshalTextString(msg) }
+
+func accessCfg(access ...string) string {
+ return tpb(&configPB.ProjectCfg{
+ Access: access,
+ })
+}
+
+func TestCheckAccess(t *testing.T) {
+ t.Parallel()
+
+ Convey(`A testing environment`, t, func() {
+ c := context.Background()
+
+ authState := authtest.FakeState{
+ Identity: identity.AnonymousIdentity,
+ }
+ c = auth.WithState(c, &authState)
+
+ tb := testingBackend{}
+ setAccess := func(access ...string) {
+ if len(access) == 0 {
+ tb.item = nil
+ return
+ }
+ tb.item = &config.Item{
+ Content: tpb(&configPB.ProjectCfg{Access: access}),
+ }
+ }
+
+ c = config.WithBackend(c, &tb)
+
+ Convey(`Will grant AsService access to any config`, func() {
+ So(Check(c, config.AsService, "foo/bar"), ShouldBeNil)
+ So(Check(c, config.AsService, "services/foo"), ShouldBeNil)
+ So(Check(c, config.AsService, "projects/nonexistent"), ShouldBeNil)
+ So(Check(c, config.AsService, "projects/public"), ShouldBeNil)
+ })
+
+ for _, tc := range []struct {
+ A config.Authority
+ Name string
+ }{
+ {config.AsUser, "AsUser"},
+ {config.AsAnonymous, "AsAnonymous"},
+ } {
+ Convey(fmt.Sprintf(`Will deny %q access to any config`, tc.Name), func() {
+ So(Check(c, tc.A, "foo/bar"), ShouldEqual, ErrNoAccess)
+ So(Check(c, tc.A, "services/foo"), ShouldEqual, ErrNoAccess)
+ So(Check(c, tc.A, "projects/nonexistent"), ShouldErrLike, "failed to load \"project.cfg\"")
+ })
+
+ Convey(fmt.Sprintf(`Will grant %q access to an all-inclusive project`, tc.Name), func() {
+ setAccess("group:all")
+ So(Check(c, tc.A, "projects/public"), ShouldBeNil)
+ })
+ }
+
+ mustMakeIdentity := func(v string) identity.Identity {
+ id, err := identity.MakeIdentity(v)
+ if err != nil {
+ panic(err)
+ }
+ return id
+ }
+ for _, tc := range []struct {
+ name string
+ apply func()
+ }{
+ {"a special user", func() { authState.Identity = mustMakeIdentity("user:cat@example.com") }},
+ {"a special user (e-mail)", func() { authState.Identity = mustMakeIdentity("user:email@example.com") }},
+ {"a member of a special group", func() { authState.IdentityGroups = []string{"special"} }},
+ } {
+ Convey(fmt.Sprintf(`When user is %s`, tc.name), func() {
+ tc.apply()
+
+ setAccess()
+ So(Check(c, config.AsService, "foo/bar"), ShouldBeNil)
+ So(Check(c, config.AsUser, "foo/bar"), ShouldEqual, ErrNoAccess)
+ So(Check(c, config.AsAnonymous, "foo/bar"), ShouldEqual, ErrNoAccess)
+
+ So(Check(c, config.AsService, "services/foo"), ShouldBeNil)
+ So(Check(c, config.AsUser, "services/foo"), ShouldEqual, ErrNoAccess)
+ So(Check(c, config.AsAnonymous, "services/foo"), ShouldEqual, ErrNoAccess)
+
+ So(Check(c, config.AsService, "projects/nonexistent"), ShouldBeNil)
+ So(Check(c, config.AsUser, "projects/nonexistent"), ShouldErrLike, "failed to load \"project.cfg\"")
+ So(Check(c, config.AsAnonymous, "projects/nonexistent"), ShouldErrLike, "failed to load \"project.cfg\"")
+
+ setAccess("group:all")
+ So(Check(c, config.AsService, "projects/public"), ShouldBeNil)
+ So(Check(c, config.AsUser, "projects/public"), ShouldBeNil)
+ So(Check(c, config.AsAnonymous, "projects/public"), ShouldBeNil)
+
+ setAccess("group:special", "user:cat@example.com", "email@example.com")
+ So(Check(c, config.AsUser, "projects/exclusive"), ShouldBeNil)
+ So(Check(c, config.AsAnonymous, "projects/exclusive"), ShouldEqual, ErrNoAccess)
+ })
+ }
+ })
+}
« server/config/access/access.go ('K') | « server/config/access/access.go ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698