Android

自定义权限项

更新时间: 2024/08/02 16:25:06

云信本身已提供较为完善的原子化权限,可供开发者调用实现基础的权限管控诉求。但不同行业的产品或同一产品的不同场景,对于用户权限管控的业务需求各有差异。因此云信圈组提供了新增自定义权限项的接口,帮助开发者快速实现符合自身需求的权限管控能力。

使用场景

  • 自定义权限适用于如下业务场景:

    • 拓展圈组现有权限

      以消息相关权限为例。目前身份组虽然提供了发送消息的基础权限,但仍无法满足关于消息类型发送限制的能力。通过自定义权限,应用层可自定义如文字、图片、地理位置、语音消息、表情等消息体的发送权限;

    • 增加圈组权限类型。

      针对类贴吧微博等非即时通讯频道,通过自定义权限,应用层可设置发帖、评论等行为权限,保持权限的一致性。

    • 减少开发者的维护成本。

      云信提供新建、查询、计算等一系列的权限管理能力,应用层不需要独立维护权限,一个接口解决所有权限管控问题。

  • 典型使用案例:

    • 通过自定义权限接口新建发送文字消息权限、发送图片消息权限等不同消息类型的发送权限。然后在不同身份组中开启相应的权限,实现根据不同的身份组给予不同用户发送不同消息类型的权限。例如身份组A 的成员只能发送文字消息,身份组B 的成员只能发送文本和图片消息,身份组B 的成员可发送文字、图片、语音、自定义表情包等所有消息类型。

    • 通过自定义权限接口创建“禁言成员”权限,在应用上层自行实现相应逻辑,使拥有该权限的用户可对频道内其他用户设置禁言时间与禁言效果。

注意事项

当用户需要使用自定义的权限项时,如果用户所在的身份组都是继承状态,那么会按照调用创建身份组自定义权限项接口时传入的 defaultRight 来判定,为 1 则可以使用。

当用户需要修改自定义的权限项时,必须在用户所在的身份组中明确该用户有修改该自定义权限项的权限,即圈组服务器管理员需要先修改该自定义权限项的权限范围(添加或移除某些人的权限),其他服务器成员才能修改该自定义权限项。

前提条件

  • 已开通圈组功能。如未开通,可通过云信官网首页提供的在线聊天、电话等方式联系商务经理开通。
  • 已完成圈组初始化。

实现流程

API 调用时序

uml diagram

流程说明

