Conflict resolved
This commit is contained in:
@@ -54,7 +54,7 @@ public class SecurityConfig {
|
||||
}
|
||||
|
||||
@Bean
|
||||
MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) {
|
||||
public MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) {
|
||||
return new MvcRequestMatcher.Builder(introspector);
|
||||
}
|
||||
|
||||
@@ -87,6 +87,7 @@ public class SecurityConfig {
|
||||
return new CorsFilter(source);
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain securityFilterChain(HttpSecurity http, MvcRequestMatcher.Builder mvc) throws Exception {
|
||||
http
|
||||
|
||||
@@ -48,6 +48,7 @@ public class TokenProvider {
|
||||
|
||||
public static final String INVALID_USER = "invalid_user";
|
||||
static final String AUTH_SECRET = "X-Api-Secret";
|
||||
private final Set<String> invalidatedTokens = new HashSet<>();
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
@@ -113,6 +114,10 @@ public class TokenProvider {
|
||||
|
||||
public boolean validateToken(String authToken) {
|
||||
try {
|
||||
if (isTokenInvalid(authToken)) {
|
||||
log.warn("Token is invalidated.");
|
||||
return false;
|
||||
}
|
||||
Jwts.parserBuilder()
|
||||
.setSigningKey(key)
|
||||
.build()
|
||||
@@ -124,6 +129,15 @@ public class TokenProvider {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void invalidateToken(String token) {
|
||||
invalidatedTokens.add(token);
|
||||
log.info("Token invalidated: {}", token);
|
||||
}
|
||||
|
||||
public boolean isTokenInvalid(String token) {
|
||||
return invalidatedTokens.contains(token);
|
||||
}
|
||||
public Map<String, Object> getUserInfoAndUserIdFromToken(HttpServletRequest request) {
|
||||
Map<String, Object> userInfo = new HashMap<>();
|
||||
String authSecretHeader=request.getHeader(AUTH_SECRET);
|
||||
@@ -196,4 +210,12 @@ public class TokenProvider {
|
||||
Claims claims = Jwts.parser().setSigningKey(key).parseClaimsJws(token).getBody();
|
||||
return claims.getSubject();
|
||||
}
|
||||
public String extractTokenFromRequest(HttpServletRequest request) {
|
||||
String bearerToken = request.getHeader("Authorization");
|
||||
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
|
||||
return bearerToken.substring(7); // Remove "Bearer " prefix
|
||||
}
|
||||
return null; // Return null if token is not found or not in Bearer format
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -63,5 +63,13 @@ public class GepafinConstant {
|
||||
public static final String LOOKUP_DATA_DELETED_SUCCESSFULLY = "lookupdata.deleted.successfully";
|
||||
public static final String DOCUMENT_UPDATED_SUCCESSFULLY = "document.updated.successfully";
|
||||
public static final String DOCUMENT_FETCHED_SUCCESSFULLY = "document.fetched.successfully";
|
||||
public static final String RESET_PASSWORD_INITIATED = "password.reset.initiated";
|
||||
public static final String PASSWORD_RESET_SUCCESS = "password.reset.success";
|
||||
public static final String INVALID_TOKEN_MSG = "invalid.token.msg";
|
||||
public static final String CURRENT_PASSWORD_INCORRECT = "current.password.incorrect";
|
||||
|
||||
public static final String LOGOUT_SUCCESSFUL_MSG = "logout.successful.msg";
|
||||
public static final String SUCCESS_PASSWORD_CHANGED = "success.password.changed";
|
||||
public static final String UPDATE_USER_STATUS_SUCCESS_MSG = "update.user.status.success";
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package net.gepafin.tendermanagement.dao;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import net.gepafin.tendermanagement.config.Translator;
|
||||
import net.gepafin.tendermanagement.constants.GepafinConstant;
|
||||
import net.gepafin.tendermanagement.entities.RoleEntity;
|
||||
import net.gepafin.tendermanagement.entities.UserEntity;
|
||||
import net.gepafin.tendermanagement.enums.UserStatusEnum;
|
||||
import net.gepafin.tendermanagement.model.request.LoginReq;
|
||||
import net.gepafin.tendermanagement.model.request.UpdateUserReq;
|
||||
import net.gepafin.tendermanagement.model.request.UserReq;
|
||||
import net.gepafin.tendermanagement.model.request.*;
|
||||
import net.gepafin.tendermanagement.model.response.RoleResponseBean;
|
||||
import net.gepafin.tendermanagement.model.response.UserResponseBean;
|
||||
import net.gepafin.tendermanagement.model.util.JWTToken;
|
||||
@@ -23,6 +23,10 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Base64;
|
||||
import java.util.Optional;
|
||||
|
||||
import static net.gepafin.tendermanagement.util.ObjectUtils.setIfUpdated;
|
||||
|
||||
@Repository
|
||||
@@ -149,4 +153,82 @@ public class UserDao {
|
||||
log.info("Login successful for email: {}", loginReq.getEmail());
|
||||
return jwtToken;
|
||||
}
|
||||
public String generateSecureToken() {
|
||||
SecureRandom secureRandom = new SecureRandom();
|
||||
byte[] tokenBytes = new byte[24];
|
||||
secureRandom.nextBytes(tokenBytes);
|
||||
String token = Base64.getUrlEncoder().withoutPadding().encodeToString(tokenBytes);
|
||||
log.debug("Generated secure token: {}", token);
|
||||
return token;
|
||||
}
|
||||
|
||||
public String initiatePasswordReset(InitiatePasswordResetReq resetReq) {
|
||||
UserEntity user = userRepository.findByEmail(resetReq.getEmail());
|
||||
if (user == null) {
|
||||
log.info("Password reset attempt for non-existent user: {}", resetReq.getEmail());
|
||||
throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG));
|
||||
}
|
||||
String token = generateSecureToken();
|
||||
user.setResetPasswordToken(token);
|
||||
userRepository.save(user);
|
||||
log.info("Password reset token generated for user: {}", resetReq.getEmail());
|
||||
return token;
|
||||
}
|
||||
|
||||
public Boolean resetPassword(ResetPasswordReq resetPasswordReq) {
|
||||
UserEntity user = userRepository.findByEmail(resetPasswordReq.getEmail());
|
||||
if (user == null) {
|
||||
log.info("Password reset attempt for non-existent user: {}", resetPasswordReq.getEmail());
|
||||
throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG));
|
||||
}
|
||||
if (!resetPasswordReq.getNewPassword().equals(resetPasswordReq.getConfirmPassword())) {
|
||||
log.info("User creation failed: Passwords do not match for email {}", user.getEmail());
|
||||
throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.PASSWORD_DOESNT_MATCH));
|
||||
}
|
||||
String dbToken = user.getResetPasswordToken();
|
||||
|
||||
if (dbToken == null || !dbToken.equals(resetPasswordReq.getToken())) {
|
||||
log.info("Invalid password reset token for user: {}", resetPasswordReq.getEmail());
|
||||
throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.INVALID_TOKEN_MSG));
|
||||
}
|
||||
|
||||
user.setPassword(passwordEncoder.encode(resetPasswordReq.getNewPassword()));
|
||||
user.setResetPasswordToken(null);
|
||||
userRepository.save(user);
|
||||
log.info("Password successfully reset for user: {}", resetPasswordReq.getEmail());
|
||||
return true;
|
||||
}
|
||||
|
||||
public Boolean changePassword(ChangePasswordRequest request) {
|
||||
UserEntity user = userRepository.findByEmail(request.getEmail());
|
||||
if (user == null) {
|
||||
log.info("Password reset attempt for non-existent user: {}", request.getEmail());
|
||||
throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG));
|
||||
}
|
||||
if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
|
||||
throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.CURRENT_PASSWORD_INCORRECT));
|
||||
}
|
||||
if (!request.getNewPassword().equals(request.getConfirmPassword())) {
|
||||
log.info("User creation failed: Passwords do not match for email {}", user.getEmail());
|
||||
throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.PASSWORD_DOESNT_MATCH));
|
||||
}
|
||||
user.setPassword(passwordEncoder.encode(request.getNewPassword()));
|
||||
userRepository.save(user);
|
||||
return true;
|
||||
}
|
||||
public void logout(HttpServletRequest request, HttpServletResponse response) {
|
||||
authService.logout(request, response);
|
||||
log.info("User successfully logged out.");
|
||||
}
|
||||
|
||||
public UserResponseBean updateUserStatus(Long userId, UserStatusEnum statusReq) {
|
||||
log.info("Updating status for user with ID: {}", userId);
|
||||
UserEntity userEntity = userRepository.findById(userId)
|
||||
.orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)));
|
||||
userEntity.setStatus(statusReq.getValue());
|
||||
userEntity = userRepository.save(userEntity);
|
||||
log.info("User status updated to {} for user ID: {}", statusReq, userId);
|
||||
return convertUserEntityToUserResponse(userEntity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -58,4 +58,6 @@ public class UserEntity extends BaseEntity {
|
||||
@Column(name = "COUNTRY", length = 50, nullable = true)
|
||||
private String country;
|
||||
|
||||
@Column(name = "RESET_PASSWORD_TOKEN", length = 255, nullable = true)
|
||||
private String resetPasswordToken;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package net.gepafin.tendermanagement.model.request;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ChangePasswordRequest {
|
||||
|
||||
|
||||
private String email;
|
||||
|
||||
private String password;
|
||||
|
||||
private String newPassword;
|
||||
|
||||
private String confirmPassword;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package net.gepafin.tendermanagement.model.request;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class InitiatePasswordResetReq {
|
||||
private String email;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package net.gepafin.tendermanagement.model.request;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class LogoutReq {
|
||||
private String email;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package net.gepafin.tendermanagement.model.request;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ResetPasswordReq {
|
||||
private String email;
|
||||
private String token;
|
||||
private String newPassword;
|
||||
private String confirmPassword;
|
||||
|
||||
|
||||
}
|
||||
@@ -8,4 +8,5 @@ import java.util.Optional;
|
||||
public interface UserRepository extends JpaRepository<UserEntity, Long> {
|
||||
Optional<UserEntity> findByEmailIgnoreCase(String email);
|
||||
boolean existsByEmailIgnoreCase(String email);
|
||||
UserEntity findByEmail(String email);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package net.gepafin.tendermanagement.service;
|
||||
|
||||
import net.gepafin.tendermanagement.model.request.LoginReq;
|
||||
import net.gepafin.tendermanagement.model.request.UpdateUserReq;
|
||||
import net.gepafin.tendermanagement.model.request.UserReq;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import net.gepafin.tendermanagement.enums.UserStatusEnum;
|
||||
import net.gepafin.tendermanagement.model.request.*;
|
||||
import net.gepafin.tendermanagement.model.response.UserResponseBean;
|
||||
import net.gepafin.tendermanagement.model.util.JWTToken;
|
||||
|
||||
@@ -16,4 +17,15 @@ public interface UserService {
|
||||
void deleteUser(Long userId);
|
||||
|
||||
JWTToken login(LoginReq loginReq);
|
||||
|
||||
|
||||
String initiatePasswordReset(InitiatePasswordResetReq resetReq);
|
||||
|
||||
Boolean resetPassword(ResetPasswordReq resetPasswordReq);
|
||||
|
||||
Boolean changePassword(ChangePasswordRequest request);
|
||||
|
||||
void logoutUser(HttpServletRequest request, HttpServletResponse response);
|
||||
|
||||
UserResponseBean updateUserStatus(Long userId, UserStatusEnum statusReq);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package net.gepafin.tendermanagement.service.impl;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import net.gepafin.tendermanagement.config.Translator;
|
||||
import net.gepafin.tendermanagement.config.jwt.TokenProvider;
|
||||
import net.gepafin.tendermanagement.constants.GepafinConstant;
|
||||
@@ -7,6 +9,7 @@ import net.gepafin.tendermanagement.dao.RoleDao;
|
||||
import net.gepafin.tendermanagement.entities.UserEntity;
|
||||
import net.gepafin.tendermanagement.enums.UserStatusEnum;
|
||||
import net.gepafin.tendermanagement.model.request.LoginReq;
|
||||
import net.gepafin.tendermanagement.model.request.LogoutReq;
|
||||
import net.gepafin.tendermanagement.model.response.LoginResponse;
|
||||
import net.gepafin.tendermanagement.model.response.RoleResponseBean;
|
||||
import net.gepafin.tendermanagement.model.util.JWTToken;
|
||||
@@ -21,7 +24,9 @@ import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Service
|
||||
@@ -54,7 +59,7 @@ public class AuthenticationService {
|
||||
UserEntity user = userRepository.findByEmailIgnoreCase(loginReq.getEmail()).orElseThrow(()-> new CustomValidationException(Status.NOT_FOUND,
|
||||
Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)));
|
||||
if (Boolean.FALSE.equals(UserStatusEnum.ACTIVE.getValue().equals(user.getStatus()))) {
|
||||
new CustomValidationException(Status.NOT_FOUND,
|
||||
throw new CustomValidationException(Status.NOT_FOUND,
|
||||
Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG));
|
||||
}
|
||||
user.setLastLogin(DateTimeUtil.DateServerToUTC(LocalDateTime.now()));
|
||||
@@ -88,6 +93,16 @@ public class AuthenticationService {
|
||||
loginResponse.setCreatedDate(user.getCreatedDate());
|
||||
loginResponse.setUpdatedDate(user.getUpdatedDate());
|
||||
return loginResponse;
|
||||
}
|
||||
public void logout(HttpServletRequest request, HttpServletResponse response)
|
||||
{ Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
if (auth != null) {
|
||||
String token = tokenProvider.extractTokenFromRequest(request);
|
||||
tokenProvider.invalidateToken(token);
|
||||
new SecurityContextLogoutHandler().logout(request, response, auth);
|
||||
}
|
||||
SecurityContextHolder.getContext().setAuthentication(null);
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package net.gepafin.tendermanagement.service.impl;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import net.gepafin.tendermanagement.dao.UserDao;
|
||||
import net.gepafin.tendermanagement.model.request.LoginReq;
|
||||
import net.gepafin.tendermanagement.model.request.UpdateUserReq;
|
||||
import net.gepafin.tendermanagement.model.request.UserReq;
|
||||
import net.gepafin.tendermanagement.enums.UserStatusEnum;
|
||||
import net.gepafin.tendermanagement.model.request.*;
|
||||
import net.gepafin.tendermanagement.model.response.LoginResponse;
|
||||
import net.gepafin.tendermanagement.model.response.UserResponseBean;
|
||||
import net.gepafin.tendermanagement.model.util.JWTToken;
|
||||
@@ -50,4 +51,27 @@ public class UserServiceImpl implements UserService {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String initiatePasswordReset(InitiatePasswordResetReq resetReq) {
|
||||
return userDao.initiatePasswordReset(resetReq);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean resetPassword(ResetPasswordReq resetPasswordReq) {
|
||||
return userDao.resetPassword(resetPasswordReq);
|
||||
}
|
||||
@Override
|
||||
public Boolean changePassword(ChangePasswordRequest request){
|
||||
return userDao.changePassword(request);
|
||||
}
|
||||
@Override
|
||||
public void logoutUser(HttpServletRequest request, HttpServletResponse response) {
|
||||
userDao.logout(request,response);
|
||||
}
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public UserResponseBean updateUserStatus(Long userId, UserStatusEnum statusReq) {
|
||||
return userDao.updateUserStatus(userId, statusReq);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,12 @@ import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.media.Content;
|
||||
import io.swagger.v3.oas.annotations.media.ExampleObject;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
import net.gepafin.tendermanagement.model.request.LoginReq;
|
||||
import net.gepafin.tendermanagement.model.request.UpdateUserReq;
|
||||
import net.gepafin.tendermanagement.model.request.UserReq;
|
||||
import net.gepafin.tendermanagement.entities.UserEntity;
|
||||
import net.gepafin.tendermanagement.enums.UserStatusEnum;
|
||||
import net.gepafin.tendermanagement.model.request.*;
|
||||
import net.gepafin.tendermanagement.model.response.UserResponseBean;
|
||||
import net.gepafin.tendermanagement.model.util.JWTToken;
|
||||
import net.gepafin.tendermanagement.model.util.Response;
|
||||
@@ -18,10 +20,7 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Validated
|
||||
public interface UserApi {
|
||||
@@ -105,4 +104,77 @@ public interface UserApi {
|
||||
method = RequestMethod.POST)
|
||||
ResponseEntity<Response<JWTToken>> login(
|
||||
@Parameter(description = "Login request object", required = true) @Valid @RequestBody LoginReq loginReq);
|
||||
@Operation(summary = "Api to initiate password reset request",
|
||||
responses = {
|
||||
@ApiResponse(responseCode = "200", description = "OK"),
|
||||
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE)})),
|
||||
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE)}))})
|
||||
@RequestMapping(value = "/reset-password/initiate",
|
||||
produces = {"application/json"},
|
||||
method = RequestMethod.POST)
|
||||
ResponseEntity<Response<String>> initiatePasswordReset(
|
||||
@Parameter(description = "Initiate password reset request object", required = true) @Valid @RequestBody InitiatePasswordResetReq initiatePasswordResetReq);
|
||||
|
||||
@Operation(summary = "Api to reset password",
|
||||
responses = {
|
||||
@ApiResponse(responseCode = "200", description = "OK"),
|
||||
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE)})),
|
||||
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE)}))})
|
||||
@RequestMapping(value = "/reset-password",
|
||||
produces = {"application/json"},
|
||||
method = RequestMethod.POST)
|
||||
ResponseEntity<Response<Boolean>> resetPassword(
|
||||
@Parameter(description = "Reset password request object", required = true) @Valid @RequestBody ResetPasswordReq resetPasswordReq);
|
||||
@Operation(summary = "Api to change user password",
|
||||
responses = {
|
||||
@ApiResponse(responseCode = "200", description = "Password Changed Successfully", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||
@ExampleObject(value = "{ \"message\": \"Password changed successfully.\" }")})),
|
||||
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE)})),
|
||||
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE)}))})
|
||||
@RequestMapping(value = "/change-password",
|
||||
produces = {"application/json"},
|
||||
method = RequestMethod.POST)
|
||||
ResponseEntity<Response<Boolean>> changePassword(
|
||||
@Parameter(description = "Change password request object", required = true) @Valid @RequestBody ChangePasswordRequest changePasswordRequest); @Operation(summary = "Api to logout user",
|
||||
responses = {
|
||||
@ApiResponse(responseCode = "200", description = "OK"),
|
||||
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE)})),
|
||||
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE)})),
|
||||
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE)}))})
|
||||
@RequestMapping(value = "/logout",
|
||||
method = RequestMethod.POST)
|
||||
ResponseEntity<Response<Void>> logoutUser(
|
||||
@Parameter(description = "The request object is not needed for logout", required = false) HttpServletRequest request,
|
||||
@Parameter(description = "The response object is not needed for logout", required = false) HttpServletResponse response);
|
||||
@Operation(summary = "Api to update user active/deactive status",
|
||||
responses = {
|
||||
@ApiResponse(responseCode = "200", description = "OK"),
|
||||
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE)})),
|
||||
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE)})),
|
||||
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE)}))
|
||||
})
|
||||
@RequestMapping(value = "/{userId}/status",
|
||||
produces = {"application/json"},
|
||||
method = RequestMethod.PUT)
|
||||
@PreAuthorize("hasRole('ROLE_SUPER_ADMIN')")
|
||||
default ResponseEntity<Response<UserResponseBean>> updateUserStatus(
|
||||
@Parameter(description = "The user id", required = true) @PathVariable("userId") Long userId,
|
||||
@Parameter(description = "status", required = true)@RequestParam(value = "status", required = true) UserStatusEnum status) {
|
||||
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
package net.gepafin.tendermanagement.web.rest.api.impl;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
import net.gepafin.tendermanagement.config.Translator;
|
||||
import net.gepafin.tendermanagement.config.jwt.TokenProvider;
|
||||
import net.gepafin.tendermanagement.constants.GepafinConstant;
|
||||
import net.gepafin.tendermanagement.model.request.LoginReq;
|
||||
import net.gepafin.tendermanagement.model.request.UpdateUserReq;
|
||||
import net.gepafin.tendermanagement.model.request.UserReq;
|
||||
import net.gepafin.tendermanagement.entities.UserEntity;
|
||||
import net.gepafin.tendermanagement.enums.UserStatusEnum;
|
||||
import net.gepafin.tendermanagement.model.request.*;
|
||||
import net.gepafin.tendermanagement.model.response.UserResponseBean;
|
||||
import net.gepafin.tendermanagement.model.util.JWTToken;
|
||||
import net.gepafin.tendermanagement.model.util.Response;
|
||||
import net.gepafin.tendermanagement.service.UserService;
|
||||
import net.gepafin.tendermanagement.web.rest.api.UserApi;
|
||||
|
||||
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -27,7 +29,8 @@ import org.springframework.web.bind.annotation.*;
|
||||
public class UserApiController implements UserApi {
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(UserApiController.class);
|
||||
|
||||
@Autowired
|
||||
private TokenProvider tokenProvider;
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@@ -74,4 +77,46 @@ public class UserApiController implements UserApi {
|
||||
JWTToken jwtToken = userService.login(loginReq);
|
||||
return ResponseEntity.ok(new Response<>(jwtToken, Status.SUCCESS, Translator.toLocale(GepafinConstant.LOGIN_SUCCESS_MSG)));
|
||||
}
|
||||
@Override
|
||||
public ResponseEntity<Response<Boolean>> changePassword(@Valid @RequestBody ChangePasswordRequest request) {
|
||||
log.info("Change Password attempt for email: {}", request.getEmail());
|
||||
userService.changePassword(request);
|
||||
return ResponseEntity.ok(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.SUCCESS_PASSWORD_CHANGED)));
|
||||
}
|
||||
@Override
|
||||
public ResponseEntity<Response<String>> initiatePasswordReset(InitiatePasswordResetReq request) {
|
||||
log.info("Initiating password reset for email: {}", request.getEmail());
|
||||
String resetToken = userService.initiatePasswordReset(request);
|
||||
log.info("Password reset token generated for email: {}", request.getEmail());
|
||||
return ResponseEntity.ok(new Response<>(resetToken, Status.SUCCESS, Translator.toLocale(GepafinConstant.RESET_PASSWORD_INITIATED)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<Response<Boolean>> resetPassword(ResetPasswordReq request) {
|
||||
log.info("Resetting password for username: {}", request.getEmail());
|
||||
Boolean success = userService.resetPassword(request);
|
||||
if (success) {
|
||||
log.info("Password reset successfully for username: {}", request.getEmail());
|
||||
} else {
|
||||
log.error("Password reset failed for username: {}", request.getEmail());
|
||||
}
|
||||
return ResponseEntity.ok(new Response<>(success, Status.SUCCESS, Translator.toLocale(GepafinConstant.PASSWORD_RESET_SUCCESS)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<Response<Void>> logoutUser(HttpServletRequest request, HttpServletResponse response) {
|
||||
userService.logoutUser(request, response);
|
||||
|
||||
log.info("User has successfully logged");
|
||||
return ResponseEntity.status(HttpStatus.OK)
|
||||
.body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.LOGOUT_SUCCESSFUL_MSG)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<Response<UserResponseBean>> updateUserStatus(@PathVariable Long userId, @RequestParam UserStatusEnum status) {
|
||||
log.info("Update User Status for- User ID: {}, Request Body: {}", userId, status);
|
||||
UserResponseBean updatedUser = userService.updateUserStatus(userId, status);
|
||||
return ResponseEntity.ok(new Response<>(updatedUser, Status.SUCCESS, Translator.toLocale(GepafinConstant.UPDATE_USER_STATUS_SUCCESS_MSG)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -395,4 +395,12 @@
|
||||
<column name="country" value="Italy"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
<changeSet id="23-08-2024_1" author="Harish Bagora">
|
||||
<addColumn tableName="gepafin_user">
|
||||
<column name="reset_password_token" type="VARCHAR(255)">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
|
||||
@@ -65,6 +65,20 @@ evaluation.criteria.created.successfully=EvaluationCriteria created successfully
|
||||
evaluation.criteria.fetch.successfully=EvaluationCriteria fetched successfully.
|
||||
evaluation.criteria.updated.successfully=EvaluationCriteria updated successfully.
|
||||
evaluation.criteria.deleted.successfully=EvaluationCriteria deleted successfully.
|
||||
# Password reset messages
|
||||
password.reset.initiated=Password reset initiated.
|
||||
password.reset.success=Password has been successfully reset.
|
||||
#Change Password
|
||||
invalid.token.msg=The token provided is invalid or expired. Please request a new token.
|
||||
current.password.incorrect = Current password is incorrect.
|
||||
success.password.changed=Password changed successfully.
|
||||
#Logout
|
||||
logout.successful.msg=Logout successful. You have been logged out successfully.
|
||||
#Update user Active or Deactive status
|
||||
update.user.status.success=User status has been successfully updated.
|
||||
|
||||
|
||||
|
||||
|
||||
#Faq-related messages
|
||||
faq.not.found=Faq not found.
|
||||
|
||||
@@ -82,3 +82,13 @@ lookupdata.deleted.successfully=LookUpData eliminato correttamente.
|
||||
#Document-related message
|
||||
document.updated.successfully=Documento aggiornato con successo.
|
||||
document.fetched.successfully=Documento recuperato con successo.
|
||||
# Password reset messages
|
||||
password.reset.initiated=Reimpostazione della password avviata.
|
||||
password.reset.success=La password <20> stata reimpostata con successo.
|
||||
invalid.token.msg=Il token fornito <20> invalido o scaduto. Si prega di richiedere un nuovo token.
|
||||
current.password.incorrect = La password attuale non <20> corretta.
|
||||
success.password.changed=Password cambiata con successo.
|
||||
logout.successful.msg=Logout riuscito. Sei stato disconnesso con successo.
|
||||
|
||||
update.user.status.success=Lo stato dell'utente <20> stato aggiornato con successo.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user