Files
HiveGrid-Wireframes/03 Quellen und Referenzen/hivegrid-cloud/apps/web/app/utils/services/rolesAndPermissionsService.ts
T

116 lines
4.4 KiB
TypeScript

import { DefaultPermission } from "~/application/dtos/shared/DefaultPermissions";
import {
defaultAdminRoleSeeds,
defaultAppRoleSeeds,
defaultPermissionSeedDescriptors,
syncDefaultRolesAndPermissions,
type DefaultPermissionSeed,
type DefaultRoleSeed,
} from "@hivegrid/db/permissions-seed.server";
import { getAllRoles } from "~/utils/db/permissions/roles.db.server";
import { createUserRoleAssignments, type UserRoleAssignment } from "~/utils/db/permissions/userRoles.db.server";
import { adminGetAllTenants } from "~/utils/db/tenants.db.server";
import { adminGetAllUsers } from "~/utils/db/users.db.server";
import { db } from "~/utils/db.server";
export type CreateRoleDto = DefaultRoleSeed;
export const defaultAdminRoles: CreateRoleDto[] = [...defaultAdminRoleSeeds];
export const defaultAppRoles: CreateRoleDto[] = [...defaultAppRoleSeeds];
export type CreatePermissionDto = Omit<DefaultPermissionSeed, "name" | "type"> & {
name: DefaultPermission;
type: string;
};
export const defaultPermissions: CreatePermissionDto[] = defaultPermissionSeedDescriptors.map((permission) => ({
...permission,
name: permission.name as DefaultPermission,
}));
export type RolesAndPermissionsSeedDiagnosticPhase = "start" | "success" | "failure";
export type RolesAndPermissionsSeedDiagnosticEvent = {
phase: RolesAndPermissionsSeedDiagnosticPhase;
adminRoleCount?: number;
appRoleCount?: number;
defaultPermissionCount?: number;
dynamicEntityPermissionCount?: number;
adminUserAssignmentCount?: number;
tenantUserAssignmentCount?: number;
error?: unknown;
};
export type RolesAndPermissionsSeedDiagnostics = (event: RolesAndPermissionsSeedDiagnosticEvent) => void | Promise<void>;
export type SeedRolesAndPermissionsOptions = {
adminEmail?: string;
diagnostics?: RolesAndPermissionsSeedDiagnostics;
excludedTenantSlugs?: readonly string[];
};
function toSeedRolesAndPermissionsOptions(adminEmailOrOptions?: string | SeedRolesAndPermissionsOptions): SeedRolesAndPermissionsOptions {
if (typeof adminEmailOrOptions === "string") {
return { adminEmail: adminEmailOrOptions };
}
return adminEmailOrOptions ?? {};
}
async function emitRolesAndPermissionsSeedDiagnostic(
diagnostics: RolesAndPermissionsSeedDiagnostics | undefined,
event: RolesAndPermissionsSeedDiagnosticEvent
): Promise<void> {
await diagnostics?.(event);
}
export async function seedRolesAndPermissions(adminEmailOrOptions?: string | SeedRolesAndPermissionsOptions): Promise<void> {
const { adminEmail, diagnostics, excludedTenantSlugs = [] } = toSeedRolesAndPermissionsOptions(adminEmailOrOptions);
const excludedTenantSlugSet = new Set(excludedTenantSlugs);
const counts = {
adminRoleCount: defaultAdminRoles.length,
appRoleCount: defaultAppRoles.length,
defaultPermissionCount: defaultPermissions.length,
dynamicEntityPermissionCount: 0,
adminUserAssignmentCount: 0,
tenantUserAssignmentCount: 0,
};
await emitRolesAndPermissionsSeedDiagnostic(diagnostics, { phase: "start", ...counts });
try {
await syncDefaultRolesAndPermissions({ client: db });
const adminRoles = await getAllRoles("admin");
counts.adminRoleCount = adminRoles.length;
const appRoles = await getAllRoles("app");
counts.appRoleCount = appRoles.length;
const users = (await adminGetAllUsers()).items;
const userRoleAssignments: UserRoleAssignment[] = [];
users
.filter((f) => f.admin && adminEmail && f.email === adminEmail)
.forEach((user) => {
adminRoles.forEach((adminRole) => {
counts.adminUserAssignmentCount += 1;
userRoleAssignments.push({ userId: user.id, roleId: adminRole.id, tenantId: null });
});
});
const tenants = await adminGetAllTenants();
tenants
.filter((tenant) => !excludedTenantSlugSet.has(tenant.slug))
.forEach((tenant) => {
tenant.users.forEach((tenantUser) => {
appRoles.forEach((appRole) => {
counts.tenantUserAssignmentCount += 1;
userRoleAssignments.push({ userId: tenantUser.userId, roleId: appRole.id, tenantId: tenant.id });
});
});
});
await createUserRoleAssignments(userRoleAssignments);
await emitRolesAndPermissionsSeedDiagnostic(diagnostics, { phase: "success", ...counts });
} catch (error) {
await emitRolesAndPermissionsSeedDiagnostic(diagnostics, { phase: "failure", ...counts, error });
throw error;
}
}