From 7a3c79a21a34d1c11daaa1e09223fc416ac53f9e Mon Sep 17 00:00:00 2001 From: "mtarrade.sap@gmail.com" Date: Tue, 31 Dec 2024 15:42:55 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8auto=20detect=20protectedApp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- configmanager/server.js | 33 +++++++++++++++++++++- controlpanel/api/routes/protected-app.js | 10 +++++++ controlpanel/api/services/configmanager.js | 17 +++++++++++ controlpanel/api/services/protected-app.js | 24 +++++++++++++++- 4 files changed, 82 insertions(+), 2 deletions(-) diff --git a/configmanager/server.js b/configmanager/server.js index f3cd72b..235fd9a 100644 --- a/configmanager/server.js +++ b/configmanager/server.js @@ -4,6 +4,8 @@ const fs = require('fs'); const hsts = require('hsts') const path = require('path') +const API_URL = "http://controlpanel-api:8050"; + app.use(hsts({ maxAge: 31536000, includeSubDomains: true @@ -35,6 +37,7 @@ app.get('/:namespace/:application', (req, res) => { // Check if the file exists fs.access(filePath, fs.constants.F_OK, (err) => { if (err) { + if (namespace != 'unknown' && application != 'unknown') addApplication(namespace, application); // If the file does not exist, try to return the default config file fs.access(defaultFilePath, fs.constants.F_OK, (err) => { if (err) { @@ -111,6 +114,7 @@ app.get('/:namespace/:application', (req, res) => { // Check if the file exists fs.access(configFilePath, fs.constants.F_OK, err => { if(err) { + if (namespace != 'unknown' && application != 'unknown') addApplication(namespace, application); fs.access(defaultConfigFilePath, fs.constants.F_OK, err => { if (err) { return res.json({ decoy: decoysJson }) } fs.readFile(defaultConfigFilePath, 'utf8', (err, config) => { @@ -280,6 +284,33 @@ app.get('/throttlelist', (req, res) => { return res.json(throttlelist) }) }) + +app.post('/file', (req, res) => { + try { + const { namespace, application } = req.body; + if (!namespace || !application) return res.send({ status: 'error', message: 'Namespace or application field is missing' }); + var filePath = '', configFilePath = '' + if (!namespace.match(/^[a-zA-Z0-9-]+$/) || !application.match(/^[a-zA-Z0-9-]+$/)) { + return res.send({ status: 'error', message: `Bad path provided for decoys config file: ${namespace}, ${application}` }); + } else { + filePath = path.resolve(`/data/cad-${namespace}-${application}.json`); + configFilePath = path.resolve(`/data/config-${namespace}-${application}.json`); + } + if(!fs.existsSync(filePath)) fs.writeFileSync(filePath, ''); + if(!fs.existsSync(configFilePath)) fs.writeFileSync(configFilePath, ''); + return res.send({ status: 'success', message: 'Files created'}); + } catch(e) { + return res.status(500).send({ status: 'error', message: "Error when creating the files" }); + } +}) + +function addApplication(namespace, application) { + try { + fetch(`${API_URL}/protected-app`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ namespace, application })}) + } catch(err) { + console.error("Error when creating the protected app in the api: ", err); + } +} // Start the server app.listen(3000, async () => { console.log('Config manager started'); @@ -299,7 +330,7 @@ app.listen(3000, async () => { loop = 0 while (loop < 5) { try { - await fetch("http://controlpanel-api:8050/configmanager/sync"); + await fetch(`${API_URL}/configmanager/sync`); break; } catch(e) { loop++; diff --git a/controlpanel/api/routes/protected-app.js b/controlpanel/api/routes/protected-app.js index 15896d2..205a620 100644 --- a/controlpanel/api/routes/protected-app.js +++ b/controlpanel/api/routes/protected-app.js @@ -17,4 +17,14 @@ router.get('/', async (req, res) => { } }) +router.post('/', async (req, res) => { + try { + const result = await protectedAppService.createProtectedApp(req.body); + return res.status(result.code).send(result); + } catch(e) { + console.error(e); + return res.status(500).send({ type: 'error', code: 500, message: "Server error", data: e }); + } +}) + module.exports = router; \ No newline at end of file diff --git a/controlpanel/api/services/configmanager.js b/controlpanel/api/services/configmanager.js index 18ad389..82a1b0d 100644 --- a/controlpanel/api/services/configmanager.js +++ b/controlpanel/api/services/configmanager.js @@ -120,5 +120,22 @@ module.exports = { } catch(e) { return { type: 'error', message: "Server error", data: e, code: 500 }; } + }, + /** + * + * @param {DataType.UUID} pa_id UUID of the protected app + * @returns {{type: 'success' | 'error' | 'warning', code: number, data?: Error, message: string}} + */ + createFile: async (pa_id) => { + try { + if (!isUUID(pa_id)) return { type: 'error', code: 400, message: 'Invalid protected app id supplied' }; + const protectedApp = await ProtectedApp.findOne({ where: { id: pa_id } }); + if (!protectedApp) return { type: 'error', code: 404, message: 'Protected app not found' }; + const response = await axios.post(`${CONFIGMANAGER_URL}/file`, { namespace: protectedApp.namespace, application: protectedApp.application }); + if (response.data.status == 'error') return { type: 'error', code: 500, message: response.data.message }; + return { type: 'success', code: 200 , message: response.data.message }; + } catch(e) { + return { type: 'error', message: "Server error", data: e, code: 500 }; + } } } \ No newline at end of file diff --git a/controlpanel/api/services/protected-app.js b/controlpanel/api/services/protected-app.js index 4a83d2e..d5b149e 100644 --- a/controlpanel/api/services/protected-app.js +++ b/controlpanel/api/services/protected-app.js @@ -1,4 +1,5 @@ const ProtectedApp = require("../models/ProtectedApp"); +const configmanager = require("./configmanager"); module.exports = { /** @@ -11,5 +12,26 @@ module.exports = { } catch (e) { throw e; } - } + }, + /** + * Create protected app and calls createFile() from configmanager service + * @param {JSON} protectedApp protectedApp object + * @returns {{type: 'success' | 'error' | 'warning', code: number, message: string}} + */ + createProtectedApp: async (protectedApp) => { + try { + if (typeof protectedApp != 'object') return { type: 'error', code: 422, message: 'Payload should be a json' }; + if (!protectedApp.namespace || !protectedApp.application) return { type: 'error', code: 400, message: 'namespace and/or application are missing' }; + const existingProtectedApp = await ProtectedApp.findOne({ where: { namespace: protectedApp.namespace, application: protectedApp.application }}) + if(existingProtectedApp) { + configmanager.createFile(existingProtectedApp.id); + return { type: 'error', message: 'Protected app alredy exists, cannot create protected app duplicates', code: 409 }; + } + const newProtectedApp = await ProtectedApp.create({ namespace: protectedApp.namespace, application: protectedApp.application }, { returning: true }); + configmanager.createFile(newProtectedApp.id); + return { type: 'success', code: 201, message: 'successful operation' } + } catch (e) { + throw e; + } + }, } \ No newline at end of file