Binding a user to a Tenant (#792)

pull/985/head
chen.ma 3 years ago
parent 61c1e4d97f
commit 0c3c2f6afb

@ -38,6 +38,8 @@ public class Constants {
public static final String DEFAULT_NAMESPACE_ID = "public"; public static final String DEFAULT_NAMESPACE_ID = "public";
public static final String ADMIN_USER = "admin";
public static final String ENCODE = "UTF-8"; public static final String ENCODE = "UTF-8";
public static final String NULL = ""; public static final String NULL = "";

@ -15,48 +15,31 @@
* limitations under the License. * limitations under the License.
*/ */
package cn.hippo4j.auth.service; package cn.hippo4j.auth.constant;
import com.baomidou.mybatisplus.core.metadata.IPage;
import cn.hippo4j.auth.model.biz.role.RoleRespDTO;
import java.util.List;
/** /**
* Role service. * Resource action type definitions.
*/ */
public interface RoleService { public enum ActionTypes {
/** /**
* Paging query role list. * Read.
*
* @param pageNo
* @param pageSize
* @return
*/ */
IPage<RoleRespDTO> listRole(int pageNo, int pageSize); READ("r"),
/** /**
* Add role. * Write.
*
* @param role
* @param userName
*/ */
void addRole(String role, String userName); WRITE("w");
/** private String action;
* Delete role.
*
* @param role
* @param userName
*/
void deleteRole(String role, String userName);
/** ActionTypes(String action) {
* Fuzzy search by role. this.action = action;
* }
* @param role
* @return @Override
*/ public String toString() {
List<String> getRoleLike(String role); return action;
}
} }

@ -23,7 +23,10 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date; import java.util.Date;
@ -31,44 +34,48 @@ import java.util.Date;
* Permission info. * Permission info.
*/ */
@Data @Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName("permission") @TableName("permission")
public class PermissionInfo { public class PermissionInfo {
/** /**
* id * ID
*/ */
@TableId(type = IdType.AUTO) @TableId(type = IdType.AUTO)
private Long id; private Long id;
/** /**
* role * Username
*/ */
private String role; @TableField(value = "role")
private String username;
/** /**
* resource * Resource
*/ */
private String resource; private String resource;
/** /**
* action * Action
*/ */
private String action; private String action;
/** /**
* gmtCreate * Gmt create
*/ */
@TableField(fill = FieldFill.INSERT) @TableField(fill = FieldFill.INSERT)
private Date gmtCreate; private Date gmtCreate;
/** /**
* gmtModified * Gmt modified
*/ */
@TableField(fill = FieldFill.INSERT_UPDATE) @TableField(fill = FieldFill.INSERT_UPDATE)
private Date gmtModified; private Date gmtModified;
/** /**
* delFlag * Del flag
*/ */
@TableLogic @TableLogic
@TableField(fill = FieldFill.INSERT) @TableField(fill = FieldFill.INSERT)

@ -1,71 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.auth.model;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;
/**
* Role info.
*/
@Data
@TableName("role")
public class RoleInfo {
/**
* id
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* role
*/
private String role;
/**
* userName
*/
private String userName;
/**
* gmtCreate
*/
@TableField(fill = FieldFill.INSERT)
private Date gmtCreate;
/**
* gmtModified
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date gmtModified;
/**
* delFlag
*/
@TableLogic
@TableField(fill = FieldFill.INSERT)
private Integer delFlag;
}

@ -15,15 +15,23 @@
* limitations under the License. * limitations under the License.
*/ */
package cn.hippo4j.auth.mapper; package cn.hippo4j.auth.model.biz.permission;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import lombok.Data;
import cn.hippo4j.auth.model.RoleInfo;
import org.apache.ibatis.annotations.Mapper;
/** /**
* Role mapper. * Permission req dto.
*/ */
@Mapper @Data
public interface RoleMapper extends BaseMapper<RoleInfo> { public class PermissionReqDTO {
/**
* Resource
*/
private String resource;
/**
* Action
*/
private String action;
} }

@ -17,26 +17,30 @@
package cn.hippo4j.auth.model.biz.permission; package cn.hippo4j.auth.model.biz.permission;
import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
/** /**
* Permission resp dto. * Permission resp dto.
*/ */
@Data @Data
@AllArgsConstructor
@NoArgsConstructor
public class PermissionRespDTO { public class PermissionRespDTO {
/** /**
* role * Username
*/ */
private String role; private String username;
/** /**
* source * Source
*/ */
private String resource; private String resource;
/** /**
* action * Action
*/ */
private String action; private String action;
} }

@ -17,12 +17,15 @@
package cn.hippo4j.auth.model.biz.user; package cn.hippo4j.auth.model.biz.user;
import cn.hippo4j.auth.model.biz.permission.PermissionReqDTO;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.Length;
import java.util.List;
/** /**
* User req dto. * User req dto.
*/ */
@ -32,19 +35,24 @@ import org.hibernate.validator.constraints.Length;
public class UserReqDTO extends Page { public class UserReqDTO extends Page {
/** /**
* userName * User name
*/ */
@Length(max = 64, message = "用户名最长为64个字符") @Length(max = 64, message = "用户名最长为64个字符")
private String userName; private String userName;
/** /**
* password * Password
*/ */
@Length(min = 6, message = "密码最少为6个字符") @Length(min = 6, message = "密码最少为6个字符")
private String password; private String password;
/** /**
* role * Role
*/ */
private String role; private String role;
/**
* Resources
*/
private List<PermissionReqDTO> resources;
} }

@ -17,10 +17,12 @@
package cn.hippo4j.auth.model.biz.user; package cn.hippo4j.auth.model.biz.user;
import cn.hippo4j.auth.model.biz.permission.PermissionRespDTO;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data; import lombok.Data;
import java.util.Date; import java.util.Date;
import java.util.List;
/** /**
* User resp dto. * User resp dto.
@ -29,23 +31,33 @@ import java.util.Date;
public class UserRespDTO { public class UserRespDTO {
/** /**
* userName * User name
*/ */
private String userName; private String userName;
/** /**
* role * Role
*/ */
private String role; private String role;
/** /**
* gmtCreate * Resource list
*/
private List<PermissionRespDTO> resources;
/**
* Temp resource list
*/
private List<String> tempResources;
/**
* Gmt create
*/ */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date gmtCreate; private Date gmtCreate;
/** /**
* gmtModified * Gmt modified
*/ */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date gmtModified; private Date gmtModified;

@ -17,8 +17,10 @@
package cn.hippo4j.auth.service; package cn.hippo4j.auth.service;
import cn.hippo4j.auth.model.biz.permission.PermissionReqDTO;
import cn.hippo4j.auth.model.biz.permission.PermissionRespDTO; import cn.hippo4j.auth.model.biz.permission.PermissionRespDTO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import java.util.List;
/** /**
* Permission service. * Permission service.
@ -26,29 +28,25 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
public interface PermissionService { public interface PermissionService {
/** /**
* Paging query permission list. * list permission by username
* *
* @param pageNo * @param username username
* @param pageSize * @return permission resp list
* @return
*/ */
IPage<PermissionRespDTO> listPermission(int pageNo, int pageSize); List<PermissionRespDTO> listPermissionByUserName(String username);
/** /**
* Add permission. * Binding permission by username.
* *
* @param role * @param username username
* @param resource * @param permissionRequestParamList permission request param list
* @param action
*/ */
void addPermission(String role, String resource, String action); void bindingPermissionByUsername(String username, List<PermissionReqDTO> permissionRequestParamList);
/** /**
* Remove permission. * Remove permission.
* *
* @param role * @param username username
* @param resource
* @param action
*/ */
void deletePermission(String role, String resource, String action); void deletePermission(String username);
} }

@ -32,45 +32,45 @@ public interface UserService {
/** /**
* Paging query user list. * Paging query user list.
* *
* @param reqDTO * @param requestParam request param
* @return * @return user response page
*/ */
IPage<UserRespDTO> listUser(UserQueryPageReqDTO reqDTO); IPage<UserRespDTO> listUser(UserQueryPageReqDTO requestParam);
/** /**
* New users. * New users.
* *
* @param reqDTO * @param requestParam request param
*/ */
void addUser(UserReqDTO reqDTO); void addUser(UserReqDTO requestParam);
/** /**
* Modify user. * Modify user.
* *
* @param reqDTO * @param requestParam request param
*/ */
void updateUser(UserReqDTO reqDTO); void updateUser(UserReqDTO requestParam);
/** /**
* Delete users. * Delete users.
* *
* @param userName * @param username username
*/ */
void deleteUser(String userName); void deleteUser(String username);
/** /**
* Fuzzy search by username. * Fuzzy search by username.
* *
* @param userName * @param userName userName
* @return * @return like username
*/ */
List<String> getUserLikeUsername(String userName); List<String> getUserLikeUsername(String userName);
/** /**
* Get user details. * Get user details.
* *
* @param reqDTO * @param requestParam request param
* @return * @return user response
*/ */
UserRespDTO getUser(UserReqDTO reqDTO); UserRespDTO getUser(UserReqDTO requestParam);
} }

@ -18,19 +18,19 @@
package cn.hippo4j.auth.service.impl; package cn.hippo4j.auth.service.impl;
import cn.hippo4j.auth.mapper.PermissionMapper; import cn.hippo4j.auth.mapper.PermissionMapper;
import cn.hippo4j.auth.model.biz.permission.PermissionQueryPageReqDTO; import cn.hippo4j.auth.model.PermissionInfo;
import cn.hippo4j.auth.model.biz.permission.PermissionReqDTO;
import cn.hippo4j.auth.model.biz.permission.PermissionRespDTO; import cn.hippo4j.auth.model.biz.permission.PermissionRespDTO;
import cn.hippo4j.auth.service.PermissionService; import cn.hippo4j.auth.service.PermissionService;
import cn.hippo4j.common.toolkit.BeanUtil; import cn.hippo4j.common.toolkit.BeanUtil;
import cn.hippo4j.common.toolkit.StringUtil; import cn.hippo4j.common.toolkit.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import cn.hippo4j.auth.model.PermissionInfo;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List;
/** /**
* Permission service impl. * Permission service impl.
*/ */
@ -41,35 +41,22 @@ public class PermissionServiceImpl implements PermissionService {
private final PermissionMapper permissionMapper; private final PermissionMapper permissionMapper;
@Override @Override
public IPage<PermissionRespDTO> listPermission(int pageNo, int pageSize) { public List<PermissionRespDTO> listPermissionByUserName(String username) {
PermissionQueryPageReqDTO queryPage = new PermissionQueryPageReqDTO(pageNo, pageSize); LambdaQueryWrapper<PermissionInfo> queryWrapper = Wrappers.lambdaQuery(PermissionInfo.class)
IPage<PermissionInfo> selectPage = permissionMapper.selectPage(queryPage, null); .eq(PermissionInfo::getUsername, username);
return selectPage.convert(each -> BeanUtil.convert(each, PermissionRespDTO.class)); return BeanUtil.convert(permissionMapper.selectList(queryWrapper), PermissionRespDTO.class);
} }
@Override @Override
public void addPermission(String role, String resource, String action) { public void bindingPermissionByUsername(String username, List<PermissionReqDTO> permissionRequestParamList) {
LambdaQueryWrapper<PermissionInfo> queryWrapper = Wrappers.lambdaQuery(PermissionInfo.class) if (CollectionUtil.isNotEmpty(permissionRequestParamList)) {
.eq(PermissionInfo::getRole, role) deletePermission(username);
.eq(PermissionInfo::getResource, resource) permissionRequestParamList.forEach(each -> permissionMapper.insert(PermissionInfo.builder().username(username).resource(each.getResource()).action(each.getAction()).build()));
.eq(PermissionInfo::getAction, action);
PermissionInfo existPermissionInfo = permissionMapper.selectOne(queryWrapper);
if (existPermissionInfo != null) {
throw new RuntimeException("权限重复");
} }
PermissionInfo insertPermission = new PermissionInfo();
insertPermission.setRole(role);
insertPermission.setResource(resource);
insertPermission.setAction(action);
permissionMapper.insert(insertPermission);
} }
@Override @Override
public void deletePermission(String role, String resource, String action) { public void deletePermission(String username) {
LambdaUpdateWrapper<PermissionInfo> updateWrapper = Wrappers.lambdaUpdate(PermissionInfo.class) permissionMapper.delete(Wrappers.lambdaUpdate(PermissionInfo.class).eq(PermissionInfo::getUsername, username));
.eq(StringUtil.isNotBlank(role), PermissionInfo::getRole, role)
.eq(StringUtil.isNotBlank(resource), PermissionInfo::getResource, resource)
.eq(StringUtil.isNotBlank(action), PermissionInfo::getAction, action);
permissionMapper.delete(updateWrapper);
} }
} }

