Merge pull request #1389 from ancienter/develop-add-api-key

[add]新增ApiKey管理功能
This commit is contained in:
648540858
2024-04-10 22:56:14 +08:00
committed by GitHub
26 changed files with 1284 additions and 25 deletions

View File

@@ -9,6 +9,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.annotation.EnableScheduling;
@@ -24,6 +25,7 @@ import java.util.Collections;
@ServletComponentScan("com.genersoft.iot.vmp.conf")
@SpringBootApplication
@EnableScheduling
@EnableCaching
public class VManageBootstrap extends SpringBootServletInitializer {
private final static Logger logger = LoggerFactory.getLogger(VManageBootstrap.class);

View File

@@ -1,6 +1,8 @@
package com.genersoft.iot.vmp.conf;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.mapping.VendorDatabaseIdProvider;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
@@ -9,6 +11,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import javax.sql.DataSource;
import java.util.Properties;
/**
* 配置mybatis
@@ -21,7 +24,29 @@ public class MybatisConfig {
private UserSetting userSetting;
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
public DatabaseIdProvider databaseIdProvider() {
VendorDatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider();
Properties properties = new Properties();
properties.setProperty("Oracle", "oracle");
properties.setProperty("MySQL", "mysql");
properties.setProperty("DB2", "db2");
properties.setProperty("Derby", "derby");
properties.setProperty("H2", "h2");
properties.setProperty("HSQL", "hsql");
properties.setProperty("Informix", "informix");
properties.setProperty("MS-SQL", "ms-sql");
properties.setProperty("PostgreSQL", "postgresql");
properties.setProperty("Sybase", "sybase");
properties.setProperty("Hana", "hana");
properties.setProperty("DM", "dm");
properties.setProperty("KingbaseES", "kingbase");
properties.setProperty("KingBase8", "kingbase");
databaseIdProvider.setProperties(properties);
return databaseIdProvider;
}
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource, DatabaseIdProvider databaseIdProvider) throws Exception {
final SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
sqlSessionFactory.setDataSource(dataSource);
org.apache.ibatis.session.Configuration config = new org.apache.ibatis.session.Configuration();
@@ -30,6 +55,7 @@ public class MybatisConfig {
}
config.setMapUnderscoreToCamelCase(true);
sqlSessionFactory.setConfiguration(config);
sqlSessionFactory.setDatabaseIdProvider(databaseIdProvider);
return sqlSessionFactory.getObject();
}

View File

@@ -51,8 +51,11 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
if (StringUtils.isBlank(jwt)) {
jwt = request.getParameter(JwtUtils.getHeader());
if (StringUtils.isBlank(jwt)) {
chain.doFilter(request, response);
return;
jwt = request.getHeader(JwtUtils.getApiKeyHeader());
if (StringUtils.isBlank(jwt)) {
chain.doFilter(request, response);
return;
}
}
}

View File

@@ -1,8 +1,12 @@
package com.genersoft.iot.vmp.conf.security;
import com.genersoft.iot.vmp.conf.security.dto.JwtUser;
import com.genersoft.iot.vmp.service.IUserApiKeyService;
import com.genersoft.iot.vmp.service.IUserService;
import com.genersoft.iot.vmp.storager.dao.dto.User;
import com.genersoft.iot.vmp.storager.dao.dto.UserApiKey;
import org.jose4j.jwk.JsonWebKey;
import org.jose4j.jwk.JsonWebKeySet;
import org.jose4j.jwk.RsaJsonWebKey;
import org.jose4j.jwk.RsaJwkGenerator;
import org.jose4j.jws.AlgorithmIdentifiers;
@@ -20,8 +24,13 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;
import java.util.Map;
@Component
public class JwtUtils implements InitializingBean {
@@ -30,6 +39,8 @@ public class JwtUtils implements InitializingBean {
public static final String HEADER = "access-token";
public static final String API_KEY_HEADER = "api-key";
private static final String AUDIENCE = "Audience";
private static final String keyId = "3e79646c4dbc408383a9eed09f2b85ae";
@@ -37,17 +48,28 @@ public class JwtUtils implements InitializingBean {
/**
* token过期时间(分钟)
*/
public static final long expirationTime = 30 * 24 * 60;
public static final long EXPIRATION_TIME = 30 * 24 * 60;
private static RsaJsonWebKey rsaJsonWebKey;
private static IUserService userService;
private static IUserApiKeyService userApiKeyService;
public static String getApiKeyHeader() {
return API_KEY_HEADER;
}
@Resource
public void setUserService(IUserService userService) {
JwtUtils.userService = userService;
}
@Resource
public void setUserApiKeyService(IUserApiKeyService userApiKeyService) {
JwtUtils.userApiKeyService = userApiKeyService;
}
@Override
public void afterPropertiesSet() {
try {
@@ -59,17 +81,34 @@ public class JwtUtils implements InitializingBean {
/**
* 创建密钥对
*
* @throws JoseException JoseException
*/
private RsaJsonWebKey generateRsaJsonWebKey() throws JoseException {
// 生成一个RSA密钥对该密钥对将用于JWT的签名和验证包装在JWK中
RsaJsonWebKey rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
// 给JWK一个密钥ID
rsaJsonWebKey.setKeyId(keyId);
RsaJsonWebKey rsaJsonWebKey = null;
try (BufferedReader reader = new BufferedReader(new InputStreamReader(getClass().getClassLoader().getResourceAsStream("/jwk.json"), StandardCharsets.UTF_8))) {
String jwkJson = reader.readLine();
JsonWebKeySet jsonWebKeySet = new JsonWebKeySet(jwkJson);
List<JsonWebKey> jsonWebKeys = jsonWebKeySet.getJsonWebKeys();
if (!jsonWebKeys.isEmpty()) {
JsonWebKey jsonWebKey = jsonWebKeys.get(0);
if (jsonWebKey instanceof RsaJsonWebKey) {
rsaJsonWebKey = (RsaJsonWebKey) jsonWebKey;
}
}
} catch (Exception e) {
// ignored
}
if (rsaJsonWebKey == null) {
// 生成一个RSA密钥对该密钥对将用于JWT的签名和验证包装在JWK中
rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
// 给JWK一个密钥ID
rsaJsonWebKey.setKeyId(keyId);
}
return rsaJsonWebKey;
}
public static String createToken(String username) {
public static String createToken(String username, Long expirationTime, Map<String, Object> extra) {
try {
/*
* “iss” (issuer) 发行人
@@ -83,13 +122,17 @@ public class JwtUtils implements InitializingBean {
claims.setGeneratedJwtId();
claims.setIssuedAtToNow();
// 令牌将过期的时间 分钟
claims.setExpirationTimeMinutesInTheFuture(expirationTime);
if (expirationTime != null) {
claims.setExpirationTimeMinutesInTheFuture(expirationTime);
}
claims.setNotBeforeMinutesInThePast(0);
claims.setSubject("login");
claims.setAudience(AUDIENCE);
//添加自定义参数,必须是字符串类型
claims.setClaim("userName", username);
if (extra != null) {
extra.forEach(claims::setClaim);
}
//jws
JsonWebSignature jws = new JsonWebSignature();
//签名算法RS256
@@ -104,10 +147,17 @@ public class JwtUtils implements InitializingBean {
} catch (JoseException e) {
logger.error("[Token生成失败] {}", e.getMessage());
}
return null;
}
public static String createToken(String username, Long expirationTime) {
return createToken(username, expirationTime, null);
}
public static String createToken(String username) {
return createToken(username, EXPIRATION_TIME);
}
public static String getHeader() {
return HEADER;
}
@@ -118,8 +168,8 @@ public class JwtUtils implements InitializingBean {
try {
JwtConsumer consumer = new JwtConsumerBuilder()
.setRequireExpirationTime()
.setMaxFutureValidityInMinutes(5256000)
//.setRequireExpirationTime()
//.setMaxFutureValidityInMinutes(5256000)
.setAllowedClockSkewInSeconds(30)
.setRequireSubject()
//.setExpectedIssuer("")
@@ -129,15 +179,27 @@ public class JwtUtils implements InitializingBean {
JwtClaims claims = consumer.processToClaims(token);
NumericDate expirationTime = claims.getExpirationTime();
// 判断是否即将过期, 默认剩余时间小于5分钟未即将过期
// 剩余时间 (秒)
long timeRemaining = LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8)) - expirationTime.getValue();
if (timeRemaining < 5 * 60) {
jwtUser.setStatus(JwtUser.TokenStatus.EXPIRING_SOON);
if (expirationTime != null) {
// 判断是否即将过期, 默认剩余时间小于5分钟未即将过期
// 剩余时间 (秒)
long timeRemaining = LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8)) - expirationTime.getValue();
if (timeRemaining < 5 * 60) {
jwtUser.setStatus(JwtUser.TokenStatus.EXPIRING_SOON);
} else {
jwtUser.setStatus(JwtUser.TokenStatus.NORMAL);
}
} else {
jwtUser.setStatus(JwtUser.TokenStatus.NORMAL);
}
Long apiKeyId = claims.getClaimValue("apiKeyId", Long.class);
if (apiKeyId != null) {
UserApiKey userApiKey = userApiKeyService.getUserApiKeyById(apiKeyId.intValue());
if (userApiKey == null || !userApiKey.isEnable()) {
jwtUser.setStatus(JwtUser.TokenStatus.EXPIRED);
}
}
String username = (String) claims.getClaimValue("userName");
User user = userService.getUserByUsername(username);

View File

@@ -0,0 +1,25 @@
package com.genersoft.iot.vmp.service;
import com.genersoft.iot.vmp.storager.dao.dto.UserApiKey;
import com.github.pagehelper.PageInfo;
public interface IUserApiKeyService {
int addApiKey(UserApiKey userApiKey);
boolean isApiKeyExists(String apiKey);
PageInfo<UserApiKey> getUserApiKeys(int page, int count);
int enable(Integer id);
int disable(Integer id);
int remark(Integer id, String remark);
int delete(Integer id);
UserApiKey getUserApiKeyById(Integer id);
int reset(Integer id, String apiKey);
}

View File

@@ -11,6 +11,8 @@ public interface IUserService {
boolean changePassword(int id, String password);
User getUserById(int id);
User getUserByUsername(String username);
int addUser(User user);

View File

@@ -0,0 +1,80 @@
package com.genersoft.iot.vmp.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.genersoft.iot.vmp.service.IUserApiKeyService;
import com.genersoft.iot.vmp.storager.dao.UserApiKeyMapper;
import com.genersoft.iot.vmp.storager.dao.dto.UserApiKey;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@DS("master")
public class UserApiKeyServiceImpl implements IUserApiKeyService {
@Autowired
UserApiKeyMapper userApiKeyMapper;
@Autowired
private RedisTemplate<Object, Object> redisTemplate;
@Override
public int addApiKey(UserApiKey userApiKey) {
return userApiKeyMapper.add(userApiKey);
}
@Override
public boolean isApiKeyExists(String apiKey) {
return userApiKeyMapper.isApiKeyExists(apiKey);
}
@Override
public PageInfo<UserApiKey> getUserApiKeys(int page, int count) {
PageHelper.startPage(page, count);
List<UserApiKey> userApiKeys = userApiKeyMapper.getUserApiKeys();
return new PageInfo<>(userApiKeys);
}
@Cacheable(cacheNames = "userApiKey", key = "#id", sync = true)
@Override
public UserApiKey getUserApiKeyById(Integer id) {
return userApiKeyMapper.selectById(id);
}
@CacheEvict(cacheNames = "userApiKey", key = "#id")
@Override
public int enable(Integer id) {
return userApiKeyMapper.enable(id);
}
@CacheEvict(cacheNames = "userApiKey", key = "#id")
@Override
public int disable(Integer id) {
return userApiKeyMapper.disable(id);
}
@CacheEvict(cacheNames = "userApiKey", key = "#id")
@Override
public int remark(Integer id, String remark) {
return userApiKeyMapper.remark(id, remark);
}
@CacheEvict(cacheNames = "userApiKey", key = "#id")
@Override
public int delete(Integer id) {
return userApiKeyMapper.delete(id);
}
@CacheEvict(cacheNames = "userApiKey", key = "#id")
@Override
public int reset(Integer id, String apiKey) {
return userApiKeyMapper.apiKey(id, apiKey);
}
}

View File

@@ -31,6 +31,11 @@ public class UserServiceImpl implements IUserService {
return userMapper.update(user) > 0;
}
@Override
public User getUserById(int id) {
return userMapper.selectById(id);
}
@Override
public User getUserByUsername(String username) {
return userMapper.getUserByUsername(username);

View File

@@ -0,0 +1,61 @@
package com.genersoft.iot.vmp.storager.dao;
import com.genersoft.iot.vmp.storager.dao.dto.UserApiKey;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface UserApiKeyMapper {
@SelectKey(databaseId = "postgresql", statement = "SELECT currval('wvp_user_api_key_id_seq'::regclass) AS id", keyProperty = "id", before = false, resultType = Integer.class)
@SelectKey(databaseId = "mysql", statement = "SELECT LAST_INSERT_ID() AS id", keyProperty = "id", before = false, resultType = Integer.class)
@Insert("INSERT INTO wvp_user_api_key (user_id, app, api_key, expired_at, remark, enable, create_time, update_time) VALUES" +
"(#{userId}, #{app}, #{apiKey}, #{expiredAt}, #{remark}, #{enable}, #{createTime}, #{updateTime})")
int add(UserApiKey userApiKey);
@Update(value = {"<script>" +
"UPDATE wvp_user_api_key " +
"SET update_time = #{updateTime} " +
"<if test=\"app != null\">, app = #{app}</if>" +
"<if test=\"apiKey != null\">, api_key = #{apiKey}</if>" +
"<if test=\"expiredAt != null\">, expired_at = #{expiredAt}</if>" +
"<if test=\"remark != null\">, username = #{remark}</if>" +
"<if test=\"enable != null\">, enable = #{enable}</if>" +
"WHERE id = #{id}" +
" </script>"})
int update(UserApiKey userApiKey);
@Update("UPDATE wvp_user_api_key SET enable = true WHERE id = #{id}")
int enable(@Param("id") int id);
@Update("UPDATE wvp_user_api_key SET enable = false WHERE id = #{id}")
int disable(@Param("id") int id);
@Update("UPDATE wvp_user_api_key SET api_key = #{apiKey} WHERE id = #{id}")
int apiKey(@Param("id") int id, @Param("apiKey") String apiKey);
@Update("UPDATE wvp_user_api_key SET remark = #{remark} WHERE id = #{id}")
int remark(@Param("id") int id, @Param("remark") String remark);
@Delete("DELETE FROM wvp_user_api_key WHERE id = #{id}")
int delete(@Param("id") int id);
@Select("SELECT uak.id, uak.user_id, uak.app, uak.api_key, uak.expired_at, uak.remark, uak.enable, uak.create_time, uak.update_time, u.username AS username FROM wvp_user_api_key uak LEFT JOIN wvp_user u on u.id = uak.user_id WHERE uak.id = #{id}")
UserApiKey selectById(@Param("id") int id);
@Select("SELECT uak.id, uak.user_id, uak.app, uak.api_key, uak.expired_at, uak.remark, uak.enable, uak.create_time, uak.update_time, u.username AS username FROM wvp_user_api_key uak LEFT JOIN wvp_user u on u.id = uak.user_id WHERE uak.api_key = #{apiKey}")
UserApiKey selectByApiKey(@Param("apiKey") String apiKey);
@Select("SELECT uak.id, uak.user_id, uak.app, uak.api_key, uak.expired_at, uak.remark, uak.enable, uak.create_time, uak.update_time, u.username AS username FROM wvp_user_api_key uak LEFT JOIN wvp_user u on u.id = uak.user_id")
List<UserApiKey> selectAll();
@Select("SELECT uak.id, uak.user_id, uak.app, uak.api_key, uak.expired_at, uak.remark, uak.enable, uak.create_time, uak.update_time, u.username AS username FROM wvp_user_api_key uak LEFT JOIN wvp_user u on u.id = uak.user_id")
List<UserApiKey> getUserApiKeys();
@Select("SELECT COUNT(0) FROM wvp_user_api_key WHERE api_key = #{apiKey}")
boolean isApiKeyExists(@Param("apiKey") String apiKey);
}

View File

@@ -0,0 +1,151 @@
package com.genersoft.iot.vmp.storager.dao.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serializable;
/**
* 用户信息
*/
@Schema(description = "用户ApiKey信息")
public class UserApiKey implements Serializable {
/**
* Id
*/
@Schema(description = "Id")
private int id;
/**
* 用户Id
*/
@Schema(description = "用户Id")
private int userId;
/**
* 应用名
*/
@Schema(description = "应用名")
private String app;
/**
* ApiKey
*/
@Schema(description = "ApiKey")
private String apiKey;
/**
* 过期时间null=永不过期)
*/
@Schema(description = "过期时间null=永不过期)")
private long expiredAt;
/**
* 备注信息
*/
@Schema(description = "备注信息")
private String remark;
/**
* 是否启用
*/
@Schema(description = "是否启用")
private boolean enable;
/**
* 创建时间
*/
@Schema(description = "创建时间")
private String createTime;
/**
* 更新时间
*/
@Schema(description = "更新时间")
private String updateTime;
/**
* 用户名
*/
private String username;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getApp() {
return app;
}
public void setApp(String app) {
this.app = app;
}
public String getApiKey() {
return apiKey;
}
public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}
public long getExpiredAt() {
return expiredAt;
}
public void setExpiredAt(long expiredAt) {
this.expiredAt = expiredAt;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public String getUpdateTime() {
return updateTime;
}
public void setUpdateTime(String updateTime) {
this.updateTime = updateTime;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}

View File

@@ -0,0 +1,251 @@
package com.genersoft.iot.vmp.vmanager.user;
import com.genersoft.iot.vmp.conf.exception.ControllerException;
import com.genersoft.iot.vmp.conf.security.JwtUtils;
import com.genersoft.iot.vmp.conf.security.SecurityUtils;
import com.genersoft.iot.vmp.service.IUserApiKeyService;
import com.genersoft.iot.vmp.service.IUserService;
import com.genersoft.iot.vmp.storager.dao.dto.User;
import com.genersoft.iot.vmp.storager.dao.dto.UserApiKey;
import com.genersoft.iot.vmp.utils.DateUtil;
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
import com.github.pagehelper.PageInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@Tag(name = "用户ApiKey管理")
@RestController
@RequestMapping("/api/userApiKey")
public class UserApiKeyController {
public static final int EXPIRATION_TIME = Integer.MAX_VALUE;
@Autowired
private IUserService userService;
@Autowired
private IUserApiKeyService userApiKeyService;
/**
* 添加用户ApiKey
*
* @param userId
* @param app
* @param remark
* @param expiresAt
* @param enable
*/
@PostMapping("/add")
@Operation(summary = "添加用户ApiKey", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Parameter(name = "userId", description = "用户Id", required = true)
@Parameter(name = "app", description = "应用名称", required = false)
@Parameter(name = "remark", description = "备注信息", required = false)
@Parameter(name = "expiredAt", description = "过期时间(不传代表永不过期)", required = false)
@Transactional
public synchronized void add(
@RequestParam(required = true) int userId,
@RequestParam(required = false) String app,
@RequestParam(required = false) String remark,
@RequestParam(required = false) String expiresAt,
@RequestParam(required = false) Boolean enable
) {
User user = userService.getUserById(userId);
if (user == null) {
throw new ControllerException(ErrorCode.ERROR400.getCode(), "用户不存在");
}
Long expirationTime = null;
if (expiresAt != null) {
long timestamp = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestampMs(expiresAt);
expirationTime = (timestamp - System.currentTimeMillis()) / (60 * 1000);
if (expirationTime < 0) {
throw new ControllerException(ErrorCode.ERROR400.getCode(), "过期时间不能早于当前时间");
}
}
UserApiKey userApiKey = new UserApiKey();
userApiKey.setUserId(userId);
userApiKey.setApp(app);
userApiKey.setApiKey(null);
userApiKey.setRemark(remark);
userApiKey.setExpiredAt(expirationTime != null ? expirationTime : 0);
userApiKey.setEnable(enable != null ? enable : false);
userApiKey.setCreateTime(DateUtil.getNow());
userApiKey.setUpdateTime(DateUtil.getNow());
int addResult = userApiKeyService.addApiKey(userApiKey);
if (addResult <= 0) {
throw new ControllerException(ErrorCode.ERROR100);
}
String apiKey;
do {
Map<String, Object> extra = new HashMap<>(1);
extra.put("apiKeyId", userApiKey.getId());
apiKey = JwtUtils.createToken(user.getUsername(), expirationTime, extra);
} while (userApiKeyService.isApiKeyExists(apiKey));
int resetResult = userApiKeyService.reset(userApiKey.getId(), apiKey);
if (resetResult <= 0) {
throw new ControllerException(ErrorCode.ERROR100);
}
}
/**
* 分页查询ApiKey
*
* @param page 当前页
* @param count 每页查询数量
* @return 分页ApiKey列表
*/
@GetMapping("/userApiKeys")
@Operation(summary = "分页查询用户", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Parameter(name = "page", description = "当前页", required = true)
@Parameter(name = "count", description = "每页查询数量", required = true)
@Transactional
public PageInfo<UserApiKey> userApiKeys(@RequestParam(required = true) int page, @RequestParam(required = true) int count) {
return userApiKeyService.getUserApiKeys(page, count);
}
@PostMapping("/enable")
@Operation(summary = "启用用户ApiKey", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Parameter(name = "id", description = "用户ApiKeyId", required = true)
@Transactional
public void enable(@RequestParam(required = true) Integer id) {
// 获取当前登录用户id
int currenRoleId = SecurityUtils.getUserInfo().getRole().getId();
if (currenRoleId != 1) {
// 只用角色id为1才可以管理UserApiKey
throw new ControllerException(ErrorCode.ERROR403);
}
UserApiKey userApiKey = userApiKeyService.getUserApiKeyById(id);
if (userApiKey == null) {
throw new ControllerException(ErrorCode.ERROR400.getCode(), "ApiKey不存在");
}
int enableResult = userApiKeyService.enable(id);
if (enableResult <= 0) {
throw new ControllerException(ErrorCode.ERROR100);
}
}
@PostMapping("/disable")
@Operation(summary = "停用用户ApiKey", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Parameter(name = "id", description = "用户ApiKeyId", required = true)
@Transactional
public void disable(@RequestParam(required = true) Integer id) {
// 获取当前登录用户id
int currenRoleId = SecurityUtils.getUserInfo().getRole().getId();
if (currenRoleId != 1) {
// 只用角色id为1才可以管理UserApiKey
throw new ControllerException(ErrorCode.ERROR403);
}
UserApiKey userApiKey = userApiKeyService.getUserApiKeyById(id);
if (userApiKey == null) {
throw new ControllerException(ErrorCode.ERROR400.getCode(), "ApiKey不存在");
}
int disableResult = userApiKeyService.disable(id);
if (disableResult <= 0) {
throw new ControllerException(ErrorCode.ERROR100);
}
}
@PostMapping("/reset")
@Operation(summary = "重置用户ApiKey", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Parameter(name = "id", description = "用户ApiKeyId", required = true)
@Transactional
public void reset(@RequestParam(required = true) Integer id) {
// 获取当前登录用户id
int currenRoleId = SecurityUtils.getUserInfo().getRole().getId();
if (currenRoleId != 1) {
// 只用角色id为1才可以管理UserApiKey
throw new ControllerException(ErrorCode.ERROR403);
}
UserApiKey userApiKey = userApiKeyService.getUserApiKeyById(id);
if (userApiKey == null) {
throw new ControllerException(ErrorCode.ERROR400.getCode(), "ApiKey不存在");
}
User user = userService.getUserById(userApiKey.getUserId());
if (user == null) {
throw new ControllerException(ErrorCode.ERROR400.getCode(), "用户不存在");
}
Long expirationTime = null;
if (userApiKey.getExpiredAt() > 0) {
long timestamp = userApiKey.getExpiredAt();
expirationTime = (timestamp - System.currentTimeMillis()) / (60 * 1000);
if (expirationTime < 0) {
throw new ControllerException(ErrorCode.ERROR400.getCode(), "ApiKey已失效");
}
}
String apiKey;
do {
Map<String, Object> extra = new HashMap<>(1);
extra.put("apiKeyId", userApiKey.getId());
apiKey = JwtUtils.createToken(user.getUsername(), expirationTime, extra);
} while (userApiKeyService.isApiKeyExists(apiKey));
int resetResult = userApiKeyService.reset(id, apiKey);
if (resetResult <= 0) {
throw new ControllerException(ErrorCode.ERROR100);
}
}
@PostMapping("/remark")
@Operation(summary = "备注用户ApiKey", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Parameter(name = "id", description = "用户ApiKeyId", required = true)
@Parameter(name = "remark", description = "用户ApiKey备注", required = false)
@Transactional
public void remark(@RequestParam(required = true) Integer id, @RequestParam(required = false) String remark) {
// 获取当前登录用户id
int currenRoleId = SecurityUtils.getUserInfo().getRole().getId();
if (currenRoleId != 1) {
// 只用角色id为1才可以管理UserApiKey
throw new ControllerException(ErrorCode.ERROR403);
}
UserApiKey userApiKey = userApiKeyService.getUserApiKeyById(id);
if (userApiKey == null) {
throw new ControllerException(ErrorCode.ERROR400.getCode(), "ApiKey不存在");
}
int remarkResult = userApiKeyService.remark(id, remark);
if (remarkResult <= 0) {
throw new ControllerException(ErrorCode.ERROR100);
}
}
@DeleteMapping("/delete")
@Operation(summary = "删除用户ApiKey", security = @SecurityRequirement(name = JwtUtils.HEADER))
@Parameter(name = "id", description = "用户ApiKeyId", required = true)
@Transactional
public void delete(@RequestParam(required = true) Integer id) {
// 获取当前登录用户id
int currenRoleId = SecurityUtils.getUserInfo().getRole().getId();
if (currenRoleId != 1) {
// 只用角色id为1才可以管理UserApiKey
throw new ControllerException(ErrorCode.ERROR403);
}
UserApiKey userApiKey = userApiKeyService.getUserApiKeyById(id);
if (userApiKey == null) {
throw new ControllerException(ErrorCode.ERROR400.getCode(), "ApiKey不存在");
}
int deleteResult = userApiKeyService.delete(id);
if (deleteResult <= 0) {
throw new ControllerException(ErrorCode.ERROR100);
}
}
}