| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. |
| 4 |
| 5 package access |
| 6 |
| 7 import ( |
| 8 "fmt" |
| 9 "testing" |
| 10 |
| 11 configPB "github.com/luci/luci-go/common/proto/config" |
| 12 "github.com/luci/luci-go/server/auth" |
| 13 "github.com/luci/luci-go/server/auth/authtest" |
| 14 "github.com/luci/luci-go/server/auth/identity" |
| 15 "github.com/luci/luci-go/server/config" |
| 16 |
| 17 "github.com/golang/protobuf/proto" |
| 18 "golang.org/x/net/context" |
| 19 |
| 20 . "github.com/luci/luci-go/common/testing/assertions" |
| 21 . "github.com/smartystreets/goconvey/convey" |
| 22 ) |
| 23 |
| 24 type testingBackend struct { |
| 25 config.Backend |
| 26 |
| 27 item *config.Item |
| 28 } |
| 29 |
| 30 func (tb *testingBackend) Get(c context.Context, configSet, path string, p confi
g.Params) (*config.Item, error) { |
| 31 if tb.item == nil { |
| 32 return nil, config.ErrNoConfig |
| 33 } |
| 34 clone := *tb.item |
| 35 return &clone, nil |
| 36 } |
| 37 |
| 38 func tpb(msg proto.Message) string { return proto.MarshalTextString(msg) } |
| 39 |
| 40 func accessCfg(access ...string) string { |
| 41 return tpb(&configPB.ProjectCfg{ |
| 42 Access: access, |
| 43 }) |
| 44 } |
| 45 |
| 46 func TestCheckAccess(t *testing.T) { |
| 47 t.Parallel() |
| 48 |
| 49 Convey(`A testing environment`, t, func() { |
| 50 c := context.Background() |
| 51 |
| 52 authState := authtest.FakeState{ |
| 53 Identity: identity.AnonymousIdentity, |
| 54 } |
| 55 c = auth.WithState(c, &authState) |
| 56 |
| 57 tb := testingBackend{} |
| 58 setAccess := func(access ...string) { |
| 59 if len(access) == 0 { |
| 60 tb.item = nil |
| 61 return |
| 62 } |
| 63 tb.item = &config.Item{ |
| 64 Content: tpb(&configPB.ProjectCfg{Access: access
}), |
| 65 } |
| 66 } |
| 67 |
| 68 c = config.WithBackend(c, &tb) |
| 69 |
| 70 Convey(`Will grant AsService access to any config`, func() { |
| 71 So(Check(c, config.AsService, "foo/bar"), ShouldBeNil) |
| 72 So(Check(c, config.AsService, "services/foo"), ShouldBeN
il) |
| 73 So(Check(c, config.AsService, "projects/nonexistent"), S
houldBeNil) |
| 74 So(Check(c, config.AsService, "projects/public"), Should
BeNil) |
| 75 }) |
| 76 |
| 77 for _, tc := range []struct { |
| 78 A config.Authority |
| 79 Name string |
| 80 }{ |
| 81 {config.AsUser, "AsUser"}, |
| 82 {config.AsAnonymous, "AsAnonymous"}, |
| 83 } { |
| 84 Convey(fmt.Sprintf(`Will deny %q access to any config`,
tc.Name), func() { |
| 85 So(Check(c, tc.A, "foo/bar"), ShouldEqual, ErrNo
Access) |
| 86 So(Check(c, tc.A, "services/foo"), ShouldEqual,
ErrNoAccess) |
| 87 So(Check(c, tc.A, "projects/nonexistent"), Shoul
dErrLike, "failed to load \"project.cfg\"") |
| 88 }) |
| 89 |
| 90 Convey(fmt.Sprintf(`Will grant %q access to an all-inclu
sive project`, tc.Name), func() { |
| 91 setAccess("group:all") |
| 92 So(Check(c, tc.A, "projects/public"), ShouldBeNi
l) |
| 93 }) |
| 94 } |
| 95 |
| 96 mustMakeIdentity := func(v string) identity.Identity { |
| 97 id, err := identity.MakeIdentity(v) |
| 98 if err != nil { |
| 99 panic(err) |
| 100 } |
| 101 return id |
| 102 } |
| 103 for _, tc := range []struct { |
| 104 name string |
| 105 apply func() |
| 106 }{ |
| 107 {"a special user", func() { authState.Identity = mustMak
eIdentity("user:cat@example.com") }}, |
| 108 {"a special user (e-mail)", func() { authState.Identity
= mustMakeIdentity("user:email@example.com") }}, |
| 109 {"a member of a special group", func() { authState.Ident
ityGroups = []string{"special"} }}, |
| 110 } { |
| 111 Convey(fmt.Sprintf(`When user is %s`, tc.name), func() { |
| 112 tc.apply() |
| 113 |
| 114 setAccess() |
| 115 So(Check(c, config.AsService, "foo/bar"), Should
BeNil) |
| 116 So(Check(c, config.AsUser, "foo/bar"), ShouldEqu
al, ErrNoAccess) |
| 117 So(Check(c, config.AsAnonymous, "foo/bar"), Shou
ldEqual, ErrNoAccess) |
| 118 |
| 119 So(Check(c, config.AsService, "services/foo"), S
houldBeNil) |
| 120 So(Check(c, config.AsUser, "services/foo"), Shou
ldEqual, ErrNoAccess) |
| 121 So(Check(c, config.AsAnonymous, "services/foo"),
ShouldEqual, ErrNoAccess) |
| 122 |
| 123 So(Check(c, config.AsService, "projects/nonexist
ent"), ShouldBeNil) |
| 124 So(Check(c, config.AsUser, "projects/nonexistent
"), ShouldErrLike, "failed to load \"project.cfg\"") |
| 125 So(Check(c, config.AsAnonymous, "projects/nonexi
stent"), ShouldErrLike, "failed to load \"project.cfg\"") |
| 126 |
| 127 setAccess("group:all") |
| 128 So(Check(c, config.AsService, "projects/public")
, ShouldBeNil) |
| 129 So(Check(c, config.AsUser, "projects/public"), S
houldBeNil) |
| 130 So(Check(c, config.AsAnonymous, "projects/public
"), ShouldBeNil) |
| 131 |
| 132 setAccess("group:special", "user:cat@example.com
", "email@example.com") |
| 133 So(Check(c, config.AsUser, "projects/exclusive")
, ShouldBeNil) |
| 134 So(Check(c, config.AsAnonymous, "projects/exclus
ive"), ShouldEqual, ErrNoAccess) |
| 135 }) |
| 136 } |
| 137 }) |
| 138 } |
| OLD | NEW |