mirror of
https://github.com/fosrl/pangolin.git
synced 2025-05-13 05:40:38 +01:00
Ensure the user's actions
This commit is contained in:
parent
143a3b756e
commit
4fc630cf42
9 changed files with 74 additions and 63 deletions
|
@ -5,11 +5,11 @@ meta {
|
||||||
}
|
}
|
||||||
|
|
||||||
get {
|
get {
|
||||||
url: http://localhost:3000/badger/verify-user?sessionId=asdf
|
url: http://localhost:3001/api/v1/badger/verify-user?sessionId=mb52273jkb6t3oys2bx6ur5x7rcrkl26c7warg3e
|
||||||
body: none
|
body: none
|
||||||
auth: none
|
auth: none
|
||||||
}
|
}
|
||||||
|
|
||||||
params:query {
|
params:query {
|
||||||
sessionId: asdf
|
sessionId: mb52273jkb6t3oys2bx6ur5x7rcrkl26c7warg3e
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ meta {
|
||||||
}
|
}
|
||||||
|
|
||||||
get {
|
get {
|
||||||
url: http://localhost:3000/api/v1/traefik-config
|
url: http://localhost:3001/api/v1/traefik-config
|
||||||
body: none
|
body: none
|
||||||
auth: none
|
auth: none
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,42 +8,31 @@ import {
|
||||||
targets,
|
targets,
|
||||||
} from "@server/db/schema";
|
} from "@server/db/schema";
|
||||||
import db from "@server/db";
|
import db from "@server/db";
|
||||||
|
import { createSuperuserRole } from "@server/db/ensureActions";
|
||||||
|
|
||||||
async function insertDummyData() {
|
async function insertDummyData() {
|
||||||
// Insert dummy orgs
|
// Insert dummy orgs
|
||||||
const org1 = db
|
const org1 = db
|
||||||
.insert(orgs)
|
.insert(orgs)
|
||||||
.values({
|
.values({
|
||||||
name: "Fossorial",
|
name: "Default",
|
||||||
domain: "localhost",
|
|
||||||
})
|
|
||||||
.returning()
|
|
||||||
.get();
|
|
||||||
|
|
||||||
const org2 = db
|
|
||||||
.insert(orgs)
|
|
||||||
.values({
|
|
||||||
name: "Fosrl",
|
|
||||||
domain: "fosrl.io",
|
domain: "fosrl.io",
|
||||||
})
|
})
|
||||||
.returning()
|
.returning()
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
// Insert dummy users
|
await createSuperuserRole(org1.orgId);
|
||||||
// await db.insert(users).values([
|
|
||||||
// {
|
const org2 = db
|
||||||
// email: "john@fossorial.com",
|
.insert(orgs)
|
||||||
// groups: "admin,developer",
|
.values({
|
||||||
// },
|
name: "Fossorial",
|
||||||
// {
|
domain: "fossorial.io",
|
||||||
// email: "jane@fossorial.com",
|
})
|
||||||
// groups: "developer",
|
.returning()
|
||||||
// },
|
.get();
|
||||||
// {
|
|
||||||
// email: "bob@fosrl.io",
|
await createSuperuserRole(org2.orgId);
|
||||||
// groups: "admin",
|
|
||||||
// },
|
|
||||||
// ]);
|
|
||||||
|
|
||||||
// Insert dummy exit nodes
|
// Insert dummy exit nodes
|
||||||
const exitNode1 = db
|
const exitNode1 = db
|
||||||
|
|
|
@ -26,7 +26,6 @@ export enum ActionsEnum {
|
||||||
getTarget = "getTarget",
|
getTarget = "getTarget",
|
||||||
listTargets = "listTargets",
|
listTargets = "listTargets",
|
||||||
updateTarget = "updateTarget",
|
updateTarget = "updateTarget",
|
||||||
getUser = "getUser",
|
|
||||||
deleteUser = "deleteUser",
|
deleteUser = "deleteUser",
|
||||||
listUsers = "listUsers"
|
listUsers = "listUsers"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,38 +1,60 @@
|
||||||
import { ActionsEnum } from "@server/auth/actions";
|
import { ActionsEnum } from "@server/auth/actions";
|
||||||
import { db } from "@server/db";
|
import { db } from "@server/db";
|
||||||
import { actions } from "./schema";
|
import { actions, roles, roleActions } from "./schema";
|
||||||
import { eq } from "drizzle-orm";
|
import { eq, and, inArray, notInArray } from "drizzle-orm";
|
||||||
|
|
||||||
// Ensure actions are in the database
|
|
||||||
export async function ensureActions() {
|
export async function ensureActions() {
|
||||||
const actionIds = Object.values(ActionsEnum);
|
const actionIds = Object.values(ActionsEnum);
|
||||||
for (const actionId of actionIds) {
|
const existingActions = await db.select().from(actions).execute();
|
||||||
const existing = await db
|
const existingActionIds = existingActions.map(action => action.actionId);
|
||||||
.select()
|
|
||||||
.from(actions)
|
const actionsToAdd = actionIds.filter(id => !existingActionIds.includes(id));
|
||||||
.where(eq(actions.name, actionId))
|
const actionsToRemove = existingActionIds.filter(id => !actionIds.includes(id as ActionsEnum));
|
||||||
|
|
||||||
|
const defaultRoles = await db
|
||||||
|
.select()
|
||||||
|
.from(roles)
|
||||||
|
.where(eq(roles.isSuperuserRole, true))
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
// Add new actions
|
||||||
|
for (const actionId of actionsToAdd) {
|
||||||
|
await db.insert(actions).values({ actionId }).execute();
|
||||||
|
// Add new actions to the Default role
|
||||||
|
await db.insert(roleActions)
|
||||||
|
.values(defaultRoles.map(role => ({ roleId: role.roleId!, actionId, orgId: role.orgId! })))
|
||||||
.execute();
|
.execute();
|
||||||
if (existing.length === 0) {
|
|
||||||
await db
|
|
||||||
.insert(actions)
|
|
||||||
.values({
|
|
||||||
actionId
|
|
||||||
})
|
|
||||||
.execute();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure all actions are in the database
|
// Remove deprecated actions
|
||||||
const existingActions = await db
|
if (actionsToRemove.length > 0) {
|
||||||
.select()
|
await db.delete(actions).where(inArray(actions.actionId, actionsToRemove)).execute();
|
||||||
.from(actions)
|
await db.delete(roleActions).where(inArray(roleActions.actionId, actionsToRemove)).execute();
|
||||||
.execute();
|
|
||||||
for (const action of existingActions) {
|
|
||||||
if (!actionIds.includes(action.actionId as ActionsEnum)) {
|
|
||||||
await db
|
|
||||||
.delete(actions)
|
|
||||||
.where(eq(actions.actionId, action.actionId))
|
|
||||||
.execute();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createSuperuserRole(orgId: number) {
|
||||||
|
// Create the Default role if it doesn't exist
|
||||||
|
const [insertedRole] = await db
|
||||||
|
.insert(roles)
|
||||||
|
.values({
|
||||||
|
orgId,
|
||||||
|
isSuperuserRole: true,
|
||||||
|
name: 'Superuser',
|
||||||
|
description: 'Superuser role with all actions'
|
||||||
|
})
|
||||||
|
.returning({ roleId: roles.roleId })
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
const roleId = insertedRole.roleId;
|
||||||
|
|
||||||
|
// Add all current actions to the new Default role
|
||||||
|
const actionIds = Object.values(ActionsEnum);
|
||||||
|
await db.insert(roleActions)
|
||||||
|
.values(actionIds.map(actionId => ({
|
||||||
|
roleId,
|
||||||
|
actionId: actionId,
|
||||||
|
orgId
|
||||||
|
})))
|
||||||
|
.execute();
|
||||||
}
|
}
|
|
@ -138,6 +138,7 @@ export const actions = sqliteTable("actions", {
|
||||||
export const roles = sqliteTable("roles", {
|
export const roles = sqliteTable("roles", {
|
||||||
roleId: integer("roleId").primaryKey({ autoIncrement: true }),
|
roleId: integer("roleId").primaryKey({ autoIncrement: true }),
|
||||||
orgId: integer("orgId").references(() => orgs.orgId, { onDelete: "cascade" }),
|
orgId: integer("orgId").references(() => orgs.orgId, { onDelete: "cascade" }),
|
||||||
|
isSuperuserRole: integer("isSuperuserRole", { mode: "boolean" }),
|
||||||
name: text("name").notNull(),
|
name: text("name").notNull(),
|
||||||
description: text("description"),
|
description: text("description"),
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,6 +14,7 @@ import internal from "@server/routers/internal";
|
||||||
import { authenticated, unauthenticated } from "@server/routers/external";
|
import { authenticated, unauthenticated } from "@server/routers/external";
|
||||||
import cookieParser from "cookie-parser";
|
import cookieParser from "cookie-parser";
|
||||||
import { User } from "@server/db/schema";
|
import { User } from "@server/db/schema";
|
||||||
|
import { ensureActions } from "./db/ensureActions";
|
||||||
|
|
||||||
const dev = environment.ENVIRONMENT !== "prod";
|
const dev = environment.ENVIRONMENT !== "prod";
|
||||||
|
|
||||||
|
@ -25,6 +26,8 @@ const internalPort = environment.INTERNAL_PORT;
|
||||||
|
|
||||||
app.prepare().then(() => {
|
app.prepare().then(() => {
|
||||||
|
|
||||||
|
ensureActions(); // This loads the actions into the database
|
||||||
|
|
||||||
// External server
|
// External server
|
||||||
const externalServer = express();
|
const externalServer = express();
|
||||||
externalServer.set("trust proxy", 1);
|
externalServer.set("trust proxy", 1);
|
||||||
|
|
|
@ -7,6 +7,7 @@ import HttpCode from '@server/types/HttpCode';
|
||||||
import createHttpError from 'http-errors';
|
import createHttpError from 'http-errors';
|
||||||
import { ActionsEnum, checkUserActionPermission } from '@server/auth/actions';
|
import { ActionsEnum, checkUserActionPermission } from '@server/auth/actions';
|
||||||
import logger from '@server/logger';
|
import logger from '@server/logger';
|
||||||
|
import { createSuperuserRole } from '@server/db/ensureActions';
|
||||||
|
|
||||||
const createOrgSchema = z.object({
|
const createOrgSchema = z.object({
|
||||||
name: z.string().min(1).max(255),
|
name: z.string().min(1).max(255),
|
||||||
|
@ -50,6 +51,8 @@ export async function createOrg(req: Request, res: Response, next: NextFunction)
|
||||||
domain,
|
domain,
|
||||||
}).returning();
|
}).returning();
|
||||||
|
|
||||||
|
await createSuperuserRole(newOrg[0].orgId);
|
||||||
|
|
||||||
return response(res, {
|
return response(res, {
|
||||||
data: newOrg[0],
|
data: newOrg[0],
|
||||||
success: true,
|
success: true,
|
||||||
|
|
|
@ -18,12 +18,6 @@ export async function getUser(req: Request, res: Response, next: NextFunction):
|
||||||
return next(createHttpError(HttpCode.UNAUTHORIZED, "User not found"));
|
return next(createHttpError(HttpCode.UNAUTHORIZED, "User not found"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// // Check if the user has permission to list sites
|
|
||||||
// const hasPermission = await checkUserActionPermission(ActionsEnum.getUser, req);
|
|
||||||
// if (!hasPermission) {
|
|
||||||
// return next(createHttpError(HttpCode.FORBIDDEN, 'User does not have permission to list sites'));
|
|
||||||
// }
|
|
||||||
|
|
||||||
const user = await db.select()
|
const user = await db.select()
|
||||||
.from(users)
|
.from(users)
|
||||||
.where(eq(users.id, userId))
|
.where(eq(users.id, userId))
|
||||||
|
|
Loading…
Reference in a new issue