Update frontend login page.jsx และ backend
This commit is contained in:
@@ -1,101 +1,136 @@
|
||||
// src/routes/rbac_admin.js (ESM)
|
||||
import { Router } from 'express';
|
||||
import sql from '../db/index.js';
|
||||
import { requirePerm } from '../middleware/requirePerm.js';
|
||||
import PERM from '../config/permissions.js';
|
||||
// FILE: src/routes/rbac_admin.js
|
||||
// RBAC Admin routes
|
||||
// - Manage roles, permissions, user-role assignments
|
||||
// - Requires appropriate permissions via requirePerm middleware
|
||||
// - Uses global scope for all permissions
|
||||
// - rbac_admin.read, rbac_admin.assign_role, rbac_admin.grant_perm
|
||||
|
||||
import { Router } from "express";
|
||||
import sql from "../db/index.js";
|
||||
import { requirePerm } from "../middleware/requirePerm.js";
|
||||
import PERM from "../config/permissions.js";
|
||||
|
||||
const r = Router();
|
||||
|
||||
/** LIST: roles */
|
||||
r.get('/roles',
|
||||
requirePerm(PERM.rbac_admin.read, { scope: 'global' }),
|
||||
r.get(
|
||||
"/roles",
|
||||
requirePerm(PERM.rbac_admin.read, { scope: "global" }),
|
||||
async (req, res) => {
|
||||
const [rows] = await sql.query('SELECT role_id, role_code, role_name, description FROM roles ORDER BY role_code');
|
||||
const [rows] = await sql.query(
|
||||
"SELECT role_id, role_code, role_name, description FROM roles ORDER BY role_code"
|
||||
);
|
||||
res.json(rows);
|
||||
}
|
||||
);
|
||||
|
||||
/** LIST: permissions */
|
||||
r.get('/permissions',
|
||||
requirePerm(PERM.rbac_admin.read, { scope: 'global' }),
|
||||
r.get(
|
||||
"/permissions",
|
||||
requirePerm(PERM.rbac_admin.read, { scope: "global" }),
|
||||
async (req, res) => {
|
||||
const [rows] = await sql.query('SELECT permission_id, permission_code, description FROM permissions ORDER BY permission_code');
|
||||
const [rows] = await sql.query(
|
||||
"SELECT permission_id, permission_code, description FROM permissions ORDER BY permission_code"
|
||||
);
|
||||
res.json(rows);
|
||||
}
|
||||
);
|
||||
|
||||
/** LIST: role→permissions */
|
||||
r.get('/roles/:role_id/permissions',
|
||||
requirePerm(PERM.rbac_admin.read, { scope: 'global' }),
|
||||
r.get(
|
||||
"/roles/:role_id/permissions",
|
||||
requirePerm(PERM.rbac_admin.read, { scope: "global" }),
|
||||
async (req, res) => {
|
||||
const role_id = Number(req.params.role_id);
|
||||
const [rows] = await sql.query(
|
||||
`SELECT p.permission_id, p.permission_code, p.description
|
||||
FROM role_permissions rp
|
||||
JOIN permissions p ON p.permission_id = rp.permission_id
|
||||
WHERE rp.role_id=? ORDER BY p.permission_code`, [role_id]);
|
||||
WHERE rp.role_id=? ORDER BY p.permission_code`,
|
||||
[role_id]
|
||||
);
|
||||
res.json(rows);
|
||||
}
|
||||
);
|
||||
|
||||
/** MAP: role↔permission (grant/revoke) */
|
||||
r.post('/roles/:role_id/permissions',
|
||||
requirePerm(PERM.rbac_admin.grant_perm, { scope: 'global' }),
|
||||
r.post(
|
||||
"/roles/:role_id/permissions",
|
||||
requirePerm(PERM.rbac_admin.grant_perm, { scope: "global" }),
|
||||
async (req, res) => {
|
||||
const role_id = Number(req.params.role_id);
|
||||
const { permission_id } = req.body || {};
|
||||
await sql.query('INSERT IGNORE INTO role_permissions (role_id, permission_id) VALUES (?,?)',
|
||||
[role_id, Number(permission_id)]);
|
||||
res.json({ ok: 1 });
|
||||
}
|
||||
);
|
||||
|
||||
r.delete('/roles/:role_id/permissions/:permission_id',
|
||||
requirePerm(PERM.rbac_admin.grant_perm, { scope: 'global' }),
|
||||
async (req, res) => {
|
||||
const role_id = Number(req.params.role_id);
|
||||
const permission_id = Number(req.params.permission_id);
|
||||
await sql.query('DELETE FROM role_permissions WHERE role_id=? AND permission_id=?', [role_id, permission_id]);
|
||||
res.json({ ok: 1 });
|
||||
}
|
||||
);
|
||||
|
||||
/** LIST: user→roles(+scope) */
|
||||
r.get('/users/:user_id/roles',
|
||||
requirePerm(PERM.rbac_admin.read, { scope: 'global' }),
|
||||
async (req, res) => {
|
||||
const user_id = Number(req.params.user_id);
|
||||
const [rows] = await sql.query(
|
||||
`SELECT ur.user_id, ur.role_id, r.role_code, r.role_name, ur.org_id, ur.project_id
|
||||
FROM user_roles ur JOIN roles r ON r.role_id = ur.role_id
|
||||
WHERE ur.user_id=? ORDER BY r.role_code`, [user_id]);
|
||||
res.json(rows);
|
||||
}
|
||||
);
|
||||
|
||||
/** MAP: user↔role(+scope) (assign / revoke) */
|
||||
r.post('/users/:user_id/roles',
|
||||
requirePerm(PERM.rbac_admin.assign_role, { scope: 'global' }),
|
||||
async (req, res) => {
|
||||
const user_id = Number(req.params.user_id);
|
||||
const { role_id, org_id = null, project_id = null } = req.body || {};
|
||||
await sql.query(
|
||||
'INSERT INTO user_roles (user_id, role_id, org_id, project_id) VALUES (?,?,?,?)',
|
||||
[user_id, Number(role_id), org_id ? Number(org_id) : null, project_id ? Number(project_id) : null]
|
||||
"INSERT IGNORE INTO role_permissions (role_id, permission_id) VALUES (?,?)",
|
||||
[role_id, Number(permission_id)]
|
||||
);
|
||||
res.json({ ok: 1 });
|
||||
}
|
||||
);
|
||||
|
||||
r.delete('/users/:user_id/roles',
|
||||
requirePerm(PERM.rbac_admin.assign_role, { scope: 'global' }),
|
||||
r.delete(
|
||||
"/roles/:role_id/permissions/:permission_id",
|
||||
requirePerm(PERM.rbac_admin.grant_perm, { scope: "global" }),
|
||||
async (req, res) => {
|
||||
const role_id = Number(req.params.role_id);
|
||||
const permission_id = Number(req.params.permission_id);
|
||||
await sql.query(
|
||||
"DELETE FROM role_permissions WHERE role_id=? AND permission_id=?",
|
||||
[role_id, permission_id]
|
||||
);
|
||||
res.json({ ok: 1 });
|
||||
}
|
||||
);
|
||||
|
||||
/** LIST: user→roles(+scope) */
|
||||
r.get(
|
||||
"/users/:user_id/roles",
|
||||
requirePerm(PERM.rbac_admin.read, { scope: "global" }),
|
||||
async (req, res) => {
|
||||
const user_id = Number(req.params.user_id);
|
||||
const [rows] = await sql.query(
|
||||
`SELECT ur.user_id, ur.role_id, r.role_code, r.role_name, ur.org_id, ur.project_id
|
||||
FROM user_roles ur JOIN roles r ON r.role_id = ur.role_id
|
||||
WHERE ur.user_id=? ORDER BY r.role_code`,
|
||||
[user_id]
|
||||
);
|
||||
res.json(rows);
|
||||
}
|
||||
);
|
||||
|
||||
/** MAP: user↔role(+scope) (assign / revoke) */
|
||||
r.post(
|
||||
"/users/:user_id/roles",
|
||||
requirePerm(PERM.rbac_admin.assign_role, { scope: "global" }),
|
||||
async (req, res) => {
|
||||
const user_id = Number(req.params.user_id);
|
||||
const { role_id, org_id = null, project_id = null } = req.body || {};
|
||||
await sql.query(
|
||||
'DELETE FROM user_roles WHERE user_id=? AND role_id=? AND <=> org_id ? AND <=> project_id ?'
|
||||
.replace('<=> org_id ?', (org_id === null ? 'org_id IS ?' : 'org_id=?'))
|
||||
.replace('<=> project_id ?', (project_id === null ? 'project_id IS ?' : 'project_id=?')),
|
||||
"INSERT INTO user_roles (user_id, role_id, org_id, project_id) VALUES (?,?,?,?)",
|
||||
[
|
||||
user_id,
|
||||
Number(role_id),
|
||||
org_id ? Number(org_id) : null,
|
||||
project_id ? Number(project_id) : null,
|
||||
]
|
||||
);
|
||||
res.json({ ok: 1 });
|
||||
}
|
||||
);
|
||||
|
||||
r.delete(
|
||||
"/users/:user_id/roles",
|
||||
requirePerm(PERM.rbac_admin.assign_role, { scope: "global" }),
|
||||
async (req, res) => {
|
||||
const user_id = Number(req.params.user_id);
|
||||
const { role_id, org_id = null, project_id = null } = req.body || {};
|
||||
await sql.query(
|
||||
"DELETE FROM user_roles WHERE user_id=? AND role_id=? AND <=> org_id ? AND <=> project_id ?"
|
||||
.replace("<=> org_id ?", org_id === null ? "org_id IS ?" : "org_id=?")
|
||||
.replace(
|
||||
"<=> project_id ?",
|
||||
project_id === null ? "project_id IS ?" : "project_id=?"
|
||||
),
|
||||
[user_id, Number(role_id), org_id, project_id]
|
||||
);
|
||||
res.json({ ok: 1 });
|
||||
|
||||
Reference in New Issue
Block a user