File: dlp_files_controller_ash.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (280 lines) | stat: -rw-r--r-- 12,186 bytes parent folder | download | duplicates (3)
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
// 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_ASH_POLICY_DLP_DLP_FILES_CONTROLLER_ASH_H_
#define CHROME_BROWSER_ASH_POLICY_DLP_DLP_FILES_CONTROLLER_ASH_H_

#include <memory>
#include <vector>

#include "base/containers/flat_map.h"
#include "base/files/file_path.h"
#include "base/functional/callback_forward.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/ash/file_manager/io_task.h"
#include "chrome/browser/ash/file_manager/volume_manager_observer.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_file_destination.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_files_controller.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_files_utils.h"
#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
#include "chromeos/dbus/dlp/dlp_service.pb.h"
#include "components/services/app_service/public/cpp/app_update.h"
#include "components/services/app_service/public/cpp/intent.h"
#include "storage/browser/file_system/file_system_url.h"
#include "ui/base/clipboard/file_info.h"
#include "ui/base/data_transfer_policy/data_transfer_endpoint.h"
#include "ui/shell_dialogs/selected_file_info.h"

namespace storage {
class FileSystemURL;
}  // namespace storage

namespace views {
class Widget;
}  // namespace views

namespace policy {

class DlpFilesEventStorage;
class DlpExtractIOTaskObserver;

// DlpFilesControllerAsh is responsible for deciding whether file transfers are
// allowed according to the files sources saved in the DLP daemon and the rules
// of the Data leak prevention policy set by the admin.
class DlpFilesControllerAsh : public DlpFilesController,
                              public file_manager::VolumeManagerObserver {
 public:
  // Returns the instance if it exists.
  static DlpFilesControllerAsh* GetForPrimaryProfile();

  // DlpFileMetadata keeps metadata about a file, such as whether it's managed
  // or not and the source URL, if it exists.
  struct DlpFileMetadata {
    DlpFileMetadata() = delete;
    DlpFileMetadata(const std::string& source_url,
                    const std::string& referrer_url,
                    bool is_dlp_restricted,
                    bool is_restricted_for_destination);

    friend bool operator==(const DlpFileMetadata&,
                           const DlpFileMetadata&) = default;

    // Source URL from which the file was downloaded.
    std::string source_url;
    // Referrer URL from which the download process was initiated.
    std::string referrer_url;
    // Whether the file is under any DLP rule or not.
    bool is_dlp_restricted;
    // Whether the file is restricted by DLP for a specific destination.
    bool is_restricted_for_destination;
  };

  // DlpFileRestrictionDetails keeps aggregated information about DLP rules
  // that apply to a file. It consists of the level (e.g. block, warn) and
  // destinations for which this level applies (URLs and/or components).
  struct DlpFileRestrictionDetails {
    DlpFileRestrictionDetails();
    DlpFileRestrictionDetails(const DlpFileRestrictionDetails&) = delete;
    DlpFileRestrictionDetails& operator=(const DlpFileRestrictionDetails&) =
        delete;
    DlpFileRestrictionDetails(DlpFileRestrictionDetails&&);
    DlpFileRestrictionDetails& operator=(DlpFileRestrictionDetails&&);
    ~DlpFileRestrictionDetails();

    // The level for which the restriction is enforced.
    DlpRulesManager::Level level;
    // List of URLs for which the restriction is enforced.
    std::vector<std::string> urls;
    // List of components for which the restriction is enforced.
    std::vector<data_controls::Component> components;
  };

  using CheckIfTransferAllowedCallback =
      base::OnceCallback<void(std::vector<storage::FileSystemURL>)>;
  using GetFilesRestrictedByAnyRuleCallback = CheckIfTransferAllowedCallback;
  using FilterDisallowedUploadsCallback =
      base::OnceCallback<void(std::vector<ui::SelectedFileInfo>)>;
  using GetDlpMetadataCallback =
      base::OnceCallback<void(std::vector<DlpFileMetadata>)>;
  using IsFilesTransferRestrictedCallback = base::OnceCallback<void(
      const std::vector<std::pair<FileDaemonInfo, ::dlp::RestrictionLevel>>&)>;

  DlpFilesControllerAsh(const DlpRulesManager& rules_manager, Profile* profile);
  DlpFilesControllerAsh(const DlpFilesControllerAsh& other) = delete;
  DlpFilesControllerAsh& operator=(const DlpFilesControllerAsh& other) = delete;

  ~DlpFilesControllerAsh() override;

  // Returns a sublist of |transferred_files| disallowed to be transferred to
  // |destination| in |result_callback|. |is_move| is true if it's a move
  // operation. Otherwise it's false.
  virtual void CheckIfTransferAllowed(
      std::optional<file_manager::io_task::IOTaskId> task_id,
      const std::vector<storage::FileSystemURL>& transferred_files,
      storage::FileSystemURL destination,
      bool is_move,
      CheckIfTransferAllowedCallback result_callback);

  // Retrieves metadata for each entry in |files| and returns it as a list in
  // |result_callback|. If |destination| is passed, marks the files that are not
  // allowed to be uploaded to that particular destination.
  virtual void GetDlpMetadata(const std::vector<storage::FileSystemURL>& files,
                              std::optional<DlpFileDestination> destination,
                              GetDlpMetadataCallback result_callback);

  // Filters files disallowed to be uploaded to `destination`.
  virtual void FilterDisallowedUploads(
      std::vector<ui::SelectedFileInfo> selected_files,
      const DlpFileDestination& destination,
      FilterDisallowedUploadsCallback result_callback);

  // Checks whether the file download from `download_src` to `file_path` is
  // allowed.
  virtual void CheckIfDownloadAllowed(
      const DlpFileDestination& download_src,
      const base::FilePath& file_path,
      CheckIfDlpAllowedCallback result_callback);

  // Returns whether downloads from `download_src` to `file_path` might be
  // blocked by DLP, and so a picker should be shown.
  virtual bool ShouldPromptBeforeDownload(
      const DlpFileDestination& download_src,
      const base::FilePath& file_path);

  // Checks whether launching `app_update` with `intent` is allowed.
  virtual void CheckIfLaunchAllowed(const apps::AppUpdate& app_update,
                                    apps::IntentPtr intent,
                                    CheckIfDlpAllowedCallback result_callback);

  // Returns true if `app_update` is blocked from opening any of the
  // files in `intent`.
  virtual bool IsLaunchBlocked(const apps::AppUpdate& app_update,
                               const apps::IntentPtr& intent);

  // Returns a sublist of `transferred_files` which aren't allowed to be
  // transferred to either `destination_url` or `destination_component` in
  // `result_callback`.
  virtual void IsFilesTransferRestricted(
      std::optional<file_manager::io_task::IOTaskId> task_id,
      const std::vector<FileDaemonInfo>& transferred_files,
      const DlpFileDestination& destination,
      dlp::FileAction files_action,
      IsFilesTransferRestrictedCallback result_callback);

  // Returns restriction information for `source_url`.
  virtual std::vector<DlpFileRestrictionDetails> GetDlpRestrictionDetails(
      const std::string& source_url);

  // Returns a list of components to which the transfer of a file with
  // `source_url` is blocked.
  virtual std::vector<data_controls::Component> GetBlockedComponents(
      const std::string& source_url);

  // Returns whether a dlp policy matches for the `file`.
  virtual bool IsDlpPolicyMatched(const FileDaemonInfo& file);

  //  VolumeManagerObserver overrides:
  void OnShutdownStart(file_manager::VolumeManager* volume_manager) override;

  DlpFilesEventStorage* GetEventStorageForTesting();

 protected:
  // DlpFilesController overrides:
  std::optional<data_controls::Component> MapFilePathToPolicyComponent(
      Profile* profile,
      const base::FilePath& file_path) override;

  bool IsInLocalFileSystem(const base::FilePath& file_path) override;

  void ShowDlpBlockedFiles(
      std::optional<file_manager::io_task::IOTaskId> task_id,
      std::vector<base::FilePath> blocked_files,
      dlp::FileAction action) override;

  // TODO(b/284122497): Cleanup friend for testing.
  FRIEND_TEST_ALL_PREFIXES(DlpFilesControllerAshComponentsTest,
                           MapFilePathToPolicyComponentTest);

  FRIEND_TEST_ALL_PREFIXES(DlpFilesControllerAshBlockUITest,
                           ShowDlpBlockedFiles);

 private:
  // Called back from warning dialog. Passes blocked files sources along
  // to |callback|. In case |should_proceed| is true, passes only
  // |files_levels|, otherwise passes also |warned_files_sources|.
  void OnDlpWarnDialogReply(
      std::vector<std::pair<FileDaemonInfo, ::dlp::RestrictionLevel>>
          files_levels,
      std::vector<FileDaemonInfo> warned_files_sources,
      std::vector<std::string> warned_src_patterns,
      std::vector<DlpRulesManager::RuleMetadata> warned_rules_metadata,
      const DlpFileDestination& dst,
      dlp::FileAction files_action,
      IsFilesTransferRestrictedCallback callback,
      std::optional<std::u16string> user_justification,
      bool should_proceed);

  void ReturnDisallowedFiles(
      std::optional<file_manager::io_task::IOTaskId> task_id,
      base::flat_map<std::string, storage::FileSystemURL> files_map,
      dlp::FileAction file_action,
      CheckIfTransferAllowedCallback result_callback,
      ::dlp::CheckFilesTransferResponse response);

  void ReturnAllowedUploads(std::vector<ui::SelectedFileInfo> uploaded_files,
                            FilterDisallowedUploadsCallback result_callback,
                            ::dlp::CheckFilesTransferResponse response);

  void ReturnDlpMetadata(const std::vector<storage::FileSystemURL>& files,
                         std::optional<DlpFileDestination> destination,
                         GetDlpMetadataCallback result_callback,
                         const ::dlp::GetFilesSourcesResponse response);

  // Reports an event if a `DlpReportingManager` instance exists. When
  // `level` is missing, we report a warning proceeded event.
  void MaybeReportEvent(ino64_t inode,
                        time_t crtime,
                        const base::FilePath& path,
                        const std::string& source_url,
                        const DlpFileDestination& dst,
                        const DlpRulesManager::RuleMetadata& rule_metadata,
                        std::optional<DlpRulesManager::Level> level);

  // Called when `transferred_files` is ready. Constructs CheckFilesTransfer
  // request and forwards it to the dlp daemon.
  void ContinueCheckIfTransferAllowed(
      std::optional<file_manager::io_task::IOTaskId> task_id,
      storage::FileSystemURL destination,
      bool is_move,
      CheckIfTransferAllowedCallback result_callback,
      std::vector<storage::FileSystemURL> transferred_files);

  // Called when `uploaded_files` is ready. Constructs CheckFilesTransfer
  // request and forwards it to the dlp daemon.
  void ContinueFilterDisallowedUploads(
      std::vector<ui::SelectedFileInfo> selected_files,
      const DlpFileDestination& destination,
      FilterDisallowedUploadsCallback result_callback,
      std::vector<storage::FileSystemURL> uploaded_files);

  // The profile with which we are associated. Not owned. It's currently always
  // the main/primary profile.
  const raw_ptr<Profile> profile_;

  // Keeps track of events and detects duplicate ones using time based
  // approach.
  std::unique_ptr<DlpFilesEventStorage> event_storage_;

  // Gets notified when an archive is extracted, and notifies the DLP daemon
  // about newly extracted files.
  std::unique_ptr<DlpExtractIOTaskObserver> extract_io_task_observer_;

  base::WeakPtrFactory<DlpFilesControllerAsh> weak_ptr_factory_{this};
};

}  // namespace policy

#endif  // CHROME_BROWSER_ASH_POLICY_DLP_DLP_FILES_CONTROLLER_ASH_H_