git.iko.soy/typeable/oauth2-proxy
on master help sign in
Add validation for Headers struct
commit098ee1d8438b850cf00b7902563365bfbd3d7b87 authorJoel Speed <joel.speed@hotmail.co.uk> dateThu 23 Jul 2020, 10:47 (6 years ago) parenta27d71b
3 files changed+104
pkg/validation/common.go+43 pkg/validation/header.go+52 pkg/validation/utils.go+9
pkg/validation/common.gonew file+43
@@ -0,0 +1,43 @@
1+package validation
2+
3+import (
4+ "encoding/base64"
5+ "fmt"
6+ "os"
7+
8+ "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
9+)
10+
11+func validateSecretSource(source options.SecretSource) string {
12+ switch {
13+ case len(source.Value) > 0 && source.FromEnv == "" && source.FromFile == "":
14+ return validateSecretSourceValue(source.Value)
15+ case len(source.Value) == 0 && source.FromEnv != "" && source.FromFile == "":
16+ return validateSecretSourceEnv(source.FromEnv)
17+ case len(source.Value) == 0 && source.FromEnv == "" && source.FromFile != "":
18+ return validateSecretSourceFile(source.FromFile)
19+ default:
20+ return "multiple values specified for secret source: specify either value, fromEnv of fromFile"
21+ }
22+}
23+
24+func validateSecretSourceValue(value []byte) string {
25+ if _, err := base64.StdEncoding.Decode([]byte{}, value); err != nil {
26+ return fmt.Sprintf("error decoding secret value: %v", err)
27+ }
28+ return ""
29+}
30+
31+func validateSecretSourceEnv(key string) string {
32+ if value := os.Getenv(key); value == "" {
33+ return fmt.Sprintf("error loading secret from environent: no value for for key %q", key)
34+ }
35+ return ""
36+}
37+
38+func validateSecretSourceFile(path string) string {
39+ if _, err := os.Stat(path); err != nil {
40+ return fmt.Sprintf("error loadig secret from file: %v", err)
41+ }
42+ return ""
43+}
pkg/validation/header.gonew file+52
@@ -0,0 +1,52 @@
1+package validation
2+
3+import (
4+ "fmt"
5+
6+ "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
7+)
8+
9+func validateHeaders(headers []options.Header) []string {
10+ msgs := []string{}
11+ names := make(map[string]struct{})
12+
13+ for _, header := range headers {
14+ msgs = append(msgs, validateHeader(header, names)...)
15+ }
16+ return msgs
17+}
18+
19+func validateHeader(header options.Header, names map[string]struct{}) []string {
20+ msgs := []string{}
21+
22+ if header.Name == "" {
23+ msgs = append(msgs, "header has empty name: names are required for all headers")
24+ }
25+
26+ if _, ok := names[header.Name]; ok {
27+ msgs = append(msgs, fmt.Sprintf("multiple headers found with name %q: header names must be unique", header.Name))
28+ }
29+
30+ for _, value := range header.Values {
31+ msgs = append(msgs, validateHeaderValue(header.Name, value)...)
32+ }
33+ return msgs
34+}
35+
36+func validateHeaderValue(name string, value options.HeaderValue) []string {
37+ switch {
38+ case value.SecretSource != nil && value.ClaimSource == nil:
39+ return prefixValues("invalid header value: ", validateSecretSource(*value.SecretSource))
40+ case value.SecretSource == nil && value.ClaimSource != nil:
41+ return validateHeaderValueClaimSource(*value.ClaimSource)
42+ default:
43+ return []string{fmt.Sprintf("header %q value has multiple entries: only one entry per value is allowed", name)}
44+ }
45+}
46+
47+func validateHeaderValueClaimSource(claim options.ClaimSource) []string {
48+ if claim.BasicAuthPassword != nil {
49+ return prefixValues("invalid basicAuthPassword: ", validateSecretSource(*claim.BasicAuthPassword))
50+ }
51+ return []string{}
52+}
pkg/validation/utils.gonew file+9
@@ -0,0 +1,9 @@
1+package validation
2+
3+func prefixValues(prefix string, values ...string) []string {
4+ msgs := make([]string, len(values))
5+ for i, value := range values {
6+ msgs[i] = prefix + value
7+ }
8+ return msgs
9+}