1
0
mirror of https://github.com/Foltik/Shimapan synced 2025-01-07 08:42:49 -05:00

Allow uploading via API key

This commit is contained in:
Jack 2017-10-22 12:19:51 -04:00
parent 826d49424e
commit ebfbcbe2ce
Signed by: foltik
GPG Key ID: 303F88F996E95541
3 changed files with 106 additions and 29 deletions

View File

@ -11,6 +11,7 @@ var UploadSchema = mongoose.Schema({
default: 0 default: 0
}, },
uploader: String, uploader: String,
uploadKey: String,
date: Date, date: Date,
file: Object file: Object
}); });

View File

@ -8,17 +8,40 @@ var login = require('./login.js');
var panel = require('./panel.js'); var panel = require('./panel.js');
var keys = require('./keys.js'); var keys = require('./keys.js');
var fs = require('fs'); var Key = require('../models/Key.js');
var path = require('path');
var requireLogin = function(req, res, next) { var checkApiKey = function (key, cb) {
Key.find({key: key}, function (err, res) {
if (err) throw err;
cb(res.length === 1);
});
};
var requireLogin = function (req, res, next) {
if (!req.session || !req.session.passport) if (!req.session || !req.session.passport)
return res.redirect('/login'); return res.redirect('/login');
else else
return next(); return next();
}; };
module.exports = function(app) { var requireLoginApi = function(req, res, next) {
if (!req.session || !req.session.passport) {
if (!req.body.apikey) {
return res.redirect('/login');
} else {
checkApiKey(res.body.apikey, function(valid) {
if (!valid)
return res.sendStatus(401);
else
return next();
});
}
} else {
return next();
}
};
module.exports = function (app) {
app.use('/', index); app.use('/', index);
app.use('/home', requireLogin, home); app.use('/home', requireLogin, home);
app.use('/v', view); app.use('/v', view);
@ -30,7 +53,7 @@ module.exports = function(app) {
app.use('/panel', requireLogin, panel); app.use('/panel', requireLogin, panel);
app.use('/panel*', requireLogin, panel); app.use('/panel*', requireLogin, panel);
app.use(function(err, req, res, next) { app.use(function (err, req, res, next) {
if (err.name === 'UnauthorizedError') { if (err.name === 'UnauthorizedError') {
res.status(401); res.status(401);
res.json({"message": err.name + ": " + err.message}); res.json({"message": err.name + ": " + err.message});

View File

@ -4,6 +4,7 @@ var router = express.Router();
var mongoose = require('mongoose'); var mongoose = require('mongoose');
var User = require('../models/User.js'); var User = require('../models/User.js');
var Upload = require('../models/Upload.js'); var Upload = require('../models/Upload.js');
var Key = require('../models/Key.js');
var multer = require('multer'); var multer = require('multer');
var dest = multer({dest: 'uploads/'}); var dest = multer({dest: 'uploads/'});
@ -14,12 +15,6 @@ function fileNameExists(name) {
}); });
} }
function updateUserStats(user, size) {
User.updateOne({username: user}, {$inc: {uploadCount: 1, uploadSize: size}}, function (err, res) {
if (err) throw err;
});
}
function genFileName() { function genFileName() {
var charset = "abcdefghijklmnopqrstuvwxyz"; var charset = "abcdefghijklmnopqrstuvwxyz";
do { do {
@ -30,32 +25,90 @@ function genFileName() {
return chars.join(''); return chars.join('');
} }
router.post('/', dest.single('file'), function (req, res) { function updateStats(type, id, size) {
// Size must be below 128 Megabytes (1024*1024*128 Bytes) if (type === 'session') {
if (req.file.size >= 134217728) { User.updateOne({username: id}, {$inc: {uploadCount: 1, uploadSize: size}}, function (err) {
res.status(413).json({'message': 'File too large.'}); if (err) throw err;
return; });
} else if (type === 'apikey') {
Key.updateOne({key: id}, {$inc: {uploadCount: 1, uploadSize: size}}, function (err) {
if (err) throw err;
});
} }
}
updateUserStats(req.session.passport.user, req.file.size); var checkApiKey = function (key, cb) {
Key.find({key: key}, function (err, res) {
if (err) throw err;
cb(res.length === 1, res);
});
};
var entry = { var checkScope = function (type, id, perm, cb) {
name: genFileName(), if (type === 'session') {
uploader: req.session.passport.user, User.findOne({username: id}, function (err, user) {
created: Date.now(), if (err) throw err;
file: req.file cb(user.scope.indexOf(perm) !== -1);
}; });
} else {
Key.findOne({key: id}, function (err, key) {
if (err) throw err;
cb(key.scope.indexOf(perm) !== -1);
});
}
};
Upload.create(entry, function (err, next) { function uploadFile(req, res, type, key) {
if (err) { if (!req.file)
next(err); return res.status(400).json({'message': 'No file specified.'});
} else {
res.send({ // Size must be below 128 Megabytes (1024*1024*128 Bytes)
if (req.file.size >= 134217728)
return res.status(413).json({'message': 'File too large.'});
var uploader = type === 'session' ? req.session.passport.user : key[0].username;
var uploadKey = type === 'apikey' ? key[0].key : null;
var id = type === 'session' ? req.session.passport.user : key[0].key;
checkScope(type, id, 'file.upload', function (valid) {
if (!valid)
return res.status(403).json({'message': 'No permission.'});
var entry = {
name: genFileName(),
uploader: uploader,
uploadKey: uploadKey,
date: Date.now(),
file: req.file
};
updateStats(type, id, req.file.size);
Upload.create(entry, function (err) {
if (err) throw err;
res.status(200).json({
name: entry.name, name: entry.name,
url: 'https://shimapan.rocks/v/' + entry.name url: 'https://shimapan.rocks/v/' + entry.name
}); });
} });
}); });
}
router.post('/', dest.single('file'), function (req, res) {
if (!req.session || !req.session.passport) {
if (!req.body.apikey) {
return res.sendStatus(401);
} else {
checkApiKey(req.body.apikey, function (valid, key) {
if (!valid)
return res.sendStatus(401);
else
uploadFile(req, res, 'apikey', key);
});
}
} else {
uploadFile(req, res, 'session');
}
}); });
module.exports = router; module.exports = router;