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

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: Simplify DCHECKs 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>
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
21 const char kPushMessagingAppIdentifierPrefix[] = "wp:";
22
19 namespace { 23 namespace {
24
25 // sizeof is strlen + 1 since it's null-terminated.
26 const size_t kPrefixLength = sizeof(kPushMessagingAppIdentifierPrefix) - 1;
27
20 const char kSeparator = '#'; // Ok as only the origin of the url is used. 28 const char kSeparator = '#'; // Ok as only the origin of the url is used.
29 const size_t kGuidLength = 36; // "%08X-%04X-%04X-%04X-%012llX"
30
31 std::string MakePrefValue(const GURL& origin,
32 int64_t service_worker_registration_id) {
33 return origin.spec() + kSeparator
34 + base::Int64ToString(service_worker_registration_id);
35 }
36
37 bool GetOriginAndSWRFromPrefValue(
38 const std::string& pref_value, GURL* origin,
39 int64_t* service_worker_registration_id) {
40 std::vector<std::string> parts;
41 base::SplitString(pref_value, kSeparator, &parts);
42 if (parts.size() != 2)
43 return false;
44
45 if (!base::StringToInt64(parts[1], service_worker_registration_id))
46 return false;
47
48 *origin = GURL(parts[0]);
49 return origin->is_valid();
50 }
51
21 } // namespace 52 } // namespace
22 53
23 const char kPushMessagingAppIdentifierPrefix[] = "wp:";
24
25 // static 54 // static
26 void PushMessagingAppIdentifier::RegisterProfilePrefs( 55 void PushMessagingAppIdentifier::RegisterProfilePrefs(
27 user_prefs::PrefRegistrySyncable* registry) { 56 user_prefs::PrefRegistrySyncable* registry) {
28 registry->RegisterDictionaryPref(prefs::kPushMessagingAppIdentifierMap); 57 registry->RegisterDictionaryPref(prefs::kPushMessagingAppIdentifierMap);
29 } 58 }
30 59
31 // static 60 // static
32 PushMessagingAppIdentifier PushMessagingAppIdentifier::Generate( 61 PushMessagingAppIdentifier PushMessagingAppIdentifier::Generate(
33 const GURL& origin, int64_t service_worker_registration_id) 62 const GURL& origin, int64_t service_worker_registration_id)
34 { 63 {
35 std::string guid = base::GenerateGUID(); 64 std::string guid = base::GenerateGUID();
36 CHECK(!guid.empty()); 65 CHECK(!guid.empty());
37 std::string app_id = kPushMessagingAppIdentifierPrefix + guid; 66 std::string app_id = kPushMessagingAppIdentifierPrefix + origin.spec()
67 + kSeparator + guid;
38 68
39 PushMessagingAppIdentifier app_identifier(app_id, origin, 69 PushMessagingAppIdentifier app_identifier(app_id, origin,
40 service_worker_registration_id); 70 service_worker_registration_id);
41 app_identifier.DCheckValid(); 71 app_identifier.DCheckValid();
42 return app_identifier; 72 return app_identifier;
43 } 73 }
44 74
45 // static 75 // static
46 PushMessagingAppIdentifier PushMessagingAppIdentifier::Get( 76 PushMessagingAppIdentifier PushMessagingAppIdentifier::FindByAppId(
47 Profile* profile, const std::string& app_id) { 77 Profile* profile, const std::string& app_id) {
48 // Workaround crbug.com/461867 in GCM where it converts subtypes to lowercase. 78 // Check case of app_id hasn't been mangled (crbug.com/461867).
49 // TODO(johnme): Remove this when obsolete 79 DCHECK_GE(app_id.size(), kPrefixLength + kGuidLength);
50 const size_t prefix_len = strlen(kPushMessagingAppIdentifierPrefix); 80 DCHECK_EQ(kPushMessagingAppIdentifierPrefix, app_id.substr(0, kPrefixLength));
51 if (app_id.size() < prefix_len) 81 DCHECK_EQ(app_id.substr(app_id.size() - kGuidLength),
52 return PushMessagingAppIdentifier(); 82 StringToUpperASCII(app_id.substr(app_id.size() - kGuidLength)));
53 std::string uppercase_app_id =
54 app_id.substr(0, prefix_len) +
55 StringToUpperASCII(app_id.substr(prefix_len, std::string::npos));
56 83
57 const base::DictionaryValue* map = 84 const base::DictionaryValue* map =
58 profile->GetPrefs()->GetDictionary(prefs::kPushMessagingAppIdentifierMap); 85 profile->GetPrefs()->GetDictionary(prefs::kPushMessagingAppIdentifierMap);
59 86
60 std::string origin_and_sw_id; 87 std::string map_value;
61 if (!map->GetStringWithoutPathExpansion(uppercase_app_id, &origin_and_sw_id)) 88 if (!map->GetStringWithoutPathExpansion(app_id, &map_value))
62 return PushMessagingAppIdentifier(); 89 return PushMessagingAppIdentifier();
63 90
64 std::vector<std::string> parts; 91 GURL origin;
65 base::SplitString(origin_and_sw_id, kSeparator, &parts); 92 int64_t service_worker_registration_id;
66 if (parts.size() != 2) 93 if (!GetOriginAndSWRFromPrefValue(map_value, &origin,
94 &service_worker_registration_id)) {
95 NOTREACHED();
67 return PushMessagingAppIdentifier(); 96 return PushMessagingAppIdentifier();
97 }
68 98
69 GURL origin = GURL(parts[0]); 99 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); 100 service_worker_registration_id);
77 app_identifier.DCheckValid(); 101 app_identifier.DCheckValid();
78 return app_identifier; 102 return app_identifier;
79 } 103 }
80 104
81 // static 105 // static
82 PushMessagingAppIdentifier PushMessagingAppIdentifier::Get( 106 PushMessagingAppIdentifier PushMessagingAppIdentifier::FindByServiceWorker(
83 Profile* profile, const GURL& origin, 107 Profile* profile, const GURL& origin,
84 int64_t service_worker_registration_id) 108 int64_t service_worker_registration_id)
85 { 109 {
86 base::StringValue origin_and_sw_id = base::StringValue(origin.spec() + 110 const base::StringValue pref_value =
87 kSeparator + base::Int64ToString(service_worker_registration_id)); 111 base::StringValue(MakePrefValue(origin, service_worker_registration_id));
88 112
89 const base::DictionaryValue* map = 113 const base::DictionaryValue* map =
90 profile->GetPrefs()->GetDictionary(prefs::kPushMessagingAppIdentifierMap); 114 profile->GetPrefs()->GetDictionary(prefs::kPushMessagingAppIdentifierMap);
91 for (auto it = base::DictionaryValue::Iterator(*map); !it.IsAtEnd(); 115 for (auto it = base::DictionaryValue::Iterator(*map); !it.IsAtEnd();
92 it.Advance()) { 116 it.Advance()) {
93 if (it.value().Equals(&origin_and_sw_id)) 117 if (it.value().Equals(&pref_value))
94 return Get(profile, it.key()); 118 return FindByAppId(profile, it.key());
95 } 119 }
96 return PushMessagingAppIdentifier(); 120 return PushMessagingAppIdentifier();
97 } 121 }
98 122
99 // static 123 // static
100 std::vector<PushMessagingAppIdentifier> PushMessagingAppIdentifier::GetAll( 124 std::vector<PushMessagingAppIdentifier> PushMessagingAppIdentifier::GetAll(
101 Profile* profile) { 125 Profile* profile) {
102 std::vector<PushMessagingAppIdentifier> result; 126 std::vector<PushMessagingAppIdentifier> result;
103 127
104 const base::DictionaryValue* map = 128 const base::DictionaryValue* map =
105 profile->GetPrefs()->GetDictionary(prefs::kPushMessagingAppIdentifierMap); 129 profile->GetPrefs()->GetDictionary(prefs::kPushMessagingAppIdentifierMap);
106 for (auto it = base::DictionaryValue::Iterator(*map); !it.IsAtEnd(); 130 for (auto it = base::DictionaryValue::Iterator(*map); !it.IsAtEnd();
107 it.Advance()) { 131 it.Advance()) {
108 result.push_back(Get(profile, it.key())); 132 result.push_back(FindByAppId(profile, it.key()));
109 } 133 }
110 134
111 return result; 135 return result;
112 } 136 }
113 137
114 PushMessagingAppIdentifier::PushMessagingAppIdentifier() 138 PushMessagingAppIdentifier::PushMessagingAppIdentifier()
115 : origin_(GURL::EmptyGURL()), 139 : origin_(GURL::EmptyGURL()),
116 service_worker_registration_id_(-1) { 140 service_worker_registration_id_(-1) {
117 } 141 }
118 142
(...skipping 11 matching lines...) Expand all
130 154
131 void PushMessagingAppIdentifier::PersistToPrefs(Profile* profile) const { 155 void PushMessagingAppIdentifier::PersistToPrefs(Profile* profile) const {
132 DCheckValid(); 156 DCheckValid();
133 157
134 DictionaryPrefUpdate update(profile->GetPrefs(), 158 DictionaryPrefUpdate update(profile->GetPrefs(),
135 prefs::kPushMessagingAppIdentifierMap); 159 prefs::kPushMessagingAppIdentifierMap);
136 base::DictionaryValue* map = update.Get(); 160 base::DictionaryValue* map = update.Get();
137 161
138 // Delete any stale entry with the same origin and Service Worker 162 // 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). 163 // registration id (hence we ensure there is a 1:1 not 1:many mapping).
140 PushMessagingAppIdentifier old = Get(profile, origin_, 164 PushMessagingAppIdentifier old = FindByServiceWorker(
141 service_worker_registration_id_); 165 profile, origin_, service_worker_registration_id_);
142 if (!old.is_null()) 166 if (!old.is_null())
143 map->RemoveWithoutPathExpansion(old.app_id_, nullptr); 167 map->RemoveWithoutPathExpansion(old.app_id_, nullptr /* out_value */);
144 168
145 std::string origin_and_sw_id = origin_.spec() + kSeparator + 169 map->SetStringWithoutPathExpansion(
146 base::Int64ToString(service_worker_registration_id_); 170 app_id_, MakePrefValue(origin_, service_worker_registration_id_));
147 map->SetStringWithoutPathExpansion(app_id_, origin_and_sw_id);
148 } 171 }
149 172
150 void PushMessagingAppIdentifier::DeleteFromPrefs(Profile* profile) const { 173 void PushMessagingAppIdentifier::DeleteFromPrefs(Profile* profile) const {
151 DCheckValid(); 174 DCheckValid();
152 175
153 DictionaryPrefUpdate update(profile->GetPrefs(), 176 DictionaryPrefUpdate update(profile->GetPrefs(),
154 prefs::kPushMessagingAppIdentifierMap); 177 prefs::kPushMessagingAppIdentifierMap);
155 base::DictionaryValue* map = update.Get(); 178 base::DictionaryValue* map = update.Get();
156 map->RemoveWithoutPathExpansion(app_id_, nullptr); 179 map->RemoveWithoutPathExpansion(app_id_, nullptr /* out_value */);
157 } 180 }
158 181
159 void PushMessagingAppIdentifier::DCheckValid() const { 182 void PushMessagingAppIdentifier::DCheckValid() const {
160 const size_t prefix_len = strlen(kPushMessagingAppIdentifierPrefix);
161 DCHECK_GE(service_worker_registration_id_, 0); 183 DCHECK_GE(service_worker_registration_id_, 0);
184
162 DCHECK(origin_.is_valid()); 185 DCHECK(origin_.is_valid());
163 DCHECK_EQ(origin_.GetOrigin(), origin_); 186 DCHECK_EQ(origin_.GetOrigin(), origin_);
164 DCHECK_EQ(app_id_.substr(0, prefix_len), kPushMessagingAppIdentifierPrefix); 187
165 DCHECK(base::IsValidGUID(app_id_.substr(prefix_len, std::string::npos))); 188 // "wp:"
189 DCHECK_EQ(kPushMessagingAppIdentifierPrefix,
190 app_id_.substr(0, kPrefixLength));
191 // Optional (origin.spec() + '#')
192 if (app_id_.size() != kPrefixLength + kGuidLength) {
193 const size_t suffix_length = 1 /* kSeparator */ + kGuidLength;
194 DCHECK(app_id_.size() > kPrefixLength + suffix_length);
195 DCHECK_EQ(origin_, GURL(app_id_.substr(
196 kPrefixLength, app_id_.size() - kPrefixLength - suffix_length)));
197 DCHECK_EQ(std::string(1, kSeparator),
198 app_id_.substr(app_id_.size() - suffix_length, 1));
199 }
200 // GUID
201 DCHECK(base::IsValidGUID(app_id_.substr(app_id_.size() - kGuidLength)));
166 } 202 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698