gristlabs_grist-core/app/server/lib/Permit.ts
Paul Fitzpatrick 54beaede84 (core) revive saml support and test against Auth0
Summary:
SAML support had broken due to SameSite changes in browsers. This
makes it work again, and tests it against Auth0 (now owned by Okta).

Logging in and out works.  The logged out state is confusing, and may
not be complete.  The "Add Account" menu item doesn't work.
But with this, an important part of self-hosting becomes easier.

SAML support works also in grist-core, for site pages, but there
is a glitch on document pages that I'll look into separately.

Test Plan: tested manually

Reviewers: dsagal

Reviewed By: dsagal

Differential Revision: https://phab.getgrist.com/D2976
2021-08-16 17:36:09 -04:00

67 lines
2.3 KiB
TypeScript

/**
* 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 {
docId?: string; // A particular document.
workspaceId?: number; // A particular workspace.
org?: string|number; // A particular org.
otherDocId?: string; // For operations involving two documents.
sessionId?: string; // A particular session.
url?: string; // A particular url.
action?: string; // A string denoting what kind of action the permit applies to.
}
/* A store of permits */
export interface IPermitStore {
// Store a permit, and return the key it is stored in.
// Permits are transient, and will expire.
setPermit(permit: Permit, ttlMs?: number): Promise<string>;
// 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>;
}
export interface IPermitStores {
getPermitStore(prefix: string, defaultTtlMs?: number): IPermitStore;
}
// Create a well formatted permit key from a seed string.
export function formatPermitKey(seed: string, prefix: string) {
return `permit-${prefix}-${seed}`;
}
// Check that permit key is well formatted.
export function checkPermitKey(key: string, prefix: string): boolean {
return key.startsWith(`permit-${prefix}-`);
}