mirror of https://github.com/halo-dev/halo
Complete password update api and refactor user create api
parent
e8a9498ea4
commit
157689b0c2
|
@ -1,9 +1,10 @@
|
|||
package cc.ryanc.halo.model.params;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.validation.constraints.Email;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
/**
|
||||
* Install parameters.
|
||||
|
@ -11,8 +12,9 @@ import javax.validation.constraints.NotBlank;
|
|||
* @author johnniang
|
||||
* @date 3/19/19
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class InstallParam {
|
||||
public class InstallParam extends UserParam {
|
||||
|
||||
/**
|
||||
* Blog locale.
|
||||
|
@ -32,28 +34,10 @@ public class InstallParam {
|
|||
@NotBlank(message = "Blog url must not be blank")
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* Username.
|
||||
*/
|
||||
@NotBlank(message = "Username must not be blank")
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* Nickname.
|
||||
*/
|
||||
@NotBlank(message = "Nickname must not be blank")
|
||||
private String nickname;
|
||||
|
||||
/**
|
||||
* Email.
|
||||
*/
|
||||
@NotBlank(message = "Email must not be blank")
|
||||
@Email(message = "It is not an email format")
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* Password.
|
||||
*/
|
||||
@NotBlank(message = "Password must not be blank")
|
||||
@Size(max = 100, message = "Length of password must not be more than {max}")
|
||||
private String password;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package cc.ryanc.halo.model.params;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
/**
|
||||
* User password param.
|
||||
*
|
||||
* @author johnniang
|
||||
* @date 3/26/19
|
||||
*/
|
||||
@Data
|
||||
public class PasswordParam {
|
||||
|
||||
@NotBlank(message = "Old password must not be blank")
|
||||
@Size(max = 100, message = "Length of password must not be more than {max}")
|
||||
private String oldPassword;
|
||||
|
||||
@NotBlank(message = "New password must not be blank")
|
||||
@Size(max = 100, message = "Length of password must not be more than {max}")
|
||||
private String newPassword;
|
||||
|
||||
}
|
|
@ -3,7 +3,7 @@ package cc.ryanc.halo.model.params;
|
|||
import cc.ryanc.halo.model.dto.base.InputConverter;
|
||||
import cc.ryanc.halo.model.entity.Tag;
|
||||
import cc.ryanc.halo.utils.HaloUtils;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cc.ryanc.halo.utils.SlugUtils;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
|
@ -30,7 +30,7 @@ public class TagParam implements InputConverter<Tag> {
|
|||
public Tag convertTo() {
|
||||
if (StringUtils.isBlank(slugName)) {
|
||||
// Handle slug name
|
||||
slugName = URLUtil.normalize(name);
|
||||
slugName = SlugUtils.slugify(name);
|
||||
}
|
||||
|
||||
slugName = HaloUtils.initializeUrlIfBlank(slugName);
|
||||
|
|
|
@ -15,13 +15,6 @@ import java.util.List;
|
|||
*/
|
||||
public interface TagService extends CrudService<Tag, Integer> {
|
||||
|
||||
/**
|
||||
* Remove tag and relationship
|
||||
*
|
||||
* @param id id
|
||||
*/
|
||||
void remove(Integer id);
|
||||
|
||||
/**
|
||||
* Get tag by slug name
|
||||
*
|
||||
|
|
|
@ -2,6 +2,7 @@ package cc.ryanc.halo.service;
|
|||
|
||||
import cc.ryanc.halo.exception.NotFoundException;
|
||||
import cc.ryanc.halo.model.entity.User;
|
||||
import cc.ryanc.halo.model.params.UserParam;
|
||||
import cc.ryanc.halo.service.base.CrudService;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
||||
|
@ -73,4 +74,25 @@ public interface UserService extends CrudService<User, Integer> {
|
|||
*/
|
||||
@NonNull
|
||||
User login(@NonNull String key, @NonNull String password);
|
||||
|
||||
/**
|
||||
* Updates user password.
|
||||
*
|
||||
* @param oldPassword old password must not be blank
|
||||
* @param newPassword new password must not be blank
|
||||
* @param userId user id must not be null
|
||||
* @return updated user detail
|
||||
*/
|
||||
@NonNull
|
||||
User updatePassword(@NonNull String oldPassword, @NonNull String newPassword, @NonNull Integer userId);
|
||||
|
||||
/**
|
||||
* Creates an user.
|
||||
*
|
||||
* @param userParam user param must not be null.
|
||||
* @param password password must not be blank
|
||||
* @return created user
|
||||
*/
|
||||
@NonNull
|
||||
User createBy(@NonNull UserParam userParam, @NonNull String password);
|
||||
}
|
||||
|
|
|
@ -192,7 +192,7 @@ public class OptionServiceImpl extends AbstractCrudService<Option, Integer> impl
|
|||
@Override
|
||||
public int getPostPageSize() {
|
||||
try {
|
||||
return getByProperty(BlogProperties.INDEX_POSTS).map(Integer::valueOf).orElse(DEFAULT_POST_PAGE_SIZE);
|
||||
return getByProperty(BlogProperties.INDEX_POSTS, Integer.class, DEFAULT_COMMENT_PAGE_SIZE);
|
||||
} catch (NumberFormatException e) {
|
||||
log.error(BlogProperties.INDEX_POSTS + " option is not a number format", e);
|
||||
return DEFAULT_POST_PAGE_SIZE;
|
||||
|
@ -202,7 +202,7 @@ public class OptionServiceImpl extends AbstractCrudService<Option, Integer> impl
|
|||
@Override
|
||||
public int getCommentPageSize() {
|
||||
try {
|
||||
return getByProperty(BlogProperties.INDEX_COMMENTS).map(Integer::valueOf).orElse(DEFAULT_COMMENT_PAGE_SIZE);
|
||||
return getByProperty(BlogProperties.INDEX_COMMENTS, Integer.class, DEFAULT_COMMENT_PAGE_SIZE);
|
||||
} catch (NumberFormatException e) {
|
||||
log.error(BlogProperties.INDEX_COMMENTS + " option is not a number format", e);
|
||||
return DEFAULT_COMMENT_PAGE_SIZE;
|
||||
|
@ -212,7 +212,7 @@ public class OptionServiceImpl extends AbstractCrudService<Option, Integer> impl
|
|||
@Override
|
||||
public int getRssPageSize() {
|
||||
try {
|
||||
return getByProperty(BlogProperties.RSS_POSTS).map(Integer::valueOf).orElse(DEFAULT_RSS_PAGE_SIZE);
|
||||
return getByProperty(BlogProperties.RSS_POSTS, Integer.class, DEFAULT_COMMENT_PAGE_SIZE);
|
||||
} catch (NumberFormatException e) {
|
||||
log.error(BlogProperties.RSS_POSTS + " setting is not a number format", e);
|
||||
return DEFAULT_RSS_PAGE_SIZE;
|
||||
|
|
|
@ -32,16 +32,6 @@ public class TagServiceImpl extends AbstractCrudService<Tag, Integer> implements
|
|||
this.tagRepository = tagRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove tag and relationship
|
||||
*
|
||||
* @param id id
|
||||
*/
|
||||
@Override
|
||||
public void remove(Integer id) {
|
||||
// TODO 删除标签,以及对应的文章关系
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag create(Tag tag) {
|
||||
// Check if the tag is exist
|
||||
|
@ -73,6 +63,8 @@ public class TagServiceImpl extends AbstractCrudService<Tag, Integer> implements
|
|||
public List<TagOutputDTO> convertTo(List<Tag> tags) {
|
||||
return CollectionUtils.isEmpty(tags) ?
|
||||
Collections.emptyList() :
|
||||
tags.stream().map(tag -> (TagOutputDTO) new TagOutputDTO().convertFrom(tag)).collect(Collectors.toList());
|
||||
tags.stream()
|
||||
.map(tag -> (TagOutputDTO) new TagOutputDTO().convertFrom(tag))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,14 @@ import cc.ryanc.halo.cache.StringCacheStore;
|
|||
import cc.ryanc.halo.exception.BadRequestException;
|
||||
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.service.UserService;
|
||||
import cc.ryanc.halo.service.base.AbstractCrudService;
|
||||
import cc.ryanc.halo.utils.DateUtils;
|
||||
import cn.hutool.core.lang.Validator;
|
||||
import cn.hutool.crypto.digest.BCrypt;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
@ -87,7 +89,7 @@ public class UserServiceImpl extends AbstractCrudService<User, Integer> implemen
|
|||
if (!BCrypt.checkpw(password, user.getPassword())) {
|
||||
// If the password is mismatched
|
||||
// Add login failure count
|
||||
Integer loginFailureCount = stringCacheStore.get(LOGIN_FAILURE_COUNT_KEY).map(countString -> Integer.valueOf(countString)).orElse(0);
|
||||
Integer loginFailureCount = stringCacheStore.get(LOGIN_FAILURE_COUNT_KEY).map(Integer::valueOf).orElse(0);
|
||||
|
||||
if (loginFailureCount >= MAX_LOGIN_TRY) {
|
||||
// Set expiration
|
||||
|
@ -103,9 +105,53 @@ public class UserServiceImpl extends AbstractCrudService<User, Integer> implemen
|
|||
throw new BadRequestException("账号或者密码错误,您还有" + (MAX_LOGIN_TRY - loginFailureCount) + "次机会");
|
||||
}
|
||||
|
||||
// TODO Set session
|
||||
// TODO Set session or cache token
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User updatePassword(String oldPassword, String newPassword, Integer userId) {
|
||||
Assert.hasText(oldPassword, "Old password must not be blank");
|
||||
Assert.hasText(newPassword, "New password must not be blank");
|
||||
Assert.notNull(userId, "User id must not be blank");
|
||||
|
||||
if (oldPassword.equals(newPassword)) {
|
||||
throw new BadRequestException("There is nothing changed because new password is equal to old password");
|
||||
}
|
||||
|
||||
// Get the user
|
||||
User user = getById(userId);
|
||||
|
||||
// Check the user old password
|
||||
if (!BCrypt.checkpw(oldPassword, user.getPassword())) {
|
||||
throw new BadRequestException("Old password is mismatch").setErrorData(oldPassword);
|
||||
}
|
||||
|
||||
// Set new password
|
||||
setPassword(newPassword, user);
|
||||
|
||||
// Update this user
|
||||
return update(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User createBy(UserParam userParam, String password) {
|
||||
Assert.notNull(userParam, "User param must not be null");
|
||||
Assert.hasText(password, "Password must not be blank");
|
||||
|
||||
User user = userParam.convertTo();
|
||||
|
||||
setPassword(password, user);
|
||||
|
||||
return create(user);
|
||||
}
|
||||
|
||||
private void setPassword(@NonNull String plainPassword, @NonNull User user) {
|
||||
Assert.hasText(plainPassword, "Plain password must not be blank");
|
||||
Assert.notNull(user, "User must not be null");
|
||||
|
||||
user.setPassword(BCrypt.hashpw(plainPassword, BCrypt.gensalt()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -89,7 +89,9 @@ public class TagController {
|
|||
@DeleteMapping("{tagId:\\d+}")
|
||||
@ApiOperation("Delete tag by id")
|
||||
public void deletePermanently(@PathVariable("tagId") Integer tagId) {
|
||||
// Remove the tag
|
||||
tagService.removeById(tagId);
|
||||
// Remove the post tag relationship
|
||||
postTagService.removeByTagId(tagId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package cc.ryanc.halo.web.controller.admin.api;
|
|||
|
||||
import cc.ryanc.halo.model.dto.UserOutputDTO;
|
||||
import cc.ryanc.halo.model.entity.User;
|
||||
import cc.ryanc.halo.model.params.PasswordParam;
|
||||
import cc.ryanc.halo.model.params.UserParam;
|
||||
import cc.ryanc.halo.service.UserService;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
@ -35,4 +36,9 @@ public class UserController {
|
|||
// Update user and convert to dto
|
||||
return new UserOutputDTO().convertFrom(userService.update(user));
|
||||
}
|
||||
|
||||
@PutMapping("profile/password")
|
||||
public void updatePassword(@Valid @RequestBody PasswordParam passwordParam, User user) {
|
||||
userService.updatePassword(passwordParam.getOldPassword(), passwordParam.getNewPassword(), user.getId());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import cc.ryanc.halo.model.support.BaseResponse;
|
|||
import cc.ryanc.halo.service.*;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.digest.BCrypt;
|
||||
import freemarker.template.Configuration;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Controller;
|
||||
|
@ -158,14 +157,7 @@ public class InstallController {
|
|||
}
|
||||
|
||||
private User createDefaultUser(InstallParam installParam) {
|
||||
User user = new User();
|
||||
user.setUsername(installParam.getUsername());
|
||||
user.setNickname(installParam.getNickname());
|
||||
user.setEmail(installParam.getEmail());
|
||||
// Hash password with BCrypt
|
||||
user.setPassword(BCrypt.hashpw(installParam.getPassword(), BCrypt.gensalt()));
|
||||
|
||||
return userService.create(user);
|
||||
return userService.createBy(installParam, installParam.getPassword());
|
||||
}
|
||||
|
||||
private void initSettings(InstallParam installParam) {
|
||||
|
|
Loading…
Reference in New Issue