feat: Implement Group Management with Create and Assign Functionality

This commit is contained in:
Ruben Talstra 2025-02-18 23:02:35 +01:00
parent 06282b584f
commit 39649ce523
No known key found for this signature in database
GPG key ID: 2A5A7174A60F3BEA
7 changed files with 167 additions and 0 deletions

6
api/models/Group.js Normal file
View file

@ -0,0 +1,6 @@
const mongoose = require('mongoose');
const groupSchema = require('~/models/schema/groupSchema');
const Group = mongoose.model('Group', groupSchema);
module.exports = Group;

View file

@ -40,6 +40,7 @@ const { getPreset, getPresets, savePreset, deletePresets } = require('./Preset')
const { createToken, findToken, updateToken, deleteTokens } = require('./Token'); const { createToken, findToken, updateToken, deleteTokens } = require('./Token');
const Balance = require('./Balance'); const Balance = require('./Balance');
const User = require('./User'); const User = require('./User');
const Group = require('./Group');
const Key = require('./Key'); const Key = require('./Key');
module.exports = { module.exports = {
@ -92,6 +93,7 @@ module.exports = {
countActiveSessions, countActiveSessions,
User, User,
Group,
Key, Key,
Balance, Balance,
}; };

View file

@ -0,0 +1,29 @@
const mongoose = require('mongoose');
const groupSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
unique: true,
},
description: {
type: String,
},
allowedEndpoints: [
{
type: String,
required: true,
},
],
allowedModels: [
{
type: String,
},
],
},
{ timestamps: true },
);
module.exports = groupSchema;

View file

@ -143,6 +143,12 @@ const userSchema = mongoose.Schema(
type: Boolean, type: Boolean,
default: false, default: false,
}, },
groups: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Group',
},
],
}, },
{ timestamps: true }, { timestamps: true },

62
config/assign-group.js Normal file
View file

@ -0,0 +1,62 @@
const path = require('path');
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
const { askQuestion, silentExit } = require('./helpers');
const User = require('~/models/User');
const Group = require('~/models/Group');
const connect = require('./connect');
(async () => {
await connect();
console.purple('---------------------------------------');
console.purple('Assign a Group to a User');
console.purple('---------------------------------------');
// Read arguments from CLI or prompt the user
let userEmail = process.argv[2] || (await askQuestion('User email: '));
let groupName = process.argv[3] || (await askQuestion('Group name to assign: '));
// Validate email format
if (!userEmail.includes('@')) {
console.red('Error: Invalid email address!');
silentExit(1);
}
// Find the group by name
const group = await Group.findOne({ name: groupName });
if (!group) {
console.red('Error: No group with that name was found!');
silentExit(1);
}
// Find the user by email
const user = await User.findOne({ email: userEmail });
if (!user) {
console.red('Error: No user with that email was found!');
silentExit(1);
}
console.purple(`Found user: ${user.email}`);
// Assign the group to the user if not already assigned
try {
if (!user.groups) {
user.groups = [];
}
if (!user.groups.includes(group._id)) {
user.groups.push(group._id);
await user.save();
}
} catch (error) {
console.red('Error assigning group to user: ' + error.message);
silentExit(1);
}
console.green(`User ${user.email} successfully assigned to group ${group.name}!`);
silentExit(0);
})();
process.on('uncaughtException', (err) => {
console.error('There was an uncaught error:');
console.error(err);
process.exit(1);
});

60
config/create-group.js Normal file
View file

@ -0,0 +1,60 @@
const path = require('path');
require('module-alias')({ base: path.resolve(__dirname, '..', 'api') });
const { askQuestion, silentExit } = require('./helpers');
const Group = require('~/models/Group');
const connect = require('./connect');
(async () => {
await connect();
console.purple('---------------------------------------');
console.purple('Create a New Group');
console.purple('---------------------------------------');
// Read arguments from CLI or prompt the user
let groupName = process.argv[2] || (await askQuestion('Group name: '));
let groupDescription =
process.argv[3] || (await askQuestion('Group description (optional): '));
let allowedEndpointsInput =
process.argv[4] ||
(await askQuestion(
'Allowed endpoints (comma separated, e.g., "assistants,agents", or enter "*" for all): ',
));
let allowedModelsInput =
process.argv[5] ||
(await askQuestion(
'Allowed models (comma separated, e.g., "gpt-4,chatgpt-4o-latest", or enter "*" for all): ',
));
// Process the comma-separated inputs into arrays
const allowedEndpoints = allowedEndpointsInput
.split(',')
.map((s) => s.trim())
.filter((s) => s);
const allowedModels = allowedModelsInput
.split(',')
.map((s) => s.trim())
.filter((s) => s);
// Create the group document
let group;
try {
group = await Group.create({
name: groupName,
description: groupDescription,
allowedEndpoints,
allowedModels,
});
} catch (error) {
console.red('Error creating group: ' + error.message);
silentExit(1);
}
console.green(`Group created successfully with id: ${group._id}`);
silentExit(0);
})();
process.on('uncaughtException', (err) => {
console.error('There was an uncaught error:');
console.error(err);
process.exit(1);
});

View file

@ -32,6 +32,8 @@
"reset-password": "node config/reset-password.js", "reset-password": "node config/reset-password.js",
"ban-user": "node config/ban-user.js", "ban-user": "node config/ban-user.js",
"delete-user": "node config/delete-user.js", "delete-user": "node config/delete-user.js",
"create-group": "node config/create-group.js",
"assign-group": "node config/assign-group.js",
"update-banner": "node config/update-banner.js", "update-banner": "node config/update-banner.js",
"delete-banner": "node config/delete-banner.js", "delete-banner": "node config/delete-banner.js",
"backend": "cross-env NODE_ENV=production node api/server/index.js", "backend": "cross-env NODE_ENV=production node api/server/index.js",