@ -1,94 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.auth.service.impl;
import cn.hippo4j.auth.mapper.RoleMapper;
import cn.hippo4j.auth.model.biz.role.RoleQueryPageReqDTO;
import cn.hippo4j.auth.model.biz.role.RoleRespDTO;
import cn.hippo4j.auth.service.PermissionService;
import cn.hippo4j.auth.service.RoleService;
import cn.hippo4j.common.toolkit.BeanUtil;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.common.toolkit.StringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import cn.hippo4j.auth.model.RoleInfo;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
/**
* Role service impl.
*/
@Service
@AllArgsConstructor
public class RoleServiceImpl implements RoleService {
private final RoleMapper roleMapper;
private final PermissionService permissionService;
@Override
public IPage<RoleRespDTO> listRole(int pageNo, int pageSize) {
RoleQueryPageReqDTO queryPage = new RoleQueryPageReqDTO(pageNo, pageSize);
IPage<RoleInfo> selectPage = roleMapper.selectPage(queryPage, null);
return selectPage.convert(each -> BeanUtil.convert(each, RoleRespDTO.class));
}
@Override
public void addRole(String role, String userName) {
LambdaQueryWrapper<RoleInfo> queryWrapper = Wrappers.lambdaQuery(RoleInfo.class)
.eq(RoleInfo::getRole, role);
RoleInfo roleInfo = roleMapper.selectOne(queryWrapper);
if (roleInfo != null) {
throw new RuntimeException("角色名重复");
}
RoleInfo insertRole = new RoleInfo();
insertRole.setRole(role);
insertRole.setUserName(userName);
roleMapper.insert(insertRole);
}
@Override
public void deleteRole(String role, String userName) {
List<String> roleStrList = CollectionUtil.toList(role);
if (StringUtil.isBlank(role)) {
LambdaQueryWrapper<RoleInfo> queryWrapper = Wrappers.lambdaQuery(RoleInfo.class).eq(RoleInfo::getUserName, userName);
roleStrList = roleMapper.selectList(queryWrapper).stream().map(RoleInfo::getRole).collect(Collectors.toList());
}
LambdaUpdateWrapper<RoleInfo> updateWrapper = Wrappers.lambdaUpdate(RoleInfo.class)
.eq(StringUtil.isNotBlank(role), RoleInfo::getRole, role)
.eq(StringUtil.isNotBlank(userName), RoleInfo::getUserName, userName);
roleMapper.delete(updateWrapper);
roleStrList.forEach(each -> permissionService.deletePermission(each, "", ""));
}
@Override
public List<String> getRoleLike(String role) {
LambdaQueryWrapper<RoleInfo> queryWrapper = Wrappers.lambdaQuery(RoleInfo.class)
.like(RoleInfo::getRole, role)
.select(RoleInfo::getRole);
List<RoleInfo> roleInfos = roleMapper.selectList(queryWrapper);
List<String> roleNames = roleInfos.stream().map(RoleInfo::getRole).collect(Collectors.toList());
return roleNames;
}
}

