Get refcode on MacOS from xattr.
This commit is contained in:
@@ -29,6 +29,13 @@ static_library("browser") {
|
||||
"//services/network/public/cpp",
|
||||
]
|
||||
|
||||
if (is_mac) {
|
||||
sources += [
|
||||
"file_extended_attribute.cc",
|
||||
"file_extended_attribute.h",
|
||||
]
|
||||
}
|
||||
|
||||
if (is_android) {
|
||||
sources += [
|
||||
"android_brave_referrer.cc",
|
||||
@@ -47,3 +54,19 @@ if (is_android) {
|
||||
sources = [ "//brave/android/java/org/chromium/chrome/browser/util/BraveReferrer.java" ]
|
||||
}
|
||||
}
|
||||
|
||||
source_set("unit_tests") {
|
||||
testonly = true
|
||||
sources = []
|
||||
deps = []
|
||||
|
||||
if (is_mac) {
|
||||
sources += [ "file_extended_attribute_unittest.cc" ]
|
||||
deps += [
|
||||
":browser",
|
||||
"//base",
|
||||
"//base/test:test_support",
|
||||
"//testing/gtest",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "base/functional/callback_helpers.h"
|
||||
#include "base/json/json_reader.h"
|
||||
#include "base/json/json_writer.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
@@ -26,6 +27,7 @@
|
||||
#include "brave/components/constants/network_constants.h"
|
||||
#include "brave/components/constants/pref_names.h"
|
||||
#include "brave_base/random.h"
|
||||
#include "build/build_config.h"
|
||||
#include "components/prefs/pref_registry_simple.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "components/url_matcher/url_matcher.h"
|
||||
@@ -40,6 +42,11 @@
|
||||
#include "services/network/public/mojom/fetch_api.mojom-shared.h"
|
||||
#include "services/network/public/mojom/url_response_head.mojom.h"
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
#include "base/apple/bundle_locations.h"
|
||||
#include "brave/components/brave_referrals/browser/file_extended_attribute.h"
|
||||
#endif // BUILDFLAG(IS_MAC)
|
||||
|
||||
// Perform finalization checks once a day.
|
||||
const int kFinalizationChecksFrequency = 60 * 60 * 24;
|
||||
|
||||
@@ -125,9 +132,46 @@ void DeletePromoCodeFile(const base::FilePath& promo_code_file) {
|
||||
}
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
std::string ReadPromoCodeFromXattr() {
|
||||
static constexpr char kRefCodeAttr[] = "com.brave.refcode";
|
||||
base::FilePath bundle_path = base::apple::OuterBundlePath();
|
||||
std::vector<char> value;
|
||||
int result_errno =
|
||||
brave::GetFileExtendedAttribute(bundle_path, kRefCodeAttr, &value);
|
||||
if (result_errno == ENOATTR) {
|
||||
VLOG(0) << "Could not get promo code from " << bundle_path
|
||||
<< ". The extended attribute " << kRefCodeAttr << " was not found.";
|
||||
} else if (result_errno != 0) {
|
||||
VLOG(0) << "Could not get promo code from " << bundle_path
|
||||
<< ". An error occurred getting value for attribute "
|
||||
<< kRefCodeAttr << ". Error code: " << result_errno << ".";
|
||||
} else {
|
||||
std::string promo_code(value.begin(), value.end());
|
||||
base::TrimWhitespaceASCII(promo_code, base::TRIM_ALL, &promo_code);
|
||||
if (promo_code.empty()) {
|
||||
VLOG(0) << "Promo code value from " << bundle_path
|
||||
<< "'s extended attribute " << kRefCodeAttr << " is empty.";
|
||||
} else {
|
||||
DVLOG(1) << "Promo code from " << kRefCodeAttr << ": " << promo_code;
|
||||
return promo_code;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
#endif // BUILDFLAG(IS_MAC)
|
||||
|
||||
std::string ReadPromoCode(const base::FilePath& promo_code_file) {
|
||||
std::string promo_code;
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
promo_code = ReadPromoCodeFromXattr();
|
||||
if (!promo_code.empty()) {
|
||||
return promo_code;
|
||||
}
|
||||
#endif // BUILDFLAG(IS_MAC)
|
||||
|
||||
if (!base::PathExists(promo_code_file)) {
|
||||
return kDefaultPromoCode;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/* Copyright (c) 2023 The Brave Authors. All rights reserved.
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "brave/components/brave_referrals/browser/file_extended_attribute.h"
|
||||
|
||||
#include <sys/xattr.h>
|
||||
|
||||
#include "base/logging.h"
|
||||
|
||||
namespace brave {
|
||||
|
||||
int GetFileExtendedAttribute(const base::FilePath& path,
|
||||
const char* name,
|
||||
std::vector<char>* value) {
|
||||
// Pass nullptr for value to retrieve the length needed.
|
||||
ssize_t expected_length =
|
||||
getxattr(path.value().c_str(), name, /*value=*/nullptr,
|
||||
/*size =*/0, /*position=*/0, /*options=*/0);
|
||||
if (expected_length < 0) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
value->resize(expected_length);
|
||||
ssize_t length = getxattr(path.value().c_str(), name, value->data(),
|
||||
expected_length, /*position=*/0,
|
||||
/*options=*/0);
|
||||
if (length != expected_length) {
|
||||
VLOG(0) << "Failed to retrieve extended attribute " << name << " from file "
|
||||
<< path << ". The expected data length (" << expected_length
|
||||
<< ") and actual data length (" << length << ") do not match.";
|
||||
return ENODATA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace brave
|
||||
@@ -0,0 +1,28 @@
|
||||
/* Copyright (c) 2023 The Brave Authors. All rights reserved.
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef BRAVE_COMPONENTS_BRAVE_REFERRALS_BROWSER_FILE_EXTENDED_ATTRIBUTE_H_
|
||||
#define BRAVE_COMPONENTS_BRAVE_REFERRALS_BROWSER_FILE_EXTENDED_ATTRIBUTE_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
|
||||
namespace brave {
|
||||
|
||||
// Extracts the value of an extended file attribute specified by |name| from the
|
||||
// file specified by the |path|. The result is placed in the |value|. On
|
||||
// success returns 0. Otherwise, returns ERRNO value. Error values of
|
||||
// interest:
|
||||
// ENOATTR - the attribute with the given |name| was not found.
|
||||
// ENOTSUP - the file system doesn't support (or disabled) extended attributes.
|
||||
// ENODATA - the value could not be retrieved.
|
||||
int GetFileExtendedAttribute(const base::FilePath& path,
|
||||
const char* name,
|
||||
std::vector<char>* value);
|
||||
|
||||
} // namespace brave
|
||||
|
||||
#endif // BRAVE_COMPONENTS_BRAVE_REFERRALS_BROWSER_FILE_EXTENDED_ATTRIBUTE_H_
|
||||
@@ -0,0 +1,60 @@
|
||||
/* Copyright (c) 2023 The Brave Authors. All rights reserved.
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <sys/xattr.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/files/scoped_temp_dir.h"
|
||||
#include "brave/components/brave_referrals/browser/file_extended_attribute.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace {
|
||||
constexpr char kXattrName[] = "com.brave.refcode";
|
||||
constexpr char kXattrValue[] = "0xDEADFACE";
|
||||
} // namespace
|
||||
|
||||
class BraveFileExtendedAttributeTest : public testing::Test {
|
||||
public:
|
||||
BraveFileExtendedAttributeTest() = default;
|
||||
~BraveFileExtendedAttributeTest() override = default;
|
||||
|
||||
void SetUp() override {
|
||||
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
|
||||
ASSERT_TRUE(
|
||||
base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &test_file_path_));
|
||||
ASSERT_EQ(0,
|
||||
setxattr(test_file_path_.value().c_str(), kXattrName, kXattrValue,
|
||||
strlen(kXattrValue), /*position=*/0, /*options=*/0));
|
||||
}
|
||||
|
||||
void TearDown() override { base::DeletePathRecursively(temp_dir_.GetPath()); }
|
||||
|
||||
const base::FilePath& test_file_path() { return test_file_path_; }
|
||||
|
||||
private:
|
||||
base::ScopedTempDir temp_dir_;
|
||||
base::FilePath test_file_path_;
|
||||
};
|
||||
|
||||
TEST_F(BraveFileExtendedAttributeTest, GetPromoCodeAttribute) {
|
||||
std::vector<char> value;
|
||||
// Test file has this extended attribute
|
||||
int result_errno =
|
||||
brave::GetFileExtendedAttribute(test_file_path(), kXattrName, &value);
|
||||
EXPECT_EQ(0, result_errno);
|
||||
std::string xattr_value(value.begin(), value.end());
|
||||
EXPECT_EQ(kXattrValue, xattr_value);
|
||||
}
|
||||
|
||||
TEST_F(BraveFileExtendedAttributeTest, GetNonexistentAttribute) {
|
||||
std::vector<char> value;
|
||||
// Test file does NOT have this extended attribute
|
||||
int result_errno = brave::GetFileExtendedAttribute(
|
||||
test_file_path(), "com.brave.MadSheep", &value);
|
||||
EXPECT_EQ(ENOATTR, result_errno);
|
||||
}
|
||||
@@ -206,6 +206,7 @@ test("brave_unit_tests") {
|
||||
"//brave/components/brave_news/browser/test:brave_news_unit_tests",
|
||||
"//brave/components/brave_perf_predictor/browser",
|
||||
"//brave/components/brave_private_cdn",
|
||||
"//brave/components/brave_referrals/browser:unit_tests",
|
||||
"//brave/components/brave_rewards/common",
|
||||
"//brave/components/brave_rewards/common:features",
|
||||
"//brave/components/brave_rewards/core/test",
|
||||
|
||||
Reference in New Issue
Block a user