diff options
author | harkness <harkness@chromium.org> | 2016-03-21 04:58:17 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-03-21 11:59:32 +0000 |
commit | 35c378e23dccd1bf2ad7da30bc93ffbb152859ea (patch) | |
tree | 08acce4f3b9f8529e1d6ed263ed7f6aa97011698 /content | |
parent | 3bdd60d1af1e6f30b1323e6e3ab3946b170f7444 (diff) | |
download | chromium_src-35c378e23dccd1bf2ad7da30bc93ffbb152859ea.zip chromium_src-35c378e23dccd1bf2ad7da30bc93ffbb152859ea.tar.gz chromium_src-35c378e23dccd1bf2ad7da30bc93ffbb152859ea.tar.bz2 |
Implementation of subscription restrictions.
Currently, chrome requires that app developers provide a "sender_id" tag in the
manifest. This id is generated by the developer console and is not standard
for all browsers.
In the future, the app developer will be able to specify a public key for their
service, which will be registered with the push service and which the push
service can use to validate app services requesting to send messages.
This is a reland of CL https://codereview.chromium.org/1701313002. The only diff is content/renderer/push_messaging/push_messaging_dispatcher.cc where the request_id is set inside the return.
BUG=583753
TBR=avi,mkwst
Cr-Commit-Position: refs/heads/master@{#379045}
Review URL: https://codereview.chromium.org/1801113003
Cr-Commit-Position: refs/heads/master@{#382268}
Diffstat (limited to 'content')
10 files changed, 145 insertions, 80 deletions
diff --git a/content/browser/push_messaging/push_messaging_message_filter.cc b/content/browser/push_messaging/push_messaging_message_filter.cc index a2eb895..ef75724 100644 --- a/content/browser/push_messaging/push_messaging_message_filter.cc +++ b/content/browser/push_messaging/push_messaging_message_filter.cc @@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" +#include "base/command_line.h" #include "base/logging.h" #include "base/macros.h" #include "base/metrics/histogram.h" @@ -27,6 +28,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/common/child_process_host.h" #include "content/public/common/console_message_level.h" +#include "content/public/common/content_switches.h" #include "content/public/common/push_messaging_status.h" #include "third_party/WebKit/public/platform/modules/push_messaging/WebPushPermissionStatus.h" @@ -250,8 +252,7 @@ bool PushMessagingMessageFilter::OnMessageReceived( void PushMessagingMessageFilter::OnSubscribeFromDocument( int render_frame_id, int request_id, - const std::string& sender_id, - bool user_visible, + const PushSubscriptionOptions& options, int64_t service_worker_registration_id) { DCHECK_CURRENTLY_ON(BrowserThread::IO); // TODO(mvanouwerkerk): Validate arguments? @@ -259,7 +260,7 @@ void PushMessagingMessageFilter::OnSubscribeFromDocument( data.request_id = request_id; data.service_worker_registration_id = service_worker_registration_id; data.render_frame_id = render_frame_id; - data.user_visible = user_visible; + data.user_visible = options.user_visible_only; ServiceWorkerRegistration* service_worker_registration = service_worker_context_->GetLiveRegistration( @@ -273,20 +274,20 @@ void PushMessagingMessageFilter::OnSubscribeFromDocument( service_worker_context_->StoreRegistrationUserData( service_worker_registration_id, data.requesting_origin, - kPushSenderIdServiceWorkerKey, sender_id, - base::Bind(&PushMessagingMessageFilter::DidPersistSenderId, - weak_factory_io_to_io_.GetWeakPtr(), data, sender_id)); + kPushSenderIdServiceWorkerKey, options.sender_info, + base::Bind(&PushMessagingMessageFilter::DidPersistSenderInfo, + weak_factory_io_to_io_.GetWeakPtr(), data, options)); } void PushMessagingMessageFilter::OnSubscribeFromWorker( int request_id, int64_t service_worker_registration_id, - bool user_visible) { + const PushSubscriptionOptions& options) { DCHECK_CURRENTLY_ON(BrowserThread::IO); RegisterData data; data.request_id = request_id; data.service_worker_registration_id = service_worker_registration_id; - data.user_visible = user_visible; + data.user_visible = options.user_visible_only; ServiceWorkerRegistration* service_worker_registration = service_worker_context_->GetLiveRegistration( @@ -297,34 +298,35 @@ void PushMessagingMessageFilter::OnSubscribeFromWorker( } data.requesting_origin = service_worker_registration->pattern().GetOrigin(); - // This sender_id will be ignored; instead it will be fetched from storage. - CheckForExistingRegistration(data, std::string() /* sender_id */); + // If there is a sender_info in the subscription options, it will be used, + // otherwise the registration sender_info will be used. + CheckForExistingRegistration(data, options); } -void PushMessagingMessageFilter::DidPersistSenderId( +void PushMessagingMessageFilter::DidPersistSenderInfo( const RegisterData& data, - const std::string& sender_id, + const PushSubscriptionOptions& options, ServiceWorkerStatusCode service_worker_status) { DCHECK_CURRENTLY_ON(BrowserThread::IO); if (service_worker_status != SERVICE_WORKER_OK) SendSubscriptionError(data, PUSH_REGISTRATION_STATUS_STORAGE_ERROR); else - CheckForExistingRegistration(data, sender_id); + CheckForExistingRegistration(data, options); } void PushMessagingMessageFilter::CheckForExistingRegistration( const RegisterData& data, - const std::string& sender_id) { + const PushSubscriptionOptions& options) { DCHECK_CURRENTLY_ON(BrowserThread::IO); service_worker_context_->GetRegistrationUserData( data.service_worker_registration_id, kPushRegistrationIdServiceWorkerKey, base::Bind(&PushMessagingMessageFilter::DidCheckForExistingRegistration, - weak_factory_io_to_io_.GetWeakPtr(), data, sender_id)); + weak_factory_io_to_io_.GetWeakPtr(), data, options)); } void PushMessagingMessageFilter::DidCheckForExistingRegistration( const RegisterData& data, - const std::string& sender_id, + const PushSubscriptionOptions& options, const std::string& push_registration_id, ServiceWorkerStatusCode service_worker_status) { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -345,11 +347,11 @@ void PushMessagingMessageFilter::DidCheckForExistingRegistration( // service_worker_status != SERVICE_WORKER_ERROR_NOT_FOUND instead of // attempting to do a fresh registration? // https://w3c.github.io/push-api/#widl-PushRegistrationManager-register-Promise-PushRegistration - if (data.FromDocument()) { + if (!options.sender_info.empty()) { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(&Core::RegisterOnUI, base::Unretained(ui_core_.get()), data, - sender_id)); + options.sender_info)); } else { service_worker_context_->GetRegistrationUserData( data.service_worker_registration_id, kPushSenderIdServiceWorkerKey, @@ -392,7 +394,7 @@ void PushMessagingMessageFilter::DidGetSenderIdFromStorage( void PushMessagingMessageFilter::Core::RegisterOnUI( const PushMessagingMessageFilter::RegisterData& data, - const std::string& sender_id) { + const std::string& sender_info) { DCHECK_CURRENTLY_ON(BrowserThread::UI); PushMessagingService* push_service = service(); if (!push_service) { @@ -438,16 +440,18 @@ void PushMessagingMessageFilter::Core::RegisterOnUI( return; } + PushSubscriptionOptions options; + options.user_visible_only = data.user_visible; + options.sender_info = sender_info; if (data.FromDocument()) { push_service->SubscribeFromDocument( - data.requesting_origin, data.service_worker_registration_id, sender_id, - render_process_id_, data.render_frame_id, data.user_visible, + data.requesting_origin, data.service_worker_registration_id, + render_process_id_, data.render_frame_id, options, base::Bind(&Core::DidRegister, weak_factory_ui_to_ui_.GetWeakPtr(), data)); } else { push_service->SubscribeFromWorker( - data.requesting_origin, data.service_worker_registration_id, sender_id, - data.user_visible, + data.requesting_origin, data.service_worker_registration_id, options, base::Bind(&Core::DidRegister, weak_factory_ui_to_ui_.GetWeakPtr(), data)); } diff --git a/content/browser/push_messaging/push_messaging_message_filter.h b/content/browser/push_messaging/push_messaging_message_filter.h index aba0b34..d2db18a 100644 --- a/content/browser/push_messaging/push_messaging_message_filter.h +++ b/content/browser/push_messaging/push_messaging_message_filter.h @@ -23,6 +23,7 @@ namespace content { class PushMessagingService; class ServiceWorkerContextWrapper; +struct PushSubscriptionOptions; extern const char kPushSenderIdServiceWorkerKey[]; extern const char kPushRegistrationIdServiceWorkerKey[]; @@ -50,26 +51,25 @@ class PushMessagingMessageFilter : public BrowserMessageFilter { void OnSubscribeFromDocument(int render_frame_id, int request_id, - const std::string& sender_id, - bool user_visible, + const PushSubscriptionOptions& options, int64_t service_worker_registration_id); void OnSubscribeFromWorker(int request_id, int64_t service_worker_registration_id, - bool user_visible); + const PushSubscriptionOptions& options); - void DidPersistSenderId(const RegisterData& data, - const std::string& sender_id, - ServiceWorkerStatusCode service_worker_status); + void DidPersistSenderInfo(const RegisterData& data, + const PushSubscriptionOptions& options, + ServiceWorkerStatusCode service_worker_status); // sender_id is ignored if data.FromDocument() is false. void CheckForExistingRegistration(const RegisterData& data, - const std::string& sender_id); + const PushSubscriptionOptions& options); // sender_id is ignored if data.FromDocument() is false. void DidCheckForExistingRegistration( const RegisterData& data, - const std::string& sender_id, + const PushSubscriptionOptions& options, const std::string& push_registration_id, ServiceWorkerStatusCode service_worker_status); diff --git a/content/child/push_messaging/push_provider.cc b/content/child/push_messaging/push_provider.cc index f8e807d..254d855 100644 --- a/content/child/push_messaging/push_provider.cc +++ b/content/child/push_messaging/push_provider.cc @@ -75,8 +75,11 @@ void PushProvider::subscribe( subscription_callbacks_.AddWithID(callbacks, request_id); int64_t service_worker_registration_id = GetServiceWorkerRegistrationId(service_worker_registration); + PushSubscriptionOptions content_options; + content_options.user_visible_only = options.userVisibleOnly; + content_options.sender_info = options.applicationServerKey.utf8(); thread_safe_sender_->Send(new PushMessagingHostMsg_SubscribeFromWorker( - request_id, service_worker_registration_id, options.userVisibleOnly)); + request_id, service_worker_registration_id, content_options)); } void PushProvider::unsubscribe( diff --git a/content/common/push_messaging_messages.h b/content/common/push_messaging_messages.h index 38a39e8..df88b2f 100644 --- a/content/common/push_messaging_messages.h +++ b/content/common/push_messaging_messages.h @@ -8,6 +8,7 @@ #include <stdint.h> #include "content/public/common/push_messaging_status.h" +#include "content/public/common/push_subscription_options.h" #include "ipc/ipc_message_macros.h" #include "third_party/WebKit/public/platform/modules/push_messaging/WebPushError.h" #include "third_party/WebKit/public/platform/modules/push_messaging/WebPushPermissionStatus.h" @@ -29,6 +30,11 @@ IPC_ENUM_TRAITS_MAX_VALUE( blink::WebPushError::ErrorType, blink::WebPushError::ErrorType::ErrorTypeLast) +IPC_STRUCT_TRAITS_BEGIN(content::PushSubscriptionOptions) + IPC_STRUCT_TRAITS_MEMBER(user_visible_only) + IPC_STRUCT_TRAITS_MEMBER(sender_info) +IPC_STRUCT_TRAITS_END() + // Messages sent from the browser to the child process. IPC_MESSAGE_ROUTED4(PushMessagingMsg_SubscribeFromDocumentSuccess, @@ -80,17 +86,16 @@ IPC_MESSAGE_CONTROL2(PushMessagingMsg_GetPermissionStatusError, // Messages sent from the child process to the browser. -IPC_MESSAGE_CONTROL5(PushMessagingHostMsg_SubscribeFromDocument, +IPC_MESSAGE_CONTROL4(PushMessagingHostMsg_SubscribeFromDocument, int32_t /* render_frame_id */, int32_t /* request_id */, - std::string /* sender_id */, - bool /* user_visible */, + content::PushSubscriptionOptions /* options */, int64_t /* service_worker_registration_id */) IPC_MESSAGE_CONTROL3(PushMessagingHostMsg_SubscribeFromWorker, int32_t /* request_id */, int64_t /* service_worker_registration_id */, - bool /* user_visible */) + content::PushSubscriptionOptions /* options */) IPC_MESSAGE_CONTROL2(PushMessagingHostMsg_Unsubscribe, int32_t /* request_id */, diff --git a/content/public/browser/push_messaging_service.h b/content/public/browser/push_messaging_service.h index 86aa34e..993e281 100644 --- a/content/public/browser/push_messaging_service.h +++ b/content/public/browser/push_messaging_service.h @@ -19,6 +19,7 @@ namespace content { class BrowserContext; class ServiceWorkerContext; +struct PushSubscriptionOptions; // A push service-agnostic interface that the Push API uses for talking to // push messaging services like GCM. Must only be used on the UI thread. @@ -49,24 +50,22 @@ class CONTENT_EXPORT PushMessagingService { // origins and push registrations. virtual GURL GetPushEndpoint() = 0; - // Subscribe the given |sender_id| with the push messaging service in a - // document context. The frame is known and a permission UI may be displayed - // to the user. + // Subscribe the given |options.sender_info| with the push messaging service + // in a document context. The frame is known and a permission UI may be + // displayed to the user. virtual void SubscribeFromDocument(const GURL& requesting_origin, int64_t service_worker_registration_id, - const std::string& sender_id, int renderer_id, int render_frame_id, - bool user_visible, + const PushSubscriptionOptions& options, const RegisterCallback& callback) = 0; - // Subscribe the given |sender_id| with the push messaging service. The frame - // is not known so if permission was not previously granted by the user this - // request should fail. + // Subscribe the given |options.sender_info| with the push messaging service. + // The frame is not known so if permission was not previously granted by the + // user this request should fail. virtual void SubscribeFromWorker(const GURL& requesting_origin, int64_t service_worker_registration_id, - const std::string& sender_id, - bool user_visible, + const PushSubscriptionOptions& options, const RegisterCallback& callback) = 0; // Retrieves the encryption information associated with the subscription diff --git a/content/public/common/push_subscription_options.h b/content/public/common/push_subscription_options.h new file mode 100644 index 0000000..1a2da0a --- /dev/null +++ b/content/public/common/push_subscription_options.h @@ -0,0 +1,32 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_PUBLIC_COMMON_PUSH_SUBSCRIPTION_OPTIONS_H_ +#define CONTENT_PUBLIC_COMMON_PUSH_SUBSCRIPTION_OPTIONS_H_ + +#include <string> + +#include "content/common/content_export.h" + +namespace content { + +// Structure to hold the options provided from the web app developer as +// part of asking for a new push subscription. +struct CONTENT_EXPORT PushSubscriptionOptions { + PushSubscriptionOptions() {} + ~PushSubscriptionOptions() {} + + // Whether or not the app developer agrees to provide user visible + // notifications whenever they receive a push message. + bool user_visible_only = false; + + // The unique identifier of the application service which is used to + // verify the push message before delivery. This could either be an ID + // assigned by the developer console or the app server's public key. + std::string sender_info; +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_COMMON_CONTENT_PUSH_SUBSCRIPTION_OPTIONS_H_ diff --git a/content/renderer/push_messaging/push_messaging_dispatcher.cc b/content/renderer/push_messaging/push_messaging_dispatcher.cc index d107043..f505f93 100644 --- a/content/renderer/push_messaging/push_messaging_dispatcher.cc +++ b/content/renderer/push_messaging/push_messaging_dispatcher.cc @@ -44,46 +44,63 @@ void PushMessagingDispatcher::subscribe( blink::WebPushSubscriptionCallbacks* callbacks) { DCHECK(service_worker_registration); DCHECK(callbacks); - RenderFrameImpl::FromRoutingID(routing_id()) - ->manifest_manager() - ->GetManifest(base::Bind( - &PushMessagingDispatcher::DoSubscribe, base::Unretained(this), - service_worker_registration, options, callbacks)); + // If a developer provided an application server key in |options|, skip + // fetching the manifest. + if (options.applicationServerKey.isEmpty()) { + RenderFrameImpl::FromRoutingID(routing_id()) + ->manifest_manager() + ->GetManifest(base::Bind( + &PushMessagingDispatcher::DidGetManifest, base::Unretained(this), + service_worker_registration, options, callbacks)); + } else { + PushSubscriptionOptions content_options; + content_options.user_visible_only = options.userVisibleOnly; + content_options.sender_info = options.applicationServerKey.utf8(); + DoSubscribe(service_worker_registration, content_options, callbacks); + } } -void PushMessagingDispatcher::DoSubscribe( +void PushMessagingDispatcher::DidGetManifest( blink::WebServiceWorkerRegistration* service_worker_registration, const blink::WebPushSubscriptionOptions& options, blink::WebPushSubscriptionCallbacks* callbacks, const Manifest& manifest) { - int request_id = subscription_callbacks_.Add(callbacks); - int64_t service_worker_registration_id = - static_cast<WebServiceWorkerRegistrationImpl*>( - service_worker_registration) - ->registration_id(); - + // Get the sender_info from the manifest since it wasn't provided by + // the caller. if (manifest.IsEmpty()) { + int request_id = subscription_callbacks_.Add(callbacks); OnSubscribeFromDocumentError( request_id, PUSH_REGISTRATION_STATUS_MANIFEST_EMPTY_OR_MISSING); return; } - std::string sender_id = - manifest.gcm_sender_id.is_null() - ? std::string() - : base::UTF16ToUTF8(manifest.gcm_sender_id.string()); - if (sender_id.empty()) { + PushSubscriptionOptions content_options; + content_options.user_visible_only = options.userVisibleOnly; + if (!manifest.gcm_sender_id.is_null()) { + content_options.sender_info = + base::UTF16ToUTF8(manifest.gcm_sender_id.string()); + } + + DoSubscribe(service_worker_registration, content_options, callbacks); +} + +void PushMessagingDispatcher::DoSubscribe( + blink::WebServiceWorkerRegistration* service_worker_registration, + const PushSubscriptionOptions& options, + blink::WebPushSubscriptionCallbacks* callbacks) { + int request_id = subscription_callbacks_.Add(callbacks); + int64_t service_worker_registration_id = + static_cast<WebServiceWorkerRegistrationImpl*>( + service_worker_registration) + ->registration_id(); + + if (options.sender_info.empty()) { OnSubscribeFromDocumentError(request_id, PUSH_REGISTRATION_STATUS_NO_SENDER_ID); return; } - Send(new PushMessagingHostMsg_SubscribeFromDocument( - routing_id(), request_id, - manifest.gcm_sender_id.is_null() - ? std::string() - : base::UTF16ToUTF8(manifest.gcm_sender_id.string()), - options.userVisibleOnly, service_worker_registration_id)); + routing_id(), request_id, options, service_worker_registration_id)); } void PushMessagingDispatcher::OnSubscribeFromDocumentSuccess( diff --git a/content/renderer/push_messaging/push_messaging_dispatcher.h b/content/renderer/push_messaging/push_messaging_dispatcher.h index ca6610b..71294e2 100644 --- a/content/renderer/push_messaging/push_messaging_dispatcher.h +++ b/content/renderer/push_messaging/push_messaging_dispatcher.h @@ -29,6 +29,7 @@ class Message; namespace content { struct Manifest; +struct PushSubscriptionOptions; class PushMessagingDispatcher : public RenderFrameObserver, public blink::WebPushClient { @@ -46,12 +47,17 @@ class PushMessagingDispatcher : public RenderFrameObserver, const blink::WebPushSubscriptionOptions& options, blink::WebPushSubscriptionCallbacks* callbacks) override; - void DoSubscribe( + void DidGetManifest( blink::WebServiceWorkerRegistration* service_worker_registration, const blink::WebPushSubscriptionOptions& options, blink::WebPushSubscriptionCallbacks* callbacks, const Manifest& manifest); + void DoSubscribe( + blink::WebServiceWorkerRegistration* service_worker_registration, + const PushSubscriptionOptions& options, + blink::WebPushSubscriptionCallbacks* callbacks); + void OnSubscribeFromDocumentSuccess(int32_t request_id, const GURL& endpoint, const std::vector<uint8_t>& p256dh, diff --git a/content/shell/browser/layout_test/layout_test_push_messaging_service.cc b/content/shell/browser/layout_test/layout_test_push_messaging_service.cc index 11554e9..c346a08 100644 --- a/content/shell/browser/layout_test/layout_test_push_messaging_service.cc +++ b/content/shell/browser/layout_test/layout_test_push_messaging_service.cc @@ -8,6 +8,7 @@ #include "base/logging.h" #include "base/macros.h" #include "content/public/browser/permission_type.h" +#include "content/public/common/push_subscription_options.h" #include "content/shell/browser/layout_test/layout_test_browser_context.h" #include "content/shell/browser/layout_test/layout_test_content_browser_client.h" #include "content/shell/browser/layout_test/layout_test_permission_manager.h" @@ -67,22 +68,20 @@ GURL LayoutTestPushMessagingService::GetPushEndpoint() { void LayoutTestPushMessagingService::SubscribeFromDocument( const GURL& requesting_origin, int64_t service_worker_registration_id, - const std::string& sender_id, int renderer_id, int render_frame_id, - bool user_visible, + const PushSubscriptionOptions& options, const PushMessagingService::RegisterCallback& callback) { SubscribeFromWorker(requesting_origin, service_worker_registration_id, - sender_id, user_visible, callback); + options, callback); } void LayoutTestPushMessagingService::SubscribeFromWorker( const GURL& requesting_origin, int64_t service_worker_registration_id, - const std::string& sender_id, - bool user_visible, + const PushSubscriptionOptions& options, const PushMessagingService::RegisterCallback& callback) { - if (GetPermissionStatus(requesting_origin, user_visible) == + if (GetPermissionStatus(requesting_origin, options.user_visible_only) == blink::WebPushPermissionStatusGranted) { std::vector<uint8_t> p256dh( kTestP256Key, kTestP256Key + arraysize(kTestP256Key)); diff --git a/content/shell/browser/layout_test/layout_test_push_messaging_service.h b/content/shell/browser/layout_test/layout_test_push_messaging_service.h index eb5e7e4..5e5a7a48 100644 --- a/content/shell/browser/layout_test/layout_test_push_messaging_service.h +++ b/content/shell/browser/layout_test/layout_test_push_messaging_service.h @@ -17,6 +17,8 @@ namespace content { +struct PushSubscriptionOptions; + class LayoutTestPushMessagingService : public PushMessagingService { public: LayoutTestPushMessagingService(); @@ -27,16 +29,14 @@ class LayoutTestPushMessagingService : public PushMessagingService { void SubscribeFromDocument( const GURL& requesting_origin, int64_t service_worker_registration_id, - const std::string& sender_id, int renderer_id, int render_frame_id, - bool user_visible, + const PushSubscriptionOptions& options, const PushMessagingService::RegisterCallback& callback) override; void SubscribeFromWorker( const GURL& requesting_origin, int64_t service_worker_registration_id, - const std::string& sender_id, - bool user_visible, + const PushSubscriptionOptions& options, const PushMessagingService::RegisterCallback& callback) override; void GetEncryptionInfo( const GURL& origin, |