blob: fceeb2d97ba736965d2017d25e47a57902920c70 [file] [log] [blame]
Owen Min0d9183b12023-08-16 19:37:501// Copyright 2023 The Chromium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/enterprise/remote_commands/job_profile_picker.h"
6
7#include "base/values.h"
8#include "build/build_config.h"
9#include "chrome/browser/profiles/profile.h"
10#include "chrome/browser/profiles/profile_attributes_storage.h"
11#include "chrome/browser/profiles/profile_manager.h"
12
13namespace enterprise_commands {
14namespace {
15
16const char kProfilePathField[] = "profile_path";
17
18} // namespace
19
20JobProfilePicker::JobProfilePicker(Profile* profile)
21 : profile_or_profile_manager_(profile) {}
22JobProfilePicker::JobProfilePicker(ProfileManager* profile_manager)
23 : profile_or_profile_manager_(profile_manager) {}
24
25JobProfilePicker::~JobProfilePicker() = default;
26
27bool JobProfilePicker::ParseCommandPayload(
28 const base::Value::Dict& command_payload) {
29 if (absl::holds_alternative<raw_ptr<Profile>>(profile_or_profile_manager_)) {
30 return true;
31 }
32
33 const std::string* path = command_payload.FindString(kProfilePathField);
34 if (!path) {
35 return false;
36 }
37
38 // On Windows, file paths are wstring as opposed to string on other platforms.
39 // On POSIX platforms other than MacOS and ChromeOS, the encoding is unknown.
40 //
41 // This path is sent from the server, which obtained it from Chrome in a
42 // previous report, and Chrome casts the path as UTF8 using UTF8Unsafe before
43 // sending it (see BrowserReportGeneratorDesktop::GenerateProfileInfo).
44 // Because of that, the best thing we can do everywhere is try to get the
45 // path from UTF8, and ending up with an invalid path will fail later in
46 // RunImpl when we attempt to get the profile from the path.
47 profile_path_ = base::FilePath::FromUTF8Unsafe(*path);
48#if BUILDFLAG(IS_WIN)
49 // For Windows machines, the path that Chrome reports for the profile is
50 // "Normalized" to all lower-case on the reporting server. This means that
51 // when the server sends the command, the path will be all lower case and
52 // the profile manager won't be able to use it as a key. To avoid this issue,
53 // This code will iterate over all profile paths and find the one that matches
54 // in a case-insensitive comparison. If this doesn't find one, RunImpl will
55 // fail in the same manner as if the profile didn't exist, which is the
56 // expected behavior.
57 ProfileAttributesStorage& storage =
58 absl::get<raw_ptr<ProfileManager>>(profile_or_profile_manager_)
59 ->GetProfileAttributesStorage();
60 for (ProfileAttributesEntry* entry : storage.GetAllProfilesAttributes()) {
61 base::FilePath entry_path = entry->GetPath();
62
63 if (base::FilePath::CompareEqualIgnoreCase(profile_path_.value(),
64 entry_path.value())) {
65 profile_path_ = entry_path;
66 break;
67 }
68 }
69#endif
70 return true;
71}
72
73Profile* JobProfilePicker::GetProfile() {
74 if (absl::holds_alternative<raw_ptr<Profile>>(profile_or_profile_manager_)) {
75 return absl::get<raw_ptr<Profile>>(profile_or_profile_manager_);
76 }
77 return absl::get<raw_ptr<ProfileManager>>(profile_or_profile_manager_)
78 ->GetProfileByPath(profile_path_);
79}
80
81} // namespace enterprise_commands