-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathenrollment_storage.cc
134 lines (103 loc) · 4.11 KB
/
enrollment_storage.cc
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
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "faced/enrollment_storage.h"
#include <algorithm>
#include <string>
#include <absl/status/status.h>
#include <absl/status/statusor.h>
#include <absl/strings/str_cat.h>
#include <base/files/file.h>
#include <base/files/file_enumerator.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/important_file_writer.h>
#include <base/strings/strcat.h>
#include <base/strings/string_piece.h>
#include "faced/mojom/faceauth.mojom.h"
namespace faced {
namespace {
// Name of daemon.
constexpr char kFaced[] = "faced";
// Name of enrollment file to read and write from.
constexpr char kEnrollmentFileName[] = "enrollment";
using ::chromeos::faceauth::mojom::EnrollmentMetadata;
using ::chromeos::faceauth::mojom::EnrollmentMetadataPtr;
} // namespace
absl::Status EnrollmentStorage::WriteEnrollment(base::StringPiece user_id,
base::StringPiece data) {
base::FilePath save_path = GetEnrollmentFilePath(user_id);
base::File::Error error;
if (!CreateDirectoryAndGetError(save_path.DirName(), &error)) {
return absl::UnavailableError(
base::StrCat({"Unable to create directory for user: ",
base::File::ErrorToString(error)}));
}
if (!base::ImportantFileWriter::WriteFileAtomically(save_path, data)) {
return absl::UnavailableError(
"Unable to save enrollment to file for user.");
}
return absl::OkStatus();
}
absl::StatusOr<std::string> EnrollmentStorage::ReadEnrollment(
base::StringPiece user_id) {
base::FilePath enrollment_path = GetEnrollmentFilePath(user_id);
std::string data;
if (!base::ReadFileToString(enrollment_path, &data)) {
return absl::UnavailableError("Unable to read enrollment for user.");
}
return data;
}
std::vector<EnrollmentMetadataPtr> EnrollmentStorage::ListEnrollments() {
std::vector<EnrollmentMetadataPtr> ret;
base::FilePath faced_path = root_path_.Append(kFaced);
base::FileEnumerator enum_users(faced_path, /*recursive=*/false,
base::FileEnumerator::DIRECTORIES);
for (base::FilePath user_path = enum_users.Next(); !user_path.empty();
user_path = enum_users.Next()) {
std::string user_id = user_path.BaseName().value();
base::FilePath user_enrollment_path = GetEnrollmentFilePath(user_id);
// Check if an enrollment exists for the user.
if (base::PathExists(user_enrollment_path)) {
ret.push_back(EnrollmentMetadata::New(user_id));
}
}
// Sort the usernames to ensure the result of this function is deterministic,
// and not based on the order the filesystem happened to list files in.
std::sort(ret.begin(), ret.end(),
[](const EnrollmentMetadataPtr& a, const EnrollmentMetadataPtr& b) {
// Sort by username.
return a->hashed_username < b->hashed_username;
});
return ret;
}
absl::Status EnrollmentStorage::RemoveEnrollment(base::StringPiece user_id) {
base::FilePath enrollment_path = GetEnrollmentFilePath(user_id);
if (!base::PathExists(enrollment_path)) {
return absl::NotFoundError("No enrollment found for user.");
}
if (!base::DeleteFile(enrollment_path)) {
return absl::InternalError("Unable to remove enrollment.");
}
return absl::OkStatus();
}
absl::Status EnrollmentStorage::ClearEnrollments() {
absl::Status ret = absl::OkStatus();
for (const EnrollmentMetadataPtr& enrollment : ListEnrollments()) {
if (!RemoveEnrollment(enrollment->hashed_username).ok()) {
ret = absl::InternalError("Unable to clear enrollments.");
}
}
return ret;
}
bool EnrollmentStorage::IsUserEnrolled(base::StringPiece user_id) {
return base::PathExists(GetEnrollmentFilePath((user_id)));
}
base::FilePath EnrollmentStorage::GetEnrollmentFilePath(
base::StringPiece user_id) {
return GetFacedFilePath().Append(user_id).Append(kEnrollmentFileName);
}
base::FilePath EnrollmentStorage::GetFacedFilePath() {
return root_path_.Append(kFaced);
}
} // namespace faced