mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-04 12:18:42 +08:00 
			
		
		
		
	1. 修改在线会话的实现
2. 接入到会员管理 OAuth2.0
This commit is contained in:
		@@ -4,6 +4,7 @@ import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenCheckRespDTO
 | 
			
		||||
import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenCreateReqDTO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenRespDTO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.convert.auth.OAuth2TokenConvert;
 | 
			
		||||
import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.service.auth.OAuth2TokenService;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
 | 
			
		||||
@@ -22,7 +23,9 @@ public class OAuth2TokenApiImpl implements OAuth2TokenApi {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public OAuth2AccessTokenRespDTO createAccessToken(OAuth2AccessTokenCreateReqDTO reqDTO) {
 | 
			
		||||
        return null;
 | 
			
		||||
        OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.createAccessToken(
 | 
			
		||||
                reqDTO.getUserId(), reqDTO.getUserType(), reqDTO.getClientId());
 | 
			
		||||
        return OAuth2TokenConvert.INSTANCE.convert2(accessTokenDO);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@@ -30,4 +33,16 @@ public class OAuth2TokenApiImpl implements OAuth2TokenApi {
 | 
			
		||||
        return OAuth2TokenConvert.INSTANCE.convert(oauth2TokenService.checkAccessToken(accessToken));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public OAuth2AccessTokenRespDTO removeAccessToken(String accessToken) {
 | 
			
		||||
        OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.removeAccessToken(accessToken);
 | 
			
		||||
        return OAuth2TokenConvert.INSTANCE.convert2(accessTokenDO);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public OAuth2AccessTokenRespDTO refreshAccessToken(String refreshToken, Long clientId) {
 | 
			
		||||
        OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.refreshAccessToken(refreshToken, clientId);
 | 
			
		||||
        return OAuth2TokenConvert.INSTANCE.convert2(accessTokenDO);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.system.convert.auth.AuthConvert;
 | 
			
		||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum;
 | 
			
		||||
import cn.iocoder.yudao.module.system.enums.permission.MenuTypeEnum;
 | 
			
		||||
import cn.iocoder.yudao.module.system.service.auth.AdminAuthService;
 | 
			
		||||
import cn.iocoder.yudao.module.system.service.permission.PermissionService;
 | 
			
		||||
@@ -70,14 +71,15 @@ public class AuthController {
 | 
			
		||||
    public CommonResult<Boolean> logout(HttpServletRequest request) {
 | 
			
		||||
        String token = obtainAuthorization(request, securityProperties.getTokenHeader());
 | 
			
		||||
        if (StrUtil.isNotBlank(token)) {
 | 
			
		||||
            authService.logout(token);
 | 
			
		||||
            authService.logout(token, LoginLogTypeEnum.LOGOUT_SELF.getType());
 | 
			
		||||
        }
 | 
			
		||||
        return success(true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @PostMapping("/refresh-token")
 | 
			
		||||
    @ApiOperation("刷新令牌")
 | 
			
		||||
    @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 TODO 接口文档
 | 
			
		||||
    @ApiImplicitParam(name = "refreshToken", value = "刷新令牌", required = true, dataTypeClass = String.class)
 | 
			
		||||
    @OperateLog(enable = false) // 避免 Post 请求被记录操作日志
 | 
			
		||||
    public CommonResult<AuthLoginRespVO> refreshToken(@RequestParam("refreshToken") String refreshToken) {
 | 
			
		||||
        return success(authService.refreshToken(refreshToken));
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,50 @@
 | 
			
		||||
package cn.iocoder.yudao.module.system.controller.admin.auth;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
 | 
			
		||||
import cn.iocoder.yudao.module.system.controller.admin.auth.vo.token.OAuth2AccessTokenPageReqVO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.controller.admin.auth.vo.token.OAuth2AccessTokenRespVO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.convert.auth.OAuth2TokenConvert;
 | 
			
		||||
import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum;
 | 
			
		||||
import cn.iocoder.yudao.module.system.service.auth.AdminAuthService;
 | 
			
		||||
import cn.iocoder.yudao.module.system.service.auth.OAuth2TokenService;
 | 
			
		||||
import io.swagger.annotations.Api;
 | 
			
		||||
import io.swagger.annotations.ApiImplicitParam;
 | 
			
		||||
import io.swagger.annotations.ApiOperation;
 | 
			
		||||
import org.springframework.security.access.prepost.PreAuthorize;
 | 
			
		||||
import org.springframework.web.bind.annotation.*;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Resource;
 | 
			
		||||
import javax.validation.Valid;
 | 
			
		||||
 | 
			
		||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 | 
			
		||||
 | 
			
		||||
@Api(tags = "管理后台 - OAuth2.0 令牌")
 | 
			
		||||
@RestController
 | 
			
		||||
@RequestMapping("/system/oauth2-token")
 | 
			
		||||
public class OAuth2TokenController {
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private OAuth2TokenService oauth2TokenService;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private AdminAuthService authService;
 | 
			
		||||
 | 
			
		||||
    @GetMapping("/page")
 | 
			
		||||
    @ApiOperation(value = "获得访问令牌分页", notes = "只返回有效期内的")
 | 
			
		||||
    @PreAuthorize("@ss.hasPermission('system:oauth2-token:page')")
 | 
			
		||||
    public CommonResult<PageResult<OAuth2AccessTokenRespVO>> getAccessTokenPage(@Valid OAuth2AccessTokenPageReqVO reqVO) {
 | 
			
		||||
        PageResult<OAuth2AccessTokenDO> pageResult = oauth2TokenService.getAccessTokenPage(reqVO);
 | 
			
		||||
        return success(OAuth2TokenConvert.INSTANCE.convert(pageResult));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @DeleteMapping("/delete")
 | 
			
		||||
    @ApiOperation("删除访问令牌")
 | 
			
		||||
    @ApiImplicitParam(name = "accessToken", value = "访问令牌", required = true, dataTypeClass = String.class, example = "tudou")
 | 
			
		||||
    @PreAuthorize("@ss.hasPermission('system:oauth2-token:delete')")
 | 
			
		||||
    public CommonResult<Boolean> deleteAccessToken(@RequestParam("accessToken") String accessToken) {
 | 
			
		||||
        authService.logout(accessToken, LoginLogTypeEnum.LOGOUT_DELETE.getType());
 | 
			
		||||
        return success(true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,23 @@
 | 
			
		||||
package cn.iocoder.yudao.module.system.controller.admin.auth.vo.token;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
 | 
			
		||||
import io.swagger.annotations.ApiModel;
 | 
			
		||||
import io.swagger.annotations.ApiModelProperty;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.EqualsAndHashCode;
 | 
			
		||||
 | 
			
		||||
@ApiModel("管理后台 - 访问令牌分页 Request VO")
 | 
			
		||||
@Data
 | 
			
		||||
@EqualsAndHashCode(callSuper = true)
 | 
			
		||||
public class OAuth2AccessTokenPageReqVO extends PageParam {
 | 
			
		||||
 | 
			
		||||
    @ApiModelProperty(value = "用户编号", required = true, example = "666")
 | 
			
		||||
    private Long userId;
 | 
			
		||||
 | 
			
		||||
    @ApiModelProperty(value = "用户类型", required = true, example = "2", notes = "参见 UserTypeEnum 枚举")
 | 
			
		||||
    private Integer userType;
 | 
			
		||||
 | 
			
		||||
    @ApiModelProperty(value = "客户端编号", required = true, example = "2")
 | 
			
		||||
    private Long clientId;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,41 @@
 | 
			
		||||
package cn.iocoder.yudao.module.system.controller.admin.auth.vo.token;
 | 
			
		||||
 | 
			
		||||
import io.swagger.annotations.ApiModel;
 | 
			
		||||
import io.swagger.annotations.ApiModelProperty;
 | 
			
		||||
import lombok.AllArgsConstructor;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.NoArgsConstructor;
 | 
			
		||||
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
 | 
			
		||||
@ApiModel("管理后台 - 访问令牌 Response VO")
 | 
			
		||||
@Data
 | 
			
		||||
@NoArgsConstructor
 | 
			
		||||
@AllArgsConstructor
 | 
			
		||||
public class OAuth2AccessTokenRespVO {
 | 
			
		||||
 | 
			
		||||
    @ApiModelProperty(value = "编号", required = true, example = "1024")
 | 
			
		||||
    private Long id;
 | 
			
		||||
 | 
			
		||||
    @ApiModelProperty(value = "访问令牌", required = true, example = "tudou")
 | 
			
		||||
    private String accessToken;
 | 
			
		||||
 | 
			
		||||
    @ApiModelProperty(value = "刷新令牌", required = true, example = "nice")
 | 
			
		||||
    private String refreshToken;
 | 
			
		||||
 | 
			
		||||
    @ApiModelProperty(value = "用户编号", required = true, example = "666")
 | 
			
		||||
    private Long userId;
 | 
			
		||||
 | 
			
		||||
    @ApiModelProperty(value = "用户类型", required = true, example = "2", notes = "参见 UserTypeEnum 枚举")
 | 
			
		||||
    private Integer userType;
 | 
			
		||||
 | 
			
		||||
    @ApiModelProperty(value = "客户端编号", required = true, example = "2")
 | 
			
		||||
    private Long clientId;
 | 
			
		||||
 | 
			
		||||
    @ApiModelProperty(value = "创建时间", required = true)
 | 
			
		||||
    private Date createTime;
 | 
			
		||||
 | 
			
		||||
    @ApiModelProperty(value = "过期时间", required = true)
 | 
			
		||||
    private Date expiresTime;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,9 @@
 | 
			
		||||
package cn.iocoder.yudao.module.system.convert.auth;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
 | 
			
		||||
import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenCheckRespDTO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenRespDTO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.controller.admin.auth.vo.token.OAuth2AccessTokenRespVO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO;
 | 
			
		||||
import org.mapstruct.Mapper;
 | 
			
		||||
import org.mapstruct.factory.Mappers;
 | 
			
		||||
@@ -12,4 +15,8 @@ public interface OAuth2TokenConvert {
 | 
			
		||||
 | 
			
		||||
    OAuth2AccessTokenCheckRespDTO convert(OAuth2AccessTokenDO bean);
 | 
			
		||||
 | 
			
		||||
    PageResult<OAuth2AccessTokenRespVO> convert(PageResult<OAuth2AccessTokenDO> page);
 | 
			
		||||
 | 
			
		||||
    OAuth2AccessTokenRespDTO convert2(OAuth2AccessTokenDO bean);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,13 @@
 | 
			
		||||
package cn.iocoder.yudao.module.system.dal.mysql.auth;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
 | 
			
		||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 | 
			
		||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 | 
			
		||||
import cn.iocoder.yudao.module.system.controller.admin.auth.vo.token.OAuth2AccessTokenPageReqVO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO;
 | 
			
		||||
import org.apache.ibatis.annotations.Mapper;
 | 
			
		||||
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
@Mapper
 | 
			
		||||
@@ -17,4 +21,13 @@ public interface OAuth2AccessTokenMapper extends BaseMapperX<OAuth2AccessTokenDO
 | 
			
		||||
        return selectList(OAuth2AccessTokenDO::getRefreshToken, refreshToken);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    default PageResult<OAuth2AccessTokenDO> selectPage(OAuth2AccessTokenPageReqVO reqVO) {
 | 
			
		||||
        return selectPage(reqVO, new LambdaQueryWrapperX<OAuth2AccessTokenDO>()
 | 
			
		||||
                .eqIfPresent(OAuth2AccessTokenDO::getUserId, reqVO.getUserId())
 | 
			
		||||
                .eqIfPresent(OAuth2AccessTokenDO::getUserType, reqVO.getUserType())
 | 
			
		||||
                .eqIfPresent(OAuth2AccessTokenDO::getClientId, reqVO.getClientId())
 | 
			
		||||
                .gt(OAuth2AccessTokenDO::getExpiresTime, new Date())
 | 
			
		||||
                .orderByDesc(OAuth2AccessTokenDO::getId));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -25,8 +25,9 @@ public interface AdminAuthService {
 | 
			
		||||
     * 基于 token 退出登录
 | 
			
		||||
     *
 | 
			
		||||
     * @param token token
 | 
			
		||||
     * @param logType 登出类型
 | 
			
		||||
     */
 | 
			
		||||
    void logout(String token);
 | 
			
		||||
    void logout(String token, Integer logType);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 短信验证码发送
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@ import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
 | 
			
		||||
import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
 | 
			
		||||
import cn.iocoder.yudao.module.system.service.common.CaptchaService;
 | 
			
		||||
import cn.iocoder.yudao.module.system.service.logger.LoginLogService;
 | 
			
		||||
import cn.iocoder.yudao.module.system.service.member.MemberService;
 | 
			
		||||
import cn.iocoder.yudao.module.system.service.social.SocialUserService;
 | 
			
		||||
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
 | 
			
		||||
import com.google.common.annotations.VisibleForTesting;
 | 
			
		||||
@@ -51,6 +52,8 @@ public class AdminAuthServiceImpl implements AdminAuthService {
 | 
			
		||||
    private OAuth2TokenService oauth2TokenService;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private SocialUserService socialUserService;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private MemberService memberService;
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private Validator validator;
 | 
			
		||||
@@ -209,23 +212,27 @@ public class AdminAuthServiceImpl implements AdminAuthService {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void logout(String token) {
 | 
			
		||||
    public void logout(String token, Integer logType) {
 | 
			
		||||
        // 删除访问令牌
 | 
			
		||||
        OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.removeAccessToken(token);
 | 
			
		||||
        if (accessTokenDO == null) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        // 删除成功,则记录登出日志
 | 
			
		||||
        createLogoutLog(accessTokenDO.getUserId());
 | 
			
		||||
        createLogoutLog(accessTokenDO.getUserId(), accessTokenDO.getUserType(), logType);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void createLogoutLog(Long userId) {
 | 
			
		||||
    private void createLogoutLog(Long userId, Integer userType, Integer logType) {
 | 
			
		||||
        LoginLogCreateReqDTO reqDTO = new LoginLogCreateReqDTO();
 | 
			
		||||
        reqDTO.setLogType(LoginLogTypeEnum.LOGOUT_SELF.getType());
 | 
			
		||||
        reqDTO.setLogType(logType);
 | 
			
		||||
        reqDTO.setTraceId(TracerUtils.getTraceId());
 | 
			
		||||
        reqDTO.setUserId(userId);
 | 
			
		||||
        reqDTO.setUsername(getUsername(userId));
 | 
			
		||||
        reqDTO.setUserType(getUserType().getValue());
 | 
			
		||||
        reqDTO.setUserType(userType);
 | 
			
		||||
        if (ObjectUtil.notEqual(getUserType(), userType)) {
 | 
			
		||||
            reqDTO.setUsername(getUsername(userId));
 | 
			
		||||
        } else {
 | 
			
		||||
            reqDTO.setUsername(memberService.getMemberUserMobile(userId));
 | 
			
		||||
        }
 | 
			
		||||
        reqDTO.setUserAgent(ServletUtils.getUserAgent());
 | 
			
		||||
        reqDTO.setUserIp(ServletUtils.getClientIP());
 | 
			
		||||
        reqDTO.setResult(LoginResultEnum.SUCCESS.getResult());
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
package cn.iocoder.yudao.module.system.service.auth;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
 | 
			
		||||
import cn.iocoder.yudao.module.system.controller.admin.auth.vo.token.OAuth2AccessTokenPageReqVO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -64,4 +66,12 @@ public interface OAuth2TokenService {
 | 
			
		||||
     */
 | 
			
		||||
    OAuth2AccessTokenDO removeAccessToken(String accessToken);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获得访问令牌分页
 | 
			
		||||
     *
 | 
			
		||||
     * @param reqVO 请求
 | 
			
		||||
     * @return 访问令牌分页
 | 
			
		||||
     */
 | 
			
		||||
    PageResult<OAuth2AccessTokenDO> getAccessTokenPage(OAuth2AccessTokenPageReqVO reqVO);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,8 +4,10 @@ import cn.hutool.core.collection.CollUtil;
 | 
			
		||||
import cn.hutool.core.util.IdUtil;
 | 
			
		||||
import cn.hutool.core.util.ObjectUtil;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
 | 
			
		||||
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
 | 
			
		||||
import cn.iocoder.yudao.module.system.controller.admin.auth.vo.token.OAuth2AccessTokenPageReqVO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2ClientDO;
 | 
			
		||||
import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2RefreshTokenDO;
 | 
			
		||||
@@ -125,6 +127,11 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService {
 | 
			
		||||
        return accessTokenDO;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public PageResult<OAuth2AccessTokenDO> getAccessTokenPage(OAuth2AccessTokenPageReqVO reqVO) {
 | 
			
		||||
        return oauth2AccessTokenMapper.selectPage(reqVO);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private OAuth2AccessTokenDO createOAuth2AccessToken(OAuth2RefreshTokenDO refreshTokenDO, OAuth2ClientDO clientDO) {
 | 
			
		||||
        OAuth2AccessTokenDO accessTokenDO = new OAuth2AccessTokenDO().setAccessToken(generateAccessToken())
 | 
			
		||||
                .setUserId(refreshTokenDO.getUserId()).setUserType(refreshTokenDO.getUserType()).setClientId(clientDO.getId())
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user