mirror of
https://github.com/electron/electron.git
synced 2026-01-09 15:38:08 -05:00
feat: add --disable-geolocation command-line flag for macOS (#45934)
* feat(macos): add --disable-geolocation-mac command-line flag * internally deny geolocation requests if flag set e * wrap PermissionRequestHandler instead * wrap custom handler and deny regardless of response * Update docs/api/command-line-switches.md Co-authored-by: Will Anderson <will@itsananderson.com> * resolving conflicts during rebase * tests added * tests added: minor changes * move IsGeolocationDisabledViaCommandLine inside ElectronPermissionManager as a static member * test: inject fixturesPath via --boot-eval * Update shell/browser/electron_permission_manager.cc Co-authored-by: Robo <hop2deep@gmail.com> * chore: Fixup after merge * fixup after merge --------- Co-authored-by: Will Anderson <will@itsananderson.com> Co-authored-by: Robo <hop2deep@gmail.com> Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
This commit is contained in:
@@ -49,6 +49,10 @@ Disables the disk cache for HTTP requests.
|
|||||||
|
|
||||||
Disable HTTP/2 and SPDY/3.1 protocols.
|
Disable HTTP/2 and SPDY/3.1 protocols.
|
||||||
|
|
||||||
|
### --disable-geolocation _macOS_
|
||||||
|
|
||||||
|
Disables the Geolocation API. Permission requests for geolocation will be denied internally regardless of the decision made by a handler set via `session.setPermissionRequestHandler`. This functionality is currently implemented only for macOS. Has no effect on other platforms.
|
||||||
|
|
||||||
### --disable-renderer-backgrounding
|
### --disable-renderer-backgrounding
|
||||||
|
|
||||||
Prevents Chromium from lowering the priority of invisible pages' renderer
|
Prevents Chromium from lowering the priority of invisible pages' renderer
|
||||||
|
|||||||
@@ -886,6 +886,24 @@ void Session::SetPermissionRequestHandler(v8::Local<v8::Value> val,
|
|||||||
blink::PermissionType permission_type,
|
blink::PermissionType permission_type,
|
||||||
ElectronPermissionManager::StatusCallback callback,
|
ElectronPermissionManager::StatusCallback callback,
|
||||||
const base::Value& details) {
|
const base::Value& details) {
|
||||||
|
#if (BUILDFLAG(IS_MAC))
|
||||||
|
if (permission_type == blink::PermissionType::GEOLOCATION) {
|
||||||
|
if (ElectronPermissionManager::
|
||||||
|
IsGeolocationDisabledViaCommandLine()) {
|
||||||
|
auto original_callback = std::move(callback);
|
||||||
|
callback = base::BindOnce(
|
||||||
|
[](ElectronPermissionManager::StatusCallback callback,
|
||||||
|
content::PermissionResult /*ignored_result*/) {
|
||||||
|
// Always deny regardless of what
|
||||||
|
// content::PermissionResult is passed here
|
||||||
|
std::move(callback).Run(content::PermissionResult(
|
||||||
|
blink::mojom::PermissionStatus::DENIED,
|
||||||
|
content::PermissionStatusSource::UNSPECIFIED));
|
||||||
|
},
|
||||||
|
std::move(original_callback));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
handler->Run(web_contents, permission_type, std::move(callback),
|
handler->Run(web_contents, permission_type, std::move(callback),
|
||||||
details);
|
details);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "services/device/public/cpp/geolocation/geolocation_system_permission_manager.h"
|
#include "services/device/public/cpp/geolocation/geolocation_system_permission_manager.h"
|
||||||
#include "services/device/public/cpp/geolocation/system_geolocation_source_apple.h"
|
#include "services/device/public/cpp/geolocation/system_geolocation_source_apple.h"
|
||||||
#include "shell/browser/browser_process_impl.h"
|
#include "shell/browser/browser_process_impl.h"
|
||||||
|
#include "shell/browser/electron_permission_manager.h"
|
||||||
#include "shell/browser/mac/electron_application.h"
|
#include "shell/browser/mac/electron_application.h"
|
||||||
#include "shell/browser/mac/electron_application_delegate.h"
|
#include "shell/browser/mac/electron_application_delegate.h"
|
||||||
#include "ui/base/l10n/l10n_util_mac.h"
|
#include "ui/base/l10n/l10n_util_mac.h"
|
||||||
@@ -32,7 +33,13 @@ void ElectronBrowserMainParts::PreCreateMainMessageLoop() {
|
|||||||
setObject:@"NO"
|
setObject:@"NO"
|
||||||
forKey:@"NSTreatUnknownArgumentsAsOpen"];
|
forKey:@"NSTreatUnknownArgumentsAsOpen"];
|
||||||
|
|
||||||
if (!device::GeolocationSystemPermissionManager::GetInstance()) {
|
const bool geolocationDisabled =
|
||||||
|
ElectronPermissionManager::IsGeolocationDisabledViaCommandLine();
|
||||||
|
|
||||||
|
// Check if geolocation api is NOT disabled via command line before
|
||||||
|
// CreateGeolocationSystemPermissionManager is called
|
||||||
|
if (!geolocationDisabled &&
|
||||||
|
!device::GeolocationSystemPermissionManager::GetInstance()) {
|
||||||
device::GeolocationSystemPermissionManager::SetInstance(
|
device::GeolocationSystemPermissionManager::SetInstance(
|
||||||
device::SystemGeolocationSourceApple::
|
device::SystemGeolocationSourceApple::
|
||||||
CreateGeolocationSystemPermissionManager());
|
CreateGeolocationSystemPermissionManager());
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "base/command_line.h"
|
||||||
#include "base/containers/to_vector.h"
|
#include "base/containers/to_vector.h"
|
||||||
#include "base/values.h"
|
#include "base/values.h"
|
||||||
#include "content/browser/permissions/permission_util.h" // nogncheck
|
#include "content/browser/permissions/permission_util.h" // nogncheck
|
||||||
@@ -146,6 +147,17 @@ void ElectronPermissionManager::SetBluetoothPairingHandler(
|
|||||||
bluetooth_pairing_handler_ = handler;
|
bluetooth_pairing_handler_ = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool ElectronPermissionManager::IsGeolocationDisabledViaCommandLine() {
|
||||||
|
// Remove platform check once flag is extended to other platforms
|
||||||
|
#if BUILDFLAG(IS_MAC)
|
||||||
|
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||||
|
return command_line->HasSwitch("disable-geolocation");
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool ElectronPermissionManager::HasPermissionRequestHandler() const {
|
bool ElectronPermissionManager::HasPermissionRequestHandler() const {
|
||||||
return !request_handler_.is_null();
|
return !request_handler_.is_null();
|
||||||
}
|
}
|
||||||
@@ -220,9 +232,16 @@ void ElectronPermissionManager::RequestPermissionsWithDetails(
|
|||||||
->GrantSendMidiSysExMessage(
|
->GrantSendMidiSysExMessage(
|
||||||
render_frame_host->GetProcess()->GetDeprecatedID());
|
render_frame_host->GetProcess()->GetDeprecatedID());
|
||||||
} else if (permission_type == blink::PermissionType::GEOLOCATION) {
|
} else if (permission_type == blink::PermissionType::GEOLOCATION) {
|
||||||
ElectronBrowserMainParts::Get()
|
if (IsGeolocationDisabledViaCommandLine()) {
|
||||||
->GetGeolocationControl()
|
results.push_back(content::PermissionResult(
|
||||||
->UserDidOptIntoLocationServices();
|
blink::mojom::PermissionStatus::DENIED,
|
||||||
|
content::PermissionStatusSource::UNSPECIFIED));
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
ElectronBrowserMainParts::Get()
|
||||||
|
->GetGeolocationControl()
|
||||||
|
->UserDidOptIntoLocationServices();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
results.push_back(content::PermissionResult(
|
results.push_back(content::PermissionResult(
|
||||||
blink::mojom::PermissionStatus::GRANTED,
|
blink::mojom::PermissionStatus::GRANTED,
|
||||||
@@ -331,6 +350,10 @@ bool ElectronPermissionManager::CheckPermissionWithDetails(
|
|||||||
content::RenderFrameHost* render_frame_host,
|
content::RenderFrameHost* render_frame_host,
|
||||||
const GURL& requesting_origin,
|
const GURL& requesting_origin,
|
||||||
base::Value::Dict details) const {
|
base::Value::Dict details) const {
|
||||||
|
if (permission == blink::PermissionType::GEOLOCATION &&
|
||||||
|
IsGeolocationDisabledViaCommandLine())
|
||||||
|
return false;
|
||||||
|
|
||||||
if (check_handler_.is_null()) {
|
if (check_handler_.is_null()) {
|
||||||
if (permission == blink::PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ) {
|
if (permission == blink::PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ) {
|
||||||
return false;
|
return false;
|
||||||
@@ -368,6 +391,10 @@ bool ElectronPermissionManager::CheckDevicePermission(
|
|||||||
const url::Origin& origin,
|
const url::Origin& origin,
|
||||||
const base::Value& device,
|
const base::Value& device,
|
||||||
ElectronBrowserContext* browser_context) const {
|
ElectronBrowserContext* browser_context) const {
|
||||||
|
if (permission == blink::PermissionType::GEOLOCATION &&
|
||||||
|
IsGeolocationDisabledViaCommandLine())
|
||||||
|
return false;
|
||||||
|
|
||||||
if (device_permission_handler_.is_null())
|
if (device_permission_handler_.is_null())
|
||||||
return browser_context->CheckDevicePermission(origin, device, permission);
|
return browser_context->CheckDevicePermission(origin, device, permission);
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ class ElectronPermissionManager : public content::PermissionControllerDelegate {
|
|||||||
using BluetoothPairingHandler =
|
using BluetoothPairingHandler =
|
||||||
base::RepeatingCallback<void(gin_helper::Dictionary, PairCallback)>;
|
base::RepeatingCallback<void(gin_helper::Dictionary, PairCallback)>;
|
||||||
|
|
||||||
|
static bool IsGeolocationDisabledViaCommandLine();
|
||||||
|
|
||||||
void RequestPermissionWithDetails(
|
void RequestPermissionWithDetails(
|
||||||
blink::mojom::PermissionDescriptorPtr permission,
|
blink::mojom::PermissionDescriptorPtr permission,
|
||||||
content::RenderFrameHost* render_frame_host,
|
content::RenderFrameHost* render_frame_host,
|
||||||
|
|||||||
@@ -898,6 +898,72 @@ describe('chromium features', () => {
|
|||||||
expect(position).to.have.property('coords');
|
expect(position).to.have.property('coords');
|
||||||
expect(position).to.have.property('timestamp');
|
expect(position).to.have.property('timestamp');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ifdescribe(process.platform === 'darwin')('with --disable-geolocation', () => {
|
||||||
|
const testSwitchBehavior = (handlerAction: 'allow' | 'deny' | 'none') => async () => {
|
||||||
|
const rc = await startRemoteControlApp([
|
||||||
|
'--disable-geolocation',
|
||||||
|
`--boot-eval=fixturesPath=${JSON.stringify(fixturesPath)}`
|
||||||
|
]);
|
||||||
|
|
||||||
|
const result = await rc.remotely(async (action: typeof handlerAction) => {
|
||||||
|
const { session, BrowserWindow } = require('electron');
|
||||||
|
const path = require('node:path');
|
||||||
|
|
||||||
|
// Isolate each test's permissions to prevent permission state leaks between the test variations
|
||||||
|
const testSession = session.fromPartition(`geolocation-disable-${action}`);
|
||||||
|
|
||||||
|
if (action !== 'none') {
|
||||||
|
// Make the PermissionRequestHandler behave according to action variable passed for this test
|
||||||
|
testSession.setPermissionRequestHandler((_wc, permission, callback) => {
|
||||||
|
if (permission === 'geolocation') {
|
||||||
|
if (action === 'allow') callback(true);
|
||||||
|
else if (action === 'deny') callback(false);
|
||||||
|
else callback(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const w = new BrowserWindow({
|
||||||
|
show: false,
|
||||||
|
webPreferences: {
|
||||||
|
session: testSession,
|
||||||
|
nodeIntegration: true,
|
||||||
|
contextIsolation: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await w.loadFile(path.join(fixturesPath, 'pages', 'blank.html'));
|
||||||
|
|
||||||
|
const permissionState = await w.webContents.executeJavaScript(`
|
||||||
|
navigator.permissions.query({ name: 'geolocation' })
|
||||||
|
.then(status => status.state)
|
||||||
|
.catch(() => 'error')
|
||||||
|
`);
|
||||||
|
|
||||||
|
const geoResult = await w.webContents.executeJavaScript(`
|
||||||
|
new Promise(resolve => {
|
||||||
|
navigator.geolocation.getCurrentPosition(
|
||||||
|
() => resolve('allowed'),
|
||||||
|
err => resolve(err.code)
|
||||||
|
);
|
||||||
|
})
|
||||||
|
`);
|
||||||
|
|
||||||
|
return { permissionState, geoResult };
|
||||||
|
}, handlerAction);
|
||||||
|
|
||||||
|
// Always expect status to be denied regardless of the decision made by a handler set via `session.setPermissionRequestHandler`
|
||||||
|
expect(result.permissionState).to.equal('denied', `Unexpected permission state for ${handlerAction} handler`);
|
||||||
|
|
||||||
|
// 1 = PERMISSION_DENIED
|
||||||
|
expect(result.geoResult).to.equal(1, `Unexpected API result for ${handlerAction} handler`);
|
||||||
|
};
|
||||||
|
|
||||||
|
it('denies geolocation when permission request handler would allow', testSwitchBehavior('allow'));
|
||||||
|
it('denies geolocation when permission request handler would deny', testSwitchBehavior('deny'));
|
||||||
|
it('denies geolocation with no permission request handler', testSwitchBehavior('none'));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('File System API,', () => {
|
describe('File System API,', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user