-
-
Notifications
You must be signed in to change notification settings - Fork 163
/
Copy pathcontext.go
114 lines (101 loc) · 3.98 KB
/
context.go
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package ffcontext
import "encoding/json"
type Context interface {
// GetKey return the unique targetingKey for the context.
GetKey() string
// IsAnonymous return if the context is about an anonymous user or not.
IsAnonymous() bool
// GetCustom return all the attributes properties added to the context.
GetCustom() map[string]interface{}
// AddCustomAttribute allows to add a attributes attribute into the context.
AddCustomAttribute(name string, value interface{})
// ExtractGOFFProtectedFields extract the goff specific attributes from the evaluation context.
ExtractGOFFProtectedFields() GoffContextSpecifics
}
// value is a type to define attributes.
type value map[string]interface{}
// NewEvaluationContext creates a new evaluation context identified by the given targetingKey.
func NewEvaluationContext(key string) EvaluationContext {
return EvaluationContext{targetingKey: key, attributes: map[string]interface{}{}}
}
// Deprecated: NewAnonymousEvaluationContext is here for compatibility reason.
// Please use NewEvaluationContext instead and add a attributes attribute to know that it is an anonymous user.
//
// ctx := NewEvaluationContext("my-targetingKey")
// ctx.AddCustomAttribute("anonymous", true)
func NewAnonymousEvaluationContext(key string) EvaluationContext {
return EvaluationContext{targetingKey: key, attributes: map[string]interface{}{
"anonymous": true,
}}
}
// EvaluationContext contains specific attributes for your evaluation.
// Most of the time it is identifying a user browsing your site.
// The only mandatory property is the Key, which must a unique identifier.
// For authenticated users, this may be a username or e-mail address.
// For anonymous users, this could be an IP address or session ID.
//
// EvaluationContext fields are immutable and can be accessed only via getter methods.
// To construct an EvaluationContext, use either a simple constructor (NewEvaluationContext) or the builder pattern
// with NewEvaluationContextBuilder.
type EvaluationContext struct {
// uniquely identifying the subject (end-user, or client service) of a flag evaluation
targetingKey string
attributes value
}
// MarshalJSON is a custom JSON marshaller for EvaluationContext.
// It will only marshal the targetingKey and the attributes of the context and avoid to expose the internal structure.
func (u EvaluationContext) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
TargetingKey string `json:"targetingKey"`
Attributes value `json:"attributes"`
}{
TargetingKey: u.targetingKey,
Attributes: u.attributes,
})
}
// GetKey return the unique targetingKey for the user.
func (u EvaluationContext) GetKey() string {
return u.targetingKey
}
// IsAnonymous return if the user is anonymous or not.
func (u EvaluationContext) IsAnonymous() bool {
anonymous := u.attributes["anonymous"]
switch v := anonymous.(type) {
case bool:
return v
default:
return false
}
}
// GetCustom return all the attributes properties of a user.
func (u EvaluationContext) GetCustom() map[string]interface{} {
return u.attributes
}
// AddCustomAttribute allows to add a attributes attribute into the user.
func (u EvaluationContext) AddCustomAttribute(name string, value interface{}) {
if name != "" {
u.attributes[name] = value
}
}
func (u EvaluationContext) ToMap() map[string]any {
resMap := u.attributes
resMap["targetingKey"] = u.targetingKey
return resMap
}
// ExtractGOFFProtectedFields extract the goff specific attributes from the evaluation context.
func (u EvaluationContext) ExtractGOFFProtectedFields() GoffContextSpecifics {
goff := GoffContextSpecifics{}
switch v := u.attributes["gofeatureflag"].(type) {
case map[string]string:
goff.addCurrentDateTime(v["currentDateTime"])
goff.addListFlags(v["flagList"])
goff.addExporterMetadata(v["exporterMetadata"])
case map[string]interface{}:
goff.addCurrentDateTime(v["currentDateTime"])
goff.addListFlags(v["flagList"])
goff.addExporterMetadata(v["exporterMetadata"])
case GoffContextSpecifics:
return v
}
return goff
}