@ -19,9 +19,11 @@ package cn.hippo4j.auth.service.impl;
import cn.hippo4j.auth.mapper.UserMapper; import cn.hippo4j.auth.mapper.UserMapper;
import cn.hippo4j.auth.model.UserInfo; import cn.hippo4j.auth.model.UserInfo;
import cn.hippo4j.auth.model.biz.permission.PermissionRespDTO;
import cn.hippo4j.auth.model.biz.user.UserQueryPageReqDTO; import cn.hippo4j.auth.model.biz.user.UserQueryPageReqDTO;
import cn.hippo4j.auth.model.biz.user.UserReqDTO; import cn.hippo4j.auth.model.biz.user.UserReqDTO;
import cn.hippo4j.auth.model.biz.user.UserRespDTO; import cn.hippo4j.auth.model.biz.user.UserRespDTO;
import cn.hippo4j.auth.service.PermissionService;
import cn.hippo4j.auth.service.UserService; import cn.hippo4j.auth.service.UserService;
import cn.hippo4j.common.toolkit.BeanUtil; import cn.hippo4j.common.toolkit.BeanUtil;
import cn.hippo4j.common.toolkit.StringUtil; import cn.hippo4j.common.toolkit.StringUtil;
@ -34,6 +36,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@ -52,39 +55,45 @@ public class UserServiceImpl implements UserService {
private final BCryptPasswordEncoder bCryptPasswordEncoder; private final BCryptPasswordEncoder bCryptPasswordEncoder;
private final PermissionService permissionService;
@Override @Override
public IPage<UserRespDTO> listUser(UserQueryPageReqDTO reqDTO) { public IPage<UserRespDTO> listUser(UserQueryPageReqDTO requestParam) {
LambdaQueryWrapper<UserInfo> queryWrapper = Wrappers.lambdaQuery(UserInfo.class) LambdaQueryWrapper<UserInfo> queryWrapper = Wrappers.lambdaQuery(UserInfo.class)
.eq(StringUtil.isNotBlank(reqDTO.getUserName()), UserInfo::getUserName, reqDTO.getUserName()); .eq(StringUtil.isNotBlank(requestParam.getUserName()), UserInfo::getUserName, requestParam.getUserName());
IPage<UserInfo> selectPage = userMapper.selectPage(reqDTO, queryWrapper); IPage<UserInfo> selectPage = userMapper.selectPage(requestParam, queryWrapper);
return selectPage.convert(each -> BeanUtil.convert(each, UserRespDTO.class)); return selectPage.convert(this::buildUserInfo);
} }
@Override @Override
public void addUser(UserReqDTO reqDTO) { @Transactional(rollbackFor = Exception.class)
public void addUser(UserReqDTO requestParam) {
LambdaQueryWrapper<UserInfo> queryWrapper = Wrappers.lambdaQuery(UserInfo.class) LambdaQueryWrapper<UserInfo> queryWrapper = Wrappers.lambdaQuery(UserInfo.class)
.eq(UserInfo::getUserName, reqDTO.getUserName()); .eq(UserInfo::getUserName, requestParam.getUserName());
UserInfo existUserInfo = userMapper.selectOne(queryWrapper); UserInfo existUserInfo = userMapper.selectOne(queryWrapper);
if (existUserInfo != null) { if (existUserInfo != null) {
throw new RuntimeException("用户名重复"); throw new RuntimeException("用户名重复");
} }
reqDTO.setPassword(bCryptPasswordEncoder.encode(reqDTO.getPassword())); requestParam.setPassword(bCryptPasswordEncoder.encode(requestParam.getPassword()));
UserInfo insertUser = BeanUtil.convert(reqDTO, UserInfo.class); UserInfo insertUser = BeanUtil.convert(requestParam, UserInfo.class);
userMapper.insert(insertUser); userMapper.insert(insertUser);
permissionService.bindingPermissionByUsername(requestParam.getUserName(), requestParam.getResources());
} }
@Override @Override
public void updateUser(UserReqDTO reqDTO) { @Transactional(rollbackFor = Exception.class)
if (StringUtil.isNotBlank(reqDTO.getPassword())) { public void updateUser(UserReqDTO requestParam) {
if (reqDTO.getPassword().length() < MINI_PASSWORD_LENGTH) { if (StringUtil.isNotBlank(requestParam.getPassword())) {
if (requestParam.getPassword().length() < MINI_PASSWORD_LENGTH) {
throw new RuntimeException("密码最少为6个字符"); throw new RuntimeException("密码最少为6个字符");
} }
reqDTO.setPassword(bCryptPasswordEncoder.encode(reqDTO.getPassword())); requestParam.setPassword(bCryptPasswordEncoder.encode(requestParam.getPassword()));
} }
UserInfo updateUser = BeanUtil.convert(reqDTO, UserInfo.class); UserInfo updateUser = BeanUtil.convert(requestParam, UserInfo.class);
LambdaUpdateWrapper<UserInfo> updateWrapper = Wrappers.lambdaUpdate(UserInfo.class) LambdaUpdateWrapper<UserInfo> updateWrapper = Wrappers.lambdaUpdate(UserInfo.class)
.eq(UserInfo::getUserName, reqDTO.getUserName()); .eq(UserInfo::getUserName, requestParam.getUserName());
userMapper.update(updateUser, updateWrapper); userMapper.update(updateUser, updateWrapper);
permissionService.bindingPermissionByUsername(requestParam.getUserName(), requestParam.getResources());
} }
@Override @Override
@ -92,6 +101,7 @@ public class UserServiceImpl implements UserService {
LambdaUpdateWrapper<UserInfo> updateWrapper = Wrappers.lambdaUpdate(UserInfo.class) LambdaUpdateWrapper<UserInfo> updateWrapper = Wrappers.lambdaUpdate(UserInfo.class)
.eq(UserInfo::getUserName, userName); .eq(UserInfo::getUserName, userName);
userMapper.delete(updateWrapper); userMapper.delete(updateWrapper);
permissionService.deletePermission(userName);
} }
@Override @Override
@ -104,11 +114,19 @@ public class UserServiceImpl implements UserService {
} }
@Override @Override
public UserRespDTO getUser(UserReqDTO reqDTO) { public UserRespDTO getUser(UserReqDTO requestParam) {
Wrapper<UserInfo> queryWrapper = Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getUserName, reqDTO.getUserName()); Wrapper<UserInfo> queryWrapper = Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getUserName, requestParam.getUserName());
UserInfo userInfo = userMapper.selectOne(queryWrapper); UserInfo userInfo = userMapper.selectOne(queryWrapper);
return Optional.ofNullable(userInfo) return Optional.ofNullable(userInfo)
.map(each -> BeanUtil.convert(each, UserRespDTO.class)) .map(this::buildUserInfo)
.orElseThrow(() -> new ServiceException("查询无此用户, 可以尝试清空缓存或退出登录.")); .orElseThrow(() -> new ServiceException("查询无此用户, 可以尝试清空缓存或退出登录"));
}
private UserRespDTO buildUserInfo(UserInfo userInfo) {
UserRespDTO result = BeanUtil.convert(userInfo, UserRespDTO.class);
List<PermissionRespDTO> permissionRespList = permissionService.listPermissionByUserName(result.getUserName());
result.setResources(permissionRespList);
result.setTempResources(permissionRespList.stream().map(PermissionRespDTO::getResource).collect(Collectors.toList()));
return result;
} }
} }

