apimiddleware done?

Not fully tested
This commit is contained in:
newtbot 2024-01-16 20:54:18 +08:00
parent 7e4b2d8026
commit 915e4a7e5c
7 changed files with 139 additions and 132 deletions

17
api.MD
View File

@ -1,7 +1,8 @@
//location
//get all
curl localhost/api/v0/location
curl localhost/api/v0/location -H "Authorization: ${1a3eabe1-e1b2-46df-b846-585540c68368}"
curl localhost/api/v0/location -H "Authorization: 1-1ec4ce9d-bcff-46c4-a023-c34171b9ca51"
curl localhost/api/v0/location -H "Authorization: 2-eb0c08b0-250a-4249-8a87-11141e2ff8fb"
//get id
@ -10,18 +11,23 @@ curl http://localhost/api/v0/location/3
//post
curl localhost/api/v0/location/new -H "Content-Type: application/json" -X POST -d '{"name": "SAMPLE", "added_by": "system" , "description": "test"}'
curl localhost/api/v0/location/new -H "Content-Type: application/json" -H "Authorization: 1-1ec4ce9d-bcff-46c4-a023-c34171b9ca51" -X POST -d '{"name": "SAMPLE", "added_by": "system", "description": "test"}'
curl localhost/api/v0/location/new -H "Content-Type: application/json" -H "Authorization: 2-eb0c08b0-250a-4249-8a87-11141e2ff8fb" -X POST -d '{"name": "SAMPLE", "added_by": "system", "description": "test"}'
status: 200
added_name allowed: system , admin
name allowed: shld contain alphanumeric only
//put
curl localhost/api/v0/location/update -X PUT -H "Content-Type: application/json" -d '{"id": "2" , "name": "test", "added_by": "noot", "description": "test12344444444"}'
curl localhost/api/v0/location/update -X PUT -H "Content-Type: application/json" -H "Authorization: 1-1ec4ce9d-bcff-46c4-a023-c34171b9ca51" -d '{"id": "7", "name": "test", "added_by": "system", "description": "test12344444444"}'
status: 200
"message": "Location 13 updated"
//delete
curl localhost/api/v0/location/delete -X DELETE -H "Content-Type: application/json" -d '{"id": "6" }'
curl localhost/api/v0/location/delete -X DELETE -H "Content-Type: application/json" -H "Authorization: 1-1ec4ce9d-bcff-46c4-a023-c34171b9ca51" -d '{"id": "7"}'
status: 200
{
"message": "Location 13 deleted"
@ -166,8 +172,9 @@ http://localhost/api/v0/sensor-data/data?week=1&sensorid=1&locationid=1&page=2&p
curl localhost/api/v0/user/new -H "Content-Type: application/json" -X POST -d '{"username": "system", "password": "thisisthesystemuserpasswordnoob", "email": "system@ecosaver.com", "address": "Nanyang Polytechnic 180 Ang Mo Kio Avenue 8 Singapore 569830", "phone": "12345678"}'
curl localhost/api/v0/user/new -H "Content-Type: application/json" -X POST -d '{"username": "testuser", "password": "thisisthesystemuserpasswordnoob", "email": "testuser@ecosaver.com", "address": "Nanyang Polytechnic 180 Ang Mo Kio Avenue 8 Singapore 569830", "phone": "12345678"}'
curl localhost/api/v0/apikey/new -H "Content-Type: application/json" -X POST -d '{"userid": 1, "permission": "canWrite"'
curl localhost/api/v0/apikey/new -H "Content-Type: application/json" -X POST -d '{"userid": "2", "permission": "canRead"}'

View File

@ -3,7 +3,7 @@ const { Sequelize, DataTypes } = require("sequelize");
const { sequelize } = require("../mySQL");
const { userModel } = require("./userModel");
sequelize.sync();
//sequelize.sync();
const apikeyModel = sequelize.define(
"apikey",
{

View File

@ -6,7 +6,7 @@ const {
isAddress,
} = require("../../functions/validateData");
sequelize.sync();
//sequelize.sync();
const userModel = sequelize.define(
"user",
{

View File

@ -1,30 +1,58 @@
const { sequelize } = require("../database/mySql.js");
const { sequelize } = require("../database/mySql.js");
const { apikeyModel } = require("../database/model/apikeyModel.js");
const { userModel } = require("../database/model/userModel.js");
const { Op, Sequelize } = require("sequelize");
const { hashAPIKey } = require("../functions/bcrypt.js");
const { generateUUID } = require("../functions/generateUUID.js");
async function getUser() {
const user = await userModel.findAll();
return user;
const user = await userModel.findAll();
return user;
}
async function addUser(user) {
//console.log(user);
await userModel.create(user);
//console.log(user);
await userModel.create(user);
}
async function getAPIKey() {
const apikey = await apikeyModel.findAll();
return apikey;
const apikey = await apikeyModel.findAll();
return apikey;
}
async function addAPIKey(apikey) {
await apikeyModel.create(apikey);
/*
1) take userid
2) generate random api key
3) hash the api key
4) append userid with - and api key
5) you give the user rowid-uuidv4
6) store in database
*/
async function addAPIKey(userId, permission) {
let token = await generateUUID();
let usertoken = userId + "-" + token;
let apikey = await hashAPIKey(token);
console.log(token);
console.log(apikey);
await apikeyModel.create({
userid: userId,
apikey: apikey,
permission: permission
});
//user token with -
//"apikey": "1-9beba05f-1bf1-4d8a-9ee8-9f61e1428e20"
return usertoken;
}
module.exports = {
getUser,
addUser,
getAPIKey,
addAPIKey,
getUser,
addUser,
getAPIKey,
addAPIKey,
};

View File

@ -1,6 +1,5 @@
const { getAPIKey , addAPIKey } = require("../functions/apiDatabase.js");
const { hashAPIKey } = require("../functions/bcrypt.js");
const { generateUUID } = require("../functions/generateUUID.js");
const express = require("express");
const router = express.Router();
@ -17,21 +16,18 @@ router.get("/", async (req, res, next) => {
/*
1) ensure user is logged in (frontend session validation blah or wtv)
2) when user click on generate api key button, it will generate a random api key
2) when user click on generate api key button, it will generate a random api key. how to get userid can be done by session or wtv
3) hash the api key
4) store the api key in database
*/
router.post("/new", async (req, res, next) => {
try {
let uuid = await generateUUID()
//attach uuid to req.body
req.body.apikey = uuid
//hash apikey
req.body.apikey = await hashAPIKey(req.body.apikey)
await addAPIKey(req.body);
res.sendStatus(200);
//curl localhost/api/v0/apikey/new -H "Content-Type: application/json" -X POST -d
//'{"userid": 1, "permission": "canWrite"}'
const apikey = await addAPIKey(req.body.userid, req.body.permission);
//console.log(typeof req.body.userid);
//console.log(typeof req.body.permission);
res.json({apikey: apikey});
} catch (error) {
console.error(error);
next(error);
@ -44,26 +40,3 @@ router.post("/new", async (req, res, next) => {
module.exports = router;
/*
async function addAPIKey(userId) {
let apikey = await generateUUID()
apikey = await hashAPIKey(req.body.apikey)
let token = await apikeyModel.create({apikey, userId});
return `${token.id}-${apikey}`
}
router.post("/new", async (req, res, next) => {
try {
let apikey = await addAPIKey(req.body.userid)
res.json({apiKey: apikey})
} catch (error) {
console.error(error);
next(error);
}
});
*/

View File

@ -1,53 +1,55 @@
const { sequelize } = require("../Database/mySql.js");
const { api_log_Model } = require("../Database/model/apiLogModel.js");
const { sequelize } = require("../Database/mySql.js");
const { api_log_Model } = require("../Database/model/apiLogModel.js");
const { sensorDataModel } = require("../Database/model/sensorDataModel.js");
const { apikeyModel } = require("../Database/model/apiKeyModel.js");
const { compareAPIKey } = require("../functions/bcrypt.js");
async function insertLogData(log){
try{
api_log_Model.create({
ip: log.ip,
time: log.time,
method: log.method,
host: log.host,
statusCode: log.statusCode,
Responsesize: log.Responsesize,
referrer: log.referrer,
userAgent: log.userAgent,
});
}
catch
(error){
console.error(error);
}
async function insertLogData(log) {
try {
api_log_Model.create({
ip: log.ip,
time: log.time,
method: log.method,
host: log.host,
statusCode: log.statusCode,
Responsesize: log.Responsesize,
referrer: log.referrer,
userAgent: log.userAgent,
});
} catch (error) {
console.error(error);
}
}
async function insertDatatoDB(data) {
try {
sensorDataModel.create({
sensorid: data.sensorid,
locationid: data.locationid,
measurement: data.measurement,
});
}
catch (error) {
console.error(error);
}
try {
sensorDataModel.create({
sensorid: data.sensorid,
locationid: data.locationid,
measurement: data.measurement,
});
} catch (error) {
console.error(error);
}
}
async function checkAPikey(unverified){
const apikey = apikeyModel.findOne({
where: {
apikey: unverified
}
});
return apikey;
async function checkAPikey(SuppliedKey, rowid) {
try {
const retrivedKey = await apikeyModel.findOne({
raw: true,
attributes: ["apikey" , "permission"],
where: {
userid: rowid,
},
});
//console.log(retrivedKey.apikey);
if (compareAPIKey(SuppliedKey, retrivedKey.apikey)) {
//return true;
return retrivedKey.permission;
}
} catch (error) {
console.error(error);
}
}
module.exports = { insertLogData , insertDatatoDB , checkAPikey};
module.exports = { insertLogData, insertDatatoDB, checkAPikey };

View File

@ -1,17 +1,35 @@
const { compareAPIKey } = require('../functions/bcrypt.js');
const { checkAPikey } = require('../functions/database.js');
async function apikeyCheck(req, res, next) {
//const authHeader = req.headers.authorization
try{
let apikey = req.headers.authorization
if(!apikey){
throw new Error('NotAuthed')
throw new Error('No API key was supplied. Invalid request')
}
else{
//compare apikey to db
//split the string by the -
let splitAPIkey = apikey.split('-');
let rowid = splitAPIkey[0];
//rejoin withouth the rowid
let SuppliedKey = splitAPIkey.slice(1).join('-');
if (checkAPikey(SuppliedKey , rowid))
{
//get permission
let permission = await checkAPikey(SuppliedKey , rowid);
console.log(permission);
if (req.method === 'GET' && permission === 'canRead'){
return next()
}
//['POST', 'PUT', 'PATCH', 'DELETE'].includes(req.method)
if (["GET" , "POST" , "PUT" , "DELETE"].includes(req.method) && permission === 'canWrite'){
console.log('write')
return next()
}
throw new Error('Your API key does not have the correct permissions to access this resource')
}
}
next()
}catch(error){
next(error);
}
@ -21,13 +39,15 @@ async function apikeyCheck(req, res, next) {
module.exports = { apikeyCheck };
/*
1) take user supplied api key
2) hash and salt
3) compare to stored hash and salt in db
4) if match, check permissions
5) if permissions allow, continue
6) else throw error
//web server microservice
1) take user supplied rowid-apikey
2) split the string by -
3) get the rowid
4) get the apikey
5) compare the apikey with the one in database
6) if match, return true
*/
/*
I plan to seed some data in user and api
@ -36,27 +56,4 @@ If it's correct API key and has canWrite perms
I allow it to access put and post
async function auth(req, res, next){
try{
let token = // get token
req.token = token
if(req.method === 'GET' && token.canRead){
return next()
}
if(req.method === 'POST' && token.canWrite){
return next()
}
throw new Error('NotAuthed')
}catch(error){
next(error);
}
}
*/