Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
129 views
in Technique[技术] by (71.8m points)

javascript - How to seed roles and capabilities in MongoDB

I am new to working on a MongoDB and Docker, I am working on an application and couldn't find a more subtle way to seed my database using an npm run command. First I created a file called seed.js and then associated it to npm run seed command on the package.json file.

On the seed.js file I import Mongoose and the models but two things I will need to do is:

  • Create roles, if they don’t exist yet

  • Create capabilities, if they don’t exist yet and associate it to the roles

The Roles that i want to create are:

  • admin (description: Administrator)

  • viewer (description: Viewer)

Capabilities

I need to check each endpoint of the Users service that should require authentication and create an adequate capability. Example: updateUser updates the user data. This could be done by the own user (so there must be an updateUserOwn capability) and by an administrator (that will have an updateUsers capability). I will have to analyse each endpoint and judge what is adequate but I cannot still find a way around getting the initial role and capabilities to the database.

UPDATE: On the seeding itself, the updated solution works, but it requires lot of code and repetition that could probably be fixed by loops. I’d like to start creating the roles first which means creating an array with objects, with the data from the roles to be created. Each role has the fields role and description

const userRole = [{
role: admin
description: Administrator
},
{
role: viewer
description: Viewer
}]

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You are on the right path overall.

Because capabilities are used as a reference you'd have to fetch or create them (get a ref) before assigning them to a role.

This could be your seed logic:

const tasks = [
  Capability.findOneAndUpdate(
    { name: 'updateUserOwn' }, // matches or creates this capability
    { capability: 'updateUser' }, // adds this to the object
    { upsert: true, new: true } // `new` guarantees an object is always returned
  }).exec(),
  Capability.findOneAndUpdate(
    { name: 'updateUsers' },
    { capability: 'updateUser' },
    { upsert: true, new: true }
  }).exec(),
  // Seed more...
];

const [
  updateUserOwn,
  updateUsers,
] = await Promise.all(tasks);

// We can use bulk write for the second transaction so it runs in one go
await Role.bulkWrite([
  { 
     updateOne: {
       filter: { role: 'Admin' },
       update: { capabilities: [updateUsers] },
       upsert: true,
     }
  },
  { 
     updateOne: {
       filter: { role: 'Viewer' },
       update: { capabilities: [updateUserOwn] },
       upsert: true,
     }
  }
]);

We seed capabilities one by one using findOneAndUpdate so we can get a reference to each capability we intend to use on the roles

Then we use bulkWrite to seed the roles

I might have swapped the capabilities and their names but I hope you get the general idea


The seed would have been simpler if there weren't references involved - you could just use bulkWrite everything in one go, but in order to create object with inner references or add references to such object you first need to have the actual reference


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...