@ -23,6 +23,8 @@ import cn.hippo4j.config.model.biz.tenant.TenantSaveReqDTO;
import cn.hippo4j.config.model.biz.tenant.TenantUpdateReqDTO; import cn.hippo4j.config.model.biz.tenant.TenantUpdateReqDTO;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import java.util.List;
/** /**
* Tenant service. * Tenant service.
*/ */
@ -72,4 +74,11 @@ public interface TenantService {
* @param tenantId * @param tenantId
*/ */
void deleteTenantById(String tenantId); void deleteTenantById(String tenantId);
/**
* List all tenant.
*
* @return
*/
List<String> listAllTenant();
} }

@ -41,6 +41,7 @@ import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
/** /**
* Tenant service impl. * Tenant service impl.
@ -124,4 +125,10 @@ public class TenantServiceImpl implements TenantService {
throw new RuntimeException("Delete error."); throw new RuntimeException("Delete error.");
} }
} }
@Override
public List<String> listAllTenant() {
List<TenantInfo> tenantInfoList = tenantInfoMapper.selectList(Wrappers.emptyWrapper());
return tenantInfoList.stream().map(TenantInfo::getTenantId).collect(Collectors.toList());
}
} }

@ -1,60 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.console.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import cn.hippo4j.auth.model.biz.permission.PermissionRespDTO;
import cn.hippo4j.auth.service.PermissionService;
import cn.hippo4j.common.web.base.Result;
import cn.hippo4j.common.web.base.Results;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Permission controller.
*/
@RestController
@AllArgsConstructor
@RequestMapping("/v1/auth/permissions")
public class PermissionController {
private final PermissionService permissionService;
@GetMapping("/{pageNo}/{pageSize}")
public Result<IPage<PermissionRespDTO>> listPermission(@PathVariable("pageNo") int pageNo, @PathVariable("pageSize") int pageSize) {
IPage<PermissionRespDTO> resultPermissionPage = permissionService.listPermission(pageNo, pageSize);
return Results.success(resultPermissionPage);
}
@PostMapping("/{role}/{resource}/{action}")
public Result<Void> addPermission(@PathVariable("role") String role, @PathVariable("resource") String resource, @PathVariable("action") String action) {
permissionService.addPermission(role, resource, action);
return Results.success();
}
@DeleteMapping("/{role}/{resource}/{action}")
public Result<Void> deleteUser(@PathVariable("role") String role, @PathVariable("resource") String resource, @PathVariable("action") String action) {
permissionService.deletePermission(role, resource, action);
return Results.success();
}
}

