-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathenvironment.go
More file actions
95 lines (80 loc) · 2.14 KB
/
environment.go
File metadata and controls
95 lines (80 loc) · 2.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package echo
import (
"os"
"slices"
"strings"
)
// EnvVar is an environment variable value stored in memory as a name / value
// pair.
type EnvVar struct {
Name, Value string
}
// EnvironmentDump represents the bits of the running environment to be dumped
// for return in a response payload.
type EnvironmentDump struct {
Variables []*EnvVar
}
// EnvironmentDumpPolicy determines what should be dumped from the running
// process' environment.
type EnvironmentDumpPolicy func(*EnvVar) bool
// denyAll prevents the environment from being dumped.
func denyAll(_ *EnvVar) bool {
return false
}
// VeryDangerousAllowAll is an EnvironmentDumpPolicy which dumps the entire
// environment. Aim this away from your foot before using.
func VeryDangerousAllowAll(_ *EnvVar) bool {
return true
}
const allowedVarsVarName = "ECHO_VARS"
// PolicyFromEnv is an EnvironmentDumpPolicy which reads the value of the
// ECHO_VARS environment variable, and allows dumping any env var names found.
// If the value is set to "..." then the entire environment is dumped (which is
// often a bad idea).
func PolicyFromEnv() func(*EnvVar) bool {
allowed := make(map[string]bool)
vv, ok := os.LookupEnv(allowedVarsVarName)
if !ok {
return denyAll
}
vv = strings.TrimSpace(vv)
if vv == "..." {
return VeryDangerousAllowAll
}
for _, vn := range strings.Split(vv, " ") {
vn = strings.TrimSpace(vn)
if vn == "" {
continue
}
allowed[vn] = true
}
return func(v *EnvVar) bool {
return allowed[v.Name]
}
}
var defaultPolicy = PolicyFromEnv()
// DumpEnv for rendering in an HTML payload.
func DumpEnv(policy EnvironmentDumpPolicy) *EnvironmentDump {
if policy == nil {
policy = defaultPolicy
}
var vars []*EnvVar
for _, rv := range os.Environ() {
vs := strings.SplitN(rv, "=", 2)
vn, vv := strings.TrimSpace(vs[0]), ""
if len(vs) > 1 {
vv = strings.TrimSpace(vs[1])
}
v := &EnvVar{vn, vv}
if policy(v) {
vars = append(vars, &EnvVar{vn, vv})
}
}
// Sort the vars for determinism and human friendliness.
slices.SortFunc(vars, func(l, r *EnvVar) int {
return strings.Compare(l.Name, r.Name)
})
return &EnvironmentDump{
Variables: vars,
}
}