Created channel perms schema and api routes.
This commit is contained in:
parent
9dbbc4e924
commit
8384e732f3
21 changed files with 250 additions and 20 deletions
43
src/schemas/channel/channelPermissionSchema.js
Normal file
43
src/schemas/channel/channelPermissionSchema.js
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*Canopy - The next generation of stoner streaming software
|
||||
Copyright (C) 2024 Rainbownapkin and the TTN Community
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||
|
||||
//NPM Imports
|
||||
const {mongoose} = require('mongoose');
|
||||
|
||||
//This originally belonged to the permissionSchema, but this avoids circular dependencies.
|
||||
const rankEnum = ["anon", "user", "gold", "bot", "mod", "admin"];
|
||||
|
||||
//Since this is intended to be used as a child schema for multiple parent schemas, we won't export it as a model
|
||||
const channelPermissionSchema = new mongoose.Schema({
|
||||
manageChannel: {
|
||||
type: mongoose.SchemaTypes.String,
|
||||
enum: rankEnum,
|
||||
default: "admin",
|
||||
required: true
|
||||
},
|
||||
deleteChannel: {
|
||||
type: mongoose.SchemaTypes.String,
|
||||
enum: rankEnum,
|
||||
default: "admin",
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
//Only putting the rank enum out, all other logic should be handled by channelSchema methods to avoid circular dependencies
|
||||
//Alternatively if things get to big we can make it it's own util.
|
||||
channelPermissionSchema.statics.rankEnum = rankEnum;
|
||||
|
||||
module.exports = channelPermissionSchema;
|
||||
186
src/schemas/channel/channelSchema.js
Normal file
186
src/schemas/channel/channelSchema.js
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
/*Canopy - The next generation of stoner streaming software
|
||||
Copyright (C) 2024 Rainbownapkin and the TTN Community
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||
|
||||
//NPM Imports
|
||||
const {mongoose} = require('mongoose');
|
||||
|
||||
//Local Imports
|
||||
const statModel = require('../statSchema.js');
|
||||
const permissionModel = require('../permissionSchema.js');
|
||||
const channelPermissionSchema = require('./channelPermissionSchema.js');
|
||||
|
||||
const channelSchema = new mongoose.Schema({
|
||||
id: {
|
||||
type: mongoose.SchemaTypes.Number,
|
||||
required: true
|
||||
},
|
||||
name: {
|
||||
type: mongoose.SchemaTypes.String,
|
||||
required: true,
|
||||
default: 0
|
||||
},
|
||||
description: {
|
||||
type: mongoose.SchemaTypes.String,
|
||||
required: true,
|
||||
default: 0
|
||||
},
|
||||
thumbnail: {
|
||||
type: mongoose.SchemaTypes.String,
|
||||
required: true,
|
||||
default: "/img/johnny.png"
|
||||
},
|
||||
settings: {
|
||||
hidden: {
|
||||
type: mongoose.SchemaTypes.Boolean,
|
||||
required: true,
|
||||
default: true
|
||||
},
|
||||
},
|
||||
permissions: {
|
||||
type: channelPermissionSchema,
|
||||
default: () => ({})
|
||||
},
|
||||
rankList: [{
|
||||
user: {
|
||||
type: mongoose.SchemaTypes.ObjectID,
|
||||
required: true,
|
||||
ref: "user"
|
||||
},
|
||||
rank: {
|
||||
type: mongoose.SchemaTypes.Boolean,
|
||||
required: true,
|
||||
enum: permissionModel.rankEnum
|
||||
}
|
||||
}]
|
||||
});
|
||||
|
||||
|
||||
channelSchema.pre('save', async function (next){
|
||||
if(this.isModified("name")){
|
||||
if(this.name.match(/^[a-z0-9_\-.]+$/i) == null){
|
||||
throw new Error("Username must only contain alpha-numerics and the following symbols: '-_.'");
|
||||
}
|
||||
}
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
//statics
|
||||
channelSchema.statics.register = async function(channelObj){
|
||||
const {name, description, thumbnail} = channelObj;
|
||||
|
||||
const chanDB = await this.findOne({ name });
|
||||
|
||||
if(chanDB){
|
||||
throw new Error("Channel name already taken!");
|
||||
}else{
|
||||
const id = await statModel.incrementChannelCount();
|
||||
const newChannel = await this.create((thumbnail ? {id, name, description, thumbnail} : {id, name, description}));
|
||||
}
|
||||
}
|
||||
|
||||
channelSchema.statics.getChannelList = async function(includeHidden = false){
|
||||
const chanDB = await this.find({});
|
||||
var chanGuide = [];
|
||||
|
||||
//crawl through channels
|
||||
chanDB.forEach((channel) => {
|
||||
//For each channel, push an object with only the information we need to the channel guide
|
||||
if(!channel.settings.hidden || includeHidden){
|
||||
chanGuide.push({
|
||||
id: channel.id,
|
||||
name: channel.name,
|
||||
description: channel.description,
|
||||
thumbnail: channel.thumbnail
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
//return the channel guide
|
||||
return chanGuide;
|
||||
}
|
||||
|
||||
//methods
|
||||
channelSchema.methods.updateSettings = async function(settingsMap){
|
||||
settingsMap.forEach((value, key) => {
|
||||
if(this.settings[key] == null){
|
||||
throw new Error("Invalid channel setting.");
|
||||
}
|
||||
|
||||
this.settings[key] = value;
|
||||
})
|
||||
|
||||
await this.save();
|
||||
|
||||
return this.settings;
|
||||
}
|
||||
|
||||
channelSchema.methods.updateChannelPerms = async function(permissionsMap){
|
||||
permissionsMap.forEach((value, key) => {
|
||||
if(this.permissions[key] == null){
|
||||
throw new Error("Invalid channel permission.");
|
||||
}
|
||||
|
||||
this.permissions[key] = value;
|
||||
})
|
||||
|
||||
await this.save();
|
||||
|
||||
return this.permissions;
|
||||
}
|
||||
|
||||
channelSchema.methods.channelPermCheck = async function(user, perm){
|
||||
const perms = await permissionSchema.getPerms();
|
||||
|
||||
//Set user to anon rank if no rank was found for the given user
|
||||
if(user == null || user.rank == null){
|
||||
user ={
|
||||
rank: "anon"
|
||||
};
|
||||
}
|
||||
|
||||
//Check if this permission exists
|
||||
if(this.permissions[perm] != null){
|
||||
//if so get required rank as a number
|
||||
requiredRank = permissionModel.rankToNum(this[perm]);
|
||||
//get the required site-wide rank to override channel perms
|
||||
requiredOverrideRank = permissionModel.rankToNum(perms.channeOverrides[perm]);
|
||||
|
||||
//get user site rank as a number
|
||||
userRank = user ? permissionModel.rankToNum(user.rank) : 0;
|
||||
|
||||
}else{
|
||||
//if not scream and shout
|
||||
throw new Error(`Permission check '${perm}' not found!`);
|
||||
}
|
||||
}
|
||||
|
||||
channelSchema.methods.nuke = async function(confirm){
|
||||
if(confirm == "" || confirm == null){
|
||||
throw new Error("Empty Confirmation String!");
|
||||
}else if(confirm != this.name){
|
||||
throw new Error("Bad Confirmation String!");
|
||||
}
|
||||
|
||||
//Annoyingly there isnt a good way to do this from 'this'
|
||||
var oldUser = await module.exports.deleteOne(this);
|
||||
|
||||
if(oldUser == null){
|
||||
throw new Error("Server Error: Unable to delete channel! Please report this error to your server administrator, and with timestamp.");
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = mongoose.model("channel", channelSchema);
|
||||
Loading…
Add table
Add a link
Reference in a new issue