@ -1,68 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.console.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import cn.hippo4j.auth.model.biz.role.RoleRespDTO;
import cn.hippo4j.auth.service.RoleService;
import cn.hippo4j.common.web.base.Result;
import cn.hippo4j.common.web.base.Results;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* Role controller.
*/
@RestController
@AllArgsConstructor
@RequestMapping("/v1/auth/roles")
public class RoleController {
private final RoleService roleService;
@GetMapping("/{pageNo}/{pageSize}")
public Result<IPage<RoleRespDTO>> listUser(@PathVariable("pageNo") int pageNo, @PathVariable("pageSize") int pageSize) {
IPage<RoleRespDTO> resultRolePage = roleService.listRole(pageNo, pageSize);
return Results.success(resultRolePage);
}
@PostMapping("/{role}/{userName}")
public Result<Void> addUser(@PathVariable("role") String role, @PathVariable("userName") String userName) {
roleService.addRole(role, userName);
return Results.success();
}
@DeleteMapping("/{role}/{userName}")
public Result<Void> deleteUser(@PathVariable("role") String role, @PathVariable("userName") String userName) {
roleService.deleteRole(role, userName);
return Results.success();
}
@GetMapping("/search/{role}")
public Result<List<String>> searchUsersLikeUserName(@PathVariable("role") String role) {
List<String> resultRole = roleService.getRoleLike(role);
return Results.success(resultRole);
}
}

