Skip to content

Commit

Permalink
Merge branch 'master' into adapter-alias/update-limelight-aliases
Browse files Browse the repository at this point in the history
  • Loading branch information
onkarvhanumante committed Oct 6, 2023
2 parents 3290984 + 8cdfe48 commit c83460e
Show file tree
Hide file tree
Showing 46 changed files with 477 additions and 2,804 deletions.
133 changes: 7 additions & 126 deletions account/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,25 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/buger/jsonparser"

"github.com/prebid/go-gdpr/consentconstants"

"github.com/prebid/prebid-server/config"
"github.com/prebid/prebid-server/errortypes"
"github.com/prebid/prebid-server/metrics"
"github.com/prebid/prebid-server/openrtb_ext"
"github.com/prebid/prebid-server/stored_requests"
"github.com/prebid/prebid-server/util/iputil"
jsonpatch "gopkg.in/evanphx/json-patch.v4"
)

// GetAccount looks up the config.Account object referenced by the given accountID, with access rules applied
func GetAccount(ctx context.Context, cfg *config.Configuration, fetcher stored_requests.AccountFetcher, accountID string, me metrics.MetricsEngine) (account *config.Account, errs []error) {
// Check BlacklistedAcctMap until we have deprecated it
if _, found := cfg.BlacklistedAcctMap[accountID]; found {
return nil, []error{&errortypes.BlacklistedAcct{
Message: fmt.Sprintf("Prebid-server has disabled Account ID: %s, please reach out to the prebid server host.", accountID),
}}
}
if cfg.AccountRequired && accountID == metrics.PublisherUnknown {
return nil, []error{&errortypes.AcctRequired{
Message: fmt.Sprintf("Prebid-server has been configured to discard requests without a valid Account ID. Please reach out to the prebid server host."),
}}
}

if accountJSON, accErrs := fetcher.FetchAccount(ctx, cfg.AccountDefaultsJSON(), accountID); len(accErrs) > 0 || accountJSON == nil {
// accountID does not reference a valid account
for _, e := range accErrs {
Expand All @@ -50,38 +45,10 @@ func GetAccount(ctx context.Context, cfg *config.Configuration, fetcher stored_r
// accountID resolved to a valid account, merge with AccountDefaults for a complete config
account = &config.Account{}
err := json.Unmarshal(accountJSON, account)

// this logic exists for backwards compatibility. If the initial unmarshal fails above, we attempt to
// resolve it by converting the GDPR enforce purpose fields and then attempting an unmarshal again before
// declaring a malformed account error.
// unmarshal fetched account to determine if it is well-formed
var deprecatedPurposeFields []string
if _, ok := err.(*json.UnmarshalTypeError); ok {
// attempt to convert deprecated GDPR enforce purpose fields to resolve issue
accountJSON, err, deprecatedPurposeFields = ConvertGDPREnforcePurposeFields(accountJSON)
// unmarshal again to check if unmarshal error still exists after GDPR field conversion
err = json.Unmarshal(accountJSON, account)

if _, ok := err.(*json.UnmarshalTypeError); ok {
return nil, []error{&errortypes.MalformedAcct{
Message: fmt.Sprintf("The prebid-server account config for account id \"%s\" is malformed. Please reach out to the prebid server host.", accountID),
}}
}
}
usingGDPRChannelEnabled := useGDPRChannelEnabled(account)
usingCCPAChannelEnabled := useCCPAChannelEnabled(account)

if usingGDPRChannelEnabled {
me.RecordAccountGDPRChannelEnabledWarning(accountID)
}
if usingCCPAChannelEnabled {
me.RecordAccountCCPAChannelEnabledWarning(accountID)
}
for _, purposeName := range deprecatedPurposeFields {
me.RecordAccountGDPRPurposeWarning(accountID, purposeName)
}
if len(deprecatedPurposeFields) > 0 || usingGDPRChannelEnabled || usingCCPAChannelEnabled {
me.RecordAccountUpgradeStatus(accountID)
return nil, []error{&errortypes.MalformedAcct{
Message: fmt.Sprintf("The prebid-server account config for account id \"%s\" is malformed. Please reach out to the prebid server host.", accountID),
}}
}

if err != nil {
Expand All @@ -97,7 +64,7 @@ func GetAccount(ctx context.Context, cfg *config.Configuration, fetcher stored_r
setDerivedConfig(account)
}
if account.Disabled {
errs = append(errs, &errortypes.BlacklistedAcct{
errs = append(errs, &errortypes.AccountDisabled{
Message: fmt.Sprintf("Prebid-server has disabled Account ID: %s, please reach out to the prebid server host.", accountID),
})
return nil, errs
Expand Down Expand Up @@ -175,89 +142,3 @@ func setDerivedConfig(account *config.Account) {
}
}
}

// PatchAccount represents the GDPR portion of a publisher account configuration that can be mutated
// for backwards compatibility reasons
type PatchAccount struct {
GDPR map[string]*PatchAccountGDPRPurpose `json:"gdpr"`
}

// PatchAccountGDPRPurpose represents account-specific GDPR purpose configuration data that can be mutated
// for backwards compatibility reasons
type PatchAccountGDPRPurpose struct {
EnforceAlgo string `json:"enforce_algo,omitempty"`
EnforcePurpose *bool `json:"enforce_purpose,omitempty"`
}

// ConvertGDPREnforcePurposeFields is responsible for ensuring account GDPR config backwards compatibility
// given the recent type change of gdpr.purpose{1-10}.enforce_purpose from a string to a bool. This function
// iterates over each GDPR purpose config and sets enforce_purpose and enforce_algo to the appropriate
// bool and string values respectively if enforce_purpose is a string and enforce_algo is not set
func ConvertGDPREnforcePurposeFields(config []byte) (newConfig []byte, err error, deprecatedPurposeFields []string) {
gdprJSON, _, _, err := jsonparser.Get(config, "gdpr")
if err != nil && err == jsonparser.KeyPathNotFoundError {
return config, nil, deprecatedPurposeFields
}
if err != nil {
return nil, err, deprecatedPurposeFields
}

newAccount := PatchAccount{
GDPR: map[string]*PatchAccountGDPRPurpose{},
}

for i := 1; i <= 10; i++ {
purposeName := fmt.Sprintf("purpose%d", i)

enforcePurpose, purposeDataType, _, err := jsonparser.Get(gdprJSON, purposeName, "enforce_purpose")
if err != nil && err == jsonparser.KeyPathNotFoundError {
continue
}
if err != nil {
return nil, err, deprecatedPurposeFields
}
if purposeDataType != jsonparser.String {
continue
} else {
deprecatedPurposeFields = append(deprecatedPurposeFields, purposeName)
}

_, _, _, err = jsonparser.Get(gdprJSON, purposeName, "enforce_algo")
if err != nil && err != jsonparser.KeyPathNotFoundError {
return nil, err, deprecatedPurposeFields
}
if err == nil {
continue
}

newEnforcePurpose := false
if string(enforcePurpose) == "full" {
newEnforcePurpose = true
}

newAccount.GDPR[purposeName] = &PatchAccountGDPRPurpose{
EnforceAlgo: "full",
EnforcePurpose: &newEnforcePurpose,
}
}

patchConfig, err := json.Marshal(newAccount)
if err != nil {
return nil, err, deprecatedPurposeFields
}

newConfig, err = jsonpatch.MergePatch(config, patchConfig)
if err != nil {
return nil, err, deprecatedPurposeFields
}

return newConfig, nil, deprecatedPurposeFields
}

func useGDPRChannelEnabled(account *config.Account) bool {
return account.GDPR.ChannelEnabled.IsSet() && !account.GDPR.IntegrationEnabled.IsSet()
}

func useCCPAChannelEnabled(account *config.Account) bool {
return account.CCPA.ChannelEnabled.IsSet() && !account.CCPA.IntegrationEnabled.IsSet()
}
Loading

0 comments on commit c83460e

Please sign in to comment.