This repository has been archived by the owner on Dec 22, 2022. It is now read-only.
forked from prebid/prebid-server
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor: move getAccount to accounts package (from openrtb2) (prebid…
- Loading branch information
Showing
6 changed files
with
170 additions
and
125 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package account | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
|
||
jsonpatch "github.com/evanphx/json-patch" | ||
"github.com/prebid/prebid-server/config" | ||
"github.com/prebid/prebid-server/errortypes" | ||
"github.com/prebid/prebid-server/pbsmetrics" | ||
"github.com/prebid/prebid-server/stored_requests" | ||
) | ||
|
||
// 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) (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 == pbsmetrics.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, accountID); len(accErrs) > 0 || accountJSON == nil { | ||
// accountID does not reference a valid account | ||
for _, e := range accErrs { | ||
if _, ok := e.(stored_requests.NotFoundError); !ok { | ||
errs = append(errs, e) | ||
} | ||
} | ||
if cfg.AccountRequired && cfg.AccountDefaults.Disabled { | ||
errs = append(errs, &errortypes.AcctRequired{ | ||
Message: fmt.Sprintf("Prebid-server could not verify the Account ID. Please reach out to the prebid server host."), | ||
}) | ||
return nil, errs | ||
} | ||
// Make a copy of AccountDefaults instead of taking a reference, | ||
// to preserve original accountID in case is needed to check NonStandardPublisherMap | ||
pubAccount := cfg.AccountDefaults | ||
pubAccount.ID = accountID | ||
account = &pubAccount | ||
} else { | ||
// accountID resolved to a valid account, merge with AccountDefaults for a complete config | ||
account = &config.Account{} | ||
completeJSON, err := jsonpatch.MergePatch(cfg.AccountDefaultsJSON(), accountJSON) | ||
if err == nil { | ||
err = json.Unmarshal(completeJSON, account) | ||
} | ||
if err != nil { | ||
errs = append(errs, err) | ||
return nil, errs | ||
} | ||
// Fill in ID if needed, so it can be left out of account definition | ||
if len(account.ID) == 0 { | ||
account.ID = accountID | ||
} | ||
} | ||
if account.Disabled { | ||
errs = append(errs, &errortypes.BlacklistedAcct{ | ||
Message: fmt.Sprintf("Prebid-server has disabled Account ID: %s, please reach out to the prebid server host.", accountID), | ||
}) | ||
return nil, errs | ||
} | ||
return account, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package account | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/prebid/prebid-server/config" | ||
"github.com/prebid/prebid-server/errortypes" | ||
"github.com/prebid/prebid-server/pbsmetrics" | ||
"github.com/prebid/prebid-server/stored_requests" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
var mockAccountData = map[string]json.RawMessage{ | ||
"valid_acct": json.RawMessage(`{"disabled":false}`), | ||
"disabled_acct": json.RawMessage(`{"disabled":true}`), | ||
} | ||
|
||
type mockAccountFetcher struct { | ||
} | ||
|
||
func (af mockAccountFetcher) FetchAccount(ctx context.Context, accountID string) (json.RawMessage, []error) { | ||
if account, ok := mockAccountData[accountID]; ok { | ||
return account, nil | ||
} | ||
return nil, []error{stored_requests.NotFoundError{accountID, "Account"}} | ||
} | ||
|
||
func TestGetAccount(t *testing.T) { | ||
unknown := pbsmetrics.PublisherUnknown | ||
testCases := []struct { | ||
accountID string | ||
// account_required | ||
required bool | ||
// account_defaults.disabled | ||
disabled bool | ||
// expected error, or nil if account should be found | ||
err error | ||
}{ | ||
// Blacklisted account is always rejected even in permissive setup | ||
{accountID: "bad_acct", required: false, disabled: false, err: &errortypes.BlacklistedAcct{}}, | ||
|
||
// empty pubID | ||
{accountID: unknown, required: false, disabled: false, err: nil}, | ||
{accountID: unknown, required: true, disabled: false, err: &errortypes.AcctRequired{}}, | ||
{accountID: unknown, required: false, disabled: true, err: &errortypes.BlacklistedAcct{}}, | ||
{accountID: unknown, required: true, disabled: true, err: &errortypes.AcctRequired{}}, | ||
|
||
// pubID given but is not a valid host account (does not exist) | ||
{accountID: "doesnt_exist_acct", required: false, disabled: false, err: nil}, | ||
{accountID: "doesnt_exist_acct", required: true, disabled: false, err: nil}, | ||
{accountID: "doesnt_exist_acct", required: false, disabled: true, err: &errortypes.BlacklistedAcct{}}, | ||
{accountID: "doesnt_exist_acct", required: true, disabled: true, err: &errortypes.AcctRequired{}}, | ||
|
||
// pubID given and matches a valid host account with Disabled: false | ||
{accountID: "valid_acct", required: false, disabled: false, err: nil}, | ||
{accountID: "valid_acct", required: true, disabled: false, err: nil}, | ||
{accountID: "valid_acct", required: false, disabled: true, err: nil}, | ||
{accountID: "valid_acct", required: true, disabled: true, err: nil}, | ||
|
||
// pubID given and matches a host account explicitly disabled (Disabled: true on account json) | ||
{accountID: "disabled_acct", required: false, disabled: false, err: &errortypes.BlacklistedAcct{}}, | ||
{accountID: "disabled_acct", required: true, disabled: false, err: &errortypes.BlacklistedAcct{}}, | ||
{accountID: "disabled_acct", required: false, disabled: true, err: &errortypes.BlacklistedAcct{}}, | ||
{accountID: "disabled_acct", required: true, disabled: true, err: &errortypes.BlacklistedAcct{}}, | ||
} | ||
|
||
for _, test := range testCases { | ||
description := fmt.Sprintf(`ID=%s/required=%t/disabled=%t`, test.accountID, test.required, test.disabled) | ||
t.Run(description, func(t *testing.T) { | ||
cfg := &config.Configuration{ | ||
BlacklistedAcctMap: map[string]bool{"bad_acct": true}, | ||
AccountRequired: test.required, | ||
AccountDefaults: config.Account{Disabled: test.disabled}, | ||
} | ||
fetcher := &mockAccountFetcher{} | ||
assert.NoError(t, cfg.MarshalAccountDefaults()) | ||
|
||
account, errors := GetAccount(context.Background(), cfg, fetcher, test.accountID) | ||
|
||
if test.err == nil { | ||
assert.Empty(t, errors) | ||
assert.Equal(t, test.accountID, account.ID, "account.ID must match requested ID") | ||
assert.Equal(t, false, account.Disabled, "returned account must not be disabled") | ||
} else { | ||
assert.NotEmpty(t, errors, "expected errors but got success") | ||
assert.Nil(t, account, "return account must be nil on error") | ||
assert.IsType(t, test.err, errors[0], "error is of unexpected type") | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters