1 // Copyright 2020 The Chromium Authors. All rights reserved.
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/nearby_sharing/logging/proto_to_dictionary_conversion.h"
6 
7 #include <string>
8 #include <utility>
9 
10 #include "base/base64url.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/time/time.h"
13 
14 namespace {
Encode(const std::string & str)15 std::string Encode(const std::string& str) {
16   std::string encoded_string;
17   base::Base64UrlEncode(str, base::Base64UrlEncodePolicy::INCLUDE_PADDING,
18                         &encoded_string);
19   return encoded_string;
20 }
21 
TruncateString(const std::string & str)22 std::string TruncateString(const std::string& str) {
23   if (str.length() <= 10)
24     return str;
25   return str.substr(0, 5) + "..." + str.substr(str.length() - 5, str.length());
26 }
27 }  // namespace
28 
ListPublicCertificatesRequestToReadableDictionary(const nearbyshare::proto::ListPublicCertificatesRequest & request)29 base::Value ListPublicCertificatesRequestToReadableDictionary(
30     const nearbyshare::proto::ListPublicCertificatesRequest& request) {
31   base::Value dict(base::Value::Type::DICTIONARY);
32   dict.SetStringKey("parent", request.parent());
33   dict.SetIntKey("page_size", request.page_size());
34   dict.SetStringKey("page_token", request.page_token());
35 
36   base::Value secret_ids_list(base::Value::Type::LIST);
37   for (const auto& secret_id : request.secret_ids()) {
38     secret_ids_list.Append(TruncateString(Encode(secret_id)));
39   }
40   dict.SetKey("secret_ids", std::move(secret_ids_list));
41   return dict;
42 }
43 
ListPublicCertificatesResponseToReadableDictionary(const nearbyshare::proto::ListPublicCertificatesResponse & response)44 base::Value ListPublicCertificatesResponseToReadableDictionary(
45     const nearbyshare::proto::ListPublicCertificatesResponse& response) {
46   base::Value dict(base::Value::Type::DICTIONARY);
47   dict.SetStringKey("next_page_token", response.next_page_token());
48 
49   base::Value public_certificates_list(base::Value::Type::LIST);
50   for (const auto& public_certificate : response.public_certificates()) {
51     public_certificates_list.Append(
52         PublicCertificateToReadableDictionary(public_certificate));
53   }
54   dict.SetKey("public_certificates", std::move(public_certificates_list));
55   return dict;
56 }
57 
PublicCertificateToReadableDictionary(const nearbyshare::proto::PublicCertificate & certificate)58 base::Value PublicCertificateToReadableDictionary(
59     const nearbyshare::proto::PublicCertificate& certificate) {
60   base::Value dict(base::Value::Type::DICTIONARY);
61   dict.SetStringKey("secret_id",
62                     TruncateString(Encode(certificate.secret_id())));
63   dict.SetStringKey("secret_key",
64                     TruncateString(Encode(certificate.secret_key())));
65   dict.SetStringKey("public_key",
66                     TruncateString(Encode(certificate.public_key())));
67   dict.SetKey("start_time",
68               TimestampToReadableDictionary(certificate.start_time()));
69   dict.SetKey("end_time",
70               TimestampToReadableDictionary(certificate.end_time()));
71   dict.SetBoolKey("for_selected_contacts", certificate.for_selected_contacts());
72   dict.SetStringKey(
73       "metadata_encryption_key",
74       TruncateString(Encode(certificate.metadata_encryption_key())));
75   dict.SetStringKey(
76       "encrypted_metadata_bytes",
77       TruncateString(Encode(certificate.encrypted_metadata_bytes())));
78   dict.SetStringKey(
79       "metadata_encryption_key_tag",
80       TruncateString(Encode(certificate.metadata_encryption_key_tag())));
81   return dict;
82 }
83 
TimestampToReadableDictionary(const nearbyshare::proto::Timestamp & timestamp)84 base::Value TimestampToReadableDictionary(
85     const nearbyshare::proto::Timestamp& timestamp) {
86   base::Value dict(base::Value::Type::DICTIONARY);
87   dict.SetStringKey("seconds", base::NumberToString(timestamp.seconds()));
88   dict.SetStringKey("nanos", base::NumberToString(timestamp.nanos()));
89   return dict;
90 }
91 
ListContactPeopleRequestToReadableDictionary(const nearbyshare::proto::ListContactPeopleRequest & request)92 base::Value ListContactPeopleRequestToReadableDictionary(
93     const nearbyshare::proto::ListContactPeopleRequest& request) {
94   base::Value dict(base::Value::Type::DICTIONARY);
95   dict.SetIntKey("page_size", request.page_size());
96   dict.SetStringKey("page_token", request.page_token());
97   return dict;
98 }
99 
ListContactPeopleResponseToReadableDictionary(const nearbyshare::proto::ListContactPeopleResponse & response)100 base::Value ListContactPeopleResponseToReadableDictionary(
101     const nearbyshare::proto::ListContactPeopleResponse& response) {
102   base::Value dict(base::Value::Type::DICTIONARY);
103   base::Value contact_records_list(base::Value::Type::LIST);
104   for (const auto& contact_record : response.contact_records()) {
105     contact_records_list.Append(
106         ContactRecordToReadableDictionary(contact_record));
107   }
108   dict.SetKey("contact_records", std::move(contact_records_list));
109   dict.SetStringKey("next_page_token", response.next_page_token());
110   return dict;
111 }
112 
ContactRecordToReadableDictionary(const nearbyshare::proto::ContactRecord & contact_record)113 base::Value ContactRecordToReadableDictionary(
114     const nearbyshare::proto::ContactRecord& contact_record) {
115   base::Value dict(base::Value::Type::DICTIONARY);
116   dict.SetStringKey("id", contact_record.id());
117   dict.SetStringKey("person_name", contact_record.person_name());
118   dict.SetStringKey("image_url", contact_record.image_url());
119   base::Value identifiers_list(base::Value::Type::LIST);
120   for (const auto& identifier : contact_record.identifiers()) {
121     identifiers_list.Append(IdentifierToReadableDictionary(identifier));
122   }
123   dict.SetKey("identifiers", std::move(identifiers_list));
124   return dict;
125 }
126 
IdentifierToReadableDictionary(const nearbyshare::proto::Contact::Identifier & identifier)127 base::Value IdentifierToReadableDictionary(
128     const nearbyshare::proto::Contact::Identifier& identifier) {
129   base::Value dict(base::Value::Type::DICTIONARY);
130   if (!identifier.obfuscated_gaia().empty()) {
131     dict.SetStringKey("identifier", identifier.obfuscated_gaia());
132   } else if (!identifier.phone_number().empty()) {
133     dict.SetStringKey("identifier", identifier.phone_number());
134   } else if (!identifier.account_name().empty()) {
135     dict.SetStringKey("identifier", identifier.account_name());
136   }
137   return dict;
138 }
139 
UpdateDeviceRequestToReadableDictionary(const nearbyshare::proto::UpdateDeviceRequest & request)140 base::Value UpdateDeviceRequestToReadableDictionary(
141     const nearbyshare::proto::UpdateDeviceRequest& request) {
142   base::Value dict(base::Value::Type::DICTIONARY);
143   dict.SetKey("device", DeviceToReadableDictionary(request.device()));
144   dict.SetKey("update_mask",
145               FieldMaskToReadableDictionary(request.update_mask()));
146   return dict;
147 }
148 
DeviceToReadableDictionary(const nearbyshare::proto::Device & device)149 base::Value DeviceToReadableDictionary(
150     const nearbyshare::proto::Device& device) {
151   base::Value dict(base::Value::Type::DICTIONARY);
152   dict.SetStringKey("name", device.name());
153   dict.SetStringKey("display_name", device.display_name());
154   base::Value contacts_list(base::Value::Type::LIST);
155   for (const auto& contact : device.contacts()) {
156     contacts_list.Append(ContactToReadableDictionary(contact));
157   }
158   dict.SetKey("contacts", std::move(contacts_list));
159   base::Value public_certificates_list(base::Value::Type::LIST);
160   for (const auto& certificate : device.public_certificates()) {
161     public_certificates_list.Append(
162         PublicCertificateToReadableDictionary(certificate));
163   }
164   dict.SetKey("public_certificates", std::move(public_certificates_list));
165   return dict;
166 }
167 
ContactToReadableDictionary(const nearbyshare::proto::Contact & contact)168 base::Value ContactToReadableDictionary(
169     const nearbyshare::proto::Contact& contact) {
170   base::Value dict(base::Value::Type::DICTIONARY);
171   dict.SetKey("identifier",
172               IdentifierToReadableDictionary(contact.identifier()));
173   dict.SetBoolKey("is_selected", contact.is_selected());
174   return dict;
175 }
176 
FieldMaskToReadableDictionary(const nearbyshare::proto::FieldMask & mask)177 base::Value FieldMaskToReadableDictionary(
178     const nearbyshare::proto::FieldMask& mask) {
179   base::Value dict(base::Value::Type::DICTIONARY);
180   base::Value paths_list(base::Value::Type::LIST);
181   for (const auto& path : mask.paths()) {
182     paths_list.Append(path);
183   }
184   dict.SetKey("paths", std::move(paths_list));
185   return dict;
186 }
187 
UpdateDeviceResponseToReadableDictionary(const nearbyshare::proto::UpdateDeviceResponse & response)188 base::Value UpdateDeviceResponseToReadableDictionary(
189     const nearbyshare::proto::UpdateDeviceResponse& response) {
190   base::Value dict(base::Value::Type::DICTIONARY);
191   dict.SetKey("device", DeviceToReadableDictionary(response.device()));
192   dict.SetStringKey("person_name", response.person_name());
193   dict.SetStringKey("image_url", response.image_url());
194   return dict;
195 }
196 
EncryptedMetadataToReadableDictionary(const nearbyshare::proto::EncryptedMetadata & data)197 base::Value EncryptedMetadataToReadableDictionary(
198     const nearbyshare::proto::EncryptedMetadata& data) {
199   base::Value dict(base::Value::Type::DICTIONARY);
200   dict.SetStringKey("device_name", data.device_name());
201   dict.SetStringKey("full_name", data.full_name());
202   dict.SetStringKey("icon_url", data.icon_url());
203   dict.SetStringKey("bluetooth_mac_address",
204                     TruncateString(Encode(data.bluetooth_mac_address())));
205   dict.SetStringKey("obfuscated_gaia_id", data.obfuscated_gaia_id());
206   return dict;
207 }
208