(core) add per-user per-org preferences to database

Summary:
Adds preferences to orgs.  There are a few flavors:
 * `userOrgPrefs`: these are specific to a certain user and a certain org.
 * `orgPrefs`: these are specific to a certain org, and apply to all users.
 * `userPrefs`: these are specific to a certain user, and apply to all orgs.

The three flavors of prefs are reported by `GET` for an org, and can be modified by `PATCH` for an org.  The user needs to have UPDATE rights to change `orgPrefs`, but can change `userOrgPrefs` and `userPrefs` without that right since the settings only affect themselves.

Test Plan: added tests

Reviewers: dsagal

Reviewed By: dsagal

Differential Revision: https://phab.getgrist.com/D2572
This commit is contained in:
Paul Fitzpatrick
2020-08-04 11:52:56 -04:00
parent 30866c6c95
commit 6b24d496db
6 changed files with 209 additions and 12 deletions

View File

@@ -1,9 +1,11 @@
import {Column, Entity, JoinColumn, ManyToOne, OneToMany, OneToOne,
PrimaryGeneratedColumn, RelationId} from "typeorm";
import {Role} from "app/common/roles";
import {OrganizationProperties, organizationPropertyKeys} from "app/common/UserAPI";
import {AclRuleOrg} from "./AclRule";
import {BillingAccount} from "./BillingAccount";
import {Pref} from "./Pref";
import {Resource} from "./Resource";
import {User} from "./User";
import {Workspace} from "./Workspace";
@@ -68,6 +70,13 @@ export class Organization extends Resource {
@Column({name: 'host', type: 'text', nullable: true})
public host: string|null;
// Any prefs relevant to the org and user. This relation is marked to not result
// in saves, since OneToMany saves in TypeORM are not reliable - see e.g. later
// parts of this issue:
// https://github.com/typeorm/typeorm/issues/3095
@OneToMany(type => Pref, pref => pref.org, {persistence: false})
public prefs?: Pref[];
public checkProperties(props: any): props is Partial<OrganizationProperties> {
return super.checkProperties(props, organizationPropertyKeys);
}

View File

@@ -0,0 +1,31 @@
import {Prefs} from 'app/common/Prefs';
import {Organization} from 'app/gen-server/entity/Organization';
import {User} from 'app/gen-server/entity/User';
import {nativeValues} from 'app/gen-server/lib/values';
import {Column, Entity, JoinColumn, ManyToOne, PrimaryColumn} from 'typeorm';
@Entity({name: 'prefs'})
export class Pref {
// This table may refer to users and/or orgs.
// We pretend userId/orgId are the primary key since TypeORM insists on having
// one, but we haven't marked them as so in the DB since the SQL standard frowns
// on nullable primary keys (and Postgres doesn't support them). We could add
// another primary key, but we don't actually need one.
@PrimaryColumn({name: 'user_id'})
public userId: number|null;
@PrimaryColumn({name: 'org_id'})
public orgId: number|null;
@ManyToOne(type => User)
@JoinColumn({name: 'user_id'})
public user?: User;
@ManyToOne(type => Organization)
@JoinColumn({name: 'org_id'})
public org?: Organization;
// Finally, the actual preferences, in JSON.
@Column({type: nativeValues.jsonEntityType})
public prefs: Prefs;
}