以下仅对上图中标为橙色的接口调用进行说明,其他相关接口说明请参考相应的接口文档。

  1. 应用后台管理员调用服务端 API qchat/createCustomAuth.action创建身份组自定义权限项,调用时可通过defaultRight参数设置自定义权限是否在身份组中默认开启,如果开启,则身份组成员拥有该权限。此处假设该自定义权限被设置为默认关闭

    自定义权限项创建后,@everyone 身份组和自定义身份组(包括已创建或新创建)将新增该自定义权限项。定义身份组权限项的QChatRoleResource中 value 大于或等于 10000 的权限项即为自定义权限项。

  2. 用户A 在新建服务器身份组中开启该自定义权限项,并邀请用户B 加入身份组,从而将自定义权限授予用户B。

    1. 用户A 调用createServerRole方法创建自定义身份组。对应上一步流程的场景,此时该自定义权限项在该身份组中默认关闭。

      • 调用该方法需要拥有MANAGE_ROLE权限,且必须是相应服务器的成员。如果没有该权限,调用该方法将返回 403 错误码。
      • 新创建的服务器自定义身份组的优先级,必须小于用户已有身份组的最高优先级。

      示例代码如下:

      QChatCreateServerRoleParam createServerRoleParam = new QChatCreateServerRoleParam(943445L,"测试身份组名称", QChatRoleType.CUSTOM);
      createServerRoleParam.setExtension("自定义扩展字段");
      //设置身份组头像url
      createServerRoleParam.setIcon("http://xxxxxx/xxxxx/x/xx");
      QChatAntiSpamConfig antiSpamConfig = new QChatAntiSpamConfig("用户配置的对某些资料内容另外的反垃圾的业务ID");
      antiSpamConfig.setAntiSpamBusinessId(antiSpamConfig);
      NIMClient.getService(QChatRoleService.class).createServerRole(createServerRoleParam).setCallback(
              new RequestCallback<QChatCreateServerRoleResult>() {
                  @Override
                  public void onSuccess(QChatCreateServerRoleResult result) {
                      //创建成功,返回创建成功的Server身份组信息
                      QChatServerRole role = result.getRole();
                  }
      
                  @Override
                  public void onFailed(int code) {
                      //创建失败,返回错误code
                  }
      
                  @Override
                  public void onException(Throwable exception) {
                      //创建异常
                  }
              });
      
    2. 用户A 调用updateServerRole方法可修该服务器身份组,将该自定义权限项开启。

      • 调用该方法需要管理角色权限(MANAGE_ROLE),且必须是相应服务器的成员。如没有该权限,调用将返回 403 错误码。
      • 该方法仅支持修改自定义身份组。创建服务器时默认创建的 @everyone 身份组不支持修改。 如调用该方法修改 @everyone 身份组信息(身份组的名称、图标、自定义扩展和优先级), 将报错(错误码 403)。
      • 调用该方法修改身份组的优先级必须小于用户已有身份组的最高优先级。
      • 用户无法配置自己没有的权限。例如用户没有权限A,则无法修改权限A 的配置。
      • 用户无法将自己拥有的某个权限在全部所属身份组中都设置为DENY。例如用户属于 10 个身份组且这 10 个身份组都开启了权限A,那么用户最多可以将其中 9 个身份组的权限A 设置为DENY

      示例代码如下

      QChatServerRole serverRole = getServerRole();
      QChatUpdateServerRoleParam param = new QChatUpdateServerRoleParam(serverRole.getServerId(), serverRole.getRoleId());
      param.setName("修改身份组名称");
      param.setIcon("http://xxxxxx/xxx/");
      param.setExt("修改自定义扩展");
      //修改优先级,注意优先级不可与其他身份组相同,不然报错
      param.setPriority(2L);
      Map<QChatRoleResource, QChatRoleOption> map = new HashMap<>();
      //赋予管理黑白名单权限
      map.put(QChatRoleResource.MANAGE_BLACK_WHITE_LIST,QChatRoleOption.ALLOW);
      param.setResourceAuths(map);
      QChatAntiSpamConfig antiSpamConfig = new QChatAntiSpamConfig("用户配置的对某些资料内容另外的反垃圾的业务ID");
      antiSpamConfig.setAntiSpamBusinessId(antiSpamConfig);
      NIMClient.getService(QChatRoleService.class).updateServerRole(param).setCallback(new RequestCallback<QChatUpdateServerRoleResult>() {
          @Override
          public void onSuccess(QChatUpdateServerRoleResult result) {
              //更新成功,返回更新后的Server身份组
              QChatServerRole role = result.getRole();
          }
      
          @Override
          public void onFailed(int code) {
              //更新失败,返回错误code
          }
      
          @Override
          public void onException(Throwable exception) {
              //更新异常
          }
      });
      
    3. 用户A 调用addMembersToServerRole 方法将用户B 加入该服务器身份组。加入后,用户B 拥有该自定义权限。

      调用该方法必须先拥有MANAGE_ROLE权限。如果没有该权限,调用该方法将返回 403 错误码。

      示例代码如下:

      NIMClient.getService(QChatRoleService.class).addMembersToServerRole(new QChatAddMembersToServerRoleParam(943445L,5673L,accids)).setCallback(
              new RequestCallback<QChatAddMembersToServerRoleResult>() {
                  @Override
                  public void onSuccess(QChatAddMembersToServerRoleResult result) {
                      //操作成功,返回加入成功和加入失败的成员accid列表
                      List<String> successAccids = result.getSuccessAccids();
                      List<String> failedAccids = result.getFailedAccids();
      
                  }
      
                  @Override
                  public void onFailed(int code) {
                      //操作失败,返回错误code
                  }
      
                  @Override
                  public void onException(Throwable exception) {
                      //操作异常
                  }
              });
      

    通过频道身份组、频道分组、频道用户定制权限实现授权的流程,与通过服务器身份组授权类似,此处不做详细说明。

  3. 用户B 调用checkPermission方法查询自己是否拥有该自定义权限。也可调用checkPermissions方法查询自己是否拥有某些权限。

    示例代码如下:

    查询自己是否拥有某权限
    QChatRoleResource roleResource = QChatRoleResource.MANAGE_BLACK_WHITE_LIST;
    QChatCheckPermissionParam param;
    if(roleResource.isOnlyServerPermission())
    {
        //仅server才有的权限,使用不需要传channelId的构造方法
        param = new QChatCheckPermissionParam(1607312,roleResource);
    }else
    {
        //其他情况,使用需要传channelId的构造方法
        param = new QChatCheckPermissionParam(1607312,1492446,roleResource);
    }
    
    NIMClient.getService(QChatRoleService.class).checkPermission(param).setCallback(new RequestCallback<QChatCheckPermissionResult>() {
        @Override
        public void onSuccess(QChatCheckPermissionResult result) {
            //查询成功,返回是否有权限布尔值
            boolean hasPermission = result.isHasPermission();
        }
    
        @Override
        public void onFailed(int code) {
            //查询失败,返回错误code
        }
    
        @Override
        public void onException(Throwable exception) {
            //查询异常
        }
    });
    
    查询自己是否拥有某些权限
    long serverId = 311254L;
    //如果只查服务器权限,channelId可不传
    long channelId = 211345L;
    //权限列表,一次最多10个权限
    List<QChatRoleResource> permissions = new ArrayList<>();
    permissions.add(QChatRoleResource.SEND_MSG);
    permissions.add(QChatRoleResource.BAN_SERVER_MEMBER);
    
    QChatCheckPermissionsParam param = new QChatCheckPermissionsParam(serverId,channelId,permissions);
    NIMClient.getService(QChatRoleService.class).checkPermissions(param).setCallback(new RequestCallback<QChatCheckPermissionsResult>() {
        @Override
        public void onSuccess(QChatCheckPermissionsResult result) {
            //查询的权限结果,以map方式返回,key为要查询的权限,value为权限结果
            Map<QChatRoleResource, QChatRoleOption> permissionMap = result.getPermissions();
            
        }
    
        @Override
        public void onFailed(int code) {
    
        }
    
        @Override
        public void onException(Throwable exception) {
    
        }
    });
    
  4. 应用上层自行实现相应逻辑,针对用户B 是否拥有该自定义权限进行相应的操作管控。

    云信 IM 服务端不对自定义权限做任何业务逻辑处理,只提供自定义权限项的定义、在身份组添加该权限项、判断某个用户在该权限项下是有权限还是无权限,对于用户在该权限项下有权限或者无权限时能完成何种操作,客户可以自行实现业务逻辑。

此文档是否对你有帮助?
有帮助
去反馈
  • 使用场景
  • 注意事项
  • 前提条件
  • 实现流程