@ -18,6 +18,7 @@
package cn.hippo4j.console.controller; package cn.hippo4j.console.controller;
import cn.hippo4j.auth.model.UserInfo; import cn.hippo4j.auth.model.UserInfo;
import cn.hippo4j.auth.model.biz.permission.PermissionRespDTO;
import cn.hippo4j.auth.model.biz.user.UserQueryPageReqDTO; import cn.hippo4j.auth.model.biz.user.UserQueryPageReqDTO;
import cn.hippo4j.auth.model.biz.user.UserReqDTO; import cn.hippo4j.auth.model.biz.user.UserReqDTO;
import cn.hippo4j.auth.model.biz.user.UserRespDTO; import cn.hippo4j.auth.model.biz.user.UserRespDTO;
@ -27,6 +28,7 @@ import cn.hippo4j.common.constant.Constants;
import cn.hippo4j.common.model.TokenInfo; import cn.hippo4j.common.model.TokenInfo;
import cn.hippo4j.common.web.base.Result; import cn.hippo4j.common.web.base.Result;
import cn.hippo4j.common.web.base.Results; import cn.hippo4j.common.web.base.Results;
import cn.hippo4j.config.service.biz.TenantService;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -40,8 +42,11 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import static cn.hippo4j.auth.constant.Constants.TOKEN_VALIDITY_IN_SECONDS; import static cn.hippo4j.auth.constant.Constants.TOKEN_VALIDITY_IN_SECONDS;
import static cn.hippo4j.common.constant.Constants.ADMIN_USER;
/** /**
* User controller. * User controller.
@ -55,6 +60,8 @@ public class UserController {
private final AuthManager authManager; private final AuthManager authManager;
private final TenantService tenantService;
@PostMapping("/apply/token") @PostMapping("/apply/token")
public Result<TokenInfo> applyToken(@RequestBody UserInfo userInfo) { public Result<TokenInfo> applyToken(@RequestBody UserInfo userInfo) {
String accessToken = authManager.resolveTokenFromUser(userInfo.getUserName(), userInfo.getPassword()); String accessToken = authManager.resolveTokenFromUser(userInfo.getUserName(), userInfo.getPassword());
@ -71,6 +78,10 @@ public class UserController {
@GetMapping("/info/{username}") @GetMapping("/info/{username}")
public Result<UserRespDTO> userInfo(@PathVariable("username") String username) { public Result<UserRespDTO> userInfo(@PathVariable("username") String username) {
UserRespDTO userRespDTO = userService.getUser(new UserReqDTO().setUserName(username)); UserRespDTO userRespDTO = userService.getUser(new UserReqDTO().setUserName(username));
if (Objects.equals(username, ADMIN_USER)) {
userRespDTO.setResources(tenantService.listAllTenant().stream().map(each -> new PermissionRespDTO(username, each, "rw")).collect(Collectors.toList()));
userRespDTO.setTempResources(tenantService.listAllTenant());
}
return Results.success(userRespDTO); return Results.success(userRespDTO);
} }

@ -24,7 +24,8 @@ export default {
}, },
data() { data() {
return { return {
title: 'hippo4j 1.4.3', title: 'hippo4j 1.5.0',
logo: '',
}; };
}, },
}; };

@ -60,6 +60,7 @@
v-if="row.status !== 'deleted'" v-if="row.status !== 'deleted'"
size="small" size="small"
type="text" type="text"
:disabled="row.userName !== 'admin' ? false : true"
@click="handleDelete(row)" @click="handleDelete(row)"
> >
删除 删除
@ -85,16 +86,32 @@
style="width: 400px; margin-left: 50px" style="width: 400px; margin-left: 50px"
> >
<el-form-item label="用户名" prop="userName"> <el-form-item label="用户名" prop="userName">
<el-input v-model="temp.userName" placeholder="用户名" /> <el-input
v-model="temp.userName"
:disabled="temp.userName !== 'admin' ? false : true"
placeholder="用户名"
/>
</el-form-item> </el-form-item>
<el-form-item label="密 码" prop="password"> <el-form-item label="密码" prop="password">
<el-input v-model="temp.password" placeholder="密码" minlength="6" /> <el-input v-model="temp.password" placeholder="密码" minlength="6" />
</el-form-item> </el-form-item>
<el-form-item label="角色" prop="role"> <el-form-item label="角色" prop="role">
<el-select v-model="temp.role" class="filter-item" placeholder="角色类型"> <el-select
v-model="temp.role"
class="filter-item"
:disabled="temp.userName !== 'admin' ? false : true"
placeholder="角色类型"
>
<el-option v-for="item in roles" :key="item.key" :label="item" :value="item" /> <el-option v-for="item in roles" :key="item.key" :label="item" :value="item" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="租户" prop="tenants" v-if="temp.userName !== 'admin' ? true : false">
<el-checkbox-group v-model="temp.tempResources">
<el-checkbox v-for="tenantKey in tenantList" :label="tenantKey" :key="tenantKey">{{
tenantKey
}}</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false"> 取消 </el-button> <el-button @click="dialogFormVisible = false"> 取消 </el-button>
@ -110,7 +127,7 @@
import * as user from '@/api/hippo4j-user'; import * as user from '@/api/hippo4j-user';
import waves from '@/directive/waves'; import waves from '@/directive/waves';
import Pagination from '@/components/Pagination'; import Pagination from '@/components/Pagination';
import * as tenantApi from '@/api/hippo4j-tenant';
export default { export default {
name: 'User', name: 'User',
components: { Pagination }, components: { Pagination },
@ -127,6 +144,7 @@ export default {
}, },
data() { data() {
return { return {
isTenantsShow: true,
list: null, list: null,
listLoading: true, listLoading: true,
total: 0, total: 0,
@ -136,6 +154,11 @@ export default {
userName: undefined, userName: undefined,
}, },
roles: ['ROLE_USER', 'ROLE_MANAGE', 'ROLE_ADMIN'], roles: ['ROLE_USER', 'ROLE_MANAGE', 'ROLE_ADMIN'],
tenantList: [],
checkedCities: ['smo'],
checkAll: false,
isIndeterminate: true,
cities: [],
dialogPluginVisible: false, dialogPluginVisible: false,
pluginData: [], pluginData: [],
dialogFormVisible: false, dialogFormVisible: false,
@ -147,6 +170,7 @@ export default {
rules: { rules: {
role: [{ required: true, message: 'role is required', trigger: 'change' }], role: [{ required: true, message: 'role is required', trigger: 'change' }],
userName: [{ required: true, message: 'userName is required', trigger: 'blur' }], userName: [{ required: true, message: 'userName is required', trigger: 'blur' }],
tenants: [{ required: false, message: 'tenants is required', trigger: 'blur' }],
password: [{ required: false, message: 'password is required', trigger: 'blur' }], password: [{ required: false, message: 'password is required', trigger: 'blur' }],
}, },
temp: { temp: {
@ -155,6 +179,7 @@ export default {
userName: '', userName: '',
password: '', password: '',
permission: '', permission: '',
resources: [],
}, },
resetTemp() { resetTemp() {
this.temp = this.$options.data().temp; this.temp = this.$options.data().temp;
@ -163,6 +188,7 @@ export default {
}, },
created() { created() {
this.fetchData(); this.fetchData();
this.initData();
}, },
methods: { methods: {
fetchData() { fetchData() {
@ -173,6 +199,14 @@ export default {
this.listLoading = false; this.listLoading = false;
}); });
}, },
initData() {
tenantApi.list({ size: this.size }).then((response) => {
const { records } = response;
for (let i = 0; i < records.length; i++) {
this.tenantList.push(records[i].tenantId);
}
});
},
handleCreate() { handleCreate() {
this.resetTemp(); this.resetTemp();
this.dialogStatus = 'create'; this.dialogStatus = 'create';
@ -201,6 +235,7 @@ export default {
this.temp = Object.assign({}, row); // copy obj this.temp = Object.assign({}, row); // copy obj
this.dialogStatus = 'update'; this.dialogStatus = 'update';
this.dialogFormVisible = true; this.dialogFormVisible = true;
console.log(this.temp);
this.$nextTick(() => { this.$nextTick(() => {
this.$refs['dataForm'].clearValidate(); this.$refs['dataForm'].clearValidate();
}); });
@ -208,7 +243,15 @@ export default {
updateData() { updateData() {
this.$refs['dataForm'].validate((valid) => { this.$refs['dataForm'].validate((valid) => {
if (valid) { if (valid) {
let resources = [];
for (let i = 0; i < this.temp.tempResources.length; i++) {
resources.push({
resource: this.temp.tempResources[i],
action: 'rw',
});
}
const tempData = Object.assign({}, this.temp); const tempData = Object.assign({}, this.temp);
tempData.resources = resources;
user.updateUser(tempData).then(() => { user.updateUser(tempData).then(() => {
this.fetchData(); this.fetchData();
this.dialogFormVisible = false; this.dialogFormVisible = false;

Loading…
Cancel
Save