mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 09:31:22 -05:00
feat: Add helper functions for permissions to std (#4258)
This commit is contained in:
parent
b0b27c4310
commit
5b10ab0984
2 changed files with 167 additions and 0 deletions
120
std/permissions/mod.ts
Normal file
120
std/permissions/mod.ts
Normal file
|
@ -0,0 +1,120 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
const { PermissionDenied } = Deno.errors;
|
||||
|
||||
function getPermissionString(descriptors: Deno.PermissionDescriptor[]): string {
|
||||
return descriptors.length
|
||||
? ` ${descriptors
|
||||
.map(pd => {
|
||||
switch (pd.name) {
|
||||
case "read":
|
||||
case "write":
|
||||
return pd.path
|
||||
? `--allow-${pd.name}=${pd.path}`
|
||||
: `--allow-${pd.name}`;
|
||||
case "net":
|
||||
return pd.url
|
||||
? `--allow-${pd.name}=${pd.url}`
|
||||
: `--allow-${pd.name}`;
|
||||
default:
|
||||
return `--allow-${pd.name}`;
|
||||
}
|
||||
})
|
||||
.join("\n ")}`
|
||||
: "";
|
||||
}
|
||||
|
||||
/** Attempts to grant a set of permissions, resolving with the descriptors of
|
||||
* the permissions that are granted.
|
||||
*
|
||||
* const perms = await grant({ name: "net" }, { name: "read" });
|
||||
* if (perms && perms.length === 2) {
|
||||
* // do something cool that connects to the net and reads files
|
||||
* } else {
|
||||
* // notify user of missing permissions
|
||||
* }
|
||||
*
|
||||
* If one of the permissions requires a prompt, the function will attempt to
|
||||
* prompt for it. The function resolves with all of the granted permissions. */
|
||||
export async function grant(
|
||||
...descriptors: Deno.PermissionDescriptor[]
|
||||
): Promise<void | Deno.PermissionDescriptor[]>;
|
||||
/** Attempts to grant a set of permissions, resolving with the descriptors of
|
||||
* the permissions that are granted.
|
||||
*
|
||||
* const perms = await grant([{ name: "net" }, { name: "read" }]);
|
||||
* if (perms && perms.length === 2) {
|
||||
* // do something cool that connects to the net and reads files
|
||||
* } else {
|
||||
* // notify user of missing permissions
|
||||
* }
|
||||
*
|
||||
* If one of the permissions requires a prompt, the function will attempt to
|
||||
* prompt for it. The function resolves with all of the granted permissions. */
|
||||
export async function grant(
|
||||
descriptors: Deno.PermissionDescriptor[]
|
||||
): Promise<void | Deno.PermissionDescriptor[]>;
|
||||
export async function grant(
|
||||
descriptor: Deno.PermissionDescriptor[] | Deno.PermissionDescriptor,
|
||||
...descriptors: Deno.PermissionDescriptor[]
|
||||
): Promise<void | Deno.PermissionDescriptor[]> {
|
||||
const result: Deno.PermissionDescriptor[] = [];
|
||||
descriptors = Array.isArray(descriptor)
|
||||
? descriptor
|
||||
: [descriptor, ...descriptors];
|
||||
for (const descriptor of descriptors) {
|
||||
let state = (await Deno.permissions.query(descriptor)).state;
|
||||
if (state === "prompt") {
|
||||
state = (await Deno.permissions.request(descriptor)).state;
|
||||
}
|
||||
if (state === "granted") {
|
||||
result.push(descriptor);
|
||||
}
|
||||
}
|
||||
return result.length ? result : undefined;
|
||||
}
|
||||
|
||||
/** Attempts to grant a set of permissions or rejects.
|
||||
*
|
||||
* await grantOrThrow({ name: "env" }, { name: "net" });
|
||||
*
|
||||
* If the permission can be prompted for, the function will attempt to prompt.
|
||||
* If any of the permissions are denied, the function will reject for the first
|
||||
* permission that is denied. If all permissions are granted, the function
|
||||
* will resolve. */
|
||||
export async function grantOrThrow(
|
||||
...descriptors: Deno.PermissionDescriptor[]
|
||||
): Promise<void>;
|
||||
/** Attempts to grant a set of permissions or rejects.
|
||||
*
|
||||
* await grantOrThrow([{ name: "env" }, { name: "net" }]);
|
||||
*
|
||||
* If the permission can be prompted for, the function will attempt to prompt.
|
||||
* If any of the permissions are denied, the function will reject mentioning the
|
||||
* the denied permissions. If all permissions are granted, the function will
|
||||
* resolve. */
|
||||
export async function grantOrThrow(
|
||||
descriptors: Deno.PermissionDescriptor[]
|
||||
): Promise<void>;
|
||||
export async function grantOrThrow(
|
||||
descriptor: Deno.PermissionDescriptor[] | Deno.PermissionDescriptor,
|
||||
...descriptors: Deno.PermissionDescriptor[]
|
||||
): Promise<void> {
|
||||
const denied: Deno.PermissionDescriptor[] = [];
|
||||
descriptors = Array.isArray(descriptor)
|
||||
? descriptor
|
||||
: [descriptor, ...descriptors];
|
||||
for (const descriptor of descriptors) {
|
||||
const { state } = await Deno.permissions.request(descriptor);
|
||||
if (state !== "granted") {
|
||||
denied.push(descriptor);
|
||||
}
|
||||
}
|
||||
if (denied.length) {
|
||||
throw new PermissionDenied(
|
||||
`The following permissions have not been granted:\n${getPermissionString(
|
||||
denied
|
||||
)}`
|
||||
);
|
||||
}
|
||||
}
|
47
std/permissions/test.ts
Normal file
47
std/permissions/test.ts
Normal file
|
@ -0,0 +1,47 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
import { grant, grantOrThrow } from "./mod.ts";
|
||||
import { assert, assertEquals } from "../testing/asserts.ts";
|
||||
|
||||
const { test } = Deno;
|
||||
|
||||
test({
|
||||
name: "grant basic",
|
||||
async fn() {
|
||||
assertEquals(await grant({ name: "net" }, { name: "env" }), [
|
||||
{ name: "net" },
|
||||
{ name: "env" }
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
test({
|
||||
name: "grant array",
|
||||
async fn() {
|
||||
assertEquals(await grant([{ name: "net" }, { name: "env" }]), [
|
||||
{ name: "net" },
|
||||
{ name: "env" }
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
test({
|
||||
name: "grant logic",
|
||||
async fn() {
|
||||
assert(await grant({ name: "net" }));
|
||||
}
|
||||
});
|
||||
|
||||
test({
|
||||
name: "grantOrThrow basic",
|
||||
async fn() {
|
||||
await grantOrThrow({ name: "net" }, { name: "env" });
|
||||
}
|
||||
});
|
||||
|
||||
test({
|
||||
name: "grantOrThrow array",
|
||||
async fn() {
|
||||
await grantOrThrow([{ name: "net" }, { name: "env" }]);
|
||||
}
|
||||
});
|
Loading…
Add table
Reference in a new issue