diff --git a/config-default.json b/config-default.json index 90f5049..f9e426c 100644 --- a/config-default.json +++ b/config-default.json @@ -17,5 +17,6 @@ "testSkipOrthophotos": false, "testSkipDems": false, "token": "", + "authorizedIps": [], "maxImages": "" } \ No newline at end of file diff --git a/config.js b/config.js index aac1dfb..f7025d7 100644 --- a/config.js +++ b/config.js @@ -107,6 +107,7 @@ config.testFailTasks = argv.test_fail_tasks || fromConfigFile("testFailTasks", f config.testSeconds = parseInt(argv.test_seconds || fromConfigFile("testSeconds", 0)); config.powercycle = argv.powercycle || fromConfigFile("powercycle", false); config.token = argv.token || fromConfigFile("token", ""); +config.authorizedIps = fromConfigFile("authorizedIps", []); config.maxImages = parseInt(argv.max_images || fromConfigFile("maxImages", "")) || null; config.webhook = argv.webhook || fromConfigFile("webhook", ""); config.s3Endpoint = argv.s3_endpoint || fromConfigFile("s3Endpoint", ""); diff --git a/libs/auth/TokenIpAuth.js b/libs/auth/TokenIpAuth.js new file mode 100644 index 0000000..e6605b9 --- /dev/null +++ b/libs/auth/TokenIpAuth.js @@ -0,0 +1,65 @@ +/* +Node-OpenDroneMap Node.js App and REST API to access OpenDroneMap. +Copyright (C) 2018 Node-OpenDroneMap Contributors + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +const TokenAuthBase = require("./TokenAuthBase"); + +module.exports = class TokenIpAuth extends TokenAuthBase { + // @param token {String} token to use for authentication + // @param authorizedIps {Array} authorizedIps to use for authentication + + constructor(token, authorizedIps) { + super(token); + + this.token = token; + this.authorizedIps = authorizedIps; + } + + validateToken(token, cb) { + if (this.token === token) { + return cb(null, true); + } else { + cb(new Error("token does not match."), false); + } + } + + validateIp(ip, cb) { + if (this.authorizedIps.indexOf(ip) !== -1) return cb(null, true) + else cb(new Error('IP is not one of authorized IPs.', false)) + } + + getMiddleware() { + return (req, res, next) => { + this.validateToken(req.query.token, (err, valid) => { + if (valid) { + this.validateIp(req.connection.remoteAddress, (err, valid) => { + if (valid) next(); + else { + res.json({ + error: "Invalid authentication IP: " + err.message, + }); + } + }); + } + else { + res.json({ + error: "Invalid authentication token: " + err.message, + }); + } + }); + }; + } +}; diff --git a/libs/auth/factory.js b/libs/auth/factory.js index 1153fb4..6bda2e2 100644 --- a/libs/auth/factory.js +++ b/libs/auth/factory.js @@ -1,12 +1,15 @@ -const NoTokenRequiredAuth = require('./NoTokenRequiredAuth'); -const SimpleTokenAuth = require('./SimpleTokenAuth'); +const NoTokenRequiredAuth = require("./NoTokenRequiredAuth"); +const TokenIpAuth = require("./TokenIpAuth"); +const SimpleTokenAuth = require("./SimpleTokenAuth"); module.exports = { - fromConfig: function(config){ - if (config.token){ + fromConfig: function (config) { + if (config.token && config.authorizedIps && config.authorizedIps.length) { + return new TokenIpAuth(config.token, config.authorizedIps); + } else if (config.token) { return new SimpleTokenAuth(config.token); - }else{ + } else { return new NoTokenRequiredAuth(); } - } -} \ No newline at end of file + }, +}; \ No newline at end of file