Commit 037c07d6 by inrgihc

配置token生命期

parent 6d198d72
......@@ -16,6 +16,8 @@ public abstract class Constants {
public static final Long CLIENT_TOKEN_DURATION_SECONDS = 7200L;
public static final Long CLIENT_TOKEN_LONGEVITY = -1L;
public static final int SC_TOO_MANY_REQUESTS = 429;
public static final String CACHE_NAME_API_RESPONSE = "response_result";
......
......@@ -29,6 +29,6 @@ public class AccessToken implements Serializable {
@ApiModelProperty("创建时的时间戳")
private Long createTimestamp;
@ApiModelProperty("有效时间(单位秒)")
@ApiModelProperty("有效期(时间段,单位:秒)")
private Long expireSeconds;
}
package com.gitee.sqlrest.common.enums;
import com.gitee.sqlrest.common.consts.Constants;
public enum AliveTimeEnum {
PERIOD("短期", Constants.CLIENT_TOKEN_DURATION_SECONDS),
LONGEVITY("长期", Constants.CLIENT_TOKEN_LONGEVITY);
private String name;
private long value;
AliveTimeEnum(String name, long value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public long getValue() {
return value;
}
}
......@@ -36,6 +36,10 @@ public final class TokenUtils {
return generateValue(UUID.randomUUID().toString());
}
public static int getTokenStringLength() {
return "9097ac1ab13198dfa4ddb2ecc1079693".length();
}
protected static String generateValue(String param) {
try {
MessageDigest algorithm = MessageDigest.getInstance("MD5");
......
package com.gitee.sqlrest.core.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.gitee.sqlrest.common.enums.AliveTimeEnum;
import com.gitee.sqlrest.common.enums.DurationTimeEnum;
import com.gitee.sqlrest.common.enums.ExpireTimeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.sql.Timestamp;
......@@ -41,6 +41,9 @@ public class AppClientDetailResponse {
@ApiModelProperty("是否过期")
private Boolean isExpired;
@ApiModelProperty("Token生命期")
private AliveTimeEnum tokenAlive;
@ApiModelProperty("创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Timestamp createTime;
......
package com.gitee.sqlrest.core.dto;
import com.gitee.sqlrest.common.enums.AliveTimeEnum;
import com.gitee.sqlrest.common.enums.ExpireTimeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
......@@ -27,4 +28,8 @@ public class AppClientSaveRequest {
@NotNull(message = "expireTime不能为null")
@ApiModelProperty("到期时间")
private ExpireTimeEnum expireTime;
@NotNull(message = "tokenAlive不能为null")
@ApiModelProperty("Token存活期")
private AliveTimeEnum tokenAlive;
}
......@@ -26,6 +26,7 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
......@@ -87,11 +88,14 @@ public class AuthenticationFilter implements Filter {
try {
if (!apiConfigEntity.getOpen()) {
String tokenStr = TokenUtils.getRequestToken(request);
if (StringUtils.isBlank(tokenStr)) {
throw new UnAuthorizedException("Need bearer token.");
}
String appKey = clientTokenService.verifyTokenAndGetAppKey(tokenStr);
accessRecordEntity.setClientKey(appKey);
if (null == appKey) {
log.error("Failed get app key from token [{}].", tokenStr);
throw new UnAuthorizedException("Failed to verify token: " + tokenStr);
log.error("Failed get app key from token [{}], maybe is invalid or expired. ", tokenStr);
throw new UnAuthorizedException("Invalid or Expired Token : " + tokenStr);
} else {
boolean verify = clientTokenService.verifyAuthGroup(appKey, apiConfigEntity.getGroupId());
if (!verify) {
......
......@@ -2,7 +2,11 @@ package com.gitee.sqlrest.core.service;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.gitee.sqlrest.cache.CacheFactory;
import com.gitee.sqlrest.common.consts.Constants;
import com.gitee.sqlrest.common.dto.AccessToken;
import com.gitee.sqlrest.common.dto.PageResult;
import com.gitee.sqlrest.common.enums.AliveTimeEnum;
import com.gitee.sqlrest.common.enums.DurationTimeEnum;
import com.gitee.sqlrest.common.enums.ExpireTimeEnum;
import com.gitee.sqlrest.common.exception.CommonException;
......@@ -18,9 +22,11 @@ import com.gitee.sqlrest.persistence.entity.AppClientEntity;
import com.gitee.sqlrest.persistence.util.PageUtils;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
@Service
......@@ -28,6 +34,8 @@ public class AppClientService {
@Resource
private AppClientDao appClientDao;
@Resource
private CacheFactory cacheFactory;
public void create(AppClientSaveRequest request) {
if (null != appClientDao.getByAppKey(request.getAppKey())) {
......@@ -41,14 +49,30 @@ public class AppClientService {
BeanUtil.copyProperties(request, appClientEntity);
appClientEntity.setAppSecret(TokenUtils.generateValue());
appClientEntity.setExpireDuration(request.getExpireTime().getDuration());
if (DurationTimeEnum.TIME_VALUE.equals(request.getExpireTime().getDuration())) {
appClientEntity.setExpireAt(request.getExpireTime().getValue() + (System.currentTimeMillis() / 1000));
} else if (DurationTimeEnum.FOR_EVER.equals(request.getExpireTime().getDuration())) {
appClientEntity.setExpireAt(-1L);
} else {
appClientEntity.setExpireAt(0L);
}
appClientEntity.setAccessToken(null);
appClientEntity.setTokenAlive(request.getTokenAlive());
appClientDao.insert(appClientEntity);
}
public void delete(Long id) {
AppClientEntity entity = appClientDao.getById(id);
if (null != entity) {
String token = entity.getAccessToken();
if (StringUtils.isNotBlank(token)) {
Map<String, AccessToken> tokenClientMap = cacheFactory
.getCacheMap(Constants.CACHE_KEY_TOKEN_CLIENT, AccessToken.class);
tokenClientMap.remove(token);
}
appClientDao.deleteById(id);
}
}
public PageResult<AppClientDetailResponse> searchList(EntitySearchRequest request) {
Supplier<List<AppClientDetailResponse>> method = () -> {
......
......@@ -3,6 +3,7 @@ package com.gitee.sqlrest.core.servlet;
import com.gitee.sqlrest.cache.CacheFactory;
import com.gitee.sqlrest.common.consts.Constants;
import com.gitee.sqlrest.common.dto.AccessToken;
import com.gitee.sqlrest.common.enums.AliveTimeEnum;
import com.gitee.sqlrest.common.enums.DurationTimeEnum;
import com.gitee.sqlrest.common.exception.CommonException;
import com.gitee.sqlrest.common.exception.ResponseErrorCode;
......@@ -10,7 +11,6 @@ import com.gitee.sqlrest.common.util.TokenUtils;
import com.gitee.sqlrest.persistence.dao.AppClientDao;
import com.gitee.sqlrest.persistence.entity.AppClientEntity;
import com.gitee.sqlrest.persistence.util.JsonUtils;
import java.time.LocalDateTime;
import java.util.Map;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
......@@ -18,6 +18,7 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Slf4j
@Service
......@@ -30,29 +31,35 @@ public class ClientTokenService {
@EventListener(ApplicationReadyEvent.class)
public void init() {
LocalDateTime now = LocalDateTime.now();
long currentTimestamp = getCurrentTimestamp();
try {
for (AppClientEntity appClient : appClientDao.listAll(null)) {
appClient.setAppSecret("******");
log.info("Load client app token from persistence :{}", JsonUtils.toJsonString(appClient));
if (StringUtils.isNotBlank(appClient.getAccessToken())) {
AccessToken clientToken = AccessToken.builder()
.realName(appClient.getName())
.appKey(appClient.getAppKey())
.accessToken(appClient.getAccessToken())
.createTimestamp(appClient.getCreateTime().getTime() / 1000)
.expireSeconds(appClient.getExpireDuration().getValue())
.createTimestamp(appClient.getUpdateTime().getTime() / 1000)
.expireSeconds(appClient.getTokenAlive().getValue())
.build();
if (DurationTimeEnum.TIME_VALUE.equals(appClient.getExpireDuration())) {
long expireSeconds = appClient.getExpireAt() - now.getSecond();
if (expireSeconds >= Constants.CLIENT_TOKEN_DURATION_SECONDS) {
clientToken.setExpireSeconds(Constants.CLIENT_TOKEN_DURATION_SECONDS);
if (appClient.getExpireAt() > 0) {
long expireSeconds = appClient.getExpireAt() - currentTimestamp;
if (expireSeconds <= 0) {
// 已经过期的无需再加载到缓存中了
continue;
}
if (expireSeconds >= appClient.getTokenAlive().getValue()) {
clientToken.setExpireSeconds(appClient.getTokenAlive().getValue());
} else {
clientToken.setExpireSeconds(expireSeconds);
}
}
// TODO: 暂时也将一次性token也加载进缓存中,缺少判断是否过期的逻辑
log.info("Load client app token from persistence :{}", JsonUtils.toJsonString(appClient));
Map<String, AccessToken> tokenClientMap = cacheFactory
.getCacheMap(Constants.CACHE_KEY_TOKEN_CLIENT, AccessToken.class);
tokenClientMap.put(appClient.getAccessToken(), clientToken);
......@@ -65,6 +72,7 @@ public class ClientTokenService {
}
}
@Transactional(rollbackFor = Exception.class)
public AccessToken generateToken(String clientId, String clientSecret) {
AppClientEntity appClient = appClientDao.getByAppKey(clientId);
if (null == appClient) {
......@@ -73,29 +81,53 @@ public class ClientTokenService {
if (!StringUtils.equals(appClient.getAppSecret(), clientSecret)) {
throw new CommonException(ResponseErrorCode.ERROR_CLIENT_FORBIDDEN, "secret invalid");
}
if (DurationTimeEnum.TIME_VALUE == appClient.getExpireDuration()) {
Boolean isExpired = getCurrentTimestamp() > appClient.getExpireAt();
if (isExpired) {
throw new CommonException(ResponseErrorCode.ERROR_CLIENT_FORBIDDEN, "clientId is expired");
}
} else if (DurationTimeEnum.ONLY_ONCE == appClient.getExpireDuration()) {
if (!appClient.getCreateTime().equals(appClient.getUpdateTime())) {
throw new CommonException(ResponseErrorCode.ERROR_CLIENT_FORBIDDEN, "clientId is expired");
}
}
String token = TokenUtils.generateValue();
Long createTimestamp = getCurrentTimestamp();
if (AliveTimeEnum.LONGEVITY.equals(appClient.getTokenAlive())
&& StringUtils.isNotBlank(appClient.getAccessToken())) {
token = appClient.getAccessToken();
createTimestamp = appClient.getUpdateTime().getTime();
}
AccessToken clientToken = AccessToken.builder()
.realName(appClient.getName())
.appKey(clientId)
.accessToken(token)
.createTimestamp(System.currentTimeMillis() / 1000)
.expireSeconds(Constants.CLIENT_TOKEN_DURATION_SECONDS)
.createTimestamp(createTimestamp)
.build();
if (DurationTimeEnum.TIME_VALUE.equals(appClient.getExpireDuration())) {
long expireSeconds = appClient.getExpireAt() - (System.currentTimeMillis() / 1000);
if (appClient.getExpireAt() > 0) {
long expireSeconds = appClient.getExpireAt() - getCurrentTimestamp();
if (expireSeconds <= 0) {
throw new CommonException(ResponseErrorCode.ERROR_CLIENT_FORBIDDEN, "app key is timeout");
throw new CommonException(ResponseErrorCode.ERROR_CLIENT_FORBIDDEN, "app key is expired");
}
if (expireSeconds >= Constants.CLIENT_TOKEN_DURATION_SECONDS) {
clientToken.setExpireSeconds(Constants.CLIENT_TOKEN_DURATION_SECONDS);
if (AliveTimeEnum.LONGEVITY.equals(appClient.getTokenAlive())) {
clientToken.setExpireSeconds(appClient.getExpireAt() - createTimestamp);
} else {
if (expireSeconds > appClient.getTokenAlive().getValue()) {
clientToken.setExpireSeconds(appClient.getTokenAlive().getValue());
} else {
clientToken.setExpireSeconds(expireSeconds);
}
}
} else if (appClient.getExpireAt() == 0) {
clientToken.setExpireSeconds(0L);
} else {
clientToken.setExpireSeconds(-1L);
}
if (!DurationTimeEnum.ONLY_ONCE.equals(appClient.getExpireDuration())) {
// 将token持久化到数据库中,以备重启服务器后原token继续可用
if (!StringUtils.equals(token, appClient.getAccessToken())) {
appClientDao.updateTokenByAppKey(clientId, token);
}
......@@ -110,26 +142,54 @@ public class ClientTokenService {
if (StringUtils.isBlank(tokenStr)) {
return null;
}
long currentTimestamp = getCurrentTimestamp();
Map<String, AccessToken> tokenClientMap = cacheFactory
.getCacheMap(Constants.CACHE_KEY_TOKEN_CLIENT, AccessToken.class);
AccessToken clientToken = tokenClientMap.get(tokenStr);
if (null == clientToken) {
if (tokenStr.length() == TokenUtils.getTokenStringLength()) {
AppClientEntity appClient = appClientDao.getByAccessToken(tokenStr);
if (null == appClient) {
return null;
}
Long expireTime = clientToken.getExpireSeconds();
if (expireTime <= 0) {
if (0 == expireTime) {
tokenClientMap.remove(tokenStr);
if ((AliveTimeEnum.LONGEVITY == appClient.getTokenAlive() & appClient.getExpireAt() < 0)
|| (appClient.getExpireAt() > currentTimestamp)) {
clientToken = AccessToken.builder()
.realName(appClient.getName())
.appKey(appClient.getAppKey())
.accessToken(tokenStr)
.createTimestamp(appClient.getUpdateTime().getTime())
.expireSeconds(appClient.getTokenAlive().getValue())
.build();
tokenClientMap.put(tokenStr, clientToken);
return clientToken.getAppKey();
}
}
return null;
}
long durationTimestamp = currentTimestamp - clientToken.getCreateTimestamp();
long expireTimestamp = clientToken.getExpireSeconds();
if (expireTimestamp <= 0) {
if (0 == expireTimestamp) {
// 一次性的应用客户端
tokenClientMap.remove(tokenStr);
log.warn("token [{}] only can use once, clientId: {}", tokenStr, clientToken.getAppKey());
} else {
// 长期性的应用客户端,使用长期的token情况
return clientToken.getAppKey();
} else if ((System.currentTimeMillis() / 1000) - clientToken.getCreateTimestamp() > expireTime) {
log.error("token [{}] expired, clientId: {}", tokenStr, clientToken.getAppKey());
}
} else if (durationTimestamp > expireTimestamp) {
log.warn("token [{}] expired, clientId: {}", tokenStr, clientToken.getAppKey());
return null;
}
return clientToken.getAppKey();
}
public boolean verifyAuthGroup(String clientId, Long groupId) {
return appClientDao.getAuthGroups(clientId).contains(groupId);
return appClientDao.existsAuthGroups(clientId, groupId);
}
private long getCurrentTimestamp() {
return System.currentTimeMillis() / 1000L;
}
}
package com.gitee.sqlrest.executor.controller;
import com.gitee.sqlrest.common.dto.AccessToken;
import com.gitee.sqlrest.common.dto.ResultEntity;
import com.gitee.sqlrest.common.exception.CommonException;
import com.gitee.sqlrest.core.servlet.ClientTokenService;
import java.util.Map;
import javax.annotation.Resource;
......@@ -18,7 +20,14 @@ public class ClientTokenController {
private ClientTokenService clientTokenService;
@PostMapping(value = "/generate", produces = MediaType.APPLICATION_JSON_VALUE)
public AccessToken generateToken(@RequestBody Map<String, String> body) {
return clientTokenService.generateToken(body.get("clientId"), body.get("secret"));
public ResultEntity generateToken(@RequestBody Map<String, String> body) {
try {
AccessToken token = clientTokenService.generateToken(body.get("clientId"), body.get("secret"));
return ResultEntity.success(token);
} catch (CommonException e) {
return ResultEntity.failed(e.getCode(), e.getMessage());
} catch (Exception e) {
return ResultEntity.failed(e.getMessage());
}
}
}
......@@ -62,6 +62,11 @@
</el-tag>
</template>
</el-table-column>
<el-table-column prop="tokenAlive"
label="Token生命期"
:formatter="stringFormatTokenAlive"
show-overflow-tooltip
min-width="18%"></el-table-column>
<el-table-column prop="createTime"
label="创建时间"
min-width="18%">
......@@ -136,12 +141,12 @@
<el-input v-model="createform.appKey"
auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="到期时长"
<el-form-item label="应用到期时长"
label-width="120px"
prop="expireTime"
style="width:85%">
<el-select v-model="createform.expireTime">
<el-option label="永远"
<el-option label="无期"
value="EXPIRE_FOR_EVER"></el-option>
<el-option label="一次"
value="EXPIRE_ONLY_ONCE"></el-option>
......@@ -161,6 +166,25 @@
value="EXPIRE_01_MOUTH"></el-option>
</el-select>
</el-form-item>
<el-form-item label-width="120px"
prop="tokenAlive"
style="width:35%">
<span slot="label"
style="display:inline-block;">
Token生命
<el-tooltip effect="dark"
content="‘短期’的token时长为7200秒,到期续约再调用认证接口获取;‘长期’的token永不会过期,但应用过期时也即随之过期,应用被删除时也即随之消亡."
placement="bottom">
<i class='el-icon-question' />
</el-tooltip>
</span>
<el-select v-model="createform.tokenAlive">
<el-option label="短期"
value="PERIOD"></el-option>
<el-option label="长期"
value="LONGEVITY"></el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer"
class="dialog-footer">
......@@ -227,7 +251,8 @@ export default {
name: "",
description: "",
appKey: "",
expireTime: ""
expireTime: "",
tokenAlive: "",
},
rules: {
name: [
......@@ -250,6 +275,13 @@ export default {
message: "到期时间必须选择",
trigger: "change"
}
],
tokenAlive: [
{
required: true,
message: "Token生命期必须选择",
trigger: "change"
}
]
},
createFormVisible: false
......@@ -310,6 +342,14 @@ export default {
}
return "-";
},
stringFormatTokenAlive (row, column) {
if (row.tokenAlive === "LONGEVITY") {
return "长期";
} else if (row.tokenAlive === "PERIOD") {
return "短期";
}
return "-";
},
searchByKeyword: function () {
this.currentPage = 1;
this.loadData();
......@@ -354,7 +394,8 @@ export default {
name: this.createform.name,
description: this.createform.description,
appKey: this.createform.appKey,
expireTime: this.createform.expireTime
expireTime: this.createform.expireTime,
tokenAlive: this.createform.tokenAlive,
})
}).then(res => {
if (0 === res.data.code) {
......
......@@ -5,3 +5,5 @@ databaseChangeLog:
file: classpath:db/changelog/log-v1.0.2.yaml
- include:
file: classpath:db/changelog/log-v1.1.1.yaml
- include:
file: classpath:db/changelog/log-v1.1.2.yaml
databaseChangeLog:
- changeSet:
id: 1.1.2
author: sqlrest
runOnChange: false
changes:
- sqlFile:
encoding: UTF-8
path: db/migration/V1_1_2__system-ddl.sql
ALTER TABLE `SQLREST_APP_CLIENT` ADD COLUMN `token_alive` varchar(16) not null default 'PERIOD' COMMENT 'TOKEN的生命期' AFTER `access_token`;
ALTER TABLE `SQLREST_APP_CLIENT` ADD INDEX `idx_access_token` (`access_token`) USING BTREE ;
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>SQLREST工具</title><link href=/static/css/app.21575699e2f9b8295d3f50748b986c67.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.37da822ab10e62d568da.js></script><script type=text/javascript src=/static/js/vendor.6bde4750a07bb5a2f647.js></script><script type=text/javascript src=/static/js/app.5b13ca32f61140a99ff5.js></script></body></html>
\ No newline at end of file
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>SQLREST工具</title><link href=/static/css/app.c8e8a852da8f5f1a381e2a81266f662e.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.1b702ecca7669457ed71.js></script><script type=text/javascript src=/static/js/vendor.6bde4750a07bb5a2f647.js></script><script type=text/javascript src=/static/js/app.eb5ff3cb290926815e5c.js></script></body></html>
\ No newline at end of file
webpackJsonp([15],{KYkU:function(e,a){},"n/J7":function(e,a,t){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var s=t("mvHQ"),o=t.n(s),r={name:"firewall",data:function(){return{status:"ON",mode:"BLACK",addresses:""}},methods:{loadData:function(){var e=this;this.$http.get("/sqlrest/manager/api/v1/firewall/detail").then(function(a){0===a.data.code?(e.status=a.data.data.status,e.mode=a.data.data.mode,e.addresses=a.data.data.addresses):alert("加载数据失败:"+a.data.message)})},modeChange:function(e){console.log(e)},handleSave:function(){var e=this;"ON"!==this.status||this.addresses&&!/^\s*$/.test(this.addresses)?this.$http({method:"POST",headers:{"Content-Type":"application/json"},url:"/sqlrest/manager/api/v1/firewall/save",data:o()({status:this.status,mode:this.mode,addresses:this.addresses})}).then(function(a){0===a.data.code?(e.$message("保存成功"),e.loadData()):alert("保存失败:"+a.data.message)}):alert("IP列表不能为空!")}},created:function(){this.loadData()}},l={render:function(){var e=this,a=e.$createElement,t=e._self._c||a;return t("div",[t("el-card",[t("el-form",{attrs:{"label-width":"200px"}},[t("el-form-item",{attrs:{label:"访问控制"}},[t("el-switch",{attrs:{"active-color":"#13ce66","active-value":"ON","inactive-value":"OFF","active-text":"开启","inactive-text":"关闭"},model:{value:e.status,callback:function(a){e.status=a},expression:"status"}})],1),e._v(" "),t("div",{directives:[{name:"show",rawName:"v-show",value:"ON"==e.status,expression:"status=='ON'"}]},[t("el-form-item",{attrs:{label:"名单"}},[t("el-radio-group",{on:{change:e.modeChange},model:{value:e.mode,callback:function(a){e.mode=a},expression:"mode"}},[t("el-radio",{attrs:{label:"BLACK"}},[e._v("黑名单")]),e._v(" "),t("el-radio",{attrs:{label:"WHITE"}},[e._v("白名单")])],1),e._v(" "),t("el-alert",{directives:[{name:"show",rawName:"v-show",value:"BLACK"==e.mode,expression:"mode == 'BLACK'"}],attrs:{title:"除了黑名单列表中的IP禁止访问API,其他IP一律允许访问",type:"warning",closable:!1}}),e._v(" "),t("el-alert",{directives:[{name:"show",rawName:"v-show",value:"WHITE"==e.mode,expression:"mode == 'WHITE'"}],attrs:{title:"只有白名单列表中的IP才允许访问API,其他IP一律禁止访问",type:"warning",closable:!1}})],1),e._v(" "),t("el-form-item",{directives:[{name:"show",rawName:"v-show",value:"BLACK"==e.mode,expression:"mode == 'BLACK'"}],attrs:{label:"黑名单IP列表"}},[t("el-input",{attrs:{type:"textarea",autosize:{minRows:8,maxRows:20},placeholder:"每行一个IP,多个IP请用换行分隔."},model:{value:e.addresses,callback:function(a){e.addresses=a},expression:"addresses"}})],1),e._v(" "),t("el-form-item",{directives:[{name:"show",rawName:"v-show",value:"WHITE"==e.mode,expression:"mode == 'WHITE'"}],attrs:{label:"白名单IP列表"}},[t("el-input",{attrs:{type:"textarea",autosize:{minRows:8,maxRows:20},placeholder:"每行一个IP,多个IP请用换行分隔."},model:{value:e.addresses,callback:function(a){e.addresses=a},expression:"addresses"}})],1)],1),e._v(" "),t("el-form-item",[t("el-button",{attrs:{type:"primary",plain:""},on:{click:e.handleSave}},[e._v("保存")])],1)],1)],1)],1)},staticRenderFns:[]};var d=t("VU/8")(r,l,!1,function(e){t("KYkU")},"data-v-7b9e1562",null);a.default=d.exports}});
//# sourceMappingURL=15.3b3f0c03ff4fed9903cc.js.map
\ No newline at end of file
webpackJsonp([16],{KYkU:function(e,a){},"n/J7":function(e,a,t){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var s=t("mvHQ"),o=t.n(s),r={name:"firewall",data:function(){return{status:"ON",mode:"BLACK",addresses:""}},methods:{loadData:function(){var e=this;this.$http.get("/sqlrest/manager/api/v1/firewall/detail").then(function(a){0===a.data.code?(e.status=a.data.data.status,e.mode=a.data.data.mode,e.addresses=a.data.data.addresses):alert("加载数据失败:"+a.data.message)})},modeChange:function(e){console.log(e)},handleSave:function(){var e=this;"ON"!==this.status||this.addresses&&!/^\s*$/.test(this.addresses)?this.$http({method:"POST",headers:{"Content-Type":"application/json"},url:"/sqlrest/manager/api/v1/firewall/save",data:o()({status:this.status,mode:this.mode,addresses:this.addresses})}).then(function(a){0===a.data.code?(e.$message("保存成功"),e.loadData()):alert("保存失败:"+a.data.message)}):alert("IP列表不能为空!")}},created:function(){this.loadData()}},l={render:function(){var e=this,a=e.$createElement,t=e._self._c||a;return t("div",[t("el-card",[t("el-form",{attrs:{"label-width":"200px"}},[t("el-form-item",{attrs:{label:"访问控制"}},[t("el-switch",{attrs:{"active-color":"#13ce66","active-value":"ON","inactive-value":"OFF","active-text":"开启","inactive-text":"关闭"},model:{value:e.status,callback:function(a){e.status=a},expression:"status"}})],1),e._v(" "),t("div",{directives:[{name:"show",rawName:"v-show",value:"ON"==e.status,expression:"status=='ON'"}]},[t("el-form-item",{attrs:{label:"名单"}},[t("el-radio-group",{on:{change:e.modeChange},model:{value:e.mode,callback:function(a){e.mode=a},expression:"mode"}},[t("el-radio",{attrs:{label:"BLACK"}},[e._v("黑名单")]),e._v(" "),t("el-radio",{attrs:{label:"WHITE"}},[e._v("白名单")])],1),e._v(" "),t("el-alert",{directives:[{name:"show",rawName:"v-show",value:"BLACK"==e.mode,expression:"mode == 'BLACK'"}],attrs:{title:"除了黑名单列表中的IP禁止访问API,其他IP一律允许访问",type:"warning",closable:!1}}),e._v(" "),t("el-alert",{directives:[{name:"show",rawName:"v-show",value:"WHITE"==e.mode,expression:"mode == 'WHITE'"}],attrs:{title:"只有白名单列表中的IP才允许访问API,其他IP一律禁止访问",type:"warning",closable:!1}})],1),e._v(" "),t("el-form-item",{directives:[{name:"show",rawName:"v-show",value:"BLACK"==e.mode,expression:"mode == 'BLACK'"}],attrs:{label:"黑名单IP列表"}},[t("el-input",{attrs:{type:"textarea",autosize:{minRows:8,maxRows:20},placeholder:"每行一个IP,多个IP请用换行分隔."},model:{value:e.addresses,callback:function(a){e.addresses=a},expression:"addresses"}})],1),e._v(" "),t("el-form-item",{directives:[{name:"show",rawName:"v-show",value:"WHITE"==e.mode,expression:"mode == 'WHITE'"}],attrs:{label:"白名单IP列表"}},[t("el-input",{attrs:{type:"textarea",autosize:{minRows:8,maxRows:20},placeholder:"每行一个IP,多个IP请用换行分隔."},model:{value:e.addresses,callback:function(a){e.addresses=a},expression:"addresses"}})],1)],1),e._v(" "),t("el-form-item",[t("el-button",{attrs:{type:"primary",plain:""},on:{click:e.handleSave}},[e._v("保存")])],1)],1)],1)],1)},staticRenderFns:[]};var d=t("VU/8")(r,l,!1,function(e){t("KYkU")},"data-v-7b9e1562",null);a.default=d.exports}});
//# sourceMappingURL=16.6d16122f45f1a1f311e2.js.map
\ No newline at end of file
webpackJsonp([18],{"T+/8":function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});r("mw3O");var a={data:function(){return{logining:!1,ruleForm2:{username:"",password:""},rules2:{username:[{required:!0,message:"请输入用户名",trigger:"blur"}],password:[{required:!0,message:"请输入密码",trigger:"blur"}]},checked:!1}},created:function(){var e=this;document.onkeydown=function(t){13==window.event.keyCode&&e.handleSubmit(t)}},methods:{handleSubmit:function(){var e=this;this.$refs.ruleForm2.validate(function(t){t&&e.$http({method:"POST",url:"/user/login",data:{username:e.ruleForm2.username,password:e.ruleForm2.password}}).then(function(t){0===t.data.code?(e.logining=!0,window.sessionStorage.setItem("token",t.data.data.accessToken),window.sessionStorage.setItem("username",e.ruleForm2.username),window.sessionStorage.setItem("realname",t.data.data.realName),e.$router.push({path:"/dashboard"})):(e.logining=!1,e.$message(t.data.message))})})}}},s={render:function(){var e=this,t=e.$createElement,r=e._self._c||t;return r("div",{staticClass:"login-container"},[r("el-form",{ref:"ruleForm2",staticClass:"demo-ruleForm login-page",attrs:{model:e.ruleForm2,rules:e.rules2,"status-icon":"","label-position":"left","label-width":"0px"}},[r("h3",{staticClass:"title",attrs:{align:"center"}},[e._v("系统登录")]),e._v(" "),r("el-form-item",{attrs:{prop:"username"}},[r("el-input",{attrs:{type:"text","auto-complete":"off",placeholder:"用户名"},model:{value:e.ruleForm2.username,callback:function(t){e.$set(e.ruleForm2,"username",t)},expression:"ruleForm2.username"}})],1),e._v(" "),r("el-form-item",{attrs:{prop:"password"}},[r("el-input",{attrs:{type:"password","auto-complete":"off",placeholder:"密码"},model:{value:e.ruleForm2.password,callback:function(t){e.$set(e.ruleForm2,"password",t)},expression:"ruleForm2.password"}})],1),e._v(" "),r("el-form-item",{staticStyle:{width:"100%"}},[r("el-button",{staticStyle:{width:"100%"},attrs:{type:"primary",loading:e.logining},on:{click:e.handleSubmit,keyup:function(t){return!t.type.indexOf("key")&&e._k(t.keyCode,"enter",13,t.key,"Enter")?null:e.handleSubmit(t)}}},[e._v("登录")])],1)],1)],1)},staticRenderFns:[]};var o=r("VU/8")(a,s,!1,function(e){r("VdEY")},"data-v-1b5aac28",null);t.default=o.exports},VdEY:function(e,t){}});
//# sourceMappingURL=18.5e7f065a8d031847e833.js.map
\ No newline at end of file
webpackJsonp([19],{"T+/8":function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});r("mw3O");var a={data:function(){return{logining:!1,ruleForm2:{username:"",password:""},rules2:{username:[{required:!0,message:"请输入用户名",trigger:"blur"}],password:[{required:!0,message:"请输入密码",trigger:"blur"}]},checked:!1}},created:function(){var e=this;document.onkeydown=function(t){13==window.event.keyCode&&e.handleSubmit(t)}},methods:{handleSubmit:function(){var e=this;this.$refs.ruleForm2.validate(function(t){t&&e.$http({method:"POST",url:"/user/login",data:{username:e.ruleForm2.username,password:e.ruleForm2.password}}).then(function(t){0===t.data.code?(e.logining=!0,window.sessionStorage.setItem("token",t.data.data.accessToken),window.sessionStorage.setItem("username",e.ruleForm2.username),window.sessionStorage.setItem("realname",t.data.data.realName),e.$router.push({path:"/dashboard"})):(e.logining=!1,e.$message(t.data.message))})})}}},s={render:function(){var e=this,t=e.$createElement,r=e._self._c||t;return r("div",{staticClass:"login-container"},[r("el-form",{ref:"ruleForm2",staticClass:"demo-ruleForm login-page",attrs:{model:e.ruleForm2,rules:e.rules2,"status-icon":"","label-position":"left","label-width":"0px"}},[r("h3",{staticClass:"title",attrs:{align:"center"}},[e._v("系统登录")]),e._v(" "),r("el-form-item",{attrs:{prop:"username"}},[r("el-input",{attrs:{type:"text","auto-complete":"off",placeholder:"用户名"},model:{value:e.ruleForm2.username,callback:function(t){e.$set(e.ruleForm2,"username",t)},expression:"ruleForm2.username"}})],1),e._v(" "),r("el-form-item",{attrs:{prop:"password"}},[r("el-input",{attrs:{type:"password","auto-complete":"off",placeholder:"密码"},model:{value:e.ruleForm2.password,callback:function(t){e.$set(e.ruleForm2,"password",t)},expression:"ruleForm2.password"}})],1),e._v(" "),r("el-form-item",{staticStyle:{width:"100%"}},[r("el-button",{staticStyle:{width:"100%"},attrs:{type:"primary",loading:e.logining},on:{click:e.handleSubmit,keyup:function(t){return!t.type.indexOf("key")&&e._k(t.keyCode,"enter",13,t.key,"Enter")?null:e.handleSubmit(t)}}},[e._v("登录")])],1)],1)],1)},staticRenderFns:[]};var o=r("VU/8")(a,s,!1,function(e){r("VdEY")},"data-v-1b5aac28",null);t.default=o.exports},VdEY:function(e,t){}});
//# sourceMappingURL=19.d8b36c25e8b686c0ae5f.js.map
\ No newline at end of file
webpackJsonp([19],{"5fz/":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o={data:function(){return{}},components:{common:n("u2+N").a},methods:{},created:function(){}},r={render:function(){var t=this.$createElement;return(this._self._c||t)("common",{attrs:{isOnlyShowDetail:!1}})},staticRenderFns:[]};var a=n("VU/8")(o,r,!1,function(t){n("b2pB")},"data-v-1762f182",null);e.default=a.exports},b2pB:function(t,e){}});
//# sourceMappingURL=19.3936346cb7e30aa279e2.js.map
\ No newline at end of file
webpackJsonp([20],{"5fz/":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o={data:function(){return{}},components:{common:n("u2+N").a},methods:{},created:function(){}},r={render:function(){var t=this.$createElement;return(this._self._c||t)("common",{attrs:{isOnlyShowDetail:!1}})},staticRenderFns:[]};var a=n("VU/8")(o,r,!1,function(t){n("b2pB")},"data-v-1762f182",null);e.default=a.exports},b2pB:function(t,e){}});
//# sourceMappingURL=20.8085ffbdaee58f2c229a.js.map
\ No newline at end of file
{"version":3,"sources":["webpack:///src/views/interface/create.vue","webpack:///./src/views/interface/create.vue?ba12","webpack:///./src/views/interface/create.vue"],"names":["create","data","components","common","methods","created","interface_create","render","_h","this","$createElement","_self","_c","attrs","isOnlyShowDetail","staticRenderFns","Component","__webpack_require__","normalizeComponent","ssrContext","__webpack_exports__"],"mappings":"4GAQAA,GACAC,KADA,WAEA,UAGAC,YAAAC,iBAAA,GACAC,WAEAC,QARA,cCLeC,GADEC,OAFjB,WAA0B,IAAaC,EAAbC,KAAaC,eAAkD,OAA/DD,KAAuCE,MAAAC,IAAAJ,GAAwB,UAAoBK,OAAOC,kBAAA,MAEnGC,oBCCjB,IAcAC,EAdyBC,EAAQ,OAcjCC,CACElB,EACAM,GATF,EAVA,SAAAa,GACEF,EAAQ,SAaV,kBAEA,MAUeG,EAAA,QAAAJ,EAAiB","file":"static/js/19.3936346cb7e30aa279e2.js","sourcesContent":["<template>\r\n <common :isOnlyShowDetail=\"false\">\r\n </common>\r\n</template>\r\n\r\n<script>\r\nimport common from '@/views/interface/common'\r\n\r\nexport default {\r\n data () {\r\n return {\r\n }\r\n },\r\n components: { common },\r\n methods: {\r\n },\r\n created () {\r\n },\r\n}\r\n</script>\r\n\r\n<style scoped>\r\n</style>\n\n\n// WEBPACK FOOTER //\n// src/views/interface/create.vue","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('common',{attrs:{\"isOnlyShowDetail\":false}})}\nvar staticRenderFns = []\nvar esExports = { render: render, staticRenderFns: staticRenderFns }\nexport default esExports\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/vue-loader/lib/template-compiler?{\"id\":\"data-v-1762f182\",\"hasScoped\":true,\"transformToRequire\":{\"video\":[\"src\",\"poster\"],\"source\":\"src\",\"img\":\"src\",\"image\":\"xlink:href\"},\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./src/views/interface/create.vue\n// module id = null\n// module chunks = ","function injectStyle (ssrContext) {\n require(\"!!../../../node_modules/extract-text-webpack-plugin/dist/loader.js?{\\\"omit\\\":1,\\\"remove\\\":true,\\\"publicPath\\\":\\\"../../\\\"}!vue-style-loader!css-loader?{\\\"sourceMap\\\":true}!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-1762f182\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./create.vue\")\n}\nvar normalizeComponent = require(\"!../../../node_modules/vue-loader/lib/component-normalizer\")\n/* script */\nexport * from \"!!babel-loader!../../../node_modules/vue-loader/lib/selector?type=script&index=0!./create.vue\"\nimport __vue_script__ from \"!!babel-loader!../../../node_modules/vue-loader/lib/selector?type=script&index=0!./create.vue\"\n/* template */\nimport __vue_template__ from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-1762f182\\\",\\\"hasScoped\\\":true,\\\"transformToRequire\\\":{\\\"video\\\":[\\\"src\\\",\\\"poster\\\"],\\\"source\\\":\\\"src\\\",\\\"img\\\":\\\"src\\\",\\\"image\\\":\\\"xlink:href\\\"},\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./create.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = \"data-v-1762f182\"\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_template__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/views/interface/create.vue\n// module id = null\n// module chunks = "],"sourceRoot":""}
\ No newline at end of file
{"version":3,"sources":["webpack:///src/views/interface/create.vue","webpack:///./src/views/interface/create.vue?ba12","webpack:///./src/views/interface/create.vue"],"names":["create","data","components","common","methods","created","interface_create","render","_h","this","$createElement","_self","_c","attrs","isOnlyShowDetail","staticRenderFns","Component","__webpack_require__","normalizeComponent","ssrContext","__webpack_exports__"],"mappings":"4GAQAA,GACAC,KADA,WAEA,UAGAC,YAAAC,iBAAA,GACAC,WAEAC,QARA,cCLeC,GADEC,OAFjB,WAA0B,IAAaC,EAAbC,KAAaC,eAAkD,OAA/DD,KAAuCE,MAAAC,IAAAJ,GAAwB,UAAoBK,OAAOC,kBAAA,MAEnGC,oBCCjB,IAcAC,EAdyBC,EAAQ,OAcjCC,CACElB,EACAM,GATF,EAVA,SAAAa,GACEF,EAAQ,SAaV,kBAEA,MAUeG,EAAA,QAAAJ,EAAiB","file":"static/js/20.8085ffbdaee58f2c229a.js","sourcesContent":["<template>\r\n <common :isOnlyShowDetail=\"false\">\r\n </common>\r\n</template>\r\n\r\n<script>\r\nimport common from '@/views/interface/common'\r\n\r\nexport default {\r\n data () {\r\n return {\r\n }\r\n },\r\n components: { common },\r\n methods: {\r\n },\r\n created () {\r\n },\r\n}\r\n</script>\r\n\r\n<style scoped>\r\n</style>\n\n\n// WEBPACK FOOTER //\n// src/views/interface/create.vue","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('common',{attrs:{\"isOnlyShowDetail\":false}})}\nvar staticRenderFns = []\nvar esExports = { render: render, staticRenderFns: staticRenderFns }\nexport default esExports\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/vue-loader/lib/template-compiler?{\"id\":\"data-v-1762f182\",\"hasScoped\":true,\"transformToRequire\":{\"video\":[\"src\",\"poster\"],\"source\":\"src\",\"img\":\"src\",\"image\":\"xlink:href\"},\"buble\":{\"transforms\":{}}}!./node_modules/vue-loader/lib/selector.js?type=template&index=0!./src/views/interface/create.vue\n// module id = null\n// module chunks = ","function injectStyle (ssrContext) {\n require(\"!!../../../node_modules/extract-text-webpack-plugin/dist/loader.js?{\\\"omit\\\":1,\\\"remove\\\":true,\\\"publicPath\\\":\\\"../../\\\"}!vue-style-loader!css-loader?{\\\"sourceMap\\\":true}!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"vue\\\":true,\\\"id\\\":\\\"data-v-1762f182\\\",\\\"scoped\\\":true,\\\"hasInlineConfig\\\":false}!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./create.vue\")\n}\nvar normalizeComponent = require(\"!../../../node_modules/vue-loader/lib/component-normalizer\")\n/* script */\nexport * from \"!!babel-loader!../../../node_modules/vue-loader/lib/selector?type=script&index=0!./create.vue\"\nimport __vue_script__ from \"!!babel-loader!../../../node_modules/vue-loader/lib/selector?type=script&index=0!./create.vue\"\n/* template */\nimport __vue_template__ from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-1762f182\\\",\\\"hasScoped\\\":true,\\\"transformToRequire\\\":{\\\"video\\\":[\\\"src\\\",\\\"poster\\\"],\\\"source\\\":\\\"src\\\",\\\"img\\\":\\\"src\\\",\\\"image\\\":\\\"xlink:href\\\"},\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./create.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = \"data-v-1762f182\"\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_template__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/views/interface/create.vue\n// module id = null\n// module chunks = "],"sourceRoot":""}
\ No newline at end of file
webpackJsonp([23],{"4/hK":function(n,e){},"6Wpa":function(n,e){},NHnr:function(n,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=t("//Fk"),i=t.n(o),r=t("7+uW"),c={render:function(){var n=this.$createElement,e=this._self._c||n;return e("div",{staticClass:"body-wrapper"},[e("router-view")],1)},staticRenderFns:[]};var a=t("VU/8")({name:"App"},c,!1,function(n){t("z/cX")},"data-v-c3654c36",null).exports,u=t("/ocq");r.default.use(u.a);var l=new u.a({routes:[{path:"/",name:"首页",component:function(){return t.e(2).then(t.bind(null,"4er+"))},redirect:"/dashboard",children:[{path:"/dashboard",name:"概览",icon:"el-icon-menu",component:function(){return t.e(10).then(t.bind(null,"ARoL"))}},{path:"/datasource",name:"连接配置",icon:"el-icon-coin",component:function(){return t.e(9).then(t.bind(null,"WGg6"))},children:[{path:"/datasource/driver",name:"驱动配置",icon:"el-icon-help",component:function(){return t.e(3).then(t.bind(null,"uOvO"))}},{path:"/datasource/list",name:"连接管理",icon:"el-icon-bank-card",component:function(){return Promise.all([t.e(0),t.e(5)]).then(t.bind(null,"U0nr"))}}]},{path:"/setting",name:"系统设置",icon:"el-icon-s-tools",component:function(){return t.e(6).then(t.bind(null,"VlR1"))},children:[{path:"/setting/group",name:"授权分组",icon:"el-icon-tickets",component:function(){return Promise.all([t.e(0),t.e(21)]).then(t.bind(null,"cGhg"))}},{path:"/setting/client",name:"客户应用",icon:"el-icon-pie-chart",component:function(){return Promise.all([t.e(0),t.e(20)]).then(t.bind(null,"i2vO"))}},{path:"/setting/firewall",name:"访问控制",icon:"el-icon-notebook-2",component:function(){return Promise.all([t.e(0),t.e(15)]).then(t.bind(null,"n/J7"))}},{path:"/setting/topology",name:"拓扑结构",icon:"el-icon-link",component:function(){return Promise.all([t.e(0),t.e(11)]).then(t.bind(null,"aSAZ"))}}]},{path:"/interface",name:"接口开发",icon:"el-icon-edit-outline",component:function(){return t.e(8).then(t.bind(null,"zsKB"))},children:[{path:"/interface/module",name:"模块配置",icon:"el-icon-folder",component:function(){return Promise.all([t.e(0),t.e(17)]).then(t.bind(null,"BOPB"))}},{path:"/interface/list",name:"接口配置",icon:"el-icon-refrigerator",component:function(){return Promise.all([t.e(0),t.e(16)]).then(t.bind(null,"6PtB"))}}]},{path:"/service",name:"接口仓库",icon:"el-icon-school",component:function(){return t.e(7).then(t.bind(null,"JpB7"))},children:[{path:"/service/interface",name:"服务接口",icon:"el-icon-lightning",component:function(){return Promise.all([t.e(0),t.e(12)]).then(t.bind(null,"vvPu"))}}]},{path:"/aboutme",name:"关于系统",icon:"el-icon-s-custom",component:function(){return t.e(1).then(t.bind(null,"AEfp"))}},{path:"/user/self",name:"个人中心",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(4)]).then(t.bind(null,"nqIE"))}},{path:"/interface/create",name:"创建任务",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(19)]).then(t.bind(null,"5fz/"))}},{path:"/interface/update",name:"修改任务",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(14)]).then(t.bind(null,"DuIM"))}},{path:"/interface/detail",name:"查看任务",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(13)]).then(t.bind(null,"+sv1"))}}]},{path:"/login",name:"登录",component:function(){return Promise.all([t.e(0),t.e(18)]).then(t.bind(null,"T+/8"))}}]}),p=t("mtWM"),s=t.n(p).a.create();s.interceptors.request.use(function(n){return n.url=""+n.url,n});var d=s,h=t("zL8q"),m=t.n(h),f=(t("muQq"),t("6Wpa"),t("zuxR"),t("tvR6"),t("XLwt")),b=t("E5Az"),v=t.n(b),g=(t("4/hK"),t("R0ti")),P=t.n(g);r.default.use(v.a),r.default.use(d),r.default.use(m.a),r.default.use(P.a),r.default.prototype.$http=d,r.default.config.productionTip=!1,r.default.prototype.$echarts=f,d.interceptors.request.use(function(n){var e=sessionStorage.getItem("token");return e&&(n.headers.Authorization="Bearer "+e),n},function(n){return i.a.reject(n)}),d.interceptors.response.use(function(n){return!n.data||401!==n.data.code&&403!==n.data.code&&404!==n.data.code||l.push({path:"/login"}),n},function(n){return i.a.reject(n.response)}),new r.default({el:"#app",router:l,components:{App:a},template:"<App/>"})},muQq:function(n,e){},tvR6:function(n,e){},"z/cX":function(n,e){},zuxR:function(n,e){}},["NHnr"]);
//# sourceMappingURL=app.5b13ca32f61140a99ff5.js.map
\ No newline at end of file
webpackJsonp([23],{"4/hK":function(n,e){},"6Wpa":function(n,e){},NHnr:function(n,e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=t("//Fk"),i=t.n(o),r=t("7+uW"),c={render:function(){var n=this.$createElement,e=this._self._c||n;return e("div",{staticClass:"body-wrapper"},[e("router-view")],1)},staticRenderFns:[]};var a=t("VU/8")({name:"App"},c,!1,function(n){t("z/cX")},"data-v-c3654c36",null).exports,u=t("/ocq");r.default.use(u.a);var l=new u.a({routes:[{path:"/",name:"首页",component:function(){return t.e(2).then(t.bind(null,"4er+"))},redirect:"/dashboard",children:[{path:"/dashboard",name:"概览",icon:"el-icon-menu",component:function(){return t.e(10).then(t.bind(null,"ARoL"))}},{path:"/datasource",name:"连接配置",icon:"el-icon-coin",component:function(){return t.e(9).then(t.bind(null,"WGg6"))},children:[{path:"/datasource/driver",name:"驱动配置",icon:"el-icon-help",component:function(){return t.e(3).then(t.bind(null,"uOvO"))}},{path:"/datasource/list",name:"连接管理",icon:"el-icon-bank-card",component:function(){return Promise.all([t.e(0),t.e(5)]).then(t.bind(null,"U0nr"))}}]},{path:"/setting",name:"系统设置",icon:"el-icon-s-tools",component:function(){return t.e(6).then(t.bind(null,"VlR1"))},children:[{path:"/setting/group",name:"授权分组",icon:"el-icon-tickets",component:function(){return Promise.all([t.e(0),t.e(21)]).then(t.bind(null,"cGhg"))}},{path:"/setting/client",name:"客户应用",icon:"el-icon-pie-chart",component:function(){return Promise.all([t.e(0),t.e(15)]).then(t.bind(null,"i2vO"))}},{path:"/setting/firewall",name:"访问控制",icon:"el-icon-notebook-2",component:function(){return Promise.all([t.e(0),t.e(16)]).then(t.bind(null,"n/J7"))}},{path:"/setting/topology",name:"拓扑结构",icon:"el-icon-link",component:function(){return Promise.all([t.e(0),t.e(11)]).then(t.bind(null,"aSAZ"))}}]},{path:"/interface",name:"接口开发",icon:"el-icon-edit-outline",component:function(){return t.e(8).then(t.bind(null,"zsKB"))},children:[{path:"/interface/module",name:"模块配置",icon:"el-icon-folder",component:function(){return Promise.all([t.e(0),t.e(18)]).then(t.bind(null,"BOPB"))}},{path:"/interface/list",name:"接口配置",icon:"el-icon-refrigerator",component:function(){return Promise.all([t.e(0),t.e(17)]).then(t.bind(null,"6PtB"))}}]},{path:"/service",name:"接口仓库",icon:"el-icon-school",component:function(){return t.e(7).then(t.bind(null,"JpB7"))},children:[{path:"/service/interface",name:"服务接口",icon:"el-icon-lightning",component:function(){return Promise.all([t.e(0),t.e(12)]).then(t.bind(null,"vvPu"))}}]},{path:"/aboutme",name:"关于系统",icon:"el-icon-s-custom",component:function(){return t.e(1).then(t.bind(null,"AEfp"))}},{path:"/user/self",name:"个人中心",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(4)]).then(t.bind(null,"nqIE"))}},{path:"/interface/create",name:"创建任务",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(20)]).then(t.bind(null,"5fz/"))}},{path:"/interface/update",name:"修改任务",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(14)]).then(t.bind(null,"DuIM"))}},{path:"/interface/detail",name:"查看任务",hidden:!0,component:function(){return Promise.all([t.e(0),t.e(13)]).then(t.bind(null,"+sv1"))}}]},{path:"/login",name:"登录",component:function(){return Promise.all([t.e(0),t.e(19)]).then(t.bind(null,"T+/8"))}}]}),p=t("mtWM"),s=t.n(p).a.create();s.interceptors.request.use(function(n){return n.url=""+n.url,n});var d=s,h=t("zL8q"),m=t.n(h),f=(t("muQq"),t("6Wpa"),t("zuxR"),t("tvR6"),t("XLwt")),b=t("E5Az"),v=t.n(b),g=(t("4/hK"),t("R0ti")),P=t.n(g);r.default.use(v.a),r.default.use(d),r.default.use(m.a),r.default.use(P.a),r.default.prototype.$http=d,r.default.config.productionTip=!1,r.default.prototype.$echarts=f,d.interceptors.request.use(function(n){var e=sessionStorage.getItem("token");return e&&(n.headers.Authorization="Bearer "+e),n},function(n){return i.a.reject(n)}),d.interceptors.response.use(function(n){return!n.data||401!==n.data.code&&403!==n.data.code&&404!==n.data.code||l.push({path:"/login"}),n},function(n){return i.a.reject(n.response)}),new r.default({el:"#app",router:l,components:{App:a},template:"<App/>"})},muQq:function(n,e){},tvR6:function(n,e){},"z/cX":function(n,e){},zuxR:function(n,e){}},["NHnr"]);
//# sourceMappingURL=app.eb5ff3cb290926815e5c.js.map
\ No newline at end of file
!function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,o,c){for(var f,d,i,u=0,b=[];u<r.length;u++)d=r[u],t[d]&&b.push(t[d][0]),t[d]=0;for(f in o)Object.prototype.hasOwnProperty.call(o,f)&&(e[f]=o[f]);for(n&&n(r,o,c);b.length;)b.shift()();if(c)for(u=0;u<c.length;u++)i=a(a.s=c[u]);return i};var r={},t={24:0};function a(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.e=function(e){var n=t[e];if(0===n)return new Promise(function(e){e()});if(n)return n[2];var r=new Promise(function(r,a){n=t[e]=[r,a]});n[2]=r;var o=document.getElementsByTagName("head")[0],c=document.createElement("script");c.type="text/javascript",c.charset="utf-8",c.async=!0,c.timeout=12e4,a.nc&&c.setAttribute("nonce",a.nc),c.src=a.p+"static/js/"+e+"."+{0:"f72dbb9d754b88a9e6e3",1:"b17200cccd46e216dcb3",2:"140338f6a5528feea1a3",3:"776d791724a8de12ff9e",4:"f8494b8dd039413f79c8",5:"530a43b5ad6055214539",6:"8f85de06573e2a5f9562",7:"061807fe4716131f26f8",8:"d1391c270de5a9f111c5",9:"cbdb7fa4f5180acfbb03",10:"7eeaa94fd42d34a86b92",11:"096c0f0eaf2850056b7e",12:"cea57d271a961f0b44ad",13:"4d2138ee1bee3ad573f4",14:"429592868e75adc95933",15:"3b3f0c03ff4fed9903cc",16:"9616cfe0a4f7517b0841",17:"b4bc5fa31e227bee8651",18:"5e7f065a8d031847e833",19:"3936346cb7e30aa279e2",20:"5ef9c751035ee9a08f94",21:"d8007e7169c085e13dab"}[e]+".js";var f=setTimeout(d,12e4);function d(){c.onerror=c.onload=null,clearTimeout(f);var n=t[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),t[e]=void 0)}return c.onerror=c.onload=d,o.appendChild(c),r},a.m=e,a.c=r,a.d=function(e,n,r){a.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},a.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(n,"a",n),n},a.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},a.p="/",a.oe=function(e){throw console.error(e),e}}([]);
//# sourceMappingURL=manifest.37da822ab10e62d568da.js.map
\ No newline at end of file
!function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,f,o){for(var c,d,i,u=0,b=[];u<r.length;u++)d=r[u],t[d]&&b.push(t[d][0]),t[d]=0;for(c in f)Object.prototype.hasOwnProperty.call(f,c)&&(e[c]=f[c]);for(n&&n(r,f,o);b.length;)b.shift()();if(o)for(u=0;u<o.length;u++)i=a(a.s=o[u]);return i};var r={},t={24:0};function a(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.e=function(e){var n=t[e];if(0===n)return new Promise(function(e){e()});if(n)return n[2];var r=new Promise(function(r,a){n=t[e]=[r,a]});n[2]=r;var f=document.getElementsByTagName("head")[0],o=document.createElement("script");o.type="text/javascript",o.charset="utf-8",o.async=!0,o.timeout=12e4,a.nc&&o.setAttribute("nonce",a.nc),o.src=a.p+"static/js/"+e+"."+{0:"f72dbb9d754b88a9e6e3",1:"b17200cccd46e216dcb3",2:"140338f6a5528feea1a3",3:"776d791724a8de12ff9e",4:"f8494b8dd039413f79c8",5:"530a43b5ad6055214539",6:"8f85de06573e2a5f9562",7:"061807fe4716131f26f8",8:"d1391c270de5a9f111c5",9:"cbdb7fa4f5180acfbb03",10:"7eeaa94fd42d34a86b92",11:"096c0f0eaf2850056b7e",12:"cea57d271a961f0b44ad",13:"4d2138ee1bee3ad573f4",14:"429592868e75adc95933",15:"7acf5544a35df2fa2634",16:"6d16122f45f1a1f311e2",17:"d0f0c2f910dd10e0f688",18:"bb8da82a2138ed7b18a8",19:"d8b36c25e8b686c0ae5f",20:"8085ffbdaee58f2c229a",21:"d8007e7169c085e13dab"}[e]+".js";var c=setTimeout(d,12e4);function d(){o.onerror=o.onload=null,clearTimeout(c);var n=t[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),t[e]=void 0)}return o.onerror=o.onload=d,f.appendChild(o),r},a.m=e,a.c=r,a.d=function(e,n,r){a.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},a.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(n,"a",n),n},a.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},a.p="/",a.oe=function(e){throw console.error(e),e}}([]);
//# sourceMappingURL=manifest.1b702ecca7669457ed71.js.map
\ No newline at end of file
......@@ -7,10 +7,7 @@ import com.gitee.sqlrest.persistence.entity.AppClientEntity;
import com.gitee.sqlrest.persistence.entity.ClientGroupEntity;
import com.gitee.sqlrest.persistence.mapper.AppClientMapper;
import com.gitee.sqlrest.persistence.mapper.ClientGroupMapper;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;
......@@ -46,23 +43,28 @@ public class AppClientDao {
return appClientMapper.selectOne(queryWrapper);
}
public AppClientEntity getByAccessToken(String accessToken) {
QueryWrapper<AppClientEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(AppClientEntity::getAccessToken, accessToken);
return appClientMapper.selectOne(queryWrapper);
}
public List<AppClientEntity> getByName(String name) {
QueryWrapper<AppClientEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(AppClientEntity::getName, name);
return appClientMapper.selectList(queryWrapper);
}
public Set<Long> getAuthGroups(String appKey) {
public boolean existsAuthGroups(String appKey, Long groupId) {
AppClientEntity appClientEntity = getByAppKey(appKey);
if (null == appClientEntity) {
return Collections.emptySet();
return false;
}
QueryWrapper<ClientGroupEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(ClientGroupEntity::getClientId, appClientEntity.getId());
return clientAuthMapper.selectList(queryWrapper)
.stream().map(ClientGroupEntity::getGroupId)
.collect(Collectors.toSet());
queryWrapper.lambda()
.eq(ClientGroupEntity::getClientId, appClientEntity.getId())
.eq(ClientGroupEntity::getGroupId, groupId);
return clientAuthMapper.selectCount(queryWrapper) > 0;
}
public void updateTokenByAppKey(String appKey, String token) {
......@@ -106,7 +108,7 @@ public class AppClientDao {
}
}
public List<IdWithName> getGroupAuth(Long id){
public List<IdWithName> getGroupAuth(Long id) {
return clientAuthMapper.getGroupAuth(id);
}
}
......@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.gitee.sqlrest.common.enums.AliveTimeEnum;
import com.gitee.sqlrest.common.enums.DurationTimeEnum;
import java.sql.Timestamp;
import lombok.AllArgsConstructor;
......@@ -44,6 +45,9 @@ public class AppClientEntity {
@TableField(value = "access_token", insertStrategy = FieldStrategy.NEVER)
private String accessToken;
@TableField(value = "token_alive", typeHandler = EnumTypeHandler.class)
private AliveTimeEnum tokenAlive;
@TableField(value = "create_time", insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
private Timestamp createTime;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment