Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The LUCI Authors. All rights reserved. | 1 // Copyright 2017 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
| 4 | 4 |
| 5 package serviceaccounts | 5 package serviceaccounts |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "golang.org/x/net/context" | 8 "golang.org/x/net/context" |
| 9 "google.golang.org/grpc" | 9 "google.golang.org/grpc" |
| 10 "google.golang.org/grpc/codes" | 10 "google.golang.org/grpc/codes" |
| 11 | 11 |
| 12 "github.com/luci/luci-go/server/auth/identity" | |
| 12 "github.com/luci/luci-go/server/auth/signing" | 13 "github.com/luci/luci-go/server/auth/signing" |
| 13 | 14 |
| 14 "github.com/luci/luci-go/tokenserver/api" | 15 "github.com/luci/luci-go/tokenserver/api" |
| 15 "github.com/luci/luci-go/tokenserver/api/admin/v1" | 16 "github.com/luci/luci-go/tokenserver/api/admin/v1" |
| 16 ) | 17 ) |
| 17 | 18 |
| 18 // InspectOAuthTokenGrantRPC implements admin.InspectOAuthTokenGrant method. | 19 // InspectOAuthTokenGrantRPC implements admin.InspectOAuthTokenGrant method. |
| 19 type InspectOAuthTokenGrantRPC struct { | 20 type InspectOAuthTokenGrantRPC struct { |
| 20 // Signer is mocked in tests. | 21 // Signer is mocked in tests. |
| 21 // | 22 // |
| 22 // In prod it is gaesigner.Signer. | 23 // In prod it is gaesigner.Signer. |
| 23 Signer signing.Signer | 24 Signer signing.Signer |
| 25 | |
| 26 // Rules returns service account rules to use for the request. | |
| 27 // | |
| 28 // In prod it is GlobalRulesCache.Rules. | |
| 29 Rules func(context.Context) (*Rules, error) | |
| 24 } | 30 } |
| 25 | 31 |
| 26 // InspectOAuthTokenGrant decodes the given OAuth token grant. | 32 // InspectOAuthTokenGrant decodes the given OAuth token grant. |
| 27 func (r *InspectOAuthTokenGrantRPC) InspectOAuthTokenGrant(c context.Context, re q *admin.InspectOAuthTokenGrantRequest) (*admin.InspectOAuthTokenGrantResponse, error) { | 33 func (r *InspectOAuthTokenGrantRPC) InspectOAuthTokenGrant(c context.Context, re q *admin.InspectOAuthTokenGrantRequest) (*admin.InspectOAuthTokenGrantResponse, error) { |
|
Vadim Sh.
2017/08/05 03:27:01
Looks like this: https://screenshot.googleplex.com
| |
| 28 inspection, err := InspectGrant(c, r.Signer, req.Token) | 34 inspection, err := InspectGrant(c, r.Signer, req.Token) |
| 29 if err != nil { | 35 if err != nil { |
| 30 return nil, grpc.Errorf(codes.Internal, err.Error()) | 36 return nil, grpc.Errorf(codes.Internal, err.Error()) |
| 31 } | 37 } |
| 38 | |
| 32 resp := &admin.InspectOAuthTokenGrantResponse{ | 39 resp := &admin.InspectOAuthTokenGrantResponse{ |
| 33 Valid: inspection.Signed && inspection.NonExpired, | 40 Valid: inspection.Signed && inspection.NonExpired, |
| 34 Signed: inspection.Signed, | 41 Signed: inspection.Signed, |
| 35 NonExpired: inspection.NonExpired, | 42 NonExpired: inspection.NonExpired, |
| 36 InvalidityReason: inspection.InvalidityReason, | 43 InvalidityReason: inspection.InvalidityReason, |
| 37 } | 44 } |
| 45 | |
| 38 if env, _ := inspection.Envelope.(*tokenserver.OAuthTokenGrantEnvelope); env != nil { | 46 if env, _ := inspection.Envelope.(*tokenserver.OAuthTokenGrantEnvelope); env != nil { |
| 39 resp.SigningKeyId = env.KeyId | 47 resp.SigningKeyId = env.KeyId |
| 40 } | 48 } |
| 49 | |
| 50 // Examine the body, even if the token is expired or unsigned. This help s to | |
| 51 // debug expired or unsigned tokens... | |
| 41 resp.TokenBody, _ = inspection.Body.(*tokenserver.OAuthTokenGrantBody) | 52 resp.TokenBody, _ = inspection.Body.(*tokenserver.OAuthTokenGrantBody) |
| 53 if resp.TokenBody != nil { | |
| 54 rules, err := r.Rules(c) | |
| 55 if err != nil { | |
| 56 return nil, grpc.Errorf(codes.Internal, "failed to load service accounts rules") | |
| 57 } | |
| 58 | |
| 59 // Always return the rule that matches the service account, even if the | |
| 60 // token itself is not allowed by it (we check it separately bel ow). | |
| 61 if rule := rules.Rule(resp.TokenBody.ServiceAccount); rule != ni l { | |
| 62 resp.MatchingRule = rule.Rule | |
| 63 } | |
| 64 | |
| 65 q := &RulesQuery{ | |
| 66 ServiceAccount: resp.TokenBody.ServiceAccount, | |
| 67 Proxy: identity.Identity(resp.TokenBody.Proxy), | |
| 68 EndUser: identity.Identity(resp.TokenBody.EndUser ), | |
| 69 } | |
| 70 switch _, err = rules.Check(c, q); { | |
| 71 case err == nil: | |
| 72 resp.AllowedByRules = true | |
| 73 case grpc.Code(err) == codes.Internal: | |
| 74 return nil, err // a transient error when checking rules | |
| 75 default: // fatal gRPC error => the rules forbid the token | |
| 76 if resp.Valid { | |
| 77 resp.Valid = false | |
| 78 resp.InvalidityReason = "not allowed by the rule s" | |
| 79 } | |
| 80 } | |
| 81 } | |
| 82 | |
| 42 return resp, nil | 83 return resp, nil |
| 43 } | 84 } |
| OLD | NEW |