Skip to content

Commit 1c6a39d

Browse files
committed
Refactor the upgrade function to use the permission properties in channels and roles defined in channels?
1 parent 424337a commit 1c6a39d

File tree

2 files changed

+127
-145
lines changed

2 files changed

+127
-145
lines changed

src/upgradeDB.js

+70-28
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {UserModel} from './model/users'
1010
import {VisualizerModel} from './model/visualizer'
1111
import {PassportModel} from './model/passport'
1212
import {RoleModel, roles} from './model/role'
13+
import {ChannelModel} from './model/channels'
1314

1415
function dedupName(name, names, num) {
1516
let newName
@@ -301,40 +302,82 @@ upgradeFuncs.push({
301302
func() {
302303
return new Promise(async (resolve, reject) => {
303304
try {
304-
// Create default roles with permissions
305-
for (const [roleName, roleData] of Object.entries(roles)) {
305+
// Fetch channels and get the role names with their associated channels
306+
const channels = await ChannelModel.find()
307+
const existingRoles = JSON.parse(JSON.stringify(roles)) // Deep clone the roles object
308+
309+
channels.forEach(channel => {
310+
if (Array.isArray(channel.allow)) {
311+
if (channel.txViewAcl && channel.txViewAcl.length > 0) {
312+
channel.txViewAcl.forEach(role => {
313+
if (!existingRoles[role]) {
314+
existingRoles[role] = { permissions: {} }
315+
}
316+
if (!existingRoles[role].permissions['transaction-view-specified']) {
317+
existingRoles[role].permissions['transaction-view-specified'] = []
318+
}
319+
existingRoles[role].permissions['transaction-view-specified'].push(channel.name)
320+
if (!existingRoles[role].permissions['channel-view-specified']) {
321+
existingRoles[role].permissions['channel-view-specified'] = []
322+
}
323+
existingRoles[role].permissions['channel-view-specified'].push(channel.name)
324+
existingRoles[role].permissions['client-view-all'] = true
325+
})
326+
}
327+
if (channel.txRerunAcl && channel.txRerunAcl.length > 0) {
328+
channel.txRerunAcl.forEach(role => {
329+
if (!existingRoles[role]) {
330+
existingRoles[role] = { permissions: {} }
331+
}
332+
if (!existingRoles[role].permissions['transaction-rerun-specified']) {
333+
existingRoles[role].permissions['transaction-rerun-specified'] = []
334+
}
335+
existingRoles[role].permissions['transaction-rerun-specified'].push(channel.name)
336+
if (!existingRoles[role].permissions['channel-view-specified']) {
337+
existingRoles[role].permissions['channel-view-specified'] = []
338+
}
339+
existingRoles[role].permissions['channel-view-specified'].push(channel.name)
340+
existingRoles[role].permissions['client-view-all'] = true
341+
})
342+
}
343+
if (channel.txViewFullAcl && channel.txViewFullAcl.length > 0) {
344+
channel.txViewFullAcl.forEach(role => {
345+
if (!existingRoles[role]) {
346+
existingRoles[role] = { permissions: {} }
347+
}
348+
if (!existingRoles[role].permissions['transaction-view-body-specified']) {
349+
existingRoles[role].permissions['transaction-view-body-specified'] = []
350+
}
351+
existingRoles[role].permissions['transaction-view-body-specified'].push(channel.name)
352+
if (!existingRoles[role].permissions['channel-view-specified']) {
353+
existingRoles[role].permissions['channel-view-specified'] = []
354+
}
355+
existingRoles[role].permissions['channel-view-specified'].push(channel.name)
356+
existingRoles[role].permissions['client-view-all'] = true
357+
})
358+
}
359+
}
360+
})
361+
362+
// Create or update roles
363+
for (const [roleName, roleData] of Object.entries(existingRoles)) {
306364
await RoleModel.findOneAndUpdate(
307365
{ name: roleName },
308-
roleData,
366+
{ name: roleName, permissions: roleData.permissions },
309367
{ upsert: true, new: true }
310-
);
311-
logger.info(`Role ${roleName} created or updated`);
368+
)
369+
logger.info(`Role ${roleName} created or updated with permissions`)
312370
}
313371

314-
const users = await UserModel.find();
315-
316-
const userPromises = users.map(async (user) => {
317-
let newGroup = 'manager';
318-
if ((user.groups && user.groups.includes('admin')) || user.superUser) {
319-
newGroup = 'admin';
320-
}
321-
// Update user's groups
322-
user.groups = [newGroup];
323-
324-
return user.save();
325-
});
326-
327-
await Promise.all(userPromises);
328-
329-
logger.info('Successfully updated user groups based on new role model');
330-
resolve();
372+
logger.info('Successfully updated roles')
373+
resolve()
331374
} catch (err) {
332-
logger.error(`Error updating user groups: ${err}`);
333-
reject(err);
375+
logger.error(`Error updating roles: ${err}`)
376+
reject(err)
334377
}
335-
});
378+
})
336379
}
337-
});
380+
})
338381

