mirror of https://github.com/xfarrow/blink
create organization_routes and organization_admin_routes
This commit is contained in:
parent
091c59d97a
commit
93baed4b0a
|
@ -12,14 +12,17 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Importing modules
|
// Importing modules
|
||||||
|
// TODO: clean up
|
||||||
|
require('dotenv').config();
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const cors = require('cors');
|
const cors = require('cors');
|
||||||
const rateLimit = require('express-rate-limit');
|
const rateLimit = require('express-rate-limit');
|
||||||
const apiController = require('./controllers/api_controller.js'); // todo refactor
|
|
||||||
const personRoutes = require('./routes/person_routes.js');
|
const personRoutes = require('./routes/person_routes.js');
|
||||||
const organizationRoutes = require('./routes/organization_routes.js');
|
const organizationRoutes = require('./routes/organization_routes.js');
|
||||||
|
const organizationAdminRoutes = require('./routes/organization_admin_routes.js');
|
||||||
|
const organizationPostRoutes = require('./routes/organization_post_routes.js')
|
||||||
const jwt_utils = require('./utils/jwt_utils.js');
|
const jwt_utils = require('./utils/jwt_utils.js');
|
||||||
require('dotenv').config();
|
|
||||||
|
|
||||||
// Application configuration
|
// Application configuration
|
||||||
const app = express();
|
const app = express();
|
||||||
|
@ -41,14 +44,14 @@ protectedRoutes.get('/person/myself', personRoutes.getMyself);
|
||||||
protectedRoutes.get('/person/:id', personRoutes.getPerson);
|
protectedRoutes.get('/person/:id', personRoutes.getPerson);
|
||||||
protectedRoutes.put('/person/:id', personRoutes.updatePerson);
|
protectedRoutes.put('/person/:id', personRoutes.updatePerson);
|
||||||
protectedRoutes.delete('/person/delete', personRoutes.deletePerson);
|
protectedRoutes.delete('/person/delete', personRoutes.deletePerson);
|
||||||
protectedRoutes.post('/organization/admin', apiController.addOrganizationAdmin);
|
protectedRoutes.post('/organization/admin', organizationAdminRoutes.addOrganizationAdmin);
|
||||||
protectedRoutes.delete('/organization/removeadmin', apiController.removeOrganizationAdmin);
|
protectedRoutes.delete('/organization/removeadmin', organizationAdminRoutes.removeOrganizationAdmin);
|
||||||
protectedRoutes.post('/organization', organizationRoutes.createOrganization);
|
protectedRoutes.post('/organization', organizationRoutes.createOrganization);
|
||||||
protectedRoutes.get('/organization/:id', organizationRoutes.getOrganization);
|
protectedRoutes.get('/organization/:id', organizationRoutes.getOrganization);
|
||||||
protectedRoutes.put('/organization/:id', organizationRoutes.updateOrganization);
|
protectedRoutes.put('/organization/:id', organizationRoutes.updateOrganization);
|
||||||
protectedRoutes.delete('/organization/:id', organizationRoutes.deleteOrganization);
|
protectedRoutes.delete('/organization/:id', organizationRoutes.deleteOrganization);
|
||||||
protectedRoutes.post('/organization/post', apiController.createOrganizationPost);
|
protectedRoutes.post('/organization/post', organizationPostRoutes.createOrganizationPost);
|
||||||
protectedRoutes.delete('/organization/post/:id', apiController.deleteOrganizationPost);
|
protectedRoutes.delete('/organization/post/:id', organizationPostRoutes.deleteOrganizationPost);
|
||||||
|
|
||||||
// Mounting routes
|
// Mounting routes
|
||||||
app.use('/api', publicRoutes); // Routes not requiring token
|
app.use('/api', publicRoutes); // Routes not requiring token
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
This code is part of Blink
|
||||||
|
licensed under GPLv3
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const knex = require('../utils/knex_config');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST Method
|
||||||
|
*
|
||||||
|
* Add an Administrator to an Organization. Allowed only if the
|
||||||
|
* logged user is an Administrator themselves.
|
||||||
|
*
|
||||||
|
* Required field(s): organization_id, person_id
|
||||||
|
*/
|
||||||
|
async function addOrganizationAdmin(req, res){
|
||||||
|
|
||||||
|
// Ensure that the required fields are present before proceeding
|
||||||
|
if (!req.body.organization_id || !req.body.person_id) {
|
||||||
|
return res.status(400).json({ error : "Invalid request"});
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const isPersonAdmin = await knex('OrganizationAdministrator')
|
||||||
|
.where('id_person', req.jwt.person_id)
|
||||||
|
.where('id_organization', req.body.organization_id)
|
||||||
|
.select('*')
|
||||||
|
.first();
|
||||||
|
|
||||||
|
if(!isPersonAdmin){
|
||||||
|
return res.status(401).json({error : "Forbidden"});
|
||||||
|
}
|
||||||
|
|
||||||
|
await knex('OrganizationAdministrator')
|
||||||
|
.insert({
|
||||||
|
id_person: req.body.person_id,
|
||||||
|
id_organization: req.body.organization_id
|
||||||
|
});
|
||||||
|
return res.status(200).json({success : true});
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error('Error while adding organization admin: ' + error);
|
||||||
|
res.status(500).json({error : "Internal server error"});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DELETE Request
|
||||||
|
*
|
||||||
|
* Deletes a Person from the list of Administrators of an Organization.
|
||||||
|
* The logged user can only remove themselves. If no more Administrators
|
||||||
|
* are left, the Organization is removed.
|
||||||
|
*
|
||||||
|
* Required field(s): organization_id
|
||||||
|
*/
|
||||||
|
async function removeOrganizationAdmin(req, res){
|
||||||
|
|
||||||
|
// Ensure that the required fields are present before proceeding
|
||||||
|
if (!req.body.organization_id) {
|
||||||
|
return res.status(400).json({ error : "Invalid request"});
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
const transaction = await knex.transaction();
|
||||||
|
|
||||||
|
// We lock the table to ensure that we won't have concurrency issues
|
||||||
|
// while checking remainingAdministrators.
|
||||||
|
// TODO: Understand whether a lock on the table is necessary
|
||||||
|
await transaction.raw('LOCK TABLE "OrganizationAdministrator" IN SHARE MODE');
|
||||||
|
|
||||||
|
await transaction('OrganizationAdministrator')
|
||||||
|
.where('id_person', req.jwt.person_id)
|
||||||
|
.where('id_organization', req.body.organization_id)
|
||||||
|
.del();
|
||||||
|
|
||||||
|
// TODO: If the user instead deletes their entire profile, the organization will not be deleted. Fix. (database schema)
|
||||||
|
const remainingAdministrators = await transaction('OrganizationAdministrator')
|
||||||
|
.where({ id_organization: req.body.organization_id });
|
||||||
|
|
||||||
|
if (remainingAdministrators.length === 0) {
|
||||||
|
// If no more users, delete the organization
|
||||||
|
await transaction('Organization')
|
||||||
|
.where('id', req.body.organization_id)
|
||||||
|
.del();
|
||||||
|
}
|
||||||
|
|
||||||
|
await transaction.commit();
|
||||||
|
return res.status(200).json({success : true});
|
||||||
|
}
|
||||||
|
catch (error){
|
||||||
|
console.error(error);
|
||||||
|
return res.status(500).json({ error: "Internal server error"});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
addOrganizationAdmin,
|
||||||
|
removeOrganizationAdmin
|
||||||
|
};
|
|
@ -10,13 +10,10 @@
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
IN THE SOFTWARE.
|
IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
// todo this file shall be deleted
|
|
||||||
require('dotenv').config();
|
|
||||||
const knex = require('../utils/knex_config');
|
const knex = require('../utils/knex_config');
|
||||||
|
|
||||||
// ======== BEGIN API ENDPOINTS ========
|
/**
|
||||||
|
|
||||||
/**
|
|
||||||
* POST Request
|
* POST Request
|
||||||
*
|
*
|
||||||
* Creates a Post belonging to an organization
|
* Creates a Post belonging to an organization
|
||||||
|
@ -24,7 +21,7 @@ const knex = require('../utils/knex_config');
|
||||||
* Required field(s): organization_id, content
|
* Required field(s): organization_id, content
|
||||||
* @returns the inserted Post
|
* @returns the inserted Post
|
||||||
*/
|
*/
|
||||||
async function createOrganizationPost(req, res){
|
async function createOrganizationPost(req, res){
|
||||||
|
|
||||||
// Ensure that the required fields are present before proceeding
|
// Ensure that the required fields are present before proceeding
|
||||||
if (!req.body.organization_id || !req.body.content) {
|
if (!req.body.organization_id || !req.body.content) {
|
||||||
|
@ -55,7 +52,7 @@ const knex = require('../utils/knex_config');
|
||||||
return res.status(200).json(organizationPost[0]);
|
return res.status(200).json(organizationPost[0]);
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.log(error);
|
console.log("Error while creating Organization Post: " + error);
|
||||||
return res.status(500).json({error : "Internal server error"});
|
return res.status(500).json({error : "Internal server error"});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,102 +94,10 @@ async function deleteOrganizationPost(req, res){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* POST Method
|
|
||||||
*
|
|
||||||
* Add an Administrator to an Organization. Allowed only if the
|
|
||||||
* logged user is an Administrator themselves.
|
|
||||||
*
|
|
||||||
* Required field(s): organization_id, person_id
|
|
||||||
*/
|
|
||||||
async function addOrganizationAdmin(req, res){
|
|
||||||
|
|
||||||
// Ensure that the required fields are present before proceeding
|
|
||||||
if (!req.body.organization_id || !req.body.person_id) {
|
|
||||||
return res.status(400).json({ error : "Invalid request"});
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const isPersonAdmin = await knex('OrganizationAdministrator')
|
|
||||||
.where('id_person', req.jwt.person_id)
|
|
||||||
.where('id_organization', req.body.organization_id)
|
|
||||||
.select('*')
|
|
||||||
.first();
|
|
||||||
|
|
||||||
if(!isPersonAdmin){
|
|
||||||
return res.status(401).json({error : "Forbidden"});
|
|
||||||
}
|
|
||||||
|
|
||||||
await knex('OrganizationAdministrator')
|
|
||||||
.insert({
|
|
||||||
id_person: req.body.person_id,
|
|
||||||
id_organization: req.body.organization_id
|
|
||||||
});
|
|
||||||
return res.status(200).json({success : true});
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.error('Error while adding organization admin: ' + error);
|
|
||||||
res.status(500).json({error : "Internal server error"});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DELETE Request
|
|
||||||
*
|
|
||||||
* Deletes a Person from the list of Administrators of an Organization.
|
|
||||||
* The logged user can only remove themselves. If no more Administrators
|
|
||||||
* are left, the Organization is removed.
|
|
||||||
*
|
|
||||||
* Required field(s): organization_id
|
|
||||||
*/
|
|
||||||
async function removeOrganizationAdmin(req, res){
|
|
||||||
|
|
||||||
// Ensure that the required fields are present before proceeding
|
|
||||||
if (!req.body.organization_id) {
|
|
||||||
return res.status(400).json({ error : "Invalid request"});
|
|
||||||
}
|
|
||||||
|
|
||||||
try{
|
|
||||||
const transaction = await knex.transaction();
|
|
||||||
|
|
||||||
// We lock the table to ensure that we won't have concurrency issues
|
|
||||||
// while checking remainingAdministrators.
|
|
||||||
// TODO: Understand whether a lock on the table is necessary
|
|
||||||
await transaction.raw('LOCK TABLE "OrganizationAdministrator" IN SHARE MODE');
|
|
||||||
|
|
||||||
await transaction('OrganizationAdministrator')
|
|
||||||
.where('id_person', req.jwt.person_id)
|
|
||||||
.where('id_organization', req.body.organization_id)
|
|
||||||
.del();
|
|
||||||
|
|
||||||
// TODO: If the user instead deletes their entire profile, the organization will not be deleted. Fix. (database schema)
|
|
||||||
const remainingAdministrators = await transaction('OrganizationAdministrator')
|
|
||||||
.where({ id_organization: req.body.organization_id });
|
|
||||||
|
|
||||||
if (remainingAdministrators.length === 0) {
|
|
||||||
// If no more users, delete the organization
|
|
||||||
await transaction('Organization')
|
|
||||||
.where('id', req.body.organization_id)
|
|
||||||
.del();
|
|
||||||
}
|
|
||||||
|
|
||||||
await transaction.commit();
|
|
||||||
return res.status(200).json({success : true});
|
|
||||||
}
|
|
||||||
catch (error){
|
|
||||||
console.error(error);
|
|
||||||
return res.status(500).json({ error: "Internal server error"});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ======== END API ENDPOINTS ========
|
|
||||||
|
|
||||||
// Exporting a function
|
// Exporting a function
|
||||||
// means making a JavaScript function defined in one
|
// means making a JavaScript function defined in one
|
||||||
// module available for use in another module.
|
// module available for use in another module.
|
||||||
module.exports = {
|
module.exports = {
|
||||||
createOrganizationPost,
|
createOrganizationPost,
|
||||||
deleteOrganizationPost,
|
deleteOrganizationPost
|
||||||
addOrganizationAdmin,
|
|
||||||
removeOrganizationAdmin
|
|
||||||
};
|
};
|
Loading…
Reference in New Issue