diff --git a/config.js b/config.js index c29eefe1350c3a8a0175fef466db2d780dec1f01..fedfc4800657f3a6c50c2fdc480369458740e474 100644 --- a/config.js +++ b/config.js @@ -1,5 +1,9 @@ const config = { - port: 9000 + port: 9000, + storage: { + type: "JSON", + path: "./assets/assets.json" + } } module.exports = config; \ No newline at end of file diff --git a/routes/assets.js b/routes/assets.js index 0170d939a66f5fe69971d714c936f8bab3288905..e4381caf9dfc5a6ecd40ef606e8213478a04c7ca 100644 --- a/routes/assets.js +++ b/routes/assets.js @@ -1,6 +1,8 @@ const express = require("express"); const path = require("path"); -const assets = require("../src/assets"); +const BaseStorage = require('../src/baseStorage'); + +const storage = new BaseStorage().getInstance(); let router = express.Router(); @@ -8,7 +10,7 @@ router.route("/*") .get((req, res, next) => { let fullUrl = `${req.protocol}://${req.get("host")}${req.originalUrl}`; - assets.isPublic(fullUrl).then(result => { + storage.isPublic(fullUrl).then(result => { if (result) { next(); } else { diff --git a/src/assets.js b/src/assets.js deleted file mode 100644 index 1e2da84cf4c129f46ade846bd469a5b2b4bbe6da..0000000000000000000000000000000000000000 --- a/src/assets.js +++ /dev/null @@ -1,120 +0,0 @@ -const fs = require("fs"); -const boxIntersect = require("box-intersect"); -const path = require('path'); - -const getLayers = (layers, boundingbox) => { - if (boundingbox === undefined) { - - return new Promise((resolve, reject) => { - fs.readFile("./assets/assets.json", (err, data) => { - if (err) { - reject(); - } - let assets = JSON.parse(data); - let requestedLayers = layers.split(","); - assets = assets.filter(asset => requestedLayers.includes(asset.id)); - assets = assets.filter(asset => asset.scope == "public"); - resolve(assets); - }); - }); - - } else { - - return getIntersectingLayers(layers, boundingbox); - - } - -} - -const getIntersectingLayers = (layers,bb) => { - - return new Promise((resolve, reject) => { - fs.readFile("./assets/assets.json", (err, data) => { - if (err) { - reject(); - } - let assets = JSON.parse(data); - let requestedBB = bb.split(",").map(token => parseFloat(token)); - let requestedLayers = layers.split(","); - - assets = assets.filter(asset => requestedLayers.includes(asset.id)); - assets = assets.filter(asset => asset.scope == "public"); - - assets = assets.filter(asset => { - - let overlaps = boxIntersect([ - [...asset.boundingbox], - [...requestedBB] - ]); - - if (overlaps.length > 0) { - return true; - } - return false; - }); - - resolve(assets); - - }); - }); - -} - -const allLayersExist = (layers) => { - - if (!layers) return Promise.reject(); - - return new Promise((resolve, reject) => { - fs.readFile("./assets/assets.json", (err, data) => { - if (err) { - reject(); - } - let assets = JSON.parse(data); - layers = layers.split(","); - layers.forEach(layer => { - if (assets.findIndex(asset => asset.id == layer) == -1) { - reject(); - } - }); - resolve(); - }); - }); - -} - -const getPublicLayers = () => { - - return new Promise((resolve, reject) => { - fs.readFile("./assets/assets.json", (err, data) => { - let assets = JSON.parse(data); - assets = assets.filter(asset => asset.scope == "public"); - resolve(assets); - }); - }); - -} - -const isPublic = (url) => { - - return new Promise((resolve, reject) => { - fs.readFile("./assets/assets.json", (err, data) => { - let assets = JSON.parse(data); - assets = assets.filter(asset => { - let parentDir = path.dirname(asset.url); - return !path.relative(parentDir, url).startsWith(".."); - }); - if (assets.length == 0) { - resolve(false); - return; - } - if (!assets[0].scope == "public") { - resolve(false); - return; - } - resolve(true); - }); - }); - -} - -module.exports = { getLayers, allLayersExist, getPublicLayers, isPublic }; \ No newline at end of file diff --git a/src/baseStorage.js b/src/baseStorage.js new file mode 100644 index 0000000000000000000000000000000000000000..a31fb7fd3d0a6dce3fbf653ca5309d678b0160b4 --- /dev/null +++ b/src/baseStorage.js @@ -0,0 +1,43 @@ +const config = require("../config"); +const { createStorage } = require("./storageFactory"); + +class BaseStorage { + + constructor(storage) { + this.storage = storage; + } + + getLayers(ids, boundingbox) { + return this.storage.getLayers(ids, boundingbox); + } + + getPublicLayers() { + return this.storage.getPublicLayers(); + } + + isPublic(url) { + return this.storage.isPublic(url); + } + + validateLayers(ids) { + return this.storage.validateLayers(ids); + } + +} + +class BaseStorageInstance { + + constructor() { + if (!BaseStorageInstance.instance) { + const storage = createStorage(config.storage); + BaseStorageInstance.instance = new BaseStorage(storage) + } + } + + getInstance() { + return BaseStorageInstance.instance; + } + +} + +module.exports = BaseStorageInstance; \ No newline at end of file diff --git a/src/getCapabilitiesHandler.js b/src/getCapabilitiesHandler.js index 9ad510a838e5490cc87f57625d5d66546c64b595..94df3890940b157eb085e149b2694697f77315b9 100644 --- a/src/getCapabilitiesHandler.js +++ b/src/getCapabilitiesHandler.js @@ -1,9 +1,11 @@ -const assets = require("../src/assets"); const pug = require("pug"); +const BaseStorage = require('./baseStorage'); + +const storage = new BaseStorage().getInstance(); const getCapabilitiesHandler = (req, res) => { - assets.getPublicLayers().then(layers => { + storage.getPublicLayers().then(layers => { const compiledFunction = pug.compileFile("./views/capabilities.pug"); let capabilities = compiledFunction({ layers: layers }); diff --git a/src/getSceneHandler.js b/src/getSceneHandler.js index 31aa4f369a6632fd407253880f8773f06758b253..fbd0c65ddd8b180468d028faab751e68aef09035 100644 --- a/src/getSceneHandler.js +++ b/src/getSceneHandler.js @@ -1,8 +1,10 @@ -const assets = require("../src/assets"); +const BaseStorage = require('./baseStorage'); + +const storage = new BaseStorage().getInstance(); const getSceneHandler = (req, res) => { - assets.getLayers(req.query.layers, req.query.boundingbox).then(layers => { + storage.getLayers(req.query.layers, req.query.boundingbox).then(layers => { layers = layers.map(layer => { delete layer.scope; diff --git a/src/storage.js b/src/storage.js new file mode 100644 index 0000000000000000000000000000000000000000..e34eaaa53d9aa7bcf3a841b2d705b5980e5e4ffb --- /dev/null +++ b/src/storage.js @@ -0,0 +1,121 @@ +const fs = require("fs"); +const boxIntersect = require("box-intersect"); +const path = require('path'); + +class JSONStorage { + + constructor(path) { + this.path = path; + } + + getLayers(ids, boundingbox) { + if (boundingbox === undefined) { + + return new Promise((resolve, reject) => { + fs.readFile(this.path, (err, data) => { + if (err) { + reject(); + } + let assets = JSON.parse(data); + let requestedLayers = ids.split(","); + assets = assets.filter(asset => requestedLayers.includes(asset.id)); + assets = assets.filter(asset => asset.scope == "public"); + resolve(assets); + }); + }); + + } else { + + return this.getIntersectingLayers(ids, boundingbox); + + } + } + + getPublicLayers() { + return new Promise((resolve, reject) => { + fs.readFile(this.path, (err, data) => { + let assets = JSON.parse(data); + assets = assets.filter(asset => asset.scope == "public"); + resolve(assets); + }); + }); + } + + isPublic(url) { + return new Promise((resolve, reject) => { + fs.readFile(this.path, (err, data) => { + let assets = JSON.parse(data); + assets = assets.filter(asset => { + let parentDir = path.dirname(asset.url); + return !path.relative(parentDir, url).startsWith(".."); + }); + if (assets.length == 0) { + resolve(false); + return; + } + if (!assets[0].scope == "public") { + resolve(false); + return; + } + resolve(true); + }); + }); + } + + validateLayers(ids) { + if (!ids) return Promise.reject(); + + return new Promise((resolve, reject) => { + fs.readFile(this.path, (err, data) => { + if (err) { + reject(); + } + let assets = JSON.parse(data); + let layers = ids.split(","); + layers.forEach(layer => { + if (assets.findIndex(asset => asset.id == layer) == -1) { + reject(); + } + }); + resolve(); + }); + }); + } + + getIntersectingLayers(ids, bb) { + + return new Promise((resolve, reject) => { + fs.readFile(this.path, (err, data) => { + if (err) { + reject(); + } + let assets = JSON.parse(data); + let requestedBB = bb.split(",").map(token => parseFloat(token)); + let requestedLayers = ids.split(","); + + assets = assets.filter(asset => requestedLayers.includes(asset.id)); + assets = assets.filter(asset => asset.scope == "public"); + + assets = assets.filter(asset => { + + let overlaps = boxIntersect([ + [...asset.boundingbox], + [...requestedBB] + ]); + + if (overlaps.length > 0) { + return true; + } + return false; + }); + + resolve(assets); + + }); + }); + + } + +} + +module.exports = JSONStorage; \ No newline at end of file diff --git a/src/storageFactory.js b/src/storageFactory.js new file mode 100644 index 0000000000000000000000000000000000000000..8548f17bde6149ab6568cf21844b6ce84647b86a --- /dev/null +++ b/src/storageFactory.js @@ -0,0 +1,17 @@ +const JSONStorage = require("./storage"); + +const createStorage = (params) => { + + switch (params.type) { + + case "JSON": { + + return new JSONStorage(params.path); + + } + + } + +} + +module.exports = {createStorage}; \ No newline at end of file diff --git a/src/validationCheckFactory.js b/src/validationCheckFactory.js index cc4a0e43021e40e5bcff8803a47546d4b33ebcf1..5e778b550d8e8250295a34068eb83f1f6b175481 100644 --- a/src/validationCheckFactory.js +++ b/src/validationCheckFactory.js @@ -1,6 +1,8 @@ const { query } = require("express-validator"); const { toLower, toUpper, boundingboxIsValid } = require("../src/customSanitizers"); -const assets = require("../src/assets"); +const BaseStorage = require('./baseStorage'); + +const storage = new BaseStorage().getInstance(); const commonChecks = () => { return [ @@ -37,7 +39,7 @@ const getChecksFor = (parameter) => { .matches(/^EPSG:\d{4,5}$/).withMessage("InvalidParameterValue"), query("layers") .exists().withMessage("MissingParameterValue") - .custom(value => assets.allLayersExist(value)).withMessage("UnknownLayer"), + .custom(value => storage.validateLayers(value)).withMessage("UnknownLayer"), query("boundingbox") .optional() .matches(/^((\-?\d+(\.\d+)?),){3}(\-?\d+(\.\d+)?)$/).withMessage("InvalidParameterValue")