File: trash_info_validator.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 (135 lines) | stat: -rw-r--r-- 5,916 bytes parent folder | download | duplicates (6)
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
// Copyright 2022 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_FILE_MANAGER_TRASH_INFO_VALIDATOR_H_
#define CHROME_BROWSER_ASH_FILE_MANAGER_TRASH_INFO_VALIDATOR_H_

#include <utility>

#include "base/files/file_path.h"
#include "base/time/time.h"
#include "base/types/expected.h"
#include "chrome/browser/ash/file_manager/trash_common_util.h"
#include "chromeos/ash/components/trash_service/public/cpp/trash_info_parser.h"

namespace file_manager::trash {

// On a successful parse of .trashinfo files, returns the restoration path,
// deletion date and actual location of the trashed file.
struct ParsedTrashInfoData {
  ParsedTrashInfoData();
  ~ParsedTrashInfoData();

  ParsedTrashInfoData(ParsedTrashInfoData&& other);
  ParsedTrashInfoData& operator=(ParsedTrashInfoData&& other);

  // The on-disk location of the .trashinfo file, e.g.
  // .Trash/info/foo.txt.trashinfo.
  base::FilePath trash_info_path;

  // The actual on-disk location of the trashed file, e.g. .Trash/files/foo.txt.
  base::FilePath trashed_file_path;

  // The path to restore the file back to. The basename here and the basename
  // for the `trashed_file_path` may differ as the path may conflict with
  // another in the trash.
  base::FilePath absolute_restore_path;

  // The date/time the file was trashed.
  base::Time deletion_date;
};

// Possible validation errors that may arise.
enum class ValidationError {
  kFileNotExist = 0,
  kInfoNotExist = 1,
  kInfoFileInvalid = 2,
  kInfoFileInvalidLocation = 3,
};

// Helper operator to enable pretty printing of the validation errors to logs.
std::ostream& operator<<(std::ostream& out, const ValidationError& value);

// Helper to convert the underlying `ValidationError` to a base::File::Error.
base::File::Error ValidationErrorToFileError(ValidationError error);

// Helper alias to define the callback type that is returned from the validator.
using ParsedTrashInfoDataOrError =
    base::expected<ParsedTrashInfoData, ValidationError>;
using ValidateAndParseTrashInfoCallback =
    base::OnceCallback<void(ParsedTrashInfoDataOrError)>;

// Validates and parses individual .trashinfo files to ensure they conform to
// the XDG specification. This is exposed here as we need to get a file handler
// and ensure files exist prior to parsing them. This can be done in a
// privileged context, but the parsing cannot. To use this:
//   1. Initialize a `TrashInfoValidator` like:
//        auto parser = std::make_unique<TrashInfoValidator>(profile,
//          base_path);
//   2. Set your disconnect handler in the event the underlying trash service
//   disconnects errorenously.
//        parser->SetDisconnectHandler(base::BindOnce(&Method, WeakPtr()));
//   3. For every file to validate and parse, call the ValidateAndParseTrashInfo
//   method, e.g.
//        parser->ValidateAndParseTrashInfo(trash_info_path,
//          base::BindOnce(&OnParsed, WeakPtr()));
class TrashInfoValidator {
 public:
  // The `base_path` here is used primarily for testing purposes to identify the
  // enabled trash locations.
  explicit TrashInfoValidator(Profile* profile);
  ~TrashInfoValidator();

  TrashInfoValidator(const TrashInfoValidator&) = delete;
  TrashInfoValidator& operator=(const TrashInfoValidator&) = delete;

  // Ensure the metadata file conforms to the following:
  //   - Has a .trashinfo suffix
  //   - Resides in an enabled trash directory
  //   - The file resides in the info directory
  //   - Has an identical item in the files directory with no .trashinfo suffix
  // In the event the above fails, the `callback` will be invoked with an error,
  // on success it then calls the TrashService to retrieve the parsed trashinfo
  // data. The `trash_info_path` must be absolute.
  void ValidateAndParseTrashInfo(const base::FilePath& trash_info_path,
                                 ValidateAndParseTrashInfoCallback callback);

  // Set the disconnect handler for the underlying TrashService.
  // TODO(b/238946031): Potentially centralize this by calling the `callback`
  // instead of having a separate disconnect callback.
  void SetDisconnectHandler(base::OnceCallback<void()> disconnect_callback);

 private:
  // Invoked after verifying if the on-disk file exists. The `mount_point_path`
  // represents the location where the .Trash folder resides (e.g. ~/MyFiles),
  // the `trashed_file_location` is the on-disk file that should be restored and
  // the `trash_info_path` represents the location of the .trashinfo file.
  void OnTrashedFileExists(const base::FilePath& mount_point_path,
                           const base::FilePath& trashed_file_location,
                           const base::FilePath& trash_info_path,
                           ValidateAndParseTrashInfoCallback callback,
                           bool exists);

  // Invoked when the TrashService has finished parsing the .trashinfo file.
  void OnTrashInfoParsed(const base::FilePath& trash_info_path,
                         const base::FilePath& mount_point_path,
                         const base::FilePath& trashed_file_location,
                         ValidateAndParseTrashInfoCallback callback,
                         base::File::Error status,
                         const base::FilePath& restore_path,
                         base::Time deletion_date);

  // A map containing paths which are enabled for trashing.
  trash::TrashPathsMap enabled_trash_locations_;

  // Holds the connection open to the `TrashService`. This is a sandboxed
  // process that performs parsing of the trashinfo files.
  std::unique_ptr<ash::trash_service::TrashInfoParser> parser_ = nullptr;

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

}  // namespace file_manager::trash

#endif  // CHROME_BROWSER_ASH_FILE_MANAGER_TRASH_INFO_VALIDATOR_H_