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

Side by Side Diff: tokenserver/appengine/delegation/rpc_mint_delegation_token_test.go

Issue 2413683004: token-server: Delegation config import, validation and evaluation. (Closed)
Patch Set: also check validity_duration Created 4 years, 1 month 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 unified diff | Download patch
OLDNEW
(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 delegation
6
7 import (
8 "fmt"
9 "net/url"
10 "testing"
11
12 "golang.org/x/net/context"
13
14 "github.com/luci/luci-go/server/auth"
15 "github.com/luci/luci-go/server/auth/authtest"
16 "github.com/luci/luci-go/server/auth/identity"
17 admin "github.com/luci/luci-go/tokenserver/api/admin/v1"
18 minter "github.com/luci/luci-go/tokenserver/api/minter/v1"
19
20 . "github.com/luci/luci-go/common/testing/assertions"
21 . "github.com/smartystreets/goconvey/convey"
22 )
23
24 func mockedFetchLUCIServiceIdentity(c context.Context, u string) (identity.Ident ity, error) {
25 l, err := url.Parse(u)
26 if err != nil {
27 return "", err
28 }
29 if l.Scheme != "https" {
30 return "", fmt.Errorf("wrong scheme")
31 }
32 if l.Host == "crash" {
33 return "", fmt.Errorf("boom")
34 }
35 return identity.MakeIdentity("service:" + l.Host)
36 }
37
38 func init() {
39 fetchLUCIServiceIdentity = mockedFetchLUCIServiceIdentity
40 }
41
42 func TestBuildRulesQuery(t *testing.T) {
43 ctx := context.Background()
44
45 Convey("Happy path", t, func() {
46 q, err := buildRulesQuery(ctx, &minter.MintDelegationTokenReques t{
47 DelegatedIdentity: "user:delegated@example.com",
48 Audience: []string{"group:A", "group:B", "user: c@example.com"},
49 Services: []string{"service:A", "*"},
50 }, "user:requestor@example.com")
51 So(err, ShouldBeNil)
52 So(q, ShouldNotBeNil)
53
54 So(q.Requestor, ShouldEqual, "user:requestor@example.com")
55 So(q.Delegatee, ShouldEqual, "user:delegated@example.com")
56 So(q.Audience.ToStrings(), ShouldResemble, []string{"group:A", " group:B", "user:c@example.com"})
57 So(q.Services.ToStrings(), ShouldResemble, []string{"*"})
58 })
59
60 Convey("REQUESTOR usage works", t, func() {
61 q, err := buildRulesQuery(ctx, &minter.MintDelegationTokenReques t{
62 DelegatedIdentity: "REQUESTOR",
63 Audience: []string{"group:A", "group:B", "REQUE STOR"},
64 Services: []string{"*"},
65 }, "user:requestor@example.com")
66 So(err, ShouldBeNil)
67 So(q, ShouldNotBeNil)
68
69 So(q.Requestor, ShouldEqual, "user:requestor@example.com")
70 So(q.Delegatee, ShouldEqual, "user:requestor@example.com")
71 So(q.Audience.ToStrings(), ShouldResemble, []string{"group:A", " group:B", "user:requestor@example.com"})
72 })
73
74 Convey("bad 'delegated_identity'", t, func() {
75 _, err := buildRulesQuery(ctx, &minter.MintDelegationTokenReques t{
76 Audience: []string{"REQUESTOR"},
77 Services: []string{"*"},
78 }, "user:requestor@example.com")
79 So(err, ShouldErrLike, `'delegated_identity' is required`)
80
81 _, err = buildRulesQuery(ctx, &minter.MintDelegationTokenRequest {
82 DelegatedIdentity: "junk",
83 Audience: []string{"REQUESTOR"},
84 Services: []string{"*"},
85 }, "user:requestor@example.com")
86 So(err, ShouldErrLike, `bad 'delegated_identity' - auth: bad ide ntity string "junk"`)
87 })
88
89 Convey("bad 'audience'", t, func() {
90 _, err := buildRulesQuery(ctx, &minter.MintDelegationTokenReques t{
91 DelegatedIdentity: "REQUESTOR",
92 Services: []string{"*"},
93 }, "user:requestor@example.com")
94 So(err, ShouldErrLike, `'audience' is required`)
95
96 _, err = buildRulesQuery(ctx, &minter.MintDelegationTokenRequest {
97 DelegatedIdentity: "REQUESTOR",
98 Audience: []string{"REQUESTOR", "junk"},
99 Services: []string{"*"},
100 }, "user:requestor@example.com")
101 So(err, ShouldErrLike, `bad 'audience' - auth: bad identity stri ng "junk"`)
102 })
103
104 Convey("bad 'services'", t, func() {
105 _, err := buildRulesQuery(ctx, &minter.MintDelegationTokenReques t{
106 DelegatedIdentity: "REQUESTOR",
107 Audience: []string{"REQUESTOR"},
108 }, "user:requestor@example.com")
109 So(err, ShouldErrLike, `'services' is required`)
110
111 _, err = buildRulesQuery(ctx, &minter.MintDelegationTokenRequest {
112 DelegatedIdentity: "REQUESTOR",
113 Audience: []string{"REQUESTOR"},
114 Services: []string{"junk"},
115 }, "user:requestor@example.com")
116 So(err, ShouldErrLike, `bad 'services' - auth: bad identity stri ng "junk"`)
117
118 _, err = buildRulesQuery(ctx, &minter.MintDelegationTokenRequest {
119 DelegatedIdentity: "REQUESTOR",
120 Audience: []string{"REQUESTOR"},
121 Services: []string{"user:abc@example.com"},
122 }, "user:requestor@example.com")
123 So(err, ShouldErrLike, `bad 'services' - "user:abc@example.com" is not a service ID`)
124
125 _, err = buildRulesQuery(ctx, &minter.MintDelegationTokenRequest {
126 DelegatedIdentity: "REQUESTOR",
127 Audience: []string{"REQUESTOR"},
128 Services: []string{"group:abc"},
129 }, "user:requestor@example.com")
130 So(err, ShouldErrLike, `bad 'services' - can't specify groups`)
131 })
132
133 Convey("resolves https:// service refs", t, func() {
134 q, err := buildRulesQuery(ctx, &minter.MintDelegationTokenReques t{
135 DelegatedIdentity: "user:delegated@example.com",
136 Audience: []string{"*"},
137 Services: []string{
138 "service:A",
139 "service:B",
140 "https://C",
141 "https://B",
142 "https://A",
143 },
144 }, "user:requestor@example.com")
145 So(err, ShouldBeNil)
146 So(q, ShouldNotBeNil)
147
148 So(q.Services.ToStrings(), ShouldResemble, []string{
149 "service:A",
150 "service:B",
151 "service:C",
152 })
153 })
154
155 Convey("handles errors when resolving https:// service refs", t, func() {
156 _, err := buildRulesQuery(ctx, &minter.MintDelegationTokenReques t{
157 DelegatedIdentity: "user:delegated@example.com",
158 Audience: []string{"*"},
159 Services: []string{
160 "https://A",
161 "https://B",
162 "https://crash",
163 },
164 }, "user:requestor@example.com")
165 So(err, ShouldErrLike, `could not resolve "https://crash" to ser vice ID - boom`)
166 })
167 }
168
169 func TestMintDelegationToken(t *testing.T) {
170 Convey("with mocked config and state", t, func() {
171 cfg, err := loadConfig(`
172 rules {
173 name: "requstor for itself"
174 requestor: "user:requestor@example.com"
175 target_service: "*"
176 allowed_to_impersonate: "REQUESTOR"
177 allowed_audience: "REQUESTOR"
178 max_validity_duration: 3600
179 }
180 `)
181 So(err, ShouldBeNil)
182
183 mintMock := func(context.Context, *minter.MintDelegationTokenReq uest,
184 *RulesQuery, *admin.DelegationRule) (*minter.MintDelegat ionTokenResponse, error) {
185 return &minter.MintDelegationTokenResponse{Token: "valid _token"}, nil
186 }
187
188 rpc := MintDelegationTokenRPC{
189 ConfigLoader: func(context.Context) (*DelegationConfig, error) { return cfg, nil },
190 mintMock: mintMock,
191 }
192
193 Convey("Happy path", func() {
194 ctx := auth.WithState(context.Background(), &authtest.Fa keState{
195 Identity: "user:requestor@example.com",
196 })
197 resp, err := rpc.MintDelegationToken(ctx, &minter.MintDe legationTokenRequest{
198 DelegatedIdentity: "REQUESTOR",
199 Audience: []string{"REQUESTOR"},
200 Services: []string{"*"},
201 })
202 So(err, ShouldBeNil)
203 So(resp.Token, ShouldEqual, "valid_token")
204 })
205
206 Convey("Using delegated identity for auth is forbidden", func() {
207 ctx := auth.WithState(context.Background(), &authtest.Fa keState{
208 Identity: "user:requestor@example.co m",
209 PeerIdentityOverride: "user:impersonator@example .com",
210 })
211 _, err := rpc.MintDelegationToken(ctx, &minter.MintDeleg ationTokenRequest{
212 DelegatedIdentity: "REQUESTOR",
213 Audience: []string{"REQUESTOR"},
214 Services: []string{"*"},
215 })
216 So(err, ShouldErrLike, `code = 7 desc = delegation is fo rbidden for this API call`)
217 })
218
219 Convey("Anonymous calls are forbidden", func() {
220 ctx := auth.WithState(context.Background(), &authtest.Fa keState{
221 Identity: "anonymous:anonymous",
222 })
223 _, err := rpc.MintDelegationToken(ctx, &minter.MintDeleg ationTokenRequest{
224 DelegatedIdentity: "REQUESTOR",
225 Audience: []string{"REQUESTOR"},
226 Services: []string{"*"},
227 })
228 So(err, ShouldErrLike, `code = 16 desc = authentication required`)
229 })
230
231 Convey("Unauthorized requestor", func() {
232 ctx := auth.WithState(context.Background(), &authtest.Fa keState{
233 Identity: "user:unknown@example.cim",
234 })
235 _, err := rpc.MintDelegationToken(ctx, &minter.MintDeleg ationTokenRequest{
236 DelegatedIdentity: "REQUESTOR",
237 Audience: []string{"REQUESTOR"},
238 Services: []string{"*"},
239 })
240 So(err, ShouldErrLike, `code = 7 desc = not authorized`)
241 })
242
243 Convey("Negative validity duration", func() {
244 ctx := auth.WithState(context.Background(), &authtest.Fa keState{
245 Identity: "user:requestor@example.com",
246 })
247 _, err := rpc.MintDelegationToken(ctx, &minter.MintDeleg ationTokenRequest{
248 DelegatedIdentity: "REQUESTOR",
249 Audience: []string{"REQUESTOR"},
250 Services: []string{"*"},
251 ValidityDuration: -1,
252 })
253 So(err, ShouldErrLike, `code = 3 desc = bad request - in valid 'validity_duration' (-1)`)
254 })
255
256 Convey("Malformed request", func() {
257 ctx := auth.WithState(context.Background(), &authtest.Fa keState{
258 Identity: "user:requestor@example.com",
259 })
260 _, err := rpc.MintDelegationToken(ctx, &minter.MintDeleg ationTokenRequest{
261 DelegatedIdentity: "REQUESTOR",
262 Audience: []string{"junk"},
263 Services: []string{"*"},
264 })
265 So(err, ShouldErrLike, `code = 3 desc = bad request - ba d 'audience' - auth: bad identity string "junk"`)
266 })
267
268 Convey("No matching rules", func() {
269 ctx := auth.WithState(context.Background(), &authtest.Fa keState{
270 Identity: "user:requestor@example.com",
271 })
272 _, err := rpc.MintDelegationToken(ctx, &minter.MintDeleg ationTokenRequest{
273 DelegatedIdentity: "REQUESTOR",
274 Audience: []string{"user:someone-else@e xample.com"},
275 Services: []string{"*"},
276 })
277 So(err, ShouldErrLike, `code = 7 desc = forbidden - no m atching delegation rules in the config`)
278 })
279
280 Convey("Forbidden validity duration", func() {
281 ctx := auth.WithState(context.Background(), &authtest.Fa keState{
282 Identity: "user:requestor@example.com",
283 })
284 _, err := rpc.MintDelegationToken(ctx, &minter.MintDeleg ationTokenRequest{
285 DelegatedIdentity: "REQUESTOR",
286 Audience: []string{"REQUESTOR"},
287 Services: []string{"*"},
288 ValidityDuration: 3601,
289 })
290 So(err, ShouldErrLike,
291 `rpc error: code = 7 desc = forbidden - the requ ested validity duration (3601 sec) exceeds the maximum allowed one (3600 sec)`)
292 })
293
294 })
295 }
OLDNEW
« no previous file with comments | « tokenserver/appengine/delegation/rpc_mint_delegation_token.go ('k') | tokenserver/appengine/delegation/validation.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698