mirror of https://github.com/halo-dev/halo
Fix user login error
parent
523afaebe4
commit
fdc294b335
|
@ -24,4 +24,13 @@ public interface SecurityContext {
|
|||
* @param authentication the new authentication or null if no further authentication should not be stored
|
||||
*/
|
||||
void setAuthentication(@Nullable Authentication authentication);
|
||||
|
||||
/**
|
||||
* Check if the current context has authenticated or not.
|
||||
*
|
||||
* @return true if authenticate; false otherwise
|
||||
*/
|
||||
default boolean isAuthenticate() {
|
||||
return getAuthentication() != null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,11 +6,13 @@ import cc.ryanc.halo.exception.NotFoundException;
|
|||
import cc.ryanc.halo.model.entity.User;
|
||||
import cc.ryanc.halo.model.params.UserParam;
|
||||
import cc.ryanc.halo.repository.UserRepository;
|
||||
import cc.ryanc.halo.security.context.SecurityContextHolder;
|
||||
import cc.ryanc.halo.security.filter.AdminAuthenticationFilter;
|
||||
import cc.ryanc.halo.security.support.UserDetail;
|
||||
import cc.ryanc.halo.service.UserService;
|
||||
import cc.ryanc.halo.service.base.AbstractCrudService;
|
||||
import cc.ryanc.halo.utils.DateUtils;
|
||||
import cc.ryanc.halo.utils.HaloUtils;
|
||||
import cn.hutool.core.lang.Validator;
|
||||
import cn.hutool.crypto.digest.BCrypt;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
@ -18,6 +20,7 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.util.Date;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -80,24 +83,32 @@ public class UserServiceImpl extends AbstractCrudService<User, Integer> implemen
|
|||
Assert.hasText(password, "Password must not be blank");
|
||||
Assert.notNull(httpSession, "Http session must not be null");
|
||||
|
||||
// Check login status
|
||||
if (SecurityContextHolder.getContext().isAuthenticate()) {
|
||||
throw new BadRequestException("You have logged in already, no need to log in again");
|
||||
}
|
||||
|
||||
// Ger user by username
|
||||
User user = Validator.isEmail(key) ? getByEmailOfNonNull(key) : getByUsernameOfNonNull(key);
|
||||
|
||||
Date now = DateUtils.now();
|
||||
|
||||
// Check expiration
|
||||
if (user.getExpireTime() != null && DateUtils.now().before(user.getExpireTime())) {
|
||||
if (user.getExpireTime() != null && user.getExpireTime().after(now)) {
|
||||
long seconds = TimeUnit.MINUTES.toSeconds(user.getExpireTime().getTime() - now.getTime());
|
||||
// If expired
|
||||
throw new BadRequestException("账号已被禁止登陆,请 " + LOCK_MINUTES + " 分钟后再试");
|
||||
throw new BadRequestException("You have been temporarily disabled,please try again " + seconds + " second(s) later").setErrorData(seconds);
|
||||
}
|
||||
|
||||
|
||||
if (!BCrypt.checkpw(password, user.getPassword())) {
|
||||
// If the password is mismatched
|
||||
// If the password is mismatch
|
||||
// Add login failure count
|
||||
Integer loginFailureCount = stringCacheStore.get(LOGIN_FAILURE_COUNT_KEY).map(Integer::valueOf).orElse(0);
|
||||
|
||||
if (loginFailureCount >= MAX_LOGIN_TRY) {
|
||||
if (loginFailureCount >= MAX_LOGIN_TRY - 1) {
|
||||
// Set expiration
|
||||
user.setExpireTime(org.apache.commons.lang3.time.DateUtils.addMilliseconds(DateUtils.now(), LOCK_MINUTES));
|
||||
user.setExpireTime(org.apache.commons.lang3.time.DateUtils.addMinutes(now, LOCK_MINUTES));
|
||||
// Update user
|
||||
update(user);
|
||||
}
|
||||
|
@ -106,9 +117,16 @@ public class UserServiceImpl extends AbstractCrudService<User, Integer> implemen
|
|||
|
||||
stringCacheStore.put(LOGIN_FAILURE_COUNT_KEY, loginFailureCount.toString(), LOCK_MINUTES, TimeUnit.MINUTES);
|
||||
|
||||
throw new BadRequestException("账号或者密码错误,您还有" + (MAX_LOGIN_TRY - loginFailureCount) + "次机会");
|
||||
int remainder = MAX_LOGIN_TRY - loginFailureCount;
|
||||
|
||||
String errorMessage = String.format("Username or password incorrect, you%shave %s", remainder <= 0 ? "" : " still ", HaloUtils.pluralize(remainder, "chance", "chances"));
|
||||
|
||||
throw new BadRequestException(errorMessage);
|
||||
}
|
||||
|
||||
// Clear the login failure count cache
|
||||
stringCacheStore.delete(LOGIN_FAILURE_COUNT_KEY);
|
||||
|
||||
// Set session
|
||||
httpSession.setAttribute(AdminAuthenticationFilter.ADMIN_SESSION_KEY, new UserDetail(user));
|
||||
|
||||
|
|
|
@ -37,6 +37,30 @@ import java.util.UUID;
|
|||
@Slf4j
|
||||
public class HaloUtils {
|
||||
|
||||
/**
|
||||
* Pluralize the time label format.
|
||||
*
|
||||
* @param time time
|
||||
* @param label label
|
||||
* @param pluralLabel plural label
|
||||
* @return pluralized format
|
||||
*/
|
||||
@NonNull
|
||||
public static String pluralize(long time, @NonNull String label, @NonNull String pluralLabel) {
|
||||
Assert.hasText(label, "Label must not be blank");
|
||||
Assert.hasText(pluralLabel, "Plural label must not be blank");
|
||||
|
||||
if (time <= 0) {
|
||||
return "no " + label;
|
||||
}
|
||||
|
||||
if (time == 1) {
|
||||
return time + " " + label;
|
||||
}
|
||||
|
||||
return time + " " + pluralLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets random uuid without dash.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
package cc.ryanc.halo.utils;
|
||||
|
||||
import org.apache.commons.lang3.RandomUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* Halo utilities test.
|
||||
*
|
||||
* @author johnniang
|
||||
* @date 3/29/19
|
||||
*/
|
||||
public class HaloUtilsTest {
|
||||
|
||||
@Test
|
||||
public void pluralizeTest() {
|
||||
|
||||
String label = "chance";
|
||||
String pluralLabel = "chances";
|
||||
|
||||
String pluralizedFormat = HaloUtils.pluralize(1, label, pluralLabel);
|
||||
assertThat(pluralizedFormat, equalTo("1 chance"));
|
||||
|
||||
pluralizedFormat = HaloUtils.pluralize(2, label, pluralLabel);
|
||||
assertThat(pluralizedFormat, equalTo("2 chances"));
|
||||
|
||||
pluralizedFormat = HaloUtils.pluralize(0, label, pluralLabel);
|
||||
assertThat(pluralizedFormat, equalTo("no chance"));
|
||||
|
||||
// Test random positive time
|
||||
IntStream.range(0, 10000).forEach(i -> {
|
||||
long time = RandomUtils.nextLong(2, Long.MAX_VALUE);
|
||||
String result = HaloUtils.pluralize(time, label, pluralLabel);
|
||||
assertThat(result, equalTo(time + " " + pluralLabel));
|
||||
});
|
||||
|
||||
// Test random negative time
|
||||
IntStream.range(0, 10000).forEach(i -> {
|
||||
long time = (-1) * RandomUtils.nextLong();
|
||||
String result = HaloUtils.pluralize(time, label, pluralLabel);
|
||||
assertThat(result, equalTo("no " + label));
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void pluralizeLabelExceptionTest() {
|
||||
HaloUtils.pluralize(1, null, null);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue