banana
/
definma-api
Archived
2
Fork 0
This repository has been archived on 2023-03-02. You can view files and clone it, but cannot push or open issues or pull requests.
definma-api/src/routes/model.ts

175 lines
5.4 KiB
TypeScript

import express from 'express';
import bodyParser from 'body-parser';
import ModelFileModel from '../models/model_file';
import ModelModel from '../models/model';
import UserModel from '../models/user';
import _ from 'lodash';
import ModelValidate from './validate/model';
import res400 from './validate/res400';
import db from '../db';
import mongoose from "mongoose";
const router = express.Router();
router.get('/model/groups', (req, res, next) => {
if (!req.auth(res, ['predict', 'read', 'write', 'dev', 'admin'], 'basic')) return;
let conditions: any = [{}, {}];
if (['dev', 'admin'].indexOf(req.authDetails.level) < 0) { // if not dev or admin, user has to possess model rights
conditions = [
{'models._id': {$in: req.authDetails.models.map(e => mongoose.Types.ObjectId(e))}},
{group: true, 'models.$': true}
]
}
ModelModel.find(...conditions).lean().exec((err, data) => {
if (err) return next(err);
// validate all and filter null values from validation errors
res.json(_.compact(data.map(e => ModelValidate.output(e))));
});
});
router.post('/model/:group', (req, res, next) => {
if (!req.auth(res, ['dev', 'admin'], 'basic')) return;
const {error, value: model} = ModelValidate.input(req.body);
if (error) return res400(error, res);
ModelModel.findOne({group: req.params.group}).lean().exec((err, data) => {
if (err) return next(err);
if (data) { // group exists
if (data.models.find(e => e.name === model.name)) { // name exists, overwrite
ModelModel.findOneAndUpdate(
{$and: [{group: req.params.group}, {'models.name': model.name}]},
{'models.$': model},
{upsert: true}).log(req).lean().exec(err => {
if (err) return next(err);
res.json({status: 'OK'})
});
}
else { // create new
ModelModel.findOneAndUpdate(
{group: req.params.group},
{$push: {models: model as never}}
).log(req).lean().exec(err => {
if (err) return next(err);
res.json({status: 'OK'});
});
}
}
else { // create new group
new ModelModel({group: req.params.group, models: [model]}).save((err, data) => {
if (err) return next(err);
db.log(req, 'models', {_id: data._id}, data.toObject());
res.json({status: 'OK'});
});
}
});
});
router.delete('/model/:group(((?!file)[^\\/]+?))/:name', (req, res, next) => {
if (!req.auth(res, ['dev', 'admin'], 'basic')) return;
ModelModel.findOne({group: req.params.group}).lean().exec((err, data) => {
if (err) return next(err);
if (!data || !data.models.find(e => e.name === req.params.name)) {
return res.status(404).json({status: 'Not found'});
}
// delete all references in user.models
UserModel.updateMany({}, {$pull: {models: data.models.find(e => e.name === req.params.name)._id as never}},
{ multi: true }).log(req).lean().exec(err => {
if (err) return next(err);
if (data.models.length > 1) { // only remove model
ModelModel.findOneAndUpdate(
{group: req.params.group},
{$pull: {models: data.models.find(e => e.name === req.params.name) as never}}
).log(req).lean().exec(err => {
if (err) return next(err);
res.json({status: 'OK'})
});
}
else { // remove document
ModelModel.findOneAndDelete({group: req.params.group}).log(req).lean().exec(err => {
if (err) return next(err);
res.json({status: 'OK'})
});
}
});
});
});
router.get('/model/files', (req, res, next) => {
if (!req.auth(res, ['dev', 'admin'], 'basic')) return;
ModelFileModel.find().exec((err, data) => {
if (err) return next(err);
res.json(data.map(e => ModelValidate.fileOutput(e)));
});
});
router.get('/model/file/:name', (req, res, next) => {
if (!req.auth(res, ['dev', 'admin'], 'all')) return;
ModelFileModel.findOne({name: req.params.name}).lean().exec((err, data) => {
if (err) return next(err);
if (data) {
res.set('Content-Type', 'application/octet-stream');
res.send(data.data.buffer);
}
else {
res.status(404).json({status: 'Not found'});
}
});
});
router.post('/model/file/:name', bodyParser.raw({limit: '50mb'}), (req, res, next) => {
if (!req.auth(res, ['dev', 'admin'], 'all')) return;
ModelFileModel.replaceOne({name: req.params.name}, {name: req.params.name, data: req.body}).setOptions({upsert: true})
.lean().exec(err => {
if (err) return next(err);
res.json({status: 'OK'});
});
});
router.delete('/model/file/:name', (req, res, next) => {
if (!req.auth(res, ['dev', 'admin'], 'basic')) return;
ModelFileModel.findOneAndDelete({name: req.params.name}).lean().exec((err, data) => {
if (err) return next(err);
if (data) {
res.json({status: 'OK'});
}
else {
res.status(404).json({status: 'Not found'});
}
});
});
router.get('/model/authorized/:url', (req, res, next) => {
if (!req.auth(res, ['predict', 'read', 'write', 'dev', 'admin'], 'basic')) return;
if (['dev', 'admin'].indexOf(req.authDetails.level) < 0) { // if not dev or admin, user has to possess model rights
ModelModel.findOne({models: { $elemMatch: {
url: decodeURIComponent(req.params.url),
'_id': {$in: req.authDetails.models.map(e => mongoose.Types.ObjectId(e))}
}}}).lean().exec((err, data) => {
if (err) return next(err);
if (data) {
res.json({status: 'OK'});
}
else {
res.status(403).json({status: 'Forbidden'});
}
});
}
else {
res.json({status: 'OK'});
}
});
module.exports = router;