fix(striker-ui-api): assert host configured before authentication

main
Tsu-ba-me 2 years ago
parent c33a7e27b6
commit 8403d7315b
  1. 55
      striker-ui-api/src/middlewares/assertInit.ts
  2. 1
      striker-ui-api/src/middlewares/index.ts
  3. 36
      striker-ui-api/src/routes/init.ts
  4. 78
      striker-ui-api/src/routes/static.ts

@ -0,0 +1,55 @@
import { Handler } from 'express';
import { LOCAL } from '../lib/consts';
import { query } from '../lib/accessModule';
import { toHostUUID } from '../lib/convertHostUUID';
import { stderr, stdoutVar } from '../lib/shell';
export const assertInit =
({
fail = (rq, rs) => rs.status(401).send(),
hostUuid: rHostUuid = LOCAL,
invert,
succeed = (rq, rs, nx) => nx(),
}: {
fail?: (...args: Parameters<Handler>) => void;
hostUuid?: string;
invert?: boolean;
succeed?: (...args: Parameters<Handler>) => void;
} = {}): Handler =>
async (...args) => {
const { 1: response } = args;
const hostUuid = toHostUUID(rHostUuid);
let rows: [[string]];
try {
rows = await query(
`SELECT variable_value
FROM variables
WHERE variable_name = 'system::configured'
AND variable_source_table = 'hosts'
AND variable_source_uuid = '${hostUuid}'
LIMIT 1;`,
);
} catch (error) {
stderr(`Failed to get system configured flag; CAUSE: ${error}`);
return response.status(500).send();
}
stdoutVar(rows, `Configured variable of host ${hostUuid}: `);
let condition = rows.length === 1 && rows[0][0] === '1';
if (invert) condition = !condition;
if (condition) {
stderr(`Assert init failed; invert=${invert}`);
return fail(...args);
}
return succeed(...args);
};

@ -2,5 +2,6 @@ import passport from './passport';
import session from './session'; import session from './session';
export * from './assertAuthentication'; export * from './assertAuthentication';
export * from './assertInit';
export { passport, session }; export { passport, session };

@ -1,7 +1,6 @@
import express from 'express'; import express from 'express';
import { getLocalHostUUID, query } from '../lib/accessModule'; import { assertInit } from '../middlewares';
import { stderr, stdoutVar } from '../lib/shell';
import { setMapNetwork } from '../lib/request_handlers/command'; import { setMapNetwork } from '../lib/request_handlers/command';
import { configStriker } from '../lib/request_handlers/host'; import { configStriker } from '../lib/request_handlers/host';
@ -9,38 +8,7 @@ import { getNetworkInterface } from '../lib/request_handlers/network-interface';
const router = express.Router(); const router = express.Router();
router.use(async (request, response, next) => { router.use(assertInit());
const localHostUuid = getLocalHostUUID();
let rows: [[string]];
try {
rows = await query(
`SELECT variable_value
FROM variables
WHERE variable_name = 'system::configured'
AND variable_source_table = 'hosts'
AND variable_source_uuid = '${localHostUuid}'
LIMIT 1;`,
);
} catch (error) {
stderr(`Failed to get system configured flag; CAUSE: ${error}`);
return response.status(500).send();
}
stdoutVar(rows, `system::configured=`);
if (rows.length === 1 && rows[0][0] === '1') {
stderr(
`The init endpoints cannot be used after initializing the local striker`,
);
return response.status(401).send();
}
return next();
});
router router
.get('/network-interface', getNetworkInterface) .get('/network-interface', getNetworkInterface)

@ -1,52 +1,70 @@
import express from 'express'; import express from 'express';
import { existsSync } from 'fs'; import { existsSync } from 'fs';
import path from 'path';
import { SERVER_PATHS } from '../lib/consts'; import { SERVER_PATHS } from '../lib/consts';
import { assertAuthentication } from '../middlewares'; import { assertAuthentication, assertInit } from '../middlewares';
import { stdout } from '../lib/shell'; import { stdout } from '../lib/shell';
const router = express.Router(); const router = express.Router();
const htmlDir = SERVER_PATHS.var.www.html.self; const htmlDir = SERVER_PATHS.var.www.html.self;
router.use( router.use((...args) => {
(...args) => { const [request, response, next] = args;
const { 0: request, 2: next } = args; const { originalUrl, path: initialPath } = request;
const { originalUrl } = request;
if (/^[/]login/.test(originalUrl)) { console.log(`originalUrl=${originalUrl},initialpath=${initialPath}`);
stdout(`Static:login requested`);
return assertAuthentication({ let path = initialPath;
fail: (rt, rq, rs, nx) => nx(),
succeed: '/', if (path.slice(-1) === '/') {
})(...args); if (path.length > 1) {
const q = originalUrl.slice(path.length);
const p = path.slice(0, -1).replace(/\/+/g, '/');
const t = `${p}${q}`;
console.log(`redirect=${t}`);
return response.redirect(t);
} else {
path = '/index';
} }
}
const parts = originalUrl.replace(/[/]$/, '').split('/'); const exted = /\.html$/.test(path) ? path : `${path}.html`;
const tail = parts.pop() || 'index'; const fpath = `${htmlDir}${exted}`;
const extended = /[.]html$/.test(tail) ? tail : `${tail}.html`; const htmlExists = existsSync(fpath);
parts.push(extended); stdout(`static:[${path}] requested; html=${htmlExists}`);
const htmlPath = path.posix.join(htmlDir, ...parts); // Request for asset, i.e., image, script.
const isHtmlExists = existsSync(htmlPath); if (!htmlExists) return next();
if (isHtmlExists) { return assertInit({
stdout(`Static:[${htmlPath}] requested`); // When not configured, redirect to the init page.
fail: (rq, rs, nx) => {
const { path: p } = rq;
const target = '/init';
return assertAuthentication({ fail: '/login', failReturnTo: true })( if (p.startsWith(target)) return nx();
...args,
); return rs.redirect(target);
} },
invert: true,
// When configured, check whether user is authenticated.
succeed: assertAuthentication({
fail: (rt, rq, rs, nx) => {
const { path: p } = rq;
const target = '/login';
if (p.startsWith(target)) return nx();
return next(); return rs.redirect(rt ? `${target}?rt=${rt}` : target);
}, },
express.static(htmlDir, { failReturnTo: !path.startsWith('/login'),
extensions: ['htm', 'html'], }),
}), })(...args);
); }, express.static(htmlDir, { extensions: ['html'] }));
export default router; export default router;

Loading…
Cancel
Save