Chromium Code Reviews| Index: content/common/origin_trials/trial_token.cc |
| diff --git a/content/common/origin_trials/trial_token.cc b/content/common/origin_trials/trial_token.cc |
| index 0a137edc68b43e780e572c1d083379c864921fc8..aaf653adf630e0b254f44fd717b5ab8f6884dad4 100644 |
| --- a/content/common/origin_trials/trial_token.cc |
| +++ b/content/common/origin_trials/trial_token.cc |
| @@ -16,6 +16,7 @@ |
| #include "base/strings/string_piece.h" |
| #include "base/time/time.h" |
| #include "base/values.h" |
| +#include "third_party/WebKit/public/platform/WebOriginTrialTokenStatus.h" |
| #include "url/gurl.h" |
| #include "url/origin.h" |
| @@ -44,48 +45,68 @@ const uint8_t kVersion2 = 2; |
| TrialToken::~TrialToken() {} |
| // static |
| -std::unique_ptr<TrialToken> TrialToken::From(const std::string& token_text, |
| - base::StringPiece public_key) { |
| - std::unique_ptr<std::string> token_payload = Extract(token_text, public_key); |
| - if (!token_payload) { |
| +std::unique_ptr<TrialToken> TrialToken::From( |
| + const std::string& token_text, |
| + base::StringPiece public_key, |
| + blink::WebOriginTrialTokenStatus* out_status) { |
| + DCHECK(out_status); |
| + std::string token_payload; |
| + *out_status = Extract(token_text, public_key, &token_payload); |
| + if (*out_status != blink::WebOriginTrialTokenStatus::Success) { |
| return nullptr; |
| } |
| - return Parse(*token_payload); |
| + std::unique_ptr<TrialToken> token = Parse(token_payload); |
| + *out_status = token ? blink::WebOriginTrialTokenStatus::Success |
| + : blink::WebOriginTrialTokenStatus::Malformed; |
| + return token; |
| } |
| -bool TrialToken::IsValidForFeature(const url::Origin& origin, |
| - base::StringPiece feature_name, |
| - const base::Time& now) const { |
| - return ValidateOrigin(origin) && ValidateFeatureName(feature_name) && |
| - ValidateDate(now); |
| +blink::WebOriginTrialTokenStatus TrialToken::IsValidForFeature( |
| + const url::Origin& origin, |
| + base::StringPiece feature_name, |
| + const base::Time& now) const { |
| + // The order of these checks is intentional. For example, will only report a |
| + // token as expired if it is valid for the origin + feature combination. |
| + if (!ValidateOrigin(origin)) { |
| + return blink::WebOriginTrialTokenStatus::WrongOrigin; |
| + } |
| + if (!ValidateFeatureName(feature_name)) { |
| + return blink::WebOriginTrialTokenStatus::WrongFeature; |
| + } |
| + if (!ValidateDate(now)) { |
| + return blink::WebOriginTrialTokenStatus::Expired; |
| + } |
| + return blink::WebOriginTrialTokenStatus::Success; |
| } |
| -std::unique_ptr<std::string> TrialToken::Extract( |
| +// static |
| +blink::WebOriginTrialTokenStatus TrialToken::Extract( |
| const std::string& token_payload, |
| - base::StringPiece public_key) { |
| + base::StringPiece public_key, |
| + std::string* out_token_json) { |
| if (token_payload.empty()) { |
| - return nullptr; |
| + return blink::WebOriginTrialTokenStatus::Malformed; |
|
iclelland
2016/04/28 17:00:58
would an "Empty" status be more descriptive in thi
chasej
2016/05/02 15:53:10
It would be more descriptive, but I don't see the
iclelland
2016/05/02 16:17:55
I suppose it's just an interesting specific varian
|
| } |
| // Token is base64-encoded; decode first. |
| std::string token_contents; |
| if (!base::Base64Decode(token_payload, &token_contents)) { |
| - return nullptr; |
| + return blink::WebOriginTrialTokenStatus::Malformed; |
| } |
| // Only version 2 currently supported. |
| if (token_contents.length() < (kVersionOffset + kVersionSize)) { |
| - return nullptr; |
| + return blink::WebOriginTrialTokenStatus::Malformed; |
| } |
| uint8_t version = token_contents[kVersionOffset]; |
| if (version != kVersion2) { |
| - return nullptr; |
| + return blink::WebOriginTrialTokenStatus::Malformed; |
|
iclelland
2016/04/28 17:00:58
This should definitely be a different status code
chasej
2016/05/02 15:53:10
Done.
|
| } |
| // Token must be large enough to contain a version, signature, and payload |
| // length. |
| if (token_contents.length() < (kPayloadLengthOffset + kPayloadLengthSize)) { |
| - return nullptr; |
| + return blink::WebOriginTrialTokenStatus::Malformed; |
| } |
| // Extract the length of the signed data (Big-endian). |
| @@ -94,7 +115,7 @@ std::unique_ptr<std::string> TrialToken::Extract( |
| // Validate that the stated length matches the actual payload length. |
| if (payload_length != token_contents.length() - kPayloadOffset) { |
| - return nullptr; |
| + return blink::WebOriginTrialTokenStatus::Malformed; |
| } |
| // Extract the version-specific contents of the token. |
| @@ -110,14 +131,15 @@ std::unique_ptr<std::string> TrialToken::Extract( |
| // Validate the signature on the data before proceeding. |
| if (!TrialToken::ValidateSignature(signature, signed_data, public_key)) { |
| - return nullptr; |
| + return blink::WebOriginTrialTokenStatus::InvalidSignature; |
| } |
| // Return just the payload, as a new string. |
| - return base::WrapUnique( |
| - new std::string(token_contents, kPayloadOffset, payload_length)); |
| + *out_token_json = token_contents.substr(kPayloadOffset, payload_length); |
| + return blink::WebOriginTrialTokenStatus::Success; |
| } |
| +// static |
| std::unique_ptr<TrialToken> TrialToken::Parse(const std::string& token_json) { |
| std::unique_ptr<base::DictionaryValue> datadict = |
| base::DictionaryValue::From(base::JSONReader::Read(token_json)); |