Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: chrome/browser/push_messaging/push_messaging_app_identifier.cc

Issue 1141613003: Push API: Include origin in generated app_ids (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ident_test
Patch Set: Add test for reading old values from prefs Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/push_messaging/push_messaging_app_identifier.h" 5 #include "chrome/browser/push_messaging/push_messaging_app_identifier.h"
6 6
7 #include <string.h>
Peter Beverloo 2015/05/14 11:26:29 <vector>?
johnme 2015/05/14 13:18:20 push_messaging_app_identifier.h already includes <
8
7 #include "base/guid.h" 9 #include "base/guid.h"
8 #include "base/logging.h" 10 #include "base/logging.h"
9 #include "base/prefs/pref_service.h" 11 #include "base/prefs/pref_service.h"
10 #include "base/prefs/scoped_user_pref_update.h" 12 #include "base/prefs/scoped_user_pref_update.h"
11 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_split.h" 14 #include "base/strings/string_split.h"
13 #include "base/strings/string_util.h" 15 #include "base/strings/string_util.h"
14 #include "base/values.h" 16 #include "base/values.h"
15 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/common/pref_names.h" 18 #include "chrome/common/pref_names.h"
17 #include "components/pref_registry/pref_registry_syncable.h" 19 #include "components/pref_registry/pref_registry_syncable.h"
18 20
19 namespace { 21 namespace {
22
20 const char kSeparator = '#'; // Ok as only the origin of the url is used. 23 const char kSeparator = '#'; // Ok as only the origin of the url is used.
24 const int kGuidLength = 36; // "%08X-%04X-%04X-%04X-%012llX"
25
26 std::string MakePrefValue(const GURL& origin,
27 int64_t service_worker_registration_id) {
28 return origin.spec() + kSeparator
29 + base::Int64ToString(service_worker_registration_id);
30 }
31
32 bool GetOriginAndSWRFromPrefValue(
33 const std::string& pref_value, GURL* origin,
34 int64_t* service_worker_registration_id) {
35 std::vector<std::string> parts;
36 base::SplitString(pref_value, kSeparator, &parts);
37 if (parts.size() != 2)
38 return false;
39
40 if (!base::StringToInt64(parts[1], service_worker_registration_id))
41 return false;
42
43 *origin = GURL(parts[0]);
Peter Beverloo 2015/05/14 11:26:29 Do we need to validate here that the origin is val
johnme 2015/05/14 13:18:20 Done.
44
45 return true;
46 }
47
21 } // namespace 48 } // namespace
22 49
23 const char kPushMessagingAppIdentifierPrefix[] = "wp:"; 50 const char kPushMessagingAppIdentifierPrefix[] = "wp:";
24 51
25 // static 52 // static
26 void PushMessagingAppIdentifier::RegisterProfilePrefs( 53 void PushMessagingAppIdentifier::RegisterProfilePrefs(
27 user_prefs::PrefRegistrySyncable* registry) { 54 user_prefs::PrefRegistrySyncable* registry) {
28 registry->RegisterDictionaryPref(prefs::kPushMessagingAppIdentifierMap); 55 registry->RegisterDictionaryPref(prefs::kPushMessagingAppIdentifierMap);
29 } 56 }
30 57
31 // static 58 // static
32 PushMessagingAppIdentifier PushMessagingAppIdentifier::Generate( 59 PushMessagingAppIdentifier PushMessagingAppIdentifier::Generate(
33 const GURL& origin, int64_t service_worker_registration_id) 60 const GURL& origin, int64_t service_worker_registration_id)
34 { 61 {
35 std::string guid = base::GenerateGUID(); 62 std::string guid = base::GenerateGUID();
36 CHECK(!guid.empty()); 63 CHECK(!guid.empty());
37 std::string app_id = kPushMessagingAppIdentifierPrefix + guid; 64 std::string app_id = kPushMessagingAppIdentifierPrefix + origin.spec()
65 + kSeparator + guid;
38 66
39 PushMessagingAppIdentifier app_identifier(app_id, origin, 67 PushMessagingAppIdentifier app_identifier(app_id, origin,
40 service_worker_registration_id); 68 service_worker_registration_id);
41 app_identifier.DCheckValid(); 69 app_identifier.DCheckValid();
42 return app_identifier; 70 return app_identifier;
43 } 71 }
44 72
45 // static 73 // static
46 PushMessagingAppIdentifier PushMessagingAppIdentifier::Get( 74 PushMessagingAppIdentifier PushMessagingAppIdentifier::FindByAppId(
47 Profile* profile, const std::string& app_id) { 75 Profile* profile, const std::string& app_id) {
48 // Workaround crbug.com/461867 in GCM where it converts subtypes to lowercase.
Peter Beverloo 2015/05/14 11:26:29 Please add 461867 to the BUG= line. Should we DCHE
johnme 2015/05/14 13:18:20 Done. I factored out a DCheckAppIdValid method fro
49 // TODO(johnme): Remove this when obsolete
50 const size_t prefix_len = strlen(kPushMessagingAppIdentifierPrefix);
51 if (app_id.size() < prefix_len)
52 return PushMessagingAppIdentifier();
53 std::string uppercase_app_id =
54 app_id.substr(0, prefix_len) +
55 StringToUpperASCII(app_id.substr(prefix_len, std::string::npos));
56
57 const base::DictionaryValue* map = 76 const base::DictionaryValue* map =
58 profile->GetPrefs()->GetDictionary(prefs::kPushMessagingAppIdentifierMap); 77 profile->GetPrefs()->GetDictionary(prefs::kPushMessagingAppIdentifierMap);
59 78
60 std::string origin_and_sw_id; 79 std::string map_value;
61 if (!map->GetStringWithoutPathExpansion(uppercase_app_id, &origin_and_sw_id)) 80 if (!map->GetStringWithoutPathExpansion(app_id, &map_value))
62 return PushMessagingAppIdentifier(); 81 return PushMessagingAppIdentifier();
63 82
64 std::vector<std::string> parts; 83 GURL origin;
65 base::SplitString(origin_and_sw_id, kSeparator, &parts); 84 int64_t service_worker_registration_id;
66 if (parts.size() != 2) 85 if (!GetOriginAndSWRFromPrefValue(map_value, &origin,
86 &service_worker_registration_id)) {
87 NOTREACHED();
67 return PushMessagingAppIdentifier(); 88 return PushMessagingAppIdentifier();
89 }
68 90
69 GURL origin = GURL(parts[0]); 91 PushMessagingAppIdentifier app_identifier(app_id, origin,
70
71 int64_t service_worker_registration_id;
72 if (!base::StringToInt64(parts[1], &service_worker_registration_id))
73 return PushMessagingAppIdentifier();
74
75 PushMessagingAppIdentifier app_identifier(uppercase_app_id, origin,
76 service_worker_registration_id); 92 service_worker_registration_id);
77 app_identifier.DCheckValid(); 93 app_identifier.DCheckValid();
78 return app_identifier; 94 return app_identifier;
79 } 95 }
80 96
81 // static 97 // static
82 PushMessagingAppIdentifier PushMessagingAppIdentifier::Get( 98 PushMessagingAppIdentifier PushMessagingAppIdentifier::FindByServiceWorker(
83 Profile* profile, const GURL& origin, 99 Profile* profile, const GURL& origin,
84 int64_t service_worker_registration_id) 100 int64_t service_worker_registration_id)
85 { 101 {
86 base::StringValue origin_and_sw_id = base::StringValue(origin.spec() + 102 const base::StringValue pref_value =
87 kSeparator + base::Int64ToString(service_worker_registration_id)); 103 base::StringValue(MakePrefValue(origin, service_worker_registration_id));
88 104
89 const base::DictionaryValue* map = 105 const base::DictionaryValue* map =
90 profile->GetPrefs()->GetDictionary(prefs::kPushMessagingAppIdentifierMap); 106 profile->GetPrefs()->GetDictionary(prefs::kPushMessagingAppIdentifierMap);
91 for (auto it = base::DictionaryValue::Iterator(*map); !it.IsAtEnd(); 107 for (auto it = base::DictionaryValue::Iterator(*map); !it.IsAtEnd();
92 it.Advance()) { 108 it.Advance()) {
93 if (it.value().Equals(&origin_and_sw_id)) 109 if (it.value().Equals(&pref_value))
94 return Get(profile, it.key()); 110 return FindByAppId(profile, it.key());
95 } 111 }
96 return PushMessagingAppIdentifier(); 112 return PushMessagingAppIdentifier();
97 } 113 }
98 114
99 // static 115 // static
100 std::vector<PushMessagingAppIdentifier> PushMessagingAppIdentifier::GetAll( 116 std::vector<PushMessagingAppIdentifier> PushMessagingAppIdentifier::GetAll(
101 Profile* profile) { 117 Profile* profile) {
102 std::vector<PushMessagingAppIdentifier> result; 118 std::vector<PushMessagingAppIdentifier> result;
103 119
104 const base::DictionaryValue* map = 120 const base::DictionaryValue* map =
105 profile->GetPrefs()->GetDictionary(prefs::kPushMessagingAppIdentifierMap); 121 profile->GetPrefs()->GetDictionary(prefs::kPushMessagingAppIdentifierMap);
106 for (auto it = base::DictionaryValue::Iterator(*map); !it.IsAtEnd(); 122 for (auto it = base::DictionaryValue::Iterator(*map); !it.IsAtEnd();
107 it.Advance()) { 123 it.Advance()) {
108 result.push_back(Get(profile, it.key())); 124 result.push_back(FindByAppId(profile, it.key()));
109 } 125 }
110 126
111 return result; 127 return result;
112 } 128 }
113 129
114 PushMessagingAppIdentifier::PushMessagingAppIdentifier() 130 PushMessagingAppIdentifier::PushMessagingAppIdentifier()
115 : origin_(GURL::EmptyGURL()), 131 : origin_(GURL::EmptyGURL()),
116 service_worker_registration_id_(-1) { 132 service_worker_registration_id_(-1) {
117 } 133 }
118 134
(...skipping 11 matching lines...) Expand all
130 146
131 void PushMessagingAppIdentifier::PersistToPrefs(Profile* profile) const { 147 void PushMessagingAppIdentifier::PersistToPrefs(Profile* profile) const {
132 DCheckValid(); 148 DCheckValid();
133 149
134 DictionaryPrefUpdate update(profile->GetPrefs(), 150 DictionaryPrefUpdate update(profile->GetPrefs(),
135 prefs::kPushMessagingAppIdentifierMap); 151 prefs::kPushMessagingAppIdentifierMap);
136 base::DictionaryValue* map = update.Get(); 152 base::DictionaryValue* map = update.Get();
137 153
138 // Delete any stale entry with the same origin and Service Worker 154 // Delete any stale entry with the same origin and Service Worker
139 // registration id (hence we ensure there is a 1:1 not 1:many mapping). 155 // registration id (hence we ensure there is a 1:1 not 1:many mapping).
140 PushMessagingAppIdentifier old = Get(profile, origin_, 156 PushMessagingAppIdentifier old = FindByServiceWorker(
141 service_worker_registration_id_); 157 profile, origin_, service_worker_registration_id_);
142 if (!old.is_null()) 158 if (!old.is_null())
143 map->RemoveWithoutPathExpansion(old.app_id_, nullptr); 159 map->RemoveWithoutPathExpansion(old.app_id_, nullptr /* out_value */);
144 160
145 std::string origin_and_sw_id = origin_.spec() + kSeparator + 161 map->SetStringWithoutPathExpansion(
146 base::Int64ToString(service_worker_registration_id_); 162 app_id_, MakePrefValue(origin_, service_worker_registration_id_));
147 map->SetStringWithoutPathExpansion(app_id_, origin_and_sw_id);
148 } 163 }
149 164
150 void PushMessagingAppIdentifier::DeleteFromPrefs(Profile* profile) const { 165 void PushMessagingAppIdentifier::DeleteFromPrefs(Profile* profile) const {
151 DCheckValid(); 166 DCheckValid();
152 167
153 DictionaryPrefUpdate update(profile->GetPrefs(), 168 DictionaryPrefUpdate update(profile->GetPrefs(),
154 prefs::kPushMessagingAppIdentifierMap); 169 prefs::kPushMessagingAppIdentifierMap);
155 base::DictionaryValue* map = update.Get(); 170 base::DictionaryValue* map = update.Get();
156 map->RemoveWithoutPathExpansion(app_id_, nullptr); 171 map->RemoveWithoutPathExpansion(app_id_, nullptr /* out_value */);
157 } 172 }
158 173
159 void PushMessagingAppIdentifier::DCheckValid() const { 174 void PushMessagingAppIdentifier::DCheckValid() const {
160 const size_t prefix_len = strlen(kPushMessagingAppIdentifierPrefix);
161 DCHECK_GE(service_worker_registration_id_, 0); 175 DCHECK_GE(service_worker_registration_id_, 0);
176
162 DCHECK(origin_.is_valid()); 177 DCHECK(origin_.is_valid());
163 DCHECK_EQ(origin_.GetOrigin(), origin_); 178 DCHECK_EQ(origin_.GetOrigin(), origin_);
179
180 // "wp:"
181 const size_t prefix_len = strlen(kPushMessagingAppIdentifierPrefix);
164 DCHECK_EQ(app_id_.substr(0, prefix_len), kPushMessagingAppIdentifierPrefix); 182 DCHECK_EQ(app_id_.substr(0, prefix_len), kPushMessagingAppIdentifierPrefix);
165 DCHECK(base::IsValidGUID(app_id_.substr(prefix_len, std::string::npos))); 183 // Optional (origin.spec() + '#')
184 if (app_id_.size() != prefix_len + kGuidLength) {
185 const size_t suffix_len = 1 /* kSeparator */ + kGuidLength;
186 DCHECK(app_id_.size() > prefix_len + suffix_len);
187 DCHECK_EQ(origin_,
188 GURL(app_id_.substr(prefix_len,
189 app_id_.size() - prefix_len - suffix_len)));
190 DCHECK_EQ(std::string(1, kSeparator),
191 app_id_.substr(app_id_.size() - suffix_len, 1));
192 }
193 // GUID
194 DCHECK(base::IsValidGUID(app_id_.substr(app_id_.size() - kGuidLength)));
166 } 195 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698