1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_AFFILIATION_SERVICE_H_
#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_AFFILIATION_SERVICE_H_
#include <string>
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/password_manager/core/browser/affiliation_utils.h"
namespace base {
class FilePath;
class SingleThreadTaskRunner;
} // namespace base
namespace net {
class URLRequestContextGetter;
} // namespace net
namespace password_manager {
class AffiliationBackend;
// A service that can be used to query the list of facets that are affiliated
// with a given facet, i.e., facets that belong to the same logical application.
// See affiliation_utils.h for details of what this means.
//
// The service must be accessed from the UI thread, and it can be utilized in
// two ways:
//
// 1.) On-demand fetching: For the one-off query that wishes to learn
// affiliations of facet X when (potentially) issuing an on-demand
// network request to the Affiliation API containing the URI of facet X
// is acceptable from the privacy and/or performance perspective.
//
// This mode of operation is achieved by invoking GetAffiliations() with
// StrategyOnCacheMiss::FETCH_OVER_NETWORK.
//
// 2.) Proactive fetching: For the compound query that is concerned with
// checking, over time, whether or not each element in a sequence of
// facets, W_1, W_2, ..., W_n, is affiliated with a fixed facet Y; and
// when it is desired, for privacy and/or performance reasons, that only
// facet Y be looked up against the Affiliation API and that subsequent
// requests regarding each W_i not trigger additional requests.
//
// This mode of operation can be useful when, for example, the password
// manager has credentials stored for facet Y and wishes to check, for
// each visited web site W_i, whether these credentials should be offered
// to be autofilled onto W_i.
//
// Example code:
//
// class ExampleAffiliatedCredentialFiller
// : public base::SupportsWeakPtr<...> {
// public:
// ExampleAffiliatedCredentialFiller(AffiliationService* service,
// const FacetURI& y)
// : service_(service), y_(y) {
// cancel_handle_ = service_->Prefetch(y_, base::Time::Max());
// }
//
// ~ExampleAffiliatedCredentialFiller() { cancel_handle_.Run(); }
//
// void ShouldFillInto(const FacetURI& wi, FillDelegate* delegate) {
// service_->GetAffiliations(wi, StrategyOnCacheMiss::FAIL,
// base::Bind(
// &ExampleAffiliatedCredentialFiller::OnAffiliationResult,
// AsWeakPtr(),
// delegate));
// }
//
// void OnAffiliationResult(FillDelegate* delegate,
// const AffiliatedFacets& results,
// bool success) {
// if (success && std::count(results.begin(), results.end(), y_))
// delegate->FillCredentialsFor(y_);
// }
//
// private:
// AffiliationService* service_;
// const FacetURI& y_;
// CancelPrefetchingHandle cancel_handle_;
// };
class AffiliationService : public KeyedService {
public:
typedef base::Callback<void(const AffiliatedFacets& /* results */,
bool /* success */)> ResultCallback;
// Controls whether to send a network request or fail on a cache miss.
enum class StrategyOnCacheMiss { FETCH_OVER_NETWORK, FAIL };
// The |backend_task_runner| should be a task runner corresponding to a thread
// that can take blocking I/O, and is normally Chrome's DB thread.
AffiliationService(
scoped_refptr<base::SingleThreadTaskRunner> backend_task_runner);
~AffiliationService() override;
// Initializes the service by creating its backend and transferring it to the
// thread corresponding to |backend_task_runner_|.
void Initialize(net::URLRequestContextGetter* request_context_getter,
const base::FilePath& db_path);
// Looks up facets affiliated with the facet identified by |facet_uri|, and
// invokes |result_callback| with the results.
//
// If the local cache contains fresh affiliation information for |facet_uri|,
// the request will be served from cache. Otherwise, |cache_miss_policy|
// controls whether to issue an on-demand network request, or to fail the
// request without fetching.
virtual void GetAffiliations(const FacetURI& facet_uri,
StrategyOnCacheMiss cache_miss_strategy,
const ResultCallback& result_callback);
// Prefetches affiliation information for the facet identified by |facet_uri|,
// and keeps the information fresh by periodic re-fetches (as needed) until
// the clock strikes |keep_fresh_until| (exclusive), until a matching call to
// CancelPrefetch(), or until Chrome is shut down, whichever is sooner. It is
// a supported use-case to pass base::Time::Max() as |keep_fresh_until|.
//
// Canceling can be useful when a password is deleted, so that resources are
// no longer wasted on repeatedly refreshing affiliation information. Note
// that canceling will not blow away data already stored in the cache unless
// it becomes stale.
virtual void Prefetch(const FacetURI& facet_uri,
const base::Time& keep_fresh_until);
// Cancels the corresponding prefetch command, i.e., the one issued for the
// same |facet_uri| and with the same |keep_fresh_until|.
virtual void CancelPrefetch(const FacetURI& facet_uri,
const base::Time& keep_fresh_until);
// Wipes results of on-demand fetches and expired prefetches from the cache,
// but retains information corresponding to facets that are being kept fresh.
// As no required data is deleted, there will be no network requests directly
// triggered by this call.
//
// The second version will only potentially remove data corresponding to the
// given |facet_uri|, but still only as long as the data is no longer needed.
virtual void TrimCache();
virtual void TrimCacheForFacet(const FacetURI& facet_uri);
// Posts a task to the |backend_task_runner| to delete the cache database file
// at |db_path|, and all auxiliary files. The database must be closed before
// calling this.
static void DeleteCache(const base::FilePath& db_path,
base::SingleThreadTaskRunner* backend_task_runner);
private:
// The backend, owned by this AffiliationService instance, but living on the
// DB thread. It will be deleted asynchronously during shutdown on the DB
// thread, so it will outlive |this| along with all its in-flight tasks.
AffiliationBackend* backend_;
// TaskRunner to be used to run the |backend_| (usually the DB thread).
scoped_refptr<base::SingleThreadTaskRunner> backend_task_runner_;
base::ThreadChecker thread_checker_;
base::WeakPtrFactory<AffiliationService> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(AffiliationService);
};
} // namespace password_manager
#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_AFFILIATION_SERVICE_H_
|