339382
if (process.env.NODE_ENV === 'test') {
340383
exports.upgradeFuncs = upgradeFuncs
@@ -346,8 +389,7 @@ async function upgradeDbInternal() {
346389
const dbVer =
347390
(await DbVersionModel.findOne()) ||
348391
new DbVersionModel({version: 0, lastUpdated: new Date()})
349-
const upgradeFuncsToRun = upgradeFuncs.slice(dbVer.version)
350-
392+
const upgradeFuncsToRun = upgradeFuncs.slice(dbVer.version)
351393
for (const upgradeFunc of upgradeFuncsToRun) {
352394
await upgradeFunc.func()
353395
dbVer.version++

test/unit/upgradeDBTest.js

+57-117
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ import {
1414
PassportModel,
1515
UserModel,
1616
VisualizerModel,
17-
RoleModel
17+
RoleModel,
18+
ChannelModel,
19+
roles
1820
} from '../../src/model'
19-
2021
describe('Upgrade DB Tests', () => {
2122
const originalUpgradeFuncs = [...upgradeDB.upgradeFuncs]
2223
upgradeDB.upgradeFuncs.length = 0
@@ -548,29 +549,29 @@ describe('Upgrade DB Tests', () => {
548549
})
549550
})
550551

551-
describe(`updateFunction4 - Create default roles with permissions and update user groups`, () => {
552+
describe(`updateFunction4 - Create default roles with permissions`, () => {
552553
const upgradeFunc = originalUpgradeFuncs[4].func
553554

554555
beforeEach(async () => {
555556
await RoleModel.deleteMany({})
556-
await UserModel.deleteMany({})
557+
await ChannelModel.deleteMany({})
557558
})
558559

559560
afterEach(async () => {
560561
await RoleModel.deleteMany({})
561-
await UserModel.deleteMany({})
562+
await ChannelModel.deleteMany({})
562563
})
563564

564565
it('should create default roles if they do not exist', async () => {
565566
await upgradeFunc()
566567

567-
const roles = await RoleModel.find()
568-
roles.length.should.be.exactly(3)
568+
const existingRoles = await RoleModel.find()
569+
existingRoles.length.should.be.exactly(Object.keys(roles).length)
569570

570-
const roleNames = roles.map(r => r.name)
571-
roleNames.should.containEql('manager')
572-
roleNames.should.containEql('admin')
573-
roleNames.should.containEql('operator')
571+
const roleNames = existingRoles.map(r => r.name)
572+
Object.keys(roles).forEach(roleName => {
573+
roleNames.should.containEql(roleName)
574+
})
574575
})
575576

576577
it('should not create duplicate roles if they already exist', async () => {
@@ -579,123 +580,62 @@ describe('Upgrade DB Tests', () => {
579580
await upgradeFunc()
580581

581582
const roles = await RoleModel.find()
582-
roles.length.should.be.exactly(3)
583+
roles.length.should.be.exactly(Object.keys(roles).length)
583584

584585
const adminRoles = roles.filter(r => r.name === 'admin')
585586
adminRoles.length.should.be.exactly(1)
586587
})
587588

588589
it('should set correct permissions for each role', async () => {
589-
await upgradeFunc()
590-
591-
const managerRole = await RoleModel.findOne({name: 'manager'})
592-
const adminRole = await RoleModel.findOne({name: 'admin'})
593-
const operatorRole = await RoleModel.findOne({name: 'operator'})
594-
595-
// Helper function to check permissions
596-
const checkPermissions = (role, expectedPermissions) => {
597-
console.log(`Checking permissions for role: ${role.name}`)
598-
Object.entries(expectedPermissions).forEach(([key, value]) => {
599-
should(role.permissions[key]).equal(value)
600-
})
601-
}
602-
603-
// Admin role permissions
604-
checkPermissions(adminRole, {
605-
'channel-view-all': true,
606-
'channel-manage-all': true,
607-
'client-view-all': true,
608-
'client-manage-all': true,
609-
'transaction-view-all': true,
610-
'transaction-view-body-all': true,
611-
'transaction-rerun-all': true,
612-
'user-view': true,
613-
'user-manage': true,
614-
'visualizer-manage': true,
615-
'visualizer-view': true
616-
// Add other admin permissions as needed
617-
})
618-
619-
// Manager role permissions
620-
checkPermissions(managerRole, {
621-
'channel-view-all': true,
622-
'channel-manage-all': true,
623-
'client-view-all': true,
624-
'client-manage-all': true,
625-
'transaction-view-all': true,
626-
'transaction-view-body-all': true,
627-
'transaction-rerun-all': true,
628-
'user-view': true,
629-
'visualizer-manage': true,
630-
'visualizer-view': true
631-
// Add other manager permissions as needed
632-
})
633-
634-
// Operator role permissions
635-
checkPermissions(operatorRole, {
636-
'channel-view-all': true,
637-
'transaction-view-all': true,
638-
'transaction-view-body-all': true,
639-
'transaction-rerun-all': true
640-
// Add other operator permissions as needed
641-
})
642-
643-
// Check that operator doesn't have certain permissions
644-
should(operatorRole.permissions['user-manage']).be.false()
645-
should(operatorRole.permissions['client-manage-all']).be.false()
646-
})
647-
648-
it('should update user groups to admin for superUsers', async () => {
649-
const superUser = new UserModel({
650-
651-
groups: ['admin'],
652-
firstname: 'Super',
653-
surname: 'User'
654-
})
655-
await superUser.save()
590+
// Create test channels
591+
const channel1 = await new ChannelModel({
592+
name: 'Channel 1',
593+
urlPattern: '/channel1',
594+
allow: ['admin', 'manager'],
595+
txViewAcl: ['admin'],
596+
txRerunAcl: ['admin'],
597+
txViewFullAcl: ['admin']
598+
}).save()
599+
600+
const channel2 = await new ChannelModel({
601+
name: 'Channel 2',
602+
urlPattern: '/channel2',
603+
allow: ['admin', 'manager', 'operator'],
604+
txViewAcl: ['admin', 'manager', 'operator'],
605+
txRerunAcl: ['admin'],
606+
txViewFullAcl: ['admin']
607+
}).save()
656608

657609
await upgradeFunc()
658610

659-
const updatedUser = await UserModel.findOne({email: '[email protected]'})
660-
updatedUser.groups.should.eql(['admin'])
661-
})
611+
const createdRoles = await RoleModel.find()
612+
613+
for (const role of createdRoles) {
614+
should.exist(role)
662615

663-
it('should handle mixed user types correctly', async () => {
664-
const users = [
665-
new UserModel({
666-
667-
groups: ['user'],
668-
firstname: 'Regular',
669-
surname: 'User'
670-
}),
671-
new UserModel({
672-
673-
groups: ['user', 'admin'],
674-
firstname: 'Admin',
675-
surname: 'User'
676-
}),
677-
new UserModel({
678-
679-
groups: ['admin'],
680-
firstname: 'Super',
681-
surname: 'User'
682-
}),
683-
new UserModel({
684-
685-
groups: ['operator'],
686-
firstname: 'Another',
687-
surname: 'User'
688-
})
689-
]
690-
await Promise.all(users.map(user => user.save()))
691-
692-
await upgradeFunc()
616+
// Check default permissions
617+
if (roles[role.name]) {
618+
Object.entries(roles[role.name].permissions).forEach(([key, value]) => {
619+
should(role.permissions[key]).eql(value)
620+
})
621+
}
693622

694-
const updatedUsers = await UserModel.find().sort('email')
695-
updatedUsers[0].groups.should.eql(['admin']) // admin@test.org
696-
updatedUsers[1].groups.should.eql(['manager']) // another@test.org
697-
updatedUsers[2].groups.should.eql(['manager']) // regular@test.org
698-
updatedUsers[3].groups.should.eql(['admin']) // super@test.org
623+
// Check channel-specific permissions
624+
if (role.name === 'admin') {
625+
role.permissions['transaction-view-specified'].should.containEql('Channel 1')
626+
role.permissions['transaction-view-specified'].should.containEql('Channel 2')
627+
role.permissions['transaction-rerun-specified'].should.containEql('Channel 1')
628+
role.permissions['transaction-rerun-specified'].should.containEql('Channel 2')
629+
role.permissions['transaction-view-body-specified'].should.containEql('Channel 1')
630+
role.permissions['transaction-view-body-specified'].should.containEql('Channel 2')
631+
} else if (role.name === 'manager') {
632+
role.permissions['transaction-view-specified'].should.not.containEql('Channel 1')
633+
role.permissions['transaction-view-specified'].should.containEql('Channel 2')
634+
} else if (role.name === 'operator') {
635+
role.permissions['transaction-view-specified'].should.not.containEql('Channel 1')
636+
role.permissions['transaction-view-specified'].should.containEql('Channel 2')
637+
}
638+
}
699639
})
700640
})
701641
})

0 commit comments

Comments
 (0)