diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/SystemContextHolder.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/SystemContextHolder.java index aaa2a75f..0b8a3b5d 100644 --- a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/SystemContextHolder.java +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/SystemContextHolder.java @@ -54,4 +54,12 @@ public class SystemContextHolder { public static SystemContext getContext() { return systemContextHolder.get(); } + + public static boolean isAdmin() { + UserDO userDO = getUser(); + if (null != userDO && userDO.getLoginName().equals("admin")) { + return true; + } + return false; + } } diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/annotation/OnlyAdmin.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/annotation/OnlyAdmin.java new file mode 100644 index 00000000..9dc6c1b7 --- /dev/null +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/annotation/OnlyAdmin.java @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2022 aoshiguchen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package fun.asgc.neutrino.proxy.server.base.rest.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 暂不做复杂权限控制,仅用该注解标注,部分接口禁止游客身份调用 + * @author: aoshiguchen + * @date: 2022/8/14 + */ +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface OnlyAdmin { + +} diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/constant/ExceptionConstant.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/constant/ExceptionConstant.java index 5f3a76b0..d53a275c 100644 --- a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/constant/ExceptionConstant.java +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/constant/ExceptionConstant.java @@ -37,6 +37,7 @@ public enum ExceptionConstant { PARAMS_INVALID(2, "参数不正确"), USER_NAME_OR_PASSWORD_ERROR(3, "用户名或密码错误"), USER_DISABLE(4, "当前用户已被禁止登录"), + NO_PERMISSION_VISIT(5, "当前用户无权访问该资源"), PARAMS_NOT_NULL(10, "参数[{}]不能为空"), PARAMS_NOT_EMPTY(11, "参数[{}]不能为空"), @@ -46,7 +47,10 @@ public enum ExceptionConstant { LICENSE_NOT_EXIST(12001, "license数据不存在"), // 端口池管理(13000) PORT_CANNOT_REPEAT(13000,"端口不能重复"), + PORT_NOT_EXIST(13001, "该端口在端口池中不存在,不允许映射"), // 端口映射管理(14000) + PORT_MAPPING_NOT_EXIST(14000, "端口映射记录不存在"), + PORT_CANNOT_REPEAT_MAPPING(14001, "服务端口[{}]不能重复映射"), SYSTEM_ERROR(500, "系统异常"), ; diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/interceptor/BaseAuthInterceptor.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/interceptor/BaseAuthInterceptor.java index 35a43604..59bba426 100644 --- a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/interceptor/BaseAuthInterceptor.java +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/interceptor/BaseAuthInterceptor.java @@ -28,6 +28,7 @@ import fun.asgc.neutrino.core.web.context.HttpRequestWrapper; import fun.asgc.neutrino.core.web.context.HttpResponseWrapper; import fun.asgc.neutrino.core.web.interceptor.HandlerInterceptor; import fun.asgc.neutrino.proxy.server.base.rest.*; +import fun.asgc.neutrino.proxy.server.base.rest.annotation.OnlyAdmin; import fun.asgc.neutrino.proxy.server.base.rest.constant.EnableStatusEnum; import fun.asgc.neutrino.proxy.server.base.rest.constant.ExceptionConstant; import fun.asgc.neutrino.proxy.server.dal.entity.UserDO; @@ -62,6 +63,10 @@ public class BaseAuthInterceptor implements HandlerInterceptor { if (EnableStatusEnum.DISABLE.getStatus().equals(userDO.getEnable())) { throw ServiceException.create(ExceptionConstant.USER_DISABLE); } + if (targetMethod.isAnnotationPresent(OnlyAdmin.class) && !userDO.getLoginName().equals("admin")) { + throw ServiceException.create(ExceptionConstant.NO_PERMISSION_VISIT); + } + systemContext.setToken(authorize); systemContext.setUser(userDO); diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/LicenseController.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/LicenseController.java index b13f81ff..3d0230ff 100644 --- a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/LicenseController.java +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/LicenseController.java @@ -26,6 +26,7 @@ import fun.asgc.neutrino.core.annotation.NonIntercept; import fun.asgc.neutrino.core.db.page.Page; import fun.asgc.neutrino.core.db.page.PageQuery; import fun.asgc.neutrino.core.web.annotation.*; +import fun.asgc.neutrino.proxy.server.base.rest.annotation.OnlyAdmin; import fun.asgc.neutrino.proxy.server.controller.req.LicenseCreateReq; import fun.asgc.neutrino.proxy.server.controller.req.LicenseListReq; import fun.asgc.neutrino.proxy.server.controller.req.LicenseUpdateEnableStatusReq; @@ -61,6 +62,7 @@ public class LicenseController { return licenseService.list(req); } + @OnlyAdmin @PostMapping("create") public LicenseCreateRes create(@RequestBody LicenseCreateReq req) { ParamCheckUtil.checkNotNull(req, "req"); @@ -70,6 +72,7 @@ public class LicenseController { return licenseService.create(req); } + @OnlyAdmin @PostMapping("update") public LicenseUpdateRes update(@RequestBody LicenseUpdateReq req) { ParamCheckUtil.checkNotNull(req, "req"); @@ -86,6 +89,7 @@ public class LicenseController { return licenseService.detail(id); } + @OnlyAdmin @PostMapping("update/enable-status") public LicenseUpdateEnableStatusRes updateEnableStatus(@RequestBody LicenseUpdateEnableStatusReq req) { ParamCheckUtil.checkNotNull(req, "req"); @@ -95,6 +99,7 @@ public class LicenseController { return licenseService.updateEnableStatus(req); } + @OnlyAdmin @PostMapping("delete") public void delete(@RequestParam("id") Integer id) { ParamCheckUtil.checkNotNull(id, "id"); @@ -102,6 +107,7 @@ public class LicenseController { licenseService.delete(id); } + @OnlyAdmin @PostMapping("reset") public void reset(@RequestParam("id") Integer id) { ParamCheckUtil.checkNotNull(id, "id"); diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/PortPoolController.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/PortPoolController.java index 833ad2bb..25910fd9 100644 --- a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/PortPoolController.java +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/controller/PortPoolController.java @@ -26,6 +26,7 @@ import fun.asgc.neutrino.core.annotation.NonIntercept; import fun.asgc.neutrino.core.db.page.Page; import fun.asgc.neutrino.core.db.page.PageQuery; import fun.asgc.neutrino.core.web.annotation.*; +import fun.asgc.neutrino.proxy.server.base.rest.annotation.OnlyAdmin; import fun.asgc.neutrino.proxy.server.controller.req.PortPoolCreateReq; import fun.asgc.neutrino.proxy.server.controller.req.PortPoolListReq; import fun.asgc.neutrino.proxy.server.controller.req.PortPoolUpdateEnableStatusReq; @@ -61,6 +62,7 @@ public class PortPoolController { return portPoolService.list(req); } + @OnlyAdmin @PostMapping("create") public PortPoolCreateRes create(@RequestBody PortPoolCreateReq req) { ParamCheckUtil.checkNotNull(req, "req"); @@ -69,6 +71,7 @@ public class PortPoolController { return portPoolService.create(req); } + @OnlyAdmin @PostMapping("update/enable-status") public PortPoolUpdateEnableStatusRes updateEnableStatus(@RequestBody PortPoolUpdateEnableStatusReq req) { ParamCheckUtil.checkNotNull(req, "req"); @@ -78,6 +81,7 @@ public class PortPoolController { return portPoolService.updateEnableStatus(req); } + @OnlyAdmin @PostMapping("delete") public void delete(@RequestParam("id") Integer id) { ParamCheckUtil.checkNotNull(id, "id"); diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/PortMappingMapper.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/PortMappingMapper.java index d5fa7993..5b90487e 100644 --- a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/PortMappingMapper.java +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/dal/PortMappingMapper.java @@ -33,6 +33,8 @@ import fun.asgc.neutrino.proxy.server.controller.req.PortMappingListReq; import fun.asgc.neutrino.proxy.server.controller.res.PortMappingListRes; import fun.asgc.neutrino.proxy.server.dal.entity.PortMappingDO; +import java.util.Set; + /** * * @author: aoshiguchen @@ -57,4 +59,10 @@ public interface PortMappingMapper extends SqlMapper { @Delete("delete from `port_mapping` where id = ?") void delete(Integer id); + + @Select("select * from port_mapping where server_port = ?") + PortMappingDO findByPort(Integer port); + + @Select("select * from port_mapping where server_port = :port and id not in (:excludeIds)") + PortMappingDO findByPort(@Param("port") Integer port, @Param("excludeIds") Set excludeIds); } diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/service/PortMappingService.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/service/PortMappingService.java index 31c69f63..37b67b02 100644 --- a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/service/PortMappingService.java +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/service/PortMappingService.java @@ -21,12 +21,15 @@ */ package fun.asgc.neutrino.proxy.server.service; +import com.google.common.collect.Sets; import fun.asgc.neutrino.core.annotation.Autowired; import fun.asgc.neutrino.core.annotation.Component; import fun.asgc.neutrino.core.db.page.Page; import fun.asgc.neutrino.core.db.page.PageQuery; import fun.asgc.neutrino.core.util.CollectionUtil; +import fun.asgc.neutrino.proxy.server.base.rest.SystemContextHolder; import fun.asgc.neutrino.proxy.server.base.rest.constant.EnableStatusEnum; +import fun.asgc.neutrino.proxy.server.base.rest.constant.ExceptionConstant; import fun.asgc.neutrino.proxy.server.base.rest.constant.OnlineStatusEnum; import fun.asgc.neutrino.proxy.server.controller.req.PortMappingCreateReq; import fun.asgc.neutrino.proxy.server.controller.req.PortMappingListReq; @@ -35,10 +38,13 @@ import fun.asgc.neutrino.proxy.server.controller.req.PortMappingUpdateReq; import fun.asgc.neutrino.proxy.server.controller.res.*; import fun.asgc.neutrino.proxy.server.dal.LicenseMapper; import fun.asgc.neutrino.proxy.server.dal.PortMappingMapper; +import fun.asgc.neutrino.proxy.server.dal.PortPoolMapper; import fun.asgc.neutrino.proxy.server.dal.UserMapper; import fun.asgc.neutrino.proxy.server.dal.entity.LicenseDO; import fun.asgc.neutrino.proxy.server.dal.entity.PortMappingDO; +import fun.asgc.neutrino.proxy.server.dal.entity.PortPoolDO; import fun.asgc.neutrino.proxy.server.dal.entity.UserDO; +import fun.asgc.neutrino.proxy.server.util.ParamCheckUtil; import java.util.Date; import java.util.List; @@ -60,6 +66,8 @@ public class PortMappingService { private LicenseMapper licenseMapper; @Autowired private UserMapper userMapper; + @Autowired + private PortPoolMapper portPoolMapper; public Page page(PageQuery pageQuery, PortMappingListReq req) { Page page = Page.create(pageQuery); @@ -89,6 +97,17 @@ public class PortMappingService { } public PortMappingCreateRes create(PortMappingCreateReq req) { + LicenseDO licenseDO = licenseMapper.findById(req.getLicenseId()); + ParamCheckUtil.checkExpression(null != licenseDO, ExceptionConstant.LICENSE_NOT_EXIST); + if (!SystemContextHolder.isAdmin()) { + // 临时处理,如果当前用户不是管理院,则操作userId不能为1 + ParamCheckUtil.checkExpression(!licenseDO.getUserId().equals(1), ExceptionConstant.NO_PERMISSION_VISIT); + } + PortPoolDO portPoolDO = portPoolMapper.findByPort(req.getServerPort()); + ParamCheckUtil.checkExpression(null != portPoolDO, ExceptionConstant.PORT_NOT_EXIST); + ParamCheckUtil.checkExpression(null == portMappingMapper.findByPort(req.getServerPort()), ExceptionConstant.PORT_CANNOT_REPEAT_MAPPING, req.getServerPort()); + + Date now = new Date(); PortMappingDO portMappingDO = new PortMappingDO(); portMappingDO.setLicenseId(req.getLicenseId()); @@ -104,6 +123,16 @@ public class PortMappingService { } public PortMappingUpdateRes update(PortMappingUpdateReq req) { + LicenseDO licenseDO = licenseMapper.findById(req.getLicenseId()); + ParamCheckUtil.checkExpression(null != licenseDO, ExceptionConstant.LICENSE_NOT_EXIST); + if (!SystemContextHolder.isAdmin()) { + // 临时处理,如果当前用户不是管理员,则操作userId不能为1 + ParamCheckUtil.checkExpression(!licenseDO.getUserId().equals(1), ExceptionConstant.NO_PERMISSION_VISIT); + } + PortPoolDO portPoolDO = portPoolMapper.findByPort(req.getServerPort()); + ParamCheckUtil.checkExpression(null != portPoolDO, ExceptionConstant.PORT_NOT_EXIST); + ParamCheckUtil.checkExpression(null == portMappingMapper.findByPort(req.getServerPort(), Sets.newHashSet(req.getId())), ExceptionConstant.PORT_CANNOT_REPEAT_MAPPING, req.getServerPort()); + PortMappingDO portMappingDO = new PortMappingDO(); portMappingDO.setId(req.getId()); portMappingDO.setLicenseId(req.getLicenseId()); @@ -145,12 +174,32 @@ public class PortMappingService { } public PortMappingUpdateEnableStatusRes updateEnableStatus(PortMappingUpdateEnableStatusReq req) { + PortMappingDO portMappingDO = portMappingMapper.findById(req.getId()); + ParamCheckUtil.checkExpression(null != portMappingDO, ExceptionConstant.PORT_MAPPING_NOT_EXIST); + + LicenseDO licenseDO = licenseMapper.findById(portMappingDO.getLicenseId()); + ParamCheckUtil.checkExpression(null != licenseDO, ExceptionConstant.LICENSE_NOT_EXIST); + if (!SystemContextHolder.isAdmin()) { + // 临时处理,如果当前用户不是管理员,则操作userId不能为1 + ParamCheckUtil.checkExpression(!licenseDO.getUserId().equals(1), ExceptionConstant.NO_PERMISSION_VISIT); + } + portMappingMapper.updateEnableStatus(req.getId(), req.getEnable()); return new PortMappingUpdateEnableStatusRes(); } public void delete(Integer id) { + PortMappingDO portMappingDO = portMappingMapper.findById(id); + ParamCheckUtil.checkExpression(null != portMappingDO, ExceptionConstant.PORT_MAPPING_NOT_EXIST); + + LicenseDO licenseDO = licenseMapper.findById(portMappingDO.getLicenseId()); + ParamCheckUtil.checkExpression(null != licenseDO, ExceptionConstant.LICENSE_NOT_EXIST); + if (!SystemContextHolder.isAdmin()) { + // 临时处理,如果当前用户不是管理员,则操作userId不能为1 + ParamCheckUtil.checkExpression(!licenseDO.getUserId().equals(1), ExceptionConstant.NO_PERMISSION_VISIT); + } + portMappingMapper.delete(id); }