CmsWing源码分析(6) 用户认证(一)

2021SC@SDUSC

结束了上次对用户日志的观察

今天我们来分析auth.js这一文件

文件位置:controller/admin/auth.js

CmsWing源码分析(6) 用户认证(一)

 这次的文件信息量还不小,因此决定分拨分析

目录

规则更新

用户分组管理首页

成员管理

管理员用户组数据写入/更新


规则更新

首先进行函数构造与初始化

规则更新就需要涉及更新、删除节点的操作

需要新增的节点将位于nodes内

而需要更新和删除的节点必然需要位于rules内

新增一个节点仅仅需要判定本页面原本没有这个节点

而更新和删除节点的步骤稍稍复杂些

一要将节点的status全部取出

二要根据条件搜索并替换更新某个节点

async updaterules() {
    const nodes = await this.returnnodes(false);
    const AuthRule = this.model('auth_rule');
    const map = {'module': 'admin', 'type': ['in', [1, 2]]};
    const rules = await AuthRule.where(map).order('name').select();

初始化一个用来保存需要插入和更新的新节点的数据数组

然后处理nodes中的节点:

遍历获取每一个nodes的url、title,保存在临时数组中,并将临时数组得到module一项设为‘admin’

然后根据这是否是一个子节点的判断结果,对数组的type一项选择性赋值1或2

再对数组的status项全部赋值为1

此时,我们的url可以被计算出来了,就是原本的url加上title加上刚刚得到的type做一个小写转变版的合成

最后将这个url存储在临时数组中

    const data = {};
nodes.forEach(value => {
      const temp = {};
      temp.name = value.url;
      temp.desc = value.title;
      temp.module = 'admin';
      if (value.pid > 0) {
        temp.type = 1;
      } else {
        temp.type = 2;
      }
      temp.status = 1;
      let url = temp.name + temp.module + temp.type;
      url = url.toLocaleLowerCase();
      data[url] = temp;
    });

保存需要更新的节点,同时也要保存需要删除的节点的id

像节点方法中做的那样,遍历获取rules中的name、module、type,并小写转换合成为新的变量,命名为kye

如果数据库中的规则与配置的节点匹配,说明是需要更新的节点

此时,为需要更新的节点补充id值

在之前就准备好的update数组中,写入需要更新的节点id值

const update = [];
    const ids = [];
    const diff = {};
    rules.forEach((rule, i) => {
      let key = rule.name + rule.module + rule.type;
      key = key.toLocaleLowerCase();
      if (!think.isEmpty(data[key])) { 
        data[key].id = rule.id;
        update.push(data[key]);
        delete data[key];
        delete rule.condition;
        delete rule.pid;
        diff[rule.id] = rule;
      } else {
        if (rule.status == 1) {
          ids.push(rule.id);
        }
      }

最后,做一些接收到的错误的处理

if (!think.isEmpty(update)) {
      update.forEach(row => {
        if (!isObjectValueEqual(row, diff[row.id])) {
          AuthRule.where({id: row.id}).update(row);
        }
      });
    }
    if (!think.isEmpty(ids)) {
      AuthRule.where({id: ['IN', ids]}).update({'status': -1});
    }
    if (!think.isEmpty(data)) {
      AuthRule.addMany(obj_values(data));
    }

    return true;
  }

用户分组管理首页

很熟悉的操作,就和上一次分析的用户日志列表查看异曲同工

先是条件搜索得到list,再将list中的元素一个一个提取出来

最后在标题为“会员管理组”的页面中进行展示

async indexAction() {
    const list = await this.model('member_group').order('sort ASC').select();
    for (const v of list) {
      v.count = await this.model('member').where({groupid: v.groupid, status: 1}).count('id');
    }
    this.assign('list', list);
    this.meta_title = '会员组管理';
    return this.display();
  }

成员管理

首先需要得到本页面使用者的ID,即条件为角色id,模型为'auth_user_role'的数据

初始化一个userdata,用于之后保存用户数据

只要获取成功使用者的ID了,就可以对成员的数据搜索,然后传输到userdata中

于是userdata中的数据可以方便操作者进行修改了

async userlistAction() {
    const id = this.get('id');
    const userid = await this.model('auth_user_role').where({role_id: id}).getField('user_id');
    let userdata;
    if (!think.isEmpty(userid)) {
      userdata = await this.model('member').where({id: ['IN', userid]}).select();
      for (const v of userdata) {
        const role_id = await this.model('auth_user_role').where({user_id: v.id}).getField('role_id', true);
        v.role = await this.model('auth_role').where({id: role_id}).getField('desc', true);
      }
    }

    this.assign('userlist', userdata);
    this.meta_title = '成员管理';
    this.active = 'admin/auth/index';
    return this.display();
  }

管理员用户组数据写入/更新

接上文,这里展现的是具体的修改方法

id是需要被获取的参数,用于确保修改的是同一个人的,而不会乱修改

同时,需要确保正在修改的人是管理员而不是哪个人都可以

在成功更新后,对此做出反馈

async writeroleAction() {
    const map = {};
    map.rule_ids = this.post('rules');
    if (think.isArray(map.rule_ids)) {
      map.rule_ids = map.rule_ids.sort(function(a, b) { return a - b }).join(',');
    }
    map.module = 'admin';
    map.type = 1;
    const id = this.post('id');
    const role = this.model('auth_role');
    await role.where({id: id}).update(map);
    return this.success({name: '更新成功'});
  }

上一篇:geth搭建私有链节点,并开始挖矿


下一篇:以太合约 JSON-RPC API