mirror of
https://github.com/PlayEdu/PlayEdu
synced 2025-10-26 14:42:59 +08:00
143
playedu-api/src/main/java/xyz/playedu/api/bus/LoginBus.java
Normal file
143
playedu-api/src/main/java/xyz/playedu/api/bus/LoginBus.java
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (C) 2023 杭州白书科技有限公司
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package xyz.playedu.api.bus;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import xyz.playedu.api.event.UserLoginEvent;
|
||||
import xyz.playedu.common.domain.LdapUser;
|
||||
import xyz.playedu.common.domain.User;
|
||||
import xyz.playedu.common.exception.ServiceException;
|
||||
import xyz.playedu.common.service.*;
|
||||
import xyz.playedu.common.util.HelperUtil;
|
||||
import xyz.playedu.common.util.IpUtil;
|
||||
import xyz.playedu.common.util.RequestUtil;
|
||||
import xyz.playedu.common.util.StringUtil;
|
||||
import xyz.playedu.common.util.ldap.LdapTransformUser;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class LoginBus {
|
||||
|
||||
@Autowired private FrontendAuthService authService;
|
||||
|
||||
@Autowired private DepartmentService departmentService;
|
||||
|
||||
@Autowired private LdapUserService ldapUserService;
|
||||
|
||||
@Autowired private UserService userService;
|
||||
|
||||
@Autowired private AppConfigService appConfigService;
|
||||
|
||||
@Autowired private ApplicationContext ctx;
|
||||
|
||||
public HashMap<String, Object> tokenByUser(User user) {
|
||||
String token = authService.loginUsingId(user.getId(), RequestUtil.url());
|
||||
|
||||
HashMap<String, Object> data = new HashMap<>();
|
||||
data.put("token", token);
|
||||
|
||||
ctx.publishEvent(
|
||||
new UserLoginEvent(
|
||||
this,
|
||||
user.getId(),
|
||||
user.getEmail(),
|
||||
token,
|
||||
IpUtil.getIpAddress(),
|
||||
RequestUtil.ua()));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public HashMap<String, Object> tokenByLdapTransformUser(LdapTransformUser ldapTransformUser)
|
||||
throws ServiceException {
|
||||
// LDAP用户的名字
|
||||
String ldapUserName = ldapTransformUser.getCn();
|
||||
|
||||
// 将LDAP用户所属的部门同步到本地
|
||||
Integer depId = departmentService.createWithChainList(ldapTransformUser.getOu());
|
||||
Integer[] depIds = depId == 0 ? null : new Integer[] {depId};
|
||||
|
||||
// LDAP用户在本地的缓存记录
|
||||
LdapUser ldapUser = ldapUserService.findByUUID(ldapTransformUser.getId());
|
||||
User user;
|
||||
|
||||
// 计算将LDAP用户关联到本地users表的email字段值
|
||||
String localUserEmail = ldapTransformUser.getUid();
|
||||
if (StringUtil.isNotEmpty(ldapTransformUser.getEmail())) {
|
||||
localUserEmail = ldapTransformUser.getEmail();
|
||||
}
|
||||
|
||||
if (ldapUser == null) {
|
||||
// 检测localUserEmail是否存在
|
||||
if (userService.find(localUserEmail) != null) {
|
||||
throw new ServiceException(String.format("已有其它账号在使用:%s", localUserEmail));
|
||||
}
|
||||
// LDAP用户数据缓存到本地
|
||||
ldapUser = ldapUserService.store(ldapTransformUser);
|
||||
// 创建本地user
|
||||
user =
|
||||
userService.createWithDepIds(
|
||||
localUserEmail,
|
||||
ldapUserName,
|
||||
appConfigService.defaultAvatar(),
|
||||
HelperUtil.randomString(20),
|
||||
"",
|
||||
depIds);
|
||||
// 将LDAP缓存数据与本地user关联
|
||||
ldapUserService.updateUserId(ldapUser.getId(), user.getId());
|
||||
} else {
|
||||
user = userService.find(ldapUser.getUserId());
|
||||
// 账号修改[账号有可能是email也有可能是uid]
|
||||
if (!localUserEmail.equals(user.getEmail())) {
|
||||
// 检测localUserEmail是否存在
|
||||
if (userService.find(localUserEmail) != null) {
|
||||
throw new ServiceException(String.format("已有其它账号在使用:%s", localUserEmail));
|
||||
}
|
||||
userService.updateEmail(user.getId(), localUserEmail);
|
||||
}
|
||||
// ldap-email的变化
|
||||
if (!ldapUser.getEmail().equals(ldapTransformUser.getEmail())) {
|
||||
ldapUserService.updateEmail(ldapUser.getId(), ldapTransformUser.getEmail());
|
||||
}
|
||||
// ldap-uid的变化
|
||||
if (!ldapUser.getUid().equals(ldapTransformUser.getUid())) {
|
||||
ldapUserService.updateUid(ldapUser.getId(), ldapTransformUser.getUid());
|
||||
}
|
||||
// 名字同步修改
|
||||
if (!ldapUserName.equals(ldapUser.getCn())) {
|
||||
userService.updateName(user.getId(), ldapUserName);
|
||||
ldapUserService.updateCN(ldapUser.getId(), ldapUserName);
|
||||
}
|
||||
// 部门修改同步
|
||||
String newOU = String.join(",", ldapTransformUser.getOu());
|
||||
if (!newOU.equals(ldapUser.getOu())) {
|
||||
userService.updateDepId(user.getId(), depIds);
|
||||
ldapUserService.updateOU(ldapUser.getId(), newOU);
|
||||
}
|
||||
}
|
||||
|
||||
return tokenByUser(user);
|
||||
}
|
||||
}
|
||||
50
playedu-api/src/main/java/xyz/playedu/api/cache/LoginLimitCache.java
vendored
Normal file
50
playedu-api/src/main/java/xyz/playedu/api/cache/LoginLimitCache.java
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2023 杭州白书科技有限公司
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package xyz.playedu.api.cache;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import xyz.playedu.common.config.PlayEduConfig;
|
||||
import xyz.playedu.common.exception.ServiceException;
|
||||
import xyz.playedu.common.service.RateLimiterService;
|
||||
import xyz.playedu.common.util.RedisUtil;
|
||||
|
||||
@Component
|
||||
public class LoginLimitCache {
|
||||
|
||||
@Autowired private RateLimiterService rateLimiterService;
|
||||
|
||||
@Autowired private PlayEduConfig playEduConfig;
|
||||
|
||||
public void check(String email) throws ServiceException {
|
||||
String limitKey = cacheKey(email);
|
||||
Long reqCount = rateLimiterService.current(limitKey, 600L);
|
||||
if (reqCount >= 10 && !playEduConfig.getTesting()) {
|
||||
Long exp = RedisUtil.ttlWithoutPrefix(limitKey);
|
||||
String msg = String.format("您的账号已被锁定,请%s后重试", exp > 60 ? exp / 60 + "分钟" : exp + "秒");
|
||||
throw new ServiceException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy(String email) {
|
||||
RedisUtil.del(cacheKey(email));
|
||||
}
|
||||
|
||||
private String cacheKey(String email) {
|
||||
return "login-limit:" + email;
|
||||
}
|
||||
}
|
||||
42
playedu-api/src/main/java/xyz/playedu/api/cache/LoginLockCache.java
vendored
Normal file
42
playedu-api/src/main/java/xyz/playedu/api/cache/LoginLockCache.java
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2023 杭州白书科技有限公司
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package xyz.playedu.api.cache;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import xyz.playedu.common.util.RedisDistributedLock;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Component
|
||||
public class LoginLockCache {
|
||||
|
||||
@Autowired private RedisDistributedLock redisDistributedLock;
|
||||
|
||||
public boolean apply(String username) {
|
||||
String key = cacheKey(username);
|
||||
return redisDistributedLock.tryLock(key, 10L, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
public void release(String username) {
|
||||
redisDistributedLock.releaseLock(cacheKey(username));
|
||||
}
|
||||
|
||||
private String cacheKey(String username) {
|
||||
return "login-lock:" + username;
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,7 @@ import xyz.playedu.common.context.BCtx;
|
||||
import xyz.playedu.common.domain.Department;
|
||||
import xyz.playedu.common.domain.User;
|
||||
import xyz.playedu.common.exception.NotFoundException;
|
||||
import xyz.playedu.common.service.AppConfigService;
|
||||
import xyz.playedu.common.service.DepartmentService;
|
||||
import xyz.playedu.common.service.UserService;
|
||||
import xyz.playedu.common.types.JsonResponse;
|
||||
@@ -66,6 +67,8 @@ public class DepartmentController {
|
||||
|
||||
@Autowired private ApplicationContext ctx;
|
||||
|
||||
@Autowired private AppConfigService appConfigService;
|
||||
|
||||
@GetMapping("/index")
|
||||
@Log(title = "部门-列表", businessType = BusinessTypeConstant.GET)
|
||||
public JsonResponse index() {
|
||||
@@ -98,6 +101,9 @@ public class DepartmentController {
|
||||
@Log(title = "部门-新建", businessType = BusinessTypeConstant.INSERT)
|
||||
public JsonResponse store(@RequestBody @Validated DepartmentRequest req)
|
||||
throws NotFoundException {
|
||||
if (appConfigService.enabledLdapLogin()) {
|
||||
return JsonResponse.error("已启用LDAP服务,禁止添加部门");
|
||||
}
|
||||
departmentService.create(req.getName(), req.getParentId(), req.getSort());
|
||||
return JsonResponse.success();
|
||||
}
|
||||
@@ -115,6 +121,9 @@ public class DepartmentController {
|
||||
@Log(title = "部门-编辑", businessType = BusinessTypeConstant.UPDATE)
|
||||
public JsonResponse update(@PathVariable Integer id, @RequestBody DepartmentRequest req)
|
||||
throws NotFoundException {
|
||||
if (appConfigService.enabledLdapLogin()) {
|
||||
return JsonResponse.error("已启用LDAP服务,禁止添加部门");
|
||||
}
|
||||
Department department = departmentService.findOrFail(id);
|
||||
departmentService.update(department, req.getName(), req.getParentId(), req.getSort());
|
||||
return JsonResponse.success();
|
||||
@@ -124,6 +133,9 @@ public class DepartmentController {
|
||||
@GetMapping("/{id}/destroy")
|
||||
@Log(title = "部门-批量删除", businessType = BusinessTypeConstant.DELETE)
|
||||
public JsonResponse preDestroy(@PathVariable Integer id) {
|
||||
if (appConfigService.enabledLdapLogin()) {
|
||||
return JsonResponse.error("已启用LDAP服务,禁止添加部门");
|
||||
}
|
||||
List<Integer> courseIds = courseDepartmentService.getCourseIdsByDepId(id);
|
||||
List<Integer> userIds = departmentService.getUserIdsByDepId(id);
|
||||
|
||||
@@ -165,6 +177,9 @@ public class DepartmentController {
|
||||
@DeleteMapping("/{id}")
|
||||
@Log(title = "部门-删除", businessType = BusinessTypeConstant.DELETE)
|
||||
public JsonResponse destroy(@PathVariable Integer id) throws NotFoundException {
|
||||
if (appConfigService.enabledLdapLogin()) {
|
||||
return JsonResponse.error("已启用LDAP服务,禁止添加部门");
|
||||
}
|
||||
Department department = departmentService.findOrFail(id);
|
||||
departmentService.destroy(department.getId());
|
||||
ctx.publishEvent(new DepartmentDestroyEvent(this, BCtx.getId(), department.getId()));
|
||||
@@ -184,6 +199,9 @@ public class DepartmentController {
|
||||
@Log(title = "部门-更新父级", businessType = BusinessTypeConstant.UPDATE)
|
||||
public JsonResponse updateParent(@RequestBody @Validated DepartmentParentRequest req)
|
||||
throws NotFoundException {
|
||||
if (appConfigService.enabledLdapLogin()) {
|
||||
return JsonResponse.error("已启用LDAP服务,禁止添加部门");
|
||||
}
|
||||
departmentService.changeParent(req.getId(), req.getParentId(), req.getIds());
|
||||
return JsonResponse.success();
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import xyz.playedu.api.request.frontend.CourseHourRecordRequest;
|
||||
import xyz.playedu.common.context.FCtx;
|
||||
import xyz.playedu.common.types.JsonResponse;
|
||||
import xyz.playedu.common.util.RedisDistributedLock;
|
||||
import xyz.playedu.course.bus.UserBus;
|
||||
import xyz.playedu.course.caches.CourseCache;
|
||||
import xyz.playedu.course.caches.UserCanSeeCourseCache;
|
||||
import xyz.playedu.course.caches.UserLastLearnTimeCache;
|
||||
@@ -61,8 +60,6 @@ public class HourController {
|
||||
|
||||
@Autowired private UserCourseHourRecordService userCourseHourRecordService;
|
||||
|
||||
@Autowired private UserBus userBus;
|
||||
|
||||
// ------- CACHE ----------
|
||||
@Autowired private UserCanSeeCourseCache userCanSeeCourseCache;
|
||||
@Autowired private CourseCache courseCache;
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package xyz.playedu.api.controller.frontend;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@@ -23,26 +26,29 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import xyz.playedu.api.event.UserLoginEvent;
|
||||
import xyz.playedu.api.bus.LoginBus;
|
||||
import xyz.playedu.api.cache.LoginLimitCache;
|
||||
import xyz.playedu.api.cache.LoginLockCache;
|
||||
import xyz.playedu.api.event.UserLogoutEvent;
|
||||
import xyz.playedu.api.request.frontend.LoginLdapRequest;
|
||||
import xyz.playedu.api.request.frontend.LoginPasswordRequest;
|
||||
import xyz.playedu.common.config.PlayEduConfig;
|
||||
import xyz.playedu.common.constant.ConfigConstant;
|
||||
import xyz.playedu.common.context.FCtx;
|
||||
import xyz.playedu.common.domain.User;
|
||||
import xyz.playedu.common.exception.LimitException;
|
||||
import xyz.playedu.common.service.FrontendAuthService;
|
||||
import xyz.playedu.common.service.RateLimiterService;
|
||||
import xyz.playedu.common.service.UserService;
|
||||
import xyz.playedu.common.exception.ServiceException;
|
||||
import xyz.playedu.common.service.*;
|
||||
import xyz.playedu.common.types.JsonResponse;
|
||||
import xyz.playedu.common.util.HelperUtil;
|
||||
import xyz.playedu.common.util.IpUtil;
|
||||
import xyz.playedu.common.util.RedisUtil;
|
||||
import xyz.playedu.common.util.RequestUtil;
|
||||
import xyz.playedu.common.util.*;
|
||||
import xyz.playedu.common.util.ldap.LdapTransformUser;
|
||||
import xyz.playedu.common.util.ldap.LdapUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/auth/login")
|
||||
@Slf4j
|
||||
public class LoginController {
|
||||
|
||||
@Autowired private UserService userService;
|
||||
@@ -51,13 +57,27 @@ public class LoginController {
|
||||
|
||||
@Autowired private ApplicationContext ctx;
|
||||
|
||||
@Autowired private RateLimiterService rateLimiterService;
|
||||
@Autowired private AppConfigService appConfigService;
|
||||
|
||||
@Autowired private PlayEduConfig playEduConfig;
|
||||
@Autowired private LdapUserService ldapUserService;
|
||||
|
||||
@Autowired private DepartmentService departmentService;
|
||||
|
||||
@Autowired private LoginBus loginBus;
|
||||
|
||||
@Autowired private LoginLimitCache loginLimitCache;
|
||||
|
||||
@Autowired private LoginLockCache loginLockCache;
|
||||
|
||||
@PostMapping("/password")
|
||||
public JsonResponse password(@RequestBody @Validated LoginPasswordRequest req)
|
||||
@SneakyThrows
|
||||
public JsonResponse password(
|
||||
@RequestBody @Validated LoginPasswordRequest req, LoginBus loginBus)
|
||||
throws LimitException {
|
||||
if (appConfigService.enabledLdapLogin()) {
|
||||
return JsonResponse.error("请使用LDAP登录");
|
||||
}
|
||||
|
||||
String email = req.getEmail();
|
||||
|
||||
User user = userService.find(email);
|
||||
@@ -65,39 +85,74 @@ public class LoginController {
|
||||
return JsonResponse.error("邮箱或密码错误");
|
||||
}
|
||||
|
||||
String limitKey = "login-limit:" + req.getEmail();
|
||||
Long reqCount = rateLimiterService.current(limitKey, 600L);
|
||||
if (reqCount >= 10 && !playEduConfig.getTesting()) {
|
||||
Long exp = RedisUtil.ttlWithoutPrefix(limitKey);
|
||||
return JsonResponse.error(
|
||||
String.format("您的账号已被锁定,请%s后重试", exp > 60 ? exp / 60 + "分钟" : exp + "秒"));
|
||||
}
|
||||
loginLimitCache.check(email);
|
||||
|
||||
if (!HelperUtil.MD5(req.getPassword() + user.getSalt()).equals(user.getPassword())) {
|
||||
return JsonResponse.error("邮箱或密码错误");
|
||||
}
|
||||
|
||||
RedisUtil.del(limitKey);
|
||||
|
||||
if (user.getIsLock() == 1) {
|
||||
return JsonResponse.error("当前学员已锁定无法登录");
|
||||
}
|
||||
|
||||
String token = authService.loginUsingId(user.getId(), RequestUtil.url());
|
||||
loginLimitCache.destroy(email);
|
||||
|
||||
HashMap<String, Object> data = new HashMap<>();
|
||||
data.put("token", token);
|
||||
return JsonResponse.data(loginBus.tokenByUser(user));
|
||||
}
|
||||
|
||||
ctx.publishEvent(
|
||||
new UserLoginEvent(
|
||||
this,
|
||||
user.getId(),
|
||||
user.getEmail(),
|
||||
token,
|
||||
IpUtil.getIpAddress(),
|
||||
RequestUtil.ua()));
|
||||
@PostMapping("/ldap")
|
||||
@SneakyThrows
|
||||
public JsonResponse ldap(@RequestBody @Validated LoginLdapRequest req) {
|
||||
String username = req.getUsername();
|
||||
|
||||
return JsonResponse.data(data);
|
||||
// 系统配置
|
||||
Map<String, String> config = appConfigService.keyValues();
|
||||
String url = config.get(ConfigConstant.LDAP_URL);
|
||||
String adminUser = config.get(ConfigConstant.LDAP_ADMIN_USER);
|
||||
String adminPass = config.get(ConfigConstant.LDAP_ADMIN_PASS);
|
||||
String baseDN = config.get(ConfigConstant.LDAP_BASE_DN);
|
||||
if (url.isEmpty() || adminUser.isEmpty() || adminPass.isEmpty() || baseDN.isEmpty()) {
|
||||
return JsonResponse.error("LDAP服务未配置");
|
||||
}
|
||||
|
||||
String mail = null;
|
||||
String uid = null;
|
||||
if (StringUtil.contains(username, "@")) {
|
||||
mail = username;
|
||||
} else {
|
||||
uid = username;
|
||||
}
|
||||
|
||||
// 限流控制
|
||||
loginLimitCache.check(username);
|
||||
|
||||
// 锁控制-防止并发登录重复写入数据
|
||||
if (!loginLockCache.apply(username)) {
|
||||
return JsonResponse.error("请稍候再试");
|
||||
}
|
||||
|
||||
try {
|
||||
LdapTransformUser ldapTransformUser =
|
||||
LdapUtil.loginByMailOrUid(
|
||||
url, adminUser, adminPass, baseDN, mail, uid, req.getPassword());
|
||||
if (ldapTransformUser == null) {
|
||||
return JsonResponse.error("登录失败.请检查账号和密码");
|
||||
}
|
||||
|
||||
HashMap<String, Object> data = loginBus.tokenByLdapTransformUser(ldapTransformUser);
|
||||
|
||||
// 删除限流控制
|
||||
loginLimitCache.destroy(username);
|
||||
|
||||
return JsonResponse.data(data);
|
||||
} catch (ServiceException e) {
|
||||
return JsonResponse.error(e.getMessage());
|
||||
} catch (Exception e) {
|
||||
log.error("LDAP登录失败", e);
|
||||
return JsonResponse.error("系统错误");
|
||||
} finally {
|
||||
loginLockCache.release(username);
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/logout")
|
||||
|
||||
@@ -53,6 +53,8 @@ public class SystemController {
|
||||
data.put("player-bullet-secret-opacity", configs.get("player.bullet_secret_opacity"));
|
||||
data.put("player-disabled-drag", configs.get("player.disabled_drag"));
|
||||
|
||||
data.put("ldap-enabled", configs.get(ConfigConstant.LDAP_ENABLED));
|
||||
|
||||
return JsonResponse.data(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2023 杭州白书科技有限公司
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package xyz.playedu.api.request.frontend;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class LoginLdapRequest {
|
||||
|
||||
@NotBlank(message = "请输入账户名")
|
||||
private String username;
|
||||
|
||||
@NotBlank(message = "请输入密码")
|
||||
private String password;
|
||||
}
|
||||
Reference in New Issue
Block a user