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 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
|
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_CONFIDENTIAL_CONTENTS_H_
#define CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_CONFIDENTIAL_CONTENTS_H_
#include <algorithm>
#include <list>
#include <string>
#include <vector>
#include "base/containers/flat_set.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
#include "ui/gfx/image/image_skia.h"
#include "url/gurl.h"
namespace aura {
class Window;
} // namespace aura
namespace content {
class WebContents;
} // namespace content
namespace policy {
// Keeps track of title and corresponding icon of a WebContents object.
// Used to cache and later show information about observed confidential contents
// to the user.
struct DlpConfidentialContent {
DlpConfidentialContent() = delete;
// Constructs DlpConfidentialContent from the title and icon obtained from
// |web_contents|, which cannot be null.
explicit DlpConfidentialContent(content::WebContents* web_contents);
// Constructs DlpConfidentialContent from the title and icon obtained from
// |window|, which cannot be null and |url|.
DlpConfidentialContent(aura::Window* window, const GURL& url);
DlpConfidentialContent(const DlpConfidentialContent& other);
DlpConfidentialContent& operator=(const DlpConfidentialContent& other);
~DlpConfidentialContent() = default;
// Contents with the same url are considered equal, ignoring the ref (part
// after #).
bool operator==(const DlpConfidentialContent& other) const;
bool operator<(const DlpConfidentialContent& other) const;
bool operator<=(const DlpConfidentialContent& other) const;
bool operator>(const DlpConfidentialContent& other) const;
bool operator>=(const DlpConfidentialContent& other) const;
gfx::ImageSkia icon;
std::u16string title;
GURL url;
};
// Provides basic functions for storing and working with DLP confidential
// contents.
class DlpConfidentialContents {
public:
DlpConfidentialContents();
explicit DlpConfidentialContents(
const std::vector<content::WebContents*>& web_contents);
DlpConfidentialContents(const DlpConfidentialContents& other);
DlpConfidentialContents& operator=(const DlpConfidentialContents& other);
~DlpConfidentialContents();
friend bool operator==(const DlpConfidentialContents& a,
const DlpConfidentialContents& b) {
return a.contents_ == b.contents_;
}
friend bool operator!=(const DlpConfidentialContents& a,
const DlpConfidentialContents& b) {
return !(a == b);
}
// Returns true if all the elements in |a| and |b| are equal (i.e. have the
// same url) and the same title, and false otherwise. Useful to detect changes
// in titles, even if the set of the confidential contents hasn't changed.
friend bool EqualWithTitles(const DlpConfidentialContents& a,
const DlpConfidentialContents& b) {
return std::ranges::equal(
a.contents_, b.contents_,
[](const DlpConfidentialContent& x, const DlpConfidentialContent& y) {
return x == y && x.title == y.title;
});
}
// Returns a reference to the underlying content container.
base::flat_set<DlpConfidentialContent>& GetContents();
// Returns a const reference to the underlying content container.
const base::flat_set<DlpConfidentialContent>& GetContents() const;
// Converts |web_contents| to a DlpConfidentialContent and adds it to the
// underlying container.
void Add(content::WebContents* web_contents);
// Same for |window| and |url| pair.
void Add(aura::Window* window, const GURL& url);
// Removes all stored confidential content, if there was any, and adds
// |web_contents| converted to a DlpConfidentialContent.
void ClearAndAdd(content::WebContents* web_contents);
// Same for |window| and |url| pair.
void ClearAndAdd(aura::Window* web_contents, const GURL& url);
// Returns whether there is any content stored or not.
bool IsEmpty() const;
// Adds all content stored in |other| to the underlying container, without
// duplicates.
void InsertOrUpdate(const DlpConfidentialContents& other);
private:
base::flat_set<DlpConfidentialContent> contents_;
};
// Used to avoid warning the user for an action and content that they already
// acknowledged and bypassed a warning for, by caching these contents for a
// certain amount of time.
//
// Automatically evicts entries after a timeout.
// If the number of cached entries exceeds a predefined limits, evicts the
// oldest entry from the cache.
class DlpConfidentialContentsCache {
public:
DlpConfidentialContentsCache();
DlpConfidentialContentsCache(const DlpConfidentialContentsCache& other) =
delete;
DlpConfidentialContentsCache& operator=(
const DlpConfidentialContentsCache& other) = delete;
~DlpConfidentialContentsCache();
// Creates and stores an entry from |web_contents| and |restriction|.
void Cache(const DlpConfidentialContent& content,
DlpRulesManager::Restriction restriction);
// Returns true if there is a cached entry corresponding to |web_contents| and
// |restriction|.
// Useful to avoid converting |web_contents| to a DlpConfidentialContent
// unnecessarily.
bool Contains(content::WebContents* web_contents,
DlpRulesManager::Restriction restriction) const;
// Returns true if there is a cached entry corresponding to |content| and
// |restriction|.
bool Contains(const DlpConfidentialContent& content,
DlpRulesManager::Restriction restriction) const;
// Returns the number of cached entries, useful for testing.
size_t GetSizeForTesting() const;
// Returns the duration for which the entries are kept in the cache.
static base::TimeDelta GetCacheTimeout();
// Used only in tests to inject a task runner for time control.
void SetTaskRunnerForTesting(
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
private:
struct Entry {
Entry() = delete;
Entry(const DlpConfidentialContent& content,
DlpRulesManager::Restriction restriction,
base::TimeTicks timestamp);
Entry(const Entry& other) = delete;
Entry& operator=(const Entry& other) = delete;
~Entry();
DlpConfidentialContent content;
DlpRulesManager::Restriction restriction;
base::TimeTicks created_at;
base::OneShotTimer eviction_timer;
};
// Starts the |entry|'s eviction timer.
void StartEvictionTimer(Entry* entry);
// Evicts an entry corresponding to |content| if it exists, no-op otherwise.
void OnEvictionTimerUp(const DlpConfidentialContent& content);
std::list<std::unique_ptr<Entry>> entries_;
const size_t cache_size_limit_;
// Used to evict cache entries after the timeout.
scoped_refptr<base::SequencedTaskRunner> task_runner_;
};
} // namespace policy
#endif // CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_CONFIDENTIAL_CONTENTS_H_
|