Commit d7b2c99e authored by Alice Gong's avatar Alice Gong Committed by Commit Bot

Update authentication code to track multiple Connectors

Bug: 1093321
Change-Id: Id513ffc0b7f2bdae8560817e5a69ecc8f52d26a9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2499082Reviewed-by: default avatarRoger Tawa <rogerta@chromium.org>
Reviewed-by: default avatarDaniel Rubery <drubery@chromium.org>
Reviewed-by: default avatarDominique Fauteux-Chapleau <domfc@chromium.org>
Commit-Queue: Alice Gong <alicego@google.com>
Cr-Commit-Position: refs/heads/master@{#821897}
parent 1ac7c2dd
...@@ -83,8 +83,10 @@ class FakeBinaryUploadService : public BinaryUploadService { ...@@ -83,8 +83,10 @@ class FakeBinaryUploadService : public BinaryUploadService {
private: private:
void UploadForDeepScanning(std::unique_ptr<Request> request) override { void UploadForDeepScanning(std::unique_ptr<Request> request) override {
// The first uploaded request is the authentication one. ++requests_count_;
if (++requests_count_ == 1) {
// A request without tags indicates that it's used for authentication
if (request->content_analysis_request().tags().empty()) {
authorization_request_.swap(request); authorization_request_.swap(request);
if (should_automatically_authorize_) if (should_automatically_authorize_)
...@@ -288,8 +290,9 @@ IN_PROC_BROWSER_TEST_F(ContentAnalysisDelegateBrowserTest, Unauthorized) { ...@@ -288,8 +290,9 @@ IN_PROC_BROWSER_TEST_F(ContentAnalysisDelegateBrowserTest, Unauthorized) {
run_loop.Run(); run_loop.Run();
EXPECT_TRUE(called); EXPECT_TRUE(called);
// Only 1 request (the authentication one) should have been uploaded. // 1 request to authenticate for upload,
ASSERT_EQ(FakeBinaryUploadServiceStorage()->requests_count(), 1); // and 1 request to authenticate for reporting.
ASSERT_EQ(FakeBinaryUploadServiceStorage()->requests_count(), 2);
} }
IN_PROC_BROWSER_TEST_F(ContentAnalysisDelegateBrowserTest, Files) { IN_PROC_BROWSER_TEST_F(ContentAnalysisDelegateBrowserTest, Files) {
...@@ -370,8 +373,10 @@ IN_PROC_BROWSER_TEST_F(ContentAnalysisDelegateBrowserTest, Files) { ...@@ -370,8 +373,10 @@ IN_PROC_BROWSER_TEST_F(ContentAnalysisDelegateBrowserTest, Files) {
EXPECT_TRUE(called); EXPECT_TRUE(called);
// There should have been 1 request per file and 1 for authentication. // There should have been 1 request per file (2 files) and 1 for
ASSERT_EQ(FakeBinaryUploadServiceStorage()->requests_count(), 3); // authentication, and 1 more for final request to validate reporting
// authentication with the corresponding request type.
ASSERT_EQ(FakeBinaryUploadServiceStorage()->requests_count(), 4);
} }
IN_PROC_BROWSER_TEST_F(ContentAnalysisDelegateBrowserTest, Texts) { IN_PROC_BROWSER_TEST_F(ContentAnalysisDelegateBrowserTest, Texts) {
...@@ -451,8 +456,10 @@ IN_PROC_BROWSER_TEST_F(ContentAnalysisDelegateBrowserTest, Texts) { ...@@ -451,8 +456,10 @@ IN_PROC_BROWSER_TEST_F(ContentAnalysisDelegateBrowserTest, Texts) {
run_loop.Run(); run_loop.Run();
EXPECT_TRUE(called); EXPECT_TRUE(called);
// There should have been 1 request for all texts and 1 for authentication. // There should have been 1 request for all texts,
ASSERT_EQ(FakeBinaryUploadServiceStorage()->requests_count(), 2); // 1 for authentication of the scanning request,
// and 1 for final request to validate reporting authentication.
ASSERT_EQ(FakeBinaryUploadServiceStorage()->requests_count(), 3);
} }
class ContentAnalysisDelegatePasswordProtectedFilesBrowserTest class ContentAnalysisDelegatePasswordProtectedFilesBrowserTest
...@@ -881,8 +888,11 @@ IN_PROC_BROWSER_TEST_P(ContentAnalysisDelegateDelayDeliveryUntilVerdictTest, ...@@ -881,8 +888,11 @@ IN_PROC_BROWSER_TEST_P(ContentAnalysisDelegateDelayDeliveryUntilVerdictTest,
run_loop.Run(); run_loop.Run();
EXPECT_TRUE(called); EXPECT_TRUE(called);
// Expect 1 request for authentication and 1 to scan the file in all cases. // Expect 1 request for initial authentication (unspecified type, to be
ASSERT_EQ(FakeBinaryUploadServiceStorage()->requests_count(), 2); // removed for crbug.com/1090088, then count should be 2), 1 to scan the file
// in all cases, and 1 more for final request to validate reportin
// authentication with the corresponding request type.
ASSERT_EQ(FakeBinaryUploadServiceStorage()->requests_count(), 3);
} }
INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P(
......
...@@ -876,7 +876,10 @@ void SafeBrowsingPrivateEventRouter::IfAuthorized( ...@@ -876,7 +876,10 @@ void SafeBrowsingPrivateEventRouter::IfAuthorized(
// TODO(crbug/1069049): Use reporting URL. // TODO(crbug/1069049): Use reporting URL.
if (binary_upload_service_) if (binary_upload_service_)
binary_upload_service_->IsAuthorized(GURL(), std::move(cont)); binary_upload_service_->IsAuthorized(
GURL(), std::move(cont),
enterprise_connectors::AnalysisConnector::
ANALYSIS_CONNECTOR_UNSPECIFIED);
} }
void SafeBrowsingPrivateEventRouter::ReportRealtimeEvent( void SafeBrowsingPrivateEventRouter::ReportRealtimeEvent(
......
...@@ -213,18 +213,21 @@ void BinaryUploadService::MaybeUploadForDeepScanning( ...@@ -213,18 +213,21 @@ void BinaryUploadService::MaybeUploadForDeepScanning(
return; return;
} }
if (!can_upload_enterprise_data_.has_value()) { auto connector = request->analysis_connector();
if (!can_upload_enterprise_data_.contains(request->analysis_connector())) {
// Get the URL first since |request| is about to move. // Get the URL first since |request| is about to move.
GURL url = request->GetUrlWithParams(); GURL url = request->GetUrlWithParams();
IsAuthorized( IsAuthorized(
std::move(url), std::move(url),
base::BindOnce(&BinaryUploadService::MaybeUploadForDeepScanningCallback, base::BindOnce(&BinaryUploadService::MaybeUploadForDeepScanningCallback,
weakptr_factory_.GetWeakPtr(), std::move(request))); weakptr_factory_.GetWeakPtr(), std::move(request)),
connector);
return; return;
} }
MaybeUploadForDeepScanningCallback(std::move(request), MaybeUploadForDeepScanningCallback(std::move(request),
can_upload_enterprise_data_.value()); can_upload_enterprise_data_[connector]);
} }
void BinaryUploadService::MaybeUploadForDeepScanningCallback( void BinaryUploadService::MaybeUploadForDeepScanningCallback(
...@@ -424,6 +427,7 @@ void BinaryUploadService::FinishRequest( ...@@ -424,6 +427,7 @@ void BinaryUploadService::FinishRequest(
void BinaryUploadService::FinishRequestCleanup(Request* request, void BinaryUploadService::FinishRequestCleanup(Request* request,
const std::string& instance_id) { const std::string& instance_id) {
auto connector = request->analysis_connector();
active_requests_.erase(request); active_requests_.erase(request);
active_timers_.erase(request); active_timers_.erase(request);
active_uploads_.erase(request); active_uploads_.erase(request);
...@@ -441,24 +445,26 @@ void BinaryUploadService::FinishRequestCleanup(Request* request, ...@@ -441,24 +445,26 @@ void BinaryUploadService::FinishRequestCleanup(Request* request,
binary_fcm_service_->UnregisterInstanceID( binary_fcm_service_->UnregisterInstanceID(
instance_id, instance_id,
base::BindOnce(&BinaryUploadService::InstanceIDUnregisteredCallback, base::BindOnce(&BinaryUploadService::InstanceIDUnregisteredCallback,
weakptr_factory_.GetWeakPtr())); weakptr_factory_.GetWeakPtr(), connector));
} else { } else {
// |binary_fcm_service_| can be null in tests, but // |binary_fcm_service_| can be null in tests, but
// InstanceIDUnregisteredCallback should be called anyway so the requests // InstanceIDUnregisteredCallback should be called anyway so the requests
// waiting on authentication can complete. // waiting on authentication can complete.
InstanceIDUnregisteredCallback(true); InstanceIDUnregisteredCallback(connector, true);
} }
active_tokens_.erase(token_it); active_tokens_.erase(token_it);
} }
void BinaryUploadService::InstanceIDUnregisteredCallback(bool) { void BinaryUploadService::InstanceIDUnregisteredCallback(
enterprise_connectors::AnalysisConnector connector,
bool) {
// Calling RunAuthorizationCallbacks after the instance ID of the initial // Calling RunAuthorizationCallbacks after the instance ID of the initial
// authentication is unregistered avoids registration/unregistration conflicts // authentication is unregistered avoids registration/unregistration conflicts
// with normal requests. // with normal requests.
if (!authorization_callbacks_.empty() && if (!authorization_callbacks_.empty() &&
can_upload_enterprise_data_.has_value()) { can_upload_enterprise_data_.contains(connector)) {
RunAuthorizationCallbacks(); RunAuthorizationCallbacks(connector);
} }
} }
...@@ -584,6 +590,11 @@ void BinaryUploadService::Request::set_email(const std::string& email) { ...@@ -584,6 +590,11 @@ void BinaryUploadService::Request::set_email(const std::string& email) {
content_analysis_request_.mutable_request_data()->set_email(email); content_analysis_request_.mutable_request_data()->set_email(email);
} }
enterprise_connectors::AnalysisConnector
BinaryUploadService::Request::analysis_connector() {
return content_analysis_request_.analysis_connector();
}
const std::string& BinaryUploadService::Request::device_token() const { const std::string& BinaryUploadService::Request::device_token() const {
return content_analysis_request_.device_token(); return content_analysis_request_.device_token();
} }
...@@ -672,8 +683,10 @@ inline void ValidateDataUploadRequest::GetRequestData(DataCallback callback) { ...@@ -672,8 +683,10 @@ inline void ValidateDataUploadRequest::GetRequestData(DataCallback callback) {
BinaryUploadService::Request::Data()); BinaryUploadService::Request::Data());
} }
void BinaryUploadService::IsAuthorized(const GURL& url, void BinaryUploadService::IsAuthorized(
AuthorizationCallback callback) { const GURL& url,
AuthorizationCallback callback,
enterprise_connectors::AnalysisConnector connector) {
// Start |timer_| on the first call to IsAuthorized. This is necessary in // Start |timer_| on the first call to IsAuthorized. This is necessary in
// order to invalidate the authorization every 24 hours. // order to invalidate the authorization every 24 hours.
if (!timer_.IsRunning()) { if (!timer_.IsRunning()) {
...@@ -683,14 +696,14 @@ void BinaryUploadService::IsAuthorized(const GURL& url, ...@@ -683,14 +696,14 @@ void BinaryUploadService::IsAuthorized(const GURL& url,
weakptr_factory_.GetWeakPtr(), url)); weakptr_factory_.GetWeakPtr(), url));
} }
if (!can_upload_enterprise_data_.has_value()) { if (!can_upload_enterprise_data_.contains(connector)) {
// Send a request to check if the browser can upload data. // Send a request to check if the browser can upload data.
authorization_callbacks_.push_back(std::move(callback)); authorization_callbacks_.push_back(std::move(callback));
if (!pending_validate_data_upload_request_) { if (!pending_validate_data_upload_request_) {
auto dm_token = policy::GetDMToken(profile_); auto dm_token = policy::GetDMToken(profile_);
if (!dm_token.is_valid()) { if (!dm_token.is_valid()) {
can_upload_enterprise_data_ = false; can_upload_enterprise_data_[connector] = false;
RunAuthorizationCallbacks(); RunAuthorizationCallbacks(connector);
return; return;
} }
...@@ -698,45 +711,58 @@ void BinaryUploadService::IsAuthorized(const GURL& url, ...@@ -698,45 +711,58 @@ void BinaryUploadService::IsAuthorized(const GURL& url,
auto request = std::make_unique<ValidateDataUploadRequest>( auto request = std::make_unique<ValidateDataUploadRequest>(
base::BindOnce( base::BindOnce(
&BinaryUploadService::ValidateDataUploadRequestConnectorCallback, &BinaryUploadService::ValidateDataUploadRequestConnectorCallback,
weakptr_factory_.GetWeakPtr()), weakptr_factory_.GetWeakPtr(), connector),
url); url);
request->set_device_token(dm_token.value()); request->set_device_token(dm_token.value());
request->set_analysis_connector(connector);
UploadForDeepScanning(std::move(request)); UploadForDeepScanning(std::move(request));
} }
return; return;
} }
std::move(callback).Run(can_upload_enterprise_data_.value()); std::move(callback).Run(can_upload_enterprise_data_[connector]);
} }
void BinaryUploadService::ValidateDataUploadRequestConnectorCallback( void BinaryUploadService::ValidateDataUploadRequestConnectorCallback(
enterprise_connectors::AnalysisConnector connector,
BinaryUploadService::Result result, BinaryUploadService::Result result,
enterprise_connectors::ContentAnalysisResponse response) { enterprise_connectors::ContentAnalysisResponse response) {
pending_validate_data_upload_request_ = false; pending_validate_data_upload_request_ = false;
can_upload_enterprise_data_ = result == BinaryUploadService::Result::SUCCESS; can_upload_enterprise_data_[connector] =
(result == BinaryUploadService::Result::SUCCESS);
} }
void BinaryUploadService::ValidateDataUploadRequestCallback( void BinaryUploadService::ValidateDataUploadRequestCallback(
enterprise_connectors::AnalysisConnector connector,
BinaryUploadService::Result result, BinaryUploadService::Result result,
DeepScanningClientResponse response) { DeepScanningClientResponse response) {
pending_validate_data_upload_request_ = false; pending_validate_data_upload_request_ = false;
can_upload_enterprise_data_ = result == BinaryUploadService::Result::SUCCESS; can_upload_enterprise_data_[connector] =
(result == BinaryUploadService::Result::SUCCESS);
} }
void BinaryUploadService::RunAuthorizationCallbacks() { void BinaryUploadService::RunAuthorizationCallbacks(
DCHECK(can_upload_enterprise_data_.has_value()); enterprise_connectors::AnalysisConnector connector) {
DCHECK(can_upload_enterprise_data_.contains(connector));
for (auto& callback : authorization_callbacks_) { for (auto& callback : authorization_callbacks_) {
std::move(callback).Run(can_upload_enterprise_data_.value()); std::move(callback).Run(can_upload_enterprise_data_[connector]);
} }
authorization_callbacks_.clear(); authorization_callbacks_.clear();
} }
void BinaryUploadService::ResetAuthorizationData(const GURL& url) { void BinaryUploadService::ResetAuthorizationData(const GURL& url) {
// Setting |can_upload_enterprise_data_| to base::nullopt will make the next // Clearing |can_upload_enterprise_data_| will make the next
// call to IsAuthorized send out a request to validate data uploads. // call to IsAuthorized send out a request to validate data uploads.
can_upload_enterprise_data_ = base::nullopt; can_upload_enterprise_data_.clear();
// Call IsAuthorized to update |can_upload_enterprise_data_| right away. // Call IsAuthorized to update |can_upload_enterprise_data_| right away.
IsAuthorized(url, base::DoNothing()); for (enterprise_connectors::AnalysisConnector connector :
{enterprise_connectors::AnalysisConnector::
ANALYSIS_CONNECTOR_UNSPECIFIED,
enterprise_connectors::AnalysisConnector::FILE_DOWNLOADED,
enterprise_connectors::AnalysisConnector::FILE_ATTACHED,
enterprise_connectors::AnalysisConnector::BULK_DATA_ENTRY}) {
IsAuthorized(url, base::DoNothing(), connector);
}
} }
void BinaryUploadService::Shutdown() { void BinaryUploadService::Shutdown() {
...@@ -745,7 +771,14 @@ void BinaryUploadService::Shutdown() { ...@@ -745,7 +771,14 @@ void BinaryUploadService::Shutdown() {
} }
void BinaryUploadService::SetAuthForTesting(bool authorized) { void BinaryUploadService::SetAuthForTesting(bool authorized) {
can_upload_enterprise_data_ = authorized; for (enterprise_connectors::AnalysisConnector connector :
{enterprise_connectors::AnalysisConnector::
ANALYSIS_CONNECTOR_UNSPECIFIED,
enterprise_connectors::AnalysisConnector::FILE_DOWNLOADED,
enterprise_connectors::AnalysisConnector::FILE_ATTACHED,
enterprise_connectors::AnalysisConnector::BULK_DATA_ENTRY}) {
can_upload_enterprise_data_[connector] = authorized;
}
} }
// static // static
......
...@@ -157,6 +157,7 @@ class BinaryUploadService : public KeyedService { ...@@ -157,6 +157,7 @@ class BinaryUploadService : public KeyedService {
void clear_dlp_scan_request(); void clear_dlp_scan_request();
// Methods for accessing the ContentAnalysisRequest. // Methods for accessing the ContentAnalysisRequest.
enterprise_connectors::AnalysisConnector analysis_connector();
const std::string& device_token() const; const std::string& device_token() const;
const std::string& request_token() const; const std::string& request_token() const;
const std::string& fcm_notification_token() const; const std::string& fcm_notification_token() const;
...@@ -188,10 +189,13 @@ class BinaryUploadService : public KeyedService { ...@@ -188,10 +189,13 @@ class BinaryUploadService : public KeyedService {
// Indicates whether the browser is allowed to upload data. // Indicates whether the browser is allowed to upload data.
using AuthorizationCallback = base::OnceCallback<void(bool)>; using AuthorizationCallback = base::OnceCallback<void(bool)>;
void IsAuthorized(const GURL& url, AuthorizationCallback callback); void IsAuthorized(const GURL& url,
AuthorizationCallback callback,
enterprise_connectors::AnalysisConnector connector);
// Run every callback in |authorization_callbacks_| and empty it. // Run every callback in |authorization_callbacks_| and empty it.
void RunAuthorizationCallbacks(); void RunAuthorizationCallbacks(
enterprise_connectors::AnalysisConnector connector);
// Resets |can_upload_data_|. Called every 24 hour by |timer_|. // Resets |can_upload_data_|. Called every 24 hour by |timer_|.
void ResetAuthorizationData(const GURL& url); void ResetAuthorizationData(const GURL& url);
...@@ -243,13 +247,18 @@ class BinaryUploadService : public KeyedService { ...@@ -243,13 +247,18 @@ class BinaryUploadService : public KeyedService {
// Callback once the response from the backend is received. // Callback once the response from the backend is received.
void ValidateDataUploadRequestConnectorCallback( void ValidateDataUploadRequestConnectorCallback(
enterprise_connectors::AnalysisConnector connector,
BinaryUploadService::Result result, BinaryUploadService::Result result,
enterprise_connectors::ContentAnalysisResponse response); enterprise_connectors::ContentAnalysisResponse response);
void ValidateDataUploadRequestCallback(BinaryUploadService::Result result, void ValidateDataUploadRequestCallback(
DeepScanningClientResponse response); enterprise_connectors::AnalysisConnector connector,
BinaryUploadService::Result result,
DeepScanningClientResponse response);
// Callback once a request's instance ID is unregistered. // Callback once a request's instance ID is unregistered.
void InstanceIDUnregisteredCallback(bool); void InstanceIDUnregisteredCallback(
enterprise_connectors::AnalysisConnector connector,
bool);
void RecordRequestMetrics(Request* request, Result result); void RecordRequestMetrics(Request* request, Result result);
void RecordRequestMetrics( void RecordRequestMetrics(
...@@ -294,7 +303,8 @@ class BinaryUploadService : public KeyedService { ...@@ -294,7 +303,8 @@ class BinaryUploadService : public KeyedService {
// yet. // yet.
// true means the response indicates data can be uploaded. // true means the response indicates data can be uploaded.
// false means the response indicates data cannot be uploaded. // false means the response indicates data cannot be uploaded.
base::Optional<bool> can_upload_enterprise_data_ = base::nullopt; base::flat_map<enterprise_connectors::AnalysisConnector, bool>
can_upload_enterprise_data_;
// Callbacks waiting on IsAuthorized request. // Callbacks waiting on IsAuthorized request.
std::list<base::OnceCallback<void(bool)>> authorization_callbacks_; std::list<base::OnceCallback<void(bool)>> authorization_callbacks_;
......
...@@ -486,7 +486,9 @@ TEST_F(BinaryUploadServiceTest, ReturnsAsynchronouslyWithNoFCM) { ...@@ -486,7 +486,9 @@ TEST_F(BinaryUploadServiceTest, ReturnsAsynchronouslyWithNoFCM) {
TEST_F(BinaryUploadServiceTest, IsAuthorizedValidTimer) { TEST_F(BinaryUploadServiceTest, IsAuthorizedValidTimer) {
// The 24 hours timer should be started on the first IsAuthorized call. // The 24 hours timer should be started on the first IsAuthorized call.
ValidateAuthorizationTimerIdle(); ValidateAuthorizationTimerIdle();
service_->IsAuthorized(GURL(), base::DoNothing()); service_->IsAuthorized(
GURL(), base::DoNothing(),
enterprise_connectors::AnalysisConnector::ANALYSIS_CONNECTOR_UNSPECIFIED);
ValidateAuthorizationTimerStarted(); ValidateAuthorizationTimerStarted();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment