UserPermission and GroupPermission models (#5860)

* fix: rename to group_permissions

* fix: delete null collectionId records before setting non null constraint

* fix: use scope with collectionId not null

* fix: update model with documentId

* fix: rename to GroupPermission

* fix: rename collection_users to user_permissions

* fix: teamPermanentDeleter test

* fix: use scope with collectionId not null

* fix: update model with documentId

* fix: rename to UserPermission

* fix: create views upon table rename for zero downtime

* fix: remove comments
This commit is contained in:
Apoorv Mishra
2023-09-25 10:51:29 +05:30
committed by GitHub
parent 43bdb97639
commit 7145f7ef51
22 changed files with 558 additions and 123 deletions

View File

@@ -30,14 +30,14 @@ import { sortNavigationNodes } from "@shared/utils/collections";
import slugify from "@shared/utils/slugify";
import { SLUG_URL_REGEX } from "@shared/utils/urlHelpers";
import { CollectionValidation } from "@shared/validations";
import CollectionGroup from "./CollectionGroup";
import CollectionUser from "./CollectionUser";
import Document from "./Document";
import FileOperation from "./FileOperation";
import Group from "./Group";
import GroupPermission from "./GroupPermission";
import GroupUser from "./GroupUser";
import Team from "./Team";
import User from "./User";
import UserPermission from "./UserPermission";
import ParanoidModel from "./base/ParanoidModel";
import Fix from "./decorators/Fix";
import IsHexColor from "./validators/IsHexColor";
@@ -48,13 +48,23 @@ import NotContainsUrl from "./validators/NotContainsUrl";
withAllMemberships: {
include: [
{
model: CollectionUser,
model: UserPermission,
as: "memberships",
where: {
collectionId: {
[Op.ne]: null,
},
},
required: false,
},
{
model: CollectionGroup,
model: GroupPermission,
as: "collectionGroupMemberships",
where: {
collectionId: {
[Op.ne]: null,
},
},
required: false,
// use of "separate" property: sequelize breaks when there are
// nested "includes" with alternating values for "required"
@@ -92,16 +102,24 @@ import NotContainsUrl from "./validators/NotContainsUrl";
withMembership: (userId: string) => ({
include: [
{
model: CollectionUser,
model: UserPermission,
as: "memberships",
where: {
userId,
collectionId: {
[Op.ne]: null,
},
},
required: false,
},
{
model: CollectionGroup,
model: GroupPermission,
as: "collectionGroupMemberships",
where: {
collectionId: {
[Op.ne]: null,
},
},
required: false,
// use of "separate" property: sequelize breaks when there are
// nested "includes" with alternating values for "required"
@@ -257,7 +275,7 @@ class Collection extends ParanoidModel {
model: Collection,
options: { transaction: Transaction }
) {
return CollectionUser.findOrCreate({
return UserPermission.findOrCreate({
where: {
collectionId: model.id,
userId: model.createdById,
@@ -282,16 +300,16 @@ class Collection extends ParanoidModel {
@HasMany(() => Document, "collectionId")
documents: Document[];
@HasMany(() => CollectionUser, "collectionId")
memberships: CollectionUser[];
@HasMany(() => UserPermission, "collectionId")
memberships: UserPermission[];
@HasMany(() => CollectionGroup, "collectionId")
collectionGroupMemberships: CollectionGroup[];
@HasMany(() => GroupPermission, "collectionId")
collectionGroupMemberships: GroupPermission[];
@BelongsToMany(() => User, () => CollectionUser)
@BelongsToMany(() => User, () => UserPermission)
users: User[];
@BelongsToMany(() => Group, () => CollectionGroup)
@BelongsToMany(() => Group, () => GroupPermission)
groups: Group[];
@BelongsTo(() => User, "createdById")

View File

@@ -11,7 +11,7 @@ import {
DataType,
Scopes,
} from "sequelize-typescript";
import CollectionGroup from "./CollectionGroup";
import GroupPermission from "./GroupPermission";
import GroupUser from "./GroupUser";
import Team from "./Team";
import User from "./User";
@@ -87,7 +87,7 @@ class Group extends ParanoidModel {
groupId: model.id,
},
});
await CollectionGroup.destroy({
await GroupPermission.destroy({
where: {
groupId: model.id,
},
@@ -106,8 +106,8 @@ class Group extends ParanoidModel {
@HasMany(() => GroupUser, { as: "members", foreignKey: "groupId" })
groupMemberships: GroupUser[];
@HasMany(() => CollectionGroup, "groupId")
collectionGroupMemberships: CollectionGroup[];
@HasMany(() => GroupPermission, "groupId")
collectionGroupMemberships: GroupPermission[];
@BelongsTo(() => Team, "teamId")
team: Team;

View File

@@ -1,3 +1,4 @@
import { Op } from "sequelize";
import {
BelongsTo,
Column,
@@ -10,6 +11,7 @@ import {
} from "sequelize-typescript";
import { CollectionPermission } from "@shared/types";
import Collection from "./Collection";
import Document from "./Document";
import Group from "./Group";
import User from "./User";
import Model from "./base/Model";
@@ -26,14 +28,20 @@ import Fix from "./decorators/Fix";
withCollection: {
include: [
{
association: "collection",
model: Collection,
as: "collection",
where: {
collectionId: {
[Op.ne]: null,
},
},
},
],
},
}))
@Table({ tableName: "collection_groups", modelName: "collection_group" })
@Table({ tableName: "group_permissions", modelName: "group_permission" })
@Fix
class CollectionGroup extends Model {
class GroupPermission extends Model {
@Default(CollectionPermission.ReadWrite)
@IsIn([Object.values(CollectionPermission)])
@Column(DataType.STRING)
@@ -42,11 +50,18 @@ class CollectionGroup extends Model {
// associations
@BelongsTo(() => Collection, "collectionId")
collection: Collection;
collection?: Collection | null;
@ForeignKey(() => Collection)
@Column(DataType.UUID)
collectionId: string;
collectionId?: string | null;
@BelongsTo(() => Document, "documentId")
document?: Document | null;
@ForeignKey(() => Document)
@Column(DataType.UUID)
documentId?: string | null;
@BelongsTo(() => Group, "groupId")
group: Group;
@@ -59,4 +74,4 @@ class CollectionGroup extends Model {
createdBy: User;
}
export default CollectionGroup;
export default GroupPermission;

View File

@@ -1,8 +1,8 @@
import { faker } from "@faker-js/faker";
import { CollectionPermission } from "@shared/types";
import { buildUser, buildTeam, buildCollection } from "@server/test/factories";
import CollectionUser from "./CollectionUser";
import UserAuthentication from "./UserAuthentication";
import UserPermission from "./UserPermission";
beforeAll(() => {
jest.useFakeTimers().setSystemTime(new Date("2018-01-02T00:00:00.000Z"));
@@ -104,7 +104,7 @@ describe("user model", () => {
teamId: team.id,
permission: null,
});
await CollectionUser.create({
await UserPermission.create({
createdById: user.id,
collectionId: collection.id,
userId: user.id,

View File

@@ -41,10 +41,10 @@ import ApiKey from "./ApiKey";
import Attachment from "./Attachment";
import AuthenticationProvider from "./AuthenticationProvider";
import Collection from "./Collection";
import CollectionUser from "./CollectionUser";
import Star from "./Star";
import Team from "./Team";
import UserAuthentication from "./UserAuthentication";
import UserPermission from "./UserPermission";
import ParanoidModel from "./base/ParanoidModel";
import Encrypted, {
setEncryptedColumn,
@@ -545,7 +545,7 @@ class User extends ParanoidModel {
},
options
);
await CollectionUser.update(
await UserPermission.update(
{
permission: CollectionPermission.Read,
},

View File

@@ -1,3 +1,4 @@
import { Op } from "sequelize";
import {
Column,
ForeignKey,
@@ -10,6 +11,7 @@ import {
} from "sequelize-typescript";
import { CollectionPermission } from "@shared/types";
import Collection from "./Collection";
import Document from "./Document";
import User from "./User";
import Model from "./base/Model";
import Fix from "./decorators/Fix";
@@ -25,14 +27,20 @@ import Fix from "./decorators/Fix";
withCollection: {
include: [
{
association: "collection",
model: Collection,
as: "collection",
where: {
collectionId: {
[Op.ne]: null,
},
},
},
],
},
}))
@Table({ tableName: "collection_users", modelName: "collection_user" })
@Table({ tableName: "user_permissions", modelName: "user_permission" })
@Fix
class CollectionUser extends Model {
class UserPermission extends Model {
@Default(CollectionPermission.ReadWrite)
@IsIn([Object.values(CollectionPermission)])
@Column(DataType.STRING)
@@ -41,11 +49,18 @@ class CollectionUser extends Model {
// associations
@BelongsTo(() => Collection, "collectionId")
collection: Collection;
collection?: Collection | null;
@ForeignKey(() => Collection)
@Column(DataType.UUID)
collectionId: string;
collectionId?: string | null;
@BelongsTo(() => Document, "documentId")
document?: Document | null;
@ForeignKey(() => Document)
@Column(DataType.UUID)
documentId?: string | null;
@BelongsTo(() => User, "userId")
user: User;
@@ -62,4 +77,4 @@ class CollectionUser extends Model {
createdById: string;
}
export default CollectionUser;
export default UserPermission;

View File

@@ -8,9 +8,9 @@ export { default as Backlink } from "./Backlink";
export { default as Collection } from "./Collection";
export { default as CollectionGroup } from "./CollectionGroup";
export { default as GroupPermission } from "./GroupPermission";
export { default as CollectionUser } from "./CollectionUser";
export { default as UserPermission } from "./UserPermission";
export { default as Comment } from "./Comment";