[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: David Dorwin <ddorwin@chromium.org>
Auto-Submit: Wez <wez@chromium.org>
Cr-Commit-Position: refs/heads/master@{#817118}
This commit is contained in:
fuchsia
engine
runners
@ -894,14 +894,6 @@ void FrameImpl::SetPermissionState(
|
||||
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 =
|
||||
FidlPermissionTypeToContentPermissionType(fidl_permission.type());
|
||||
|
||||
@ -910,6 +902,23 @@ void FrameImpl::SetPermissionState(
|
||||
? blink::mojom::PermissionStatus::GRANTED
|
||||
: 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);
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "base/check_op.h"
|
||||
#include "url/origin.h"
|
||||
|
||||
using PermissionState = blink::mojom::PermissionStatus;
|
||||
using PermissionStatus = blink::mojom::PermissionStatus;
|
||||
using PermissionType = content::PermissionType;
|
||||
|
||||
namespace {
|
||||
@ -18,59 +18,90 @@ size_t GetPermissionIndex(PermissionType type) {
|
||||
return index;
|
||||
}
|
||||
|
||||
constexpr PermissionStatus kDefaultPerOriginStatus = PermissionStatus::ASK;
|
||||
|
||||
} // namespace
|
||||
|
||||
FramePermissionController::PermissionSet::PermissionSet() {
|
||||
for (auto& permission : permission_state) {
|
||||
permission = PermissionState::DENIED;
|
||||
FramePermissionController::PermissionSet::PermissionSet(
|
||||
PermissionStatus initial_state) {
|
||||
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;
|
||||
|
||||
void FramePermissionController::SetPermissionState(PermissionType permission,
|
||||
const url::Origin& origin,
|
||||
PermissionState state) {
|
||||
PermissionStatus state) {
|
||||
auto it = per_origin_permissions_.find(origin);
|
||||
if (it == per_origin_permissions_.end()) {
|
||||
// All permissions are denied by default.
|
||||
if (state == PermissionState::DENIED)
|
||||
// Don't create a PermissionSet for |origin| if |state| is set to the
|
||||
// per-origin default, since that would have no effect.
|
||||
if (state == kDefaultPerOriginStatus)
|
||||
return;
|
||||
|
||||
it = per_origin_permissions_.insert(std::make_pair(origin, PermissionSet()))
|
||||
it = per_origin_permissions_
|
||||
.insert(
|
||||
std::make_pair(origin, PermissionSet(kDefaultPerOriginStatus)))
|
||||
.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,
|
||||
const url::Origin& origin) {
|
||||
auto it = per_origin_permissions_.find(origin);
|
||||
if (it == per_origin_permissions_.end()) {
|
||||
return PermissionState::DENIED;
|
||||
}
|
||||
return it->second.permission_state[GetPermissionIndex(permission)];
|
||||
PermissionSet effective = GetEffectivePermissionsForOrigin(origin);
|
||||
return effective.permission_states[GetPermissionIndex(permission)];
|
||||
}
|
||||
|
||||
void FramePermissionController::RequestPermissions(
|
||||
const std::vector<PermissionType>& permissions,
|
||||
const url::Origin& origin,
|
||||
bool user_gesture,
|
||||
base::OnceCallback<void(const std::vector<PermissionState>&)> callback) {
|
||||
std::vector<PermissionState> result;
|
||||
base::OnceCallback<void(const std::vector<PermissionStatus>&)> callback) {
|
||||
std::vector<PermissionStatus> result;
|
||||
result.reserve(permissions.size());
|
||||
|
||||
auto it = per_origin_permissions_.find(origin);
|
||||
if (it == per_origin_permissions_.end()) {
|
||||
result.resize(permissions.size(), PermissionState::DENIED);
|
||||
} else {
|
||||
result.reserve(permissions.size());
|
||||
for (auto& permission : permissions) {
|
||||
result.push_back(
|
||||
it->second.permission_state[GetPermissionIndex(permission)]);
|
||||
}
|
||||
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);
|
||||
if (it != per_origin_permissions_.end()) {
|
||||
// Apply per-origin GRANTED and DENIED states. Permissions with the ASK
|
||||
// state defer to the defaults.
|
||||
for (size_t i = 0; i < it->second.permission_states.size(); ++i) {
|
||||
if (it->second.permission_states[i] != kDefaultPerOriginStatus)
|
||||
result.permission_states[i] = it->second.permission_states[i];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -5,10 +5,11 @@
|
||||
#ifndef FUCHSIA_ENGINE_BROWSER_FRAME_PERMISSION_CONTROLLER_H_
|
||||
#define FUCHSIA_ENGINE_BROWSER_FRAME_PERMISSION_CONTROLLER_H_
|
||||
|
||||
#include <map>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
#include "base/callback_forward.h"
|
||||
#include "base/containers/flat_map.h"
|
||||
#include "content/public/browser/permission_type.h"
|
||||
#include "third_party/blink/public/mojom/permissions/permission_status.mojom.h"
|
||||
|
||||
@ -31,6 +32,14 @@ class FramePermissionController {
|
||||
const url::Origin& origin,
|
||||
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
|
||||
// |origin|.
|
||||
blink::mojom::PermissionStatus GetPermissionState(
|
||||
@ -41,8 +50,8 @@ class FramePermissionController {
|
||||
// is resolved, the |callback| is called with a list of status values, one for
|
||||
// each value in |permissions|, in the same order.
|
||||
//
|
||||
// TODO(crbug.com/922833): Current implementation doesn't actually prompt the
|
||||
// user: all permissions in the PROMPT state are denied silently. Define
|
||||
// TODO(crbug.com/1063094): Current implementation doesn't actually prompt the
|
||||
// user: all permissions in the ASK state are denied silently. Define
|
||||
// fuchsia.web.PermissionManager protocol and use it to request permissions.
|
||||
void RequestPermissions(
|
||||
const std::vector<content::PermissionType>& permissions,
|
||||
@ -53,13 +62,26 @@ class FramePermissionController {
|
||||
|
||||
private:
|
||||
struct PermissionSet {
|
||||
PermissionSet();
|
||||
// Initializes all permissions with |initial_state|.
|
||||
explicit PermissionSet(blink::mojom::PermissionStatus initial_state);
|
||||
|
||||
blink::mojom::PermissionStatus
|
||||
permission_state[static_cast<int>(content::PermissionType::NUM)];
|
||||
PermissionSet(const PermissionSet& other);
|
||||
PermissionSet& operator=(const PermissionSet& other);
|
||||
|
||||
std::array<blink::mojom::PermissionStatus,
|
||||
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_
|
||||
|
@ -136,14 +136,22 @@ void CastComponent::StartComponent() {
|
||||
application_controller_ = std::make_unique<ApplicationControllerImpl>(
|
||||
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()) {
|
||||
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()) {
|
||||
fuchsia::web::PermissionDescriptor permission_clone;
|
||||
zx_status_t status = permission.Clone(&permission_clone);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user