Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ads.Cert Call Sign support #2241

Merged
merged 46 commits into from
Jul 27, 2022
Merged

Ads.Cert Call Sign support #2241

merged 46 commits into from
Jul 27, 2022

Conversation

VeronikaSolovei9
Copy link
Contributor

@VeronikaSolovei9 VeronikaSolovei9 commented May 6, 2022

Call Sign support for Prebid Server. For more info refer to adscertsigner.md

config/bidderinfo.go Outdated Show resolved Hide resolved
config/config.go Outdated Show resolved Hide resolved
config/experiment.go Show resolved Hide resolved
config/experiment.go Outdated Show resolved Hide resolved
exchange/bidder.go Outdated Show resolved Hide resolved
experiment/adscert/signer.go Show resolved Hide resolved
experiment/adscert/signer.go Show resolved Hide resolved
experiment/adscert/signer.go Outdated Show resolved Hide resolved
go.mod Show resolved Hide resolved
experiment/adscert/signer.go Outdated Show resolved Hide resolved
@VeronikaSolovei9 VeronikaSolovei9 marked this pull request as ready for review May 25, 2022 06:03
@VeronikaSolovei9
Copy link
Contributor Author

What kind of unit tests can be added here?

@VeronikaSolovei9
Copy link
Contributor Author

VeronikaSolovei9 commented May 26, 2022

Discussed unit tests offline. Will add them in next commit

config/bidderinfo.go Outdated Show resolved Hide resolved
config/bidderinfo.go Outdated Show resolved Hide resolved
config/config.go Outdated Show resolved Hide resolved
config/config.go Outdated Show resolved Hide resolved
exchange/bidder.go Outdated Show resolved Hide resolved
exchange/bidder.go Outdated Show resolved Hide resolved
exchange/bidder_test.go Outdated Show resolved Hide resolved
experiment/adscert/README.md Outdated Show resolved Hide resolved
experiment/adscert/signer.go Outdated Show resolved Hide resolved
experiment/adscert/signer.go Outdated Show resolved Hide resolved
Experiment BidderInfoExperiment `yaml:"experiment"`
}

// BidderInfoExperiment specified non-production ready features.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: specified -> specifies

//Url - address of grpc server
Url string `mapstructure:"url"`
//SigningTimeoutMs specifies how long this client will wait for signing to finish before abandoning
SigningTimeoutMs int `mapstructure:"signing_timeout"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that you included the ms unit in the name. Could you please carry that over into the map structure name too so the unit is available in the config?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed

@@ -0,0 +1,90 @@
##Ads Cert
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recommend moving this up to just /docs instead of /docs/developers. Make it easier to discover. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved

@@ -88,6 +88,7 @@ func BenchmarkOpenrtbEndpoint(b *testing.B) {
func(ctx context.Context, id uint16) (vendorlist.VendorList, error) { return nil, nil },
currency.NewRateConverter(&http.Client{}, "", time.Duration(0)),
empty_fetcher.EmptyFetcher{},
nil,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using a NilSigner here instead to document what the argument is for.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, replaced in all occurrences

@@ -704,8 +704,8 @@ func TestMultiCurrencies(t *testing.T) {
1,
currencyConverter.Rates(),
&adapters.ExtraRequestInfo{},
true,
true,
nil,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for all of these tests. A NilSigner would be self-documenting and easier for the reader to understand.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, replaced in all occurrences

experiment/adscert/signer.go Outdated Show resolved Hide resolved
opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
conn, err := grpc.Dial(remoteSignerConfig.Url, opts...)
if err != nil {
fmt.Errorf("failed to dial remote signer: %v", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you're missing a return statement here. Consider adding a unit test. I don't know if that's feasible for the dialer code though. Maybe Google or StackOverflow know of some tricks to test something like this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added return statement.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unit tests with fake input data fail with null pointer exception that I cannot "catch"

if err != nil {
fmt.Errorf("failed to dial remote signer: %v", err)
}
//defer conn.Close() -- where this should be?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, this should be triggered when the app is gracefully shutting down. You might be able to just get away without it though, since the connections are expected to remain open for the life of the application.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, this should live and die with application. I removed this line :/


func (ns *NilSigner) Sign(destinationURL string, body []byte) (string, error) {
return "", nil
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it would be a good idea to separate the in process signer, remote signer, and nil signer to their own files?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separated In-Process and Remote signers to separate files. NilSigner is now in the same file with interface. Should I move it too?

assert.EqualError(t, err, "Test error", "incorrect error")
} else {
if test.operationStatusOk {
assert.NoError(t, err, "error should not be returned")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO there is no need to include an error message like "error should not be returned" since that's pretty obvious in the test results. I usually include the name/description of the test case and what i'm asserting to help with debugging, since those will not automatically appear in the test results.

vsolovei added 2 commits July 11, 2022 12:54
# Conflicts:
#	config/config.go
#	exchange/exchange.go

// AdsCertInProcess configures data to sign requests using ads certs library in core PBS logic
type AdsCertInProcess struct {
//Origin is ads.cert hostname for the originating party
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: Please add a space before the comment (ie // Origin) for the field comments for AdsCertInProcess and AdsCertRemote.

httpRequest: &adapters.RequestData{
Method: "POST",
Uri: server.URL,
Body: []byte("{\"key\":\"val\"}"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: You can use the backtick string notation here too.

Adapters: make(map[string]config.Adapter, 1),
}
cfg.Adapters["appnexus"] = config.Adapter{
Endpoint: "test.com", //Note the '&' character in there
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a left over copy/paste? I don't see an & character.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy paste, yes, sorry, fixed.

@@ -4073,6 +4074,132 @@ func TestAuctionDebugEnabled(t *testing.T) {

}

func TestExperimentConfigs(t *testing.T) {
//This test just pass experiment ads cert configs to HoldAuction
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider choosing a more descriptive test name and removing the comment. Looks like the test assets and error, but is that a real error from trying to determine if test.com has a call sign registered?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to TestPassExperimentConfigsToHoldAuction. This test runs HoldAuction with MockSigner and only tests correct data was passed to the signer.

}

func validateInProcessSignerConfig(inProcessSignerConfig config.AdsCertInProcess) error {
_, err := url.ParseRequestURI(inProcessSignerConfig.Origin)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe all config validation logic is currently in config.fo, so it moving it there would keep it central

I understand about knowing which side to configure. I didn't focus on that before. Perhaps we need to change Enabled to Mode (or some such, whatever language we use elsewhere) which can be something like "off", "inprocess" or "remote". Then we know exactly the host's intent on which one to validate, and also perhaps that the other choice has not been configured.

return nil, err
}
// Establish the gRPC connection that the client will use to connect to the
// signatory server. Authenticated connections are not implemented at this time
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eeek! This now reads "Authenticated connections are not implemented at this time" .. but the problem is this PR is literally implementing "ads.cert authenticated connections". Sorry for misguiding you here. How about:

Secure connections are not implemented at this time.

errBothSignersSpecified = errors.New("both inprocess and remote signers are specified. Please use just one signer")
)

//Signer represents interface to access request Ads Cert signing functionality
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: Add space at the start of the comment.

@VeronikaSolovei9
Copy link
Contributor Author

Modified config from experiment.adscert.enabled to experiment.adscert.mode

config/config.go Outdated
ErrInvalidRemoteSignerURL = errors.New("invalid url for remote signer")
ErrInvalidRemoteSignerSigningTimeout = errors.New("invalid signing timeout for remote signer")

AdCertsSignerModeOff = "off"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it make more sense to have these defined as constants?

Also, I'd recommend moving all these values to experiment.go since they are AdsCert specific and all the other AdsCert specific structs live there

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to experiment.go. Extracted to constants.

config/config.go Outdated
@@ -139,6 +156,41 @@ type AuctionTimeouts struct {
Max uint64 `mapstructure:"max"`
}

func (cfg *Experiment) validate(errs []error) []error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also move this validate method over to experiment.go since the Experiment struct is defined there. I'd group the struct and the methods on that struct in the same file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, moved

config/config.go Outdated
if cfg.AdCerts.Mode == AdCertsSignerModeInprocess {
_, err := url.ParseRequestURI(cfg.AdCerts.InProcess.Origin)
if err != nil {
errs = append(errs, ErrInProcessSignerInvalidURL)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd recommend appending the actual values that are set in the config to the error messages so that it's clear from the error message why that value is invalid. You'll see similar behavior in other config validate functions as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is how it was before and modified due to this discussion: #2241 (comment)

Copy link
Contributor Author

@VeronikaSolovei9 VeronikaSolovei9 Jul 20, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

appending the actual values - I read it like appending actual error strings to array. Modified

@@ -164,6 +172,13 @@ func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest Bidde
if reqInfo.GlobalPrivacyControlHeader == "1" {
reqData[i].Headers.Add("Sec-GPC", reqInfo.GlobalPrivacyControlHeader)
}
if bidRequestMetadata.addCallSignHeader {
signatureMessage, err := adCertSigner.Sign(reqData[i].Uri, reqData[i].Body)
if err == nil && len(signatureMessage) > 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separate PR sounds good to me 👍 @VeronikaSolovei9 would you mind just modifying the comment to add a warning message in debug mode as well in addition to the metrics please? Just so that we don't forget about it

@mansinahar
Copy link
Contributor

Looking pretty close to me other than the very few minor comments above

SyntaxNode
SyntaxNode previously approved these changes Jul 19, 2022
SyntaxNode
SyntaxNode previously approved these changes Jul 20, 2022
Copy link
Contributor

@mansinahar mansinahar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM except for the above minor comment regarding the test

@@ -98,15 +101,15 @@ func TestExperimentValidate(t *testing.T) {
AdCerts: ExperimentAdsCert{Mode: AdCertsSignerModeInprocess, InProcess: AdsCertInProcess{Origin: "http://test.com", PrivateKey: "pk", DNSCheckIntervalInSeconds: -10, DNSRenewalIntervalInSeconds: 10}},
},
expectErrors: true,
expectedErrors: []error{ErrInProcessSignerInvalidDNSCheckInterval},
expectedErrors: []error{fmt.Errorf("invalid dns check interval for inprocess signer: -10")},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fmt.Errorf should be used when you have a formatted error string i.e. when you're using %s, %d, etc for which the values are going to filled in run time. Here for expectedErrors you already have a constant string that you're expecting so you can just use errors.New.

Same for L112, L123 and L124

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, I missed it accidentally. Fixed.

@SyntaxNode SyntaxNode merged commit 9bfc1ad into master Jul 27, 2022
pm-nilesh-chate pushed a commit to pm-nilesh-chate/prebid-server that referenced this pull request Aug 9, 2022
pm-aadit-patil pushed a commit to PubMatic-OpenWrap/prebid-server that referenced this pull request Sep 22, 2022
pm-aadit-patil pushed a commit to PubMatic-OpenWrap/prebid-server that referenced this pull request Sep 22, 2022
pm-aadit-patil pushed a commit to PubMatic-OpenWrap/prebid-server that referenced this pull request Sep 22, 2022
jorgeluisrocha pushed a commit to jwplayer/prebid-server that referenced this pull request Sep 28, 2022
shunj-nb pushed a commit to ParticleMedia/prebid-server that referenced this pull request Nov 8, 2022
@SyntaxNode SyntaxNode deleted the ads_cert branch March 13, 2023 13:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants