go.chromium.org/luci@v0.0.0-20250314024836-d9a61d0730e6/tokenserver/appengine/impl/utils/rpc_utils.go (about) 1 // Copyright 2019 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package utils 16 17 import ( 18 "context" 19 "fmt" 20 "time" 21 22 "google.golang.org/protobuf/encoding/protojson" 23 "google.golang.org/protobuf/proto" 24 25 "go.chromium.org/luci/auth/identity" 26 "go.chromium.org/luci/common/logging" 27 ) 28 29 const ( 30 // maxAllowedMinValidityDuration specifies the maximum project identity token validity period 31 // that a client may ask for. 32 maxAllowedMinValidityDuration = 30 * time.Minute 33 34 // DefaultMinValidityDuration is a value for minimal returned token lifetime if 'min_validity_duration' 35 // field is not specified in the request. 36 DefaultMinValidityDuration = 5 * time.Minute 37 ) 38 39 // RPC interface specifies custom functionality implemented per RPC object. 40 type RPC interface { 41 Name() string 42 } 43 44 // ValidateProject validates a LUCI project string. 45 func ValidateProject(c context.Context, project string) error { 46 if project == "" { 47 return fmt.Errorf("luci_project is empty") 48 } 49 return nil 50 } 51 52 // ValidateAndNormalizeRequest validates and normalizes RPC requests. 53 func ValidateAndNormalizeRequest(c context.Context, oauthScope []string, durationSecs *int64, auditTags []string) error { 54 minDur := time.Duration(*durationSecs) * time.Second 55 // Test error cases 56 switch { 57 case len(oauthScope) <= 0: 58 return fmt.Errorf("oauth_scope is required") 59 case minDur < 0: 60 return fmt.Errorf("min_validity_duration must be positive") 61 case minDur > maxAllowedMinValidityDuration: 62 return fmt.Errorf("min_validity_duration must not exceed %d", maxAllowedMinValidityDuration/time.Second) 63 } 64 if err := ValidateTags(auditTags); err != nil { 65 return fmt.Errorf("bad audit_tags - %s", err) 66 } 67 68 // Perform normalization 69 if minDur == 0 { 70 *durationSecs = int64(DefaultMinValidityDuration.Seconds()) 71 } 72 return nil 73 } 74 75 // LogRequest logs the RPC request. 76 func LogRequest(c context.Context, rpc RPC, req proto.Message, caller identity.Identity) { 77 if logging.IsLogging(c, logging.Debug) { 78 opts := protojson.MarshalOptions{Indent: " "} 79 logging.Debugf(c, "Identity: %s, %s:\n%s", caller, rpc.Name(), opts.Format(req)) 80 } 81 }