Commit 0c5037ad authored by Wez's avatar Wez Committed by Commit Bot

[fuchsia] Grant web permissions to Frame contents regardless of origin.

Temporarily allow the default permissions granted to each Frame to be
configured by passing a wildcard origin to SetPermissionState().

Bug: b/170198665, 1136994
Change-Id: I653622a5bbe8d8f7d08bc4f1c0fa6da94dc207cf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2452633
Commit-Queue: Wez <wez@chromium.org>
Reviewed-by: default avatarDavid Dorwin <ddorwin@chromium.org>
Auto-Submit: Wez <wez@chromium.org>
Cr-Commit-Position: refs/heads/master@{#817118}
parent 22b2cdc0
...@@ -894,14 +894,6 @@ void FrameImpl::SetPermissionState( ...@@ -894,14 +894,6 @@ void FrameImpl::SetPermissionState(
return; return;
} }
auto web_origin = ParseAndValidateWebOrigin(web_origin_string);
if (!web_origin) {
LOG(ERROR) << "SetPermissionState() called with invalid web_origin: "
<< web_origin_string;
CloseAndDestroyFrame(ZX_ERR_INVALID_ARGS);
return;
}
content::PermissionType type = content::PermissionType type =
FidlPermissionTypeToContentPermissionType(fidl_permission.type()); FidlPermissionTypeToContentPermissionType(fidl_permission.type());
...@@ -910,6 +902,23 @@ void FrameImpl::SetPermissionState( ...@@ -910,6 +902,23 @@ void FrameImpl::SetPermissionState(
? blink::mojom::PermissionStatus::GRANTED ? blink::mojom::PermissionStatus::GRANTED
: blink::mojom::PermissionStatus::DENIED; : blink::mojom::PermissionStatus::DENIED;
// TODO(crbug.com/1136994): Remove this once the PermissionManager API is
// available.
if (web_origin_string == "*" &&
type == content::PermissionType::PROTECTED_MEDIA_IDENTIFIER) {
permission_controller_.SetDefaultPermissionState(type, state);
return;
}
// Handle per-origin permissions specifications.
auto web_origin = ParseAndValidateWebOrigin(web_origin_string);
if (!web_origin) {
LOG(ERROR) << "SetPermissionState() called with invalid web_origin: "
<< web_origin_string;
CloseAndDestroyFrame(ZX_ERR_INVALID_ARGS);
return;
}
permission_controller_.SetPermissionState(type, web_origin.value(), state); permission_controller_.SetPermissionState(type, web_origin.value(), state);
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include "base/check_op.h" #include "base/check_op.h"
#include "url/origin.h" #include "url/origin.h"
using PermissionState = blink::mojom::PermissionStatus; using PermissionStatus = blink::mojom::PermissionStatus;
using PermissionType = content::PermissionType; using PermissionType = content::PermissionType;
namespace { namespace {
...@@ -18,59 +18,90 @@ size_t GetPermissionIndex(PermissionType type) { ...@@ -18,59 +18,90 @@ size_t GetPermissionIndex(PermissionType type) {
return index; return index;
} }
constexpr PermissionStatus kDefaultPerOriginStatus = PermissionStatus::ASK;
} // namespace } // namespace
FramePermissionController::PermissionSet::PermissionSet() { FramePermissionController::PermissionSet::PermissionSet(
for (auto& permission : permission_state) { PermissionStatus initial_state) {
permission = PermissionState::DENIED; for (auto& permission : permission_states) {
permission = initial_state;
} }
} }
FramePermissionController::PermissionSet::PermissionSet(
const PermissionSet& other) = default;
FramePermissionController::PermissionSet&
FramePermissionController::PermissionSet::operator=(
const PermissionSet& other) = default;
FramePermissionController::FramePermissionController() = default; FramePermissionController::FramePermissionController() = default;
FramePermissionController::~FramePermissionController() = default; FramePermissionController::~FramePermissionController() = default;
void FramePermissionController::SetPermissionState(PermissionType permission, void FramePermissionController::SetPermissionState(PermissionType permission,
const url::Origin& origin, const url::Origin& origin,
PermissionState state) { PermissionStatus state) {
auto it = per_origin_permissions_.find(origin); auto it = per_origin_permissions_.find(origin);
if (it == per_origin_permissions_.end()) { if (it == per_origin_permissions_.end()) {
// All permissions are denied by default. // Don't create a PermissionSet for |origin| if |state| is set to the
if (state == PermissionState::DENIED) // per-origin default, since that would have no effect.
if (state == kDefaultPerOriginStatus)
return; return;
it = per_origin_permissions_.insert(std::make_pair(origin, PermissionSet())) it = per_origin_permissions_
.insert(
std::make_pair(origin, PermissionSet(kDefaultPerOriginStatus)))
.first; .first;
} }
it->second.permission_state[GetPermissionIndex(permission)] = state; it->second.permission_states[GetPermissionIndex(permission)] = state;
} }
PermissionState FramePermissionController::GetPermissionState( void FramePermissionController::SetDefaultPermissionState(
PermissionType permission,
PermissionStatus state) {
DCHECK(state != PermissionStatus::ASK);
default_permissions_.permission_states[GetPermissionIndex(permission)] =
state;
}
PermissionStatus FramePermissionController::GetPermissionState(
PermissionType permission, PermissionType permission,
const url::Origin& origin) { const url::Origin& origin) {
auto it = per_origin_permissions_.find(origin); PermissionSet effective = GetEffectivePermissionsForOrigin(origin);
if (it == per_origin_permissions_.end()) { return effective.permission_states[GetPermissionIndex(permission)];
return PermissionState::DENIED;
}
return it->second.permission_state[GetPermissionIndex(permission)];
} }
void FramePermissionController::RequestPermissions( void FramePermissionController::RequestPermissions(
const std::vector<PermissionType>& permissions, const std::vector<PermissionType>& permissions,
const url::Origin& origin, const url::Origin& origin,
bool user_gesture, bool user_gesture,
base::OnceCallback<void(const std::vector<PermissionState>&)> callback) { base::OnceCallback<void(const std::vector<PermissionStatus>&)> callback) {
std::vector<PermissionState> result; std::vector<PermissionStatus> result;
result.reserve(permissions.size());
PermissionSet effective = GetEffectivePermissionsForOrigin(origin);
for (auto& permission : permissions) {
result.push_back(
effective.permission_states[GetPermissionIndex(permission)]);
}
std::move(callback).Run(result);
}
FramePermissionController::PermissionSet
FramePermissionController::GetEffectivePermissionsForOrigin(
const url::Origin& origin) {
PermissionSet result = default_permissions_;
auto it = per_origin_permissions_.find(origin); auto it = per_origin_permissions_.find(origin);
if (it == per_origin_permissions_.end()) { if (it != per_origin_permissions_.end()) {
result.resize(permissions.size(), PermissionState::DENIED); // Apply per-origin GRANTED and DENIED states. Permissions with the ASK
} else { // state defer to the defaults.
result.reserve(permissions.size()); for (size_t i = 0; i < it->second.permission_states.size(); ++i) {
for (auto& permission : permissions) { if (it->second.permission_states[i] != kDefaultPerOriginStatus)
result.push_back( result.permission_states[i] = it->second.permission_states[i];
it->second.permission_state[GetPermissionIndex(permission)]);
} }
} }
std::move(callback).Run(result); return result;
} }
...@@ -5,10 +5,11 @@ ...@@ -5,10 +5,11 @@
#ifndef FUCHSIA_ENGINE_BROWSER_FRAME_PERMISSION_CONTROLLER_H_ #ifndef FUCHSIA_ENGINE_BROWSER_FRAME_PERMISSION_CONTROLLER_H_
#define FUCHSIA_ENGINE_BROWSER_FRAME_PERMISSION_CONTROLLER_H_ #define FUCHSIA_ENGINE_BROWSER_FRAME_PERMISSION_CONTROLLER_H_
#include <map> #include <array>
#include <vector> #include <vector>
#include "base/callback_forward.h" #include "base/callback_forward.h"
#include "base/containers/flat_map.h"
#include "content/public/browser/permission_type.h" #include "content/public/browser/permission_type.h"
#include "third_party/blink/public/mojom/permissions/permission_status.mojom.h" #include "third_party/blink/public/mojom/permissions/permission_status.mojom.h"
...@@ -31,6 +32,14 @@ class FramePermissionController { ...@@ -31,6 +32,14 @@ class FramePermissionController {
const url::Origin& origin, const url::Origin& origin,
blink::mojom::PermissionStatus state); blink::mojom::PermissionStatus state);
// Sets the default |state| for the specified |permission|. Setting |state| to
// ASK causes the |default_permissions_| state to be used for |permission| for
// this origin.
// TODO(crbug.com/1063094): Allow ASK to be the default state, to indicate
// that the user should be prompted.
void SetDefaultPermissionState(content::PermissionType permission,
blink::mojom::PermissionStatus state);
// Returns current permission state of the specified |permission| and // Returns current permission state of the specified |permission| and
// |origin|. // |origin|.
blink::mojom::PermissionStatus GetPermissionState( blink::mojom::PermissionStatus GetPermissionState(
...@@ -41,8 +50,8 @@ class FramePermissionController { ...@@ -41,8 +50,8 @@ class FramePermissionController {
// is resolved, the |callback| is called with a list of status values, one for // is resolved, the |callback| is called with a list of status values, one for
// each value in |permissions|, in the same order. // each value in |permissions|, in the same order.
// //
// TODO(crbug.com/922833): Current implementation doesn't actually prompt the // TODO(crbug.com/1063094): Current implementation doesn't actually prompt the
// user: all permissions in the PROMPT state are denied silently. Define // user: all permissions in the ASK state are denied silently. Define
// fuchsia.web.PermissionManager protocol and use it to request permissions. // fuchsia.web.PermissionManager protocol and use it to request permissions.
void RequestPermissions( void RequestPermissions(
const std::vector<content::PermissionType>& permissions, const std::vector<content::PermissionType>& permissions,
...@@ -53,13 +62,26 @@ class FramePermissionController { ...@@ -53,13 +62,26 @@ class FramePermissionController {
private: private:
struct PermissionSet { struct PermissionSet {
PermissionSet(); // Initializes all permissions with |initial_state|.
explicit PermissionSet(blink::mojom::PermissionStatus initial_state);
PermissionSet(const PermissionSet& other);
PermissionSet& operator=(const PermissionSet& other);
blink::mojom::PermissionStatus std::array<blink::mojom::PermissionStatus,
permission_state[static_cast<int>(content::PermissionType::NUM)]; static_cast<int>(content::PermissionType::NUM)>
permission_states;
}; };
std::map<url::Origin, PermissionSet> per_origin_permissions_; // Returns the effective PermissionStatus for |origin|. If the per-|origin|
// state is ASK, or there are no specific permissions set for |origin|, then
// the default permission status takes effect. This means that it is not
// currently possible to set a default of GRANTED/DENIED, and to override that
// to ASK for specific origins.
PermissionSet GetEffectivePermissionsForOrigin(const url::Origin& origin);
base::flat_map<url::Origin, PermissionSet> per_origin_permissions_;
PermissionSet default_permissions_{blink::mojom::PermissionStatus::DENIED};
}; };
#endif // FUCHSIA_ENGINE_BROWSER_FRAME_PERMISSION_CONTROLLER_H_ #endif // FUCHSIA_ENGINE_BROWSER_FRAME_PERMISSION_CONTROLLER_H_
\ No newline at end of file
...@@ -136,14 +136,22 @@ void CastComponent::StartComponent() { ...@@ -136,14 +136,22 @@ void CastComponent::StartComponent() {
application_controller_ = std::make_unique<ApplicationControllerImpl>( application_controller_ = std::make_unique<ApplicationControllerImpl>(
frame(), application_context_.get()); frame(), application_context_.get());
// Pass application permissions to the frame. // Apply application-specific web permissions to the fuchsia.web.Frame.
if (application_config_.has_permissions()) { if (application_config_.has_permissions()) {
std::string origin = GURL(application_config_.web_url()).GetOrigin().spec(); // TODO(crbug.com/1136994): Replace this with the PermissionManager API
// when available.
const std::string origin =
GURL(application_config_.web_url()).GetOrigin().spec();
for (auto& permission : application_config_.permissions()) { for (auto& permission : application_config_.permissions()) {
fuchsia::web::PermissionDescriptor permission_clone; fuchsia::web::PermissionDescriptor permission_clone;
zx_status_t status = permission.Clone(&permission_clone); zx_status_t status = permission.Clone(&permission_clone);
ZX_DCHECK(status == ZX_OK, status); ZX_DCHECK(status == ZX_OK, status);
frame()->SetPermissionState(std::move(permission_clone), origin, const bool all_origins =
permission_clone.has_type() &&
(permission_clone.type() ==
fuchsia::web::PermissionType::PROTECTED_MEDIA_IDENTIFIER);
frame()->SetPermissionState(std::move(permission_clone),
all_origins ? "*" : origin,
fuchsia::web::PermissionState::GRANTED); fuchsia::web::PermissionState::GRANTED);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment