Skip to content
This repository has been archived by the owner on Jun 9, 2023. It is now read-only.

feat: rework instance role tables #958

Merged
merged 9 commits into from
Mar 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions server/prisma/generator/factories/instanceRoles.factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { prisma } from '../../../src/prisma';

const instancePermissions = ['chapter-create', 'chapter-edit'] as const;
type Permissions = typeof instancePermissions[number];
interface InstanceRole {
name: string;
permissions: Permissions[];
}

const roles: InstanceRole[] = [
{ name: 'administrator', permissions: ['chapter-create', 'chapter-edit'] },
{ name: 'member', permissions: [] },
];

const createRole = async ({ name, permissions }: InstanceRole) => {
const permissionsData = permissions.map((permission) => ({
instance_permission: {
connect: { name: permission },
},
}));
const createdRole = await prisma.instance_roles.create({
data: {
name: name,
instance_role_permissions: { create: permissionsData },
},
});
return { [name]: { name: createdRole.name, id: createdRole.id } };
};

const createInstanceRoles = async () => {
await prisma.instance_permissions.createMany({
data: instancePermissions.map((permission) => ({ name: permission })),
});
return Object.assign({}, ...(await Promise.all(roles.map(createRole))));
};

export default createInstanceRoles;
6 changes: 5 additions & 1 deletion server/prisma/generator/factories/user.factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ import { prisma } from '../../../src/prisma';

const { name, internet } = faker;

const createUsers = async (): Promise<[number, number[]]> => {
const createUsers = async (
instanceRoles: Record<string, { name: string; id: number }>,
): Promise<[number, number[]]> => {
// TODO: add seeding admin
const userData: Prisma.usersCreateInput = {
email: 'foo@bar.com',
first_name: name.firstName(),
last_name: name.lastName(),
instance_role: { connect: { id: instanceRoles.administrator.id } },
};

const user = await prisma.users.create({ data: userData });
Expand All @@ -21,6 +24,7 @@ const createUsers = async (): Promise<[number, number[]]> => {
email: internet.email(),
first_name: name.firstName(),
last_name: name.lastName(),
instance_role: { connect: { id: instanceRoles.member.id } },
}),
);

Expand Down
5 changes: 4 additions & 1 deletion server/prisma/generator/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import createRsvps from './factories/rsvps.factory';
import createSponsors from './factories/sponsors.factory';
import createUsers from './factories/user.factory';
import createVenues from './factories/venues.factory';
import createInstanceRoles from './factories/instanceRoles.factory';
import setupRoles from './setupRoles';

(async () => {
Expand All @@ -24,7 +25,9 @@ import setupRoles from './setupRoles';
}
}

const [userId, userIds] = await createUsers();
const instanceRoles = await createInstanceRoles();

const [userId, userIds] = await createUsers(instanceRoles);
const sponsorIds = await createSponsors();

const chapterIds = await createChapters(userId);
Expand Down
35 changes: 27 additions & 8 deletions server/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -163,14 +163,32 @@ model user_event_roles {
@@id([user_id, event_id, role_name])
}

model user_instance_roles {
created_at DateTime @default(now())
updated_at DateTime @updatedAt
user_id Int
role_name String
users users @relation(fields: [user_id], references: [id], onDelete: NoAction, onUpdate: NoAction)
model instance_permissions {
created_at DateTime @default(now())
updated_at DateTime @updatedAt
id Int @id @default(autoincrement())
name String @unique
instance_role_permissions instance_role_permissions[]
}

model instance_role_permissions {
created_at DateTime @default(now())
updated_at DateTime @updatedAt
instance_role_id Int
instance_permission_id Int
instance_role instance_roles @relation(fields: [instance_role_id], references: [id], onDelete: Cascade, onUpdate: NoAction)
instance_permission instance_permissions @relation(fields: [instance_permission_id], references: [id], onDelete: Cascade, onUpdate: NoAction)

@@id([instance_role_id, instance_permission_id])
}

@@id([user_id, role_name])
model instance_roles {
created_at DateTime @default(now())
updated_at DateTime @updatedAt
id Int @id @default(autoincrement())
name String @unique
instance_role_permissions instance_role_permissions[]
users users[]
}

model users {
Expand All @@ -184,7 +202,8 @@ model users {
user_bans user_bans[]
chapter_roles user_chapter_roles[]
user_event_roles user_event_roles[]
user_instance_roles user_instance_roles[]
instance_role_id Int
instance_role instance_roles @relation(fields: [instance_role_id], references: [id])
event_reminders event_reminders[]
}

Expand Down
13 changes: 12 additions & 1 deletion server/src/controllers/Auth/resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,18 @@ export class AuthResolver {
throw new Error('EMAIL_IN_USE');
}

const userData: Prisma.usersCreateInput = data;
const instanceMember = await prisma.instance_roles.findUnique({
where: { name: 'member' },
});

const userData: Prisma.usersCreateInput = {
...data,
instance_role: {
connect: {
id: instanceMember.id,
},
},
};

return await prisma.users.create({ data: userData });
}
Expand Down
22 changes: 22 additions & 0 deletions server/src/graphql-types/InstanceRole.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ObjectType, Field } from 'type-graphql';

@ObjectType()
export class InstancePermission {
@Field(() => String)
name: string;
}

@ObjectType()
export class InstanceRolePermission {
@Field(() => InstancePermission)
instance_permission: InstancePermission;
}

@ObjectType()
export class InstanceRole {
@Field(() => String)
name: string;

@Field(() => [InstanceRolePermission])
instance_role_permissions: InstanceRolePermission[];
}
14 changes: 10 additions & 4 deletions server/src/graphql-types/User.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { ObjectType, Field, Resolver, Root, FieldResolver } from 'type-graphql';
import { BaseObject } from './BaseObject';
import { UserInstanceRole } from './UserInstanceRole';
import { Chapter, Rsvp, UserBan, UserChapterRole, UserEventRole } from '.';
import {
Chapter,
InstanceRole,
Rsvp,
UserBan,
UserChapterRole,
UserEventRole,
} from '.';

@ObjectType()
export class User extends BaseObject {
Expand Down Expand Up @@ -40,8 +46,8 @@ export class UserWithRelations extends User {
@Field(() => [UserChapterRole])
chapter_roles: UserChapterRole[];

@Field(() => [UserInstanceRole])
instance_roles: UserInstanceRole[];
@Field(() => [InstanceRole])
instance_role: InstanceRole[];

@Field(() => [UserEventRole])
event_roles: UserEventRole[];
Expand Down
18 changes: 0 additions & 18 deletions server/src/graphql-types/UserInstanceRole.ts

This file was deleted.

1 change: 1 addition & 0 deletions server/src/graphql-types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export * from './Event';
export * from './EventReminder';
export * from './EventSponsor';
export * from './EventTag';
export * from './InstanceRole';
export * from './Rsvp';
export * from './Sponsor';
export * from './Tag';
Expand Down