We saw earlier that API route can bind function or menu, and then perform function authorizationor menu authorization. Actually, API route also provides another type of authorization: Atom Authorization

Atom Authorization is data-based authorization. This chapter describes the basic concepts and usage of Atom Authorization. For more details, see: Cabloy:Atom Authorization

API Route

The core module a-base provides a set of API routes for centralized encapsulation of Atom Actions. For example, API route atom/read is used to read single atom data. Its API route configuration is as follows:

node-modules/a-base-sync/backend/src/routes.js

{ method: 'post', path: 'atom/read', controller: atom,
  meta: { right: { type: 'atom', action: 2 } },
},
name description
meta the metadata of route, which can specify parameters related to middleware
right parameters of middleware right
type authorization type, here is atom
action atom action code

We don’t care whether the user has access to this API route, but whether the user has access to the corresponding atom data. This is the difference between function authorization and atom authorization

Content of Authorization

Authorization of atom action for atomClass, such as the following authorization record:

role atomClass actom action
superuser todo create

Resource Scope of Authorization

When authorizing, you can specify the resource scope of the permission, such as the following authorization record:

role atomClass atom action resource scope
superuser todo read finance department

The role superuser can only read todo data of finance department

Ways to Authorize

Like function authorization, atom authorization has also three ways. Here, appropriate initial privileges are assigned to the relevant roles through the initial authorization approach

Authorization Records

role atomClass atom action resource scope
authenticated todo create
authenticated todo write self
authenticated todo delete self
authenticated todo read self
superuser todo read authenticated

Authorization Codes

src/module/test-todo/backend/src/service/version.js

async init(options) {
  if (options.version === 1) {
    // atomClassName
    const atomClassName = 'todo';
    // add role rights
    const roleRights = [
      { roleName: 'authenticated', action: 'create' },
      { roleName: 'authenticated', action: 'write', scopeNames: 0 },
      { roleName: 'authenticated', action: 'delete', scopeNames: 0 },
      { roleName: 'authenticated', action: 'read', scopeNames: 0 },
      { roleName: 'superuser', action: 'read', scopeNames: 'authenticated' },
    ];
    const module = this.ctx.app.meta.modules[this.ctx.module.info.relativeName];
    const atomClass = await this.ctx.meta.atomClass.get({ atomClassName });
    for (const roleRight of roleRights) {
      // role
      const role = await this.ctx.meta.role.get({ roleName: roleRight.roleName });
      // scope
      let scope;
      if (!roleRight.scopeNames) {
        scope = 0;
      } else {
        const roleScope = await this.ctx.meta.role.get({ roleName: roleRight.scopeNames });
        scope = [ roleScope.id ];
      }
      // add role right
      await this.ctx.meta.role.addRoleRight({
        roleId: role.id,
        atomClassId: atomClass.id,
        action: this.ctx.constant.module('a-base').atom.action[roleRight.action] || module.main.meta.base.atoms.todo
          .actions[roleRight.action].code,
        scope,
      });
    }
    ...
  }
}

Menu of Atom Action

There are two special menu types: Create Atom and Atom List, whose permissions are associated with Atom Actions. For example, when we configure create and read permissions for todo, we have corresponding permissions for Create todo and todo List

Therefore, we need to declare these two types of menu items as follows:

src/module/test-todo/backend/src/meta.js

const meta = {
  base: {
    ...
    functions: {
      createTodo: {
        title: 'Create Todo',
        scene: 'create',
        autoRight: 1,
        atomClassName: 'todo',
        action: 'create',
        sorting: 1,
        menu: 1,
      },
      listTodo: {
        title: 'Todo List',
        scene: 'list',
        autoRight: 1,
        atomClassName: 'todo',
        action: 'read',
        sorting: 1,
        menu: 1,
      },
      ...
    },
  },
名称 说明
autoRight 1: indicates auto right, consistent with the corresponding atom action right
atomClassName atomClass name
action atom action name