2020-07-23 14:34:05 +00:00
|
|
|
/**
|
|
|
|
* An exceptional grant of rights on a resource, for when work needs to be
|
|
|
|
* initiated by Grist systems rather than a user. Cases where this may happen:
|
|
|
|
*
|
|
|
|
* - Deletion of documents and workspaces in the trash
|
|
|
|
*
|
|
|
|
* Permits are stored in redis (or, in a single-process dev environment, in memory)
|
|
|
|
* as json, in keys that expire within minutes. The keys should be effectively
|
|
|
|
* unguessable.
|
|
|
|
*
|
|
|
|
* To use a permit:
|
|
|
|
*
|
|
|
|
* - Prepare a Permit object that includes the id of the document or
|
|
|
|
* workspace to be operated on.
|
|
|
|
*
|
|
|
|
* - It the operation you care about involves the database, check
|
|
|
|
* that "allowSpecialPermit" is enabled for it in HomeDBManager
|
|
|
|
* (currently only deletion of docs/workspaces has this enabled).
|
|
|
|
*
|
|
|
|
* - Save the permit in the permit store, with setPermit, noting its
|
|
|
|
* generated key.
|
|
|
|
*
|
|
|
|
* - Call the API with a "Permit: <permit-key>" header.
|
|
|
|
*
|
|
|
|
* - Optionally, remove the permit with removePermit().
|
|
|
|
*/
|
|
|
|
export interface Permit {
|
2021-08-16 15:11:17 +00:00
|
|
|
docId?: string; // A particular document.
|
|
|
|
workspaceId?: number; // A particular workspace.
|
|
|
|
org?: string|number; // A particular org.
|
2021-01-12 15:48:40 +00:00
|
|
|
otherDocId?: string; // For operations involving two documents.
|
2021-08-16 15:11:17 +00:00
|
|
|
sessionId?: string; // A particular session.
|
|
|
|
url?: string; // A particular url.
|
|
|
|
action?: string; // A string denoting what kind of action the permit applies to.
|
2020-07-23 14:34:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* A store of permits */
|
|
|
|
export interface IPermitStore {
|
|
|
|
|
|
|
|
// Store a permit, and return the key it is stored in.
|
|
|
|
// Permits are transient, and will expire.
|
2021-08-16 15:11:17 +00:00
|
|
|
setPermit(permit: Permit, ttlMs?: number): Promise<string>;
|
2020-07-23 14:34:05 +00:00
|
|
|
|
|
|
|
// Get any permit associated with the given key, or null if none.
|
|
|
|
getPermit(permitKey: string): Promise<Permit|null>;
|
|
|
|
|
|
|
|
// Remove any permit associated with the given key.
|
|
|
|
removePermit(permitKey: string): Promise<void>;
|
|
|
|
|
|
|
|
// Close down the permit store.
|
|
|
|
close(): Promise<void>;
|
|
|
|
}
|
|
|
|
|
2021-08-16 15:11:17 +00:00
|
|
|
export interface IPermitStores {
|
|
|
|
getPermitStore(prefix: string, defaultTtlMs?: number): IPermitStore;
|
|
|
|
}
|
|
|
|
|
2020-07-23 14:34:05 +00:00
|
|
|
// Create a well formatted permit key from a seed string.
|
2021-08-16 15:11:17 +00:00
|
|
|
export function formatPermitKey(seed: string, prefix: string) {
|
|
|
|
return `permit-${prefix}-${seed}`;
|
2020-07-23 14:34:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check that permit key is well formatted.
|
2021-08-16 15:11:17 +00:00
|
|
|
export function checkPermitKey(key: string, prefix: string): boolean {
|
|
|
|
return key.startsWith(`permit-${prefix}-`);
|
2020-07-23 14:34:05 +00:00
|
|
|
}
|