-
Notifications
You must be signed in to change notification settings - Fork 726
/
purpose_enforcer.go
111 lines (95 loc) · 3.61 KB
/
purpose_enforcer.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
package gdpr
import (
"github.com/prebid/go-gdpr/api"
"github.com/prebid/go-gdpr/consentconstants"
tcf2 "github.com/prebid/go-gdpr/vendorconsent/tcf2"
"github.com/prebid/prebid-server/v2/config"
"github.com/prebid/prebid-server/v2/openrtb_ext"
)
// PurposeEnforcer represents the enforcement strategy for determining if legal basis is achieved for a purpose
type PurposeEnforcer interface {
LegalBasis(vendorInfo VendorInfo, name string, consent tcf2.ConsentMetadata, overrides Overrides) bool
}
// PurposeEnforcerBuilder generates an instance of PurposeEnforcer for a given purpose and bidder
type PurposeEnforcerBuilder func(p consentconstants.Purpose, name string) PurposeEnforcer
// Overrides specifies enforcement algorithm rule adjustments
type Overrides struct {
allowLITransparency bool
blockVendorExceptions bool
enforcePurpose bool
enforceVendors bool
}
type BidderInfo struct {
bidderCoreName openrtb_ext.BidderName
bidder openrtb_ext.BidderName
}
type VendorInfo struct {
vendorID uint16
vendor api.Vendor
}
// PurposeEnforcers holds the full and basic enforcers for a purpose
type PurposeEnforcers struct {
Full PurposeEnforcer
Basic PurposeEnforcer
}
// NewPurposeEnforcerBuilder creates a new instance of PurposeEnforcerBuilder. This function uses
// closures so that any enforcer generated by the returned builder may use the config and also be
// cached and reused within a request context
func NewPurposeEnforcerBuilder(cfg TCF2ConfigReader) PurposeEnforcerBuilder {
cachedEnforcers := make([]PurposeEnforcers, 10)
return func(purpose consentconstants.Purpose, name string) PurposeEnforcer {
index := purpose - 1
var basicEnforcementVendor bool
if purpose == consentconstants.Purpose(1) {
basicEnforcementVendor = false
} else {
basicEnforcementVendors := cfg.BasicEnforcementVendors()
_, basicEnforcementVendor = basicEnforcementVendors[name]
}
enforceAlgo := cfg.PurposeEnforcementAlgo(purpose)
downgraded := isDowngraded(enforceAlgo, basicEnforcementVendor)
if enforceAlgo == config.TCF2BasicEnforcement || downgraded {
if cachedEnforcers[index].Basic != nil {
return cachedEnforcers[index].Basic
}
purposeCfg := purposeConfig{
PurposeID: purpose,
EnforceAlgo: enforceAlgo,
EnforcePurpose: cfg.PurposeEnforced(purpose),
EnforceVendors: cfg.PurposeEnforcingVendors(purpose),
VendorExceptionMap: cfg.PurposeVendorExceptions(purpose),
BasicEnforcementVendorsMap: cfg.BasicEnforcementVendors(),
}
enforcer := &BasicEnforcement{
cfg: purposeCfg,
}
cachedEnforcers[index].Basic = enforcer
return enforcer
} else {
if cachedEnforcers[index].Full != nil {
return cachedEnforcers[index].Full
}
purposeCfg := purposeConfig{
PurposeID: purpose,
EnforceAlgo: enforceAlgo,
EnforcePurpose: cfg.PurposeEnforced(purpose),
EnforceVendors: cfg.PurposeEnforcingVendors(purpose),
VendorExceptionMap: cfg.PurposeVendorExceptions(purpose),
BasicEnforcementVendorsMap: cfg.BasicEnforcementVendors(),
}
enforcer := &FullEnforcement{
cfg: purposeCfg,
}
cachedEnforcers[index].Full = enforcer
return enforcer
}
}
}
// isDowngraded determines if the enforcement algorithm used to determine legal basis for a
// purpose should be downgraded from full enforcement to basic
func isDowngraded(enforceAlgo config.TCF2EnforcementAlgo, basicEnforcementVendor bool) bool {
if enforceAlgo == config.TCF2FullEnforcement && basicEnforcementVendor {
return true
}
return false
}