UNPKG

terriajs

Version:

Geospatial data visualization platform.

104 lines (88 loc) 3.19 kB
import { action, computed, observable, makeObservable } from "mobx"; import AbstractConstructor from "../Core/AbstractConstructor"; import Model, { BaseModel } from "../Models/Definition/Model"; import ModelTraits from "../Traits/ModelTraits"; type BaseType = Model<ModelTraits>; /** * API for setting an access type for the model. Note that the intended use of * this mixin is just to flag public and private models differently in the UI * and does not provide any security guarantees. * * The implementation is a bit fluid and maybe that makes it a bit hard to * reason about because we are not strongly typing the possible values for * `accessType`. For use in frontend, we formally recognizes only one acessType * which is "public". All other access type values are treated as "private". The * models overriding this mixin are free to choose any other string valued * access type for their own purpose. */ function AccessControlMixin<T extends AbstractConstructor<BaseType>>(Base: T) { abstract class _AccessControlMixin extends Base { @observable private _accessType: string | undefined; constructor(...args: any[]) { super(...args); makeObservable(this); } get hasAccessControlMixin() { return true; } /** * Resolve accessType for this model in the following order: * 1. Return the access type that was set on this model by explicitly calling setAccessType() * 2. If this model is referenced by another, return the access type of the referrer * 3. Return the access type of a parent with valid access type * 4. If none of the above works - return "public" */ @computed get accessType(): string { // Return the explicitly set accessType if (this._accessType) { return this._accessType; } // Return the accessType of the referrer. if (AccessControlMixin.isMixedInto(this.sourceReference)) { return this.sourceReference.accessType; } // Try and return any ancestor's accessType if (this.knownContainerUniqueIds.length > 0) { const parentId = this.knownContainerUniqueIds[0]; const parent = parentId && this.terria.getModelById(BaseModel, parentId); if (AccessControlMixin.isMixedInto(parent)) { return parent.accessType; } } // Default return "public"; } @action setAccessType(accessType: string) { this._accessType = accessType; } /** * Returns true if this model public. */ @computed get isPublic() { return this.accessType === "public"; } /** * Returns true if this model is private. * * Note that any accessType other than "public" is treated as private. */ @computed get isPrivate() { return this.accessType !== "public"; } } return _AccessControlMixin; } namespace AccessControlMixin { export interface Instance extends InstanceType< ReturnType<typeof AccessControlMixin> > {} export function isMixedInto(model: any): model is Instance { return model && model.hasAccessControlMixin; } } export default AccessControlMixin;