Get user by login; Codes; acs/open endpoint
This commit is contained in:
parent
126c8e0cb0
commit
15320350e3
@ -0,0 +1,26 @@
|
||||
package com.displaynone.acss.components.acs;
|
||||
|
||||
import com.displaynone.acss.components.acs.code.CodeModel;
|
||||
import com.displaynone.acss.components.acs.code.service.CodeService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class ACSComponent {
|
||||
private final CodeService codeService;
|
||||
|
||||
public Optional<CodeModel> getCodeByValue(Long value) {
|
||||
return codeService.getCodeByValue(value);
|
||||
}
|
||||
|
||||
public CodeModel getCodeByValueStrict(Long value) {
|
||||
return codeService.getCodeByValueStrict(value);
|
||||
}
|
||||
|
||||
public boolean isValid(Long code) {
|
||||
return codeService.isValid(code);
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.displaynone.acss.components.acs.code;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
@Data
|
||||
public class CodeDTO {
|
||||
private Long id;
|
||||
private Long codeValue;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.displaynone.acss.components.auth.models.code;
|
||||
package com.displaynone.acss.components.acs.code;
|
||||
|
||||
import com.displaynone.acss.components.auth.models.role.RoleDTO;
|
||||
import com.displaynone.acss.components.auth.models.role.RoleMapper;
|
||||
@ -15,7 +15,7 @@ public class CodeMapper {
|
||||
CodeDTO dto = new CodeDTO();
|
||||
|
||||
dto.setId(model.getId());
|
||||
dto.setValue(model.getValue());
|
||||
dto.setCodeValue(model.getCodeValue());
|
||||
|
||||
return dto;
|
||||
}
|
@ -1,9 +1,6 @@
|
||||
package com.displaynone.acss.components.auth.models.code;
|
||||
package com.displaynone.acss.components.acs.code;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
@ -12,11 +9,12 @@ import lombok.NoArgsConstructor;
|
||||
@Entity
|
||||
@Data
|
||||
@Builder
|
||||
@Table(name = "codes")
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CodeModel {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private long id;
|
||||
private long value;
|
||||
private long codeValue;
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
package com.displaynone.acss.components.auth.models.code;
|
||||
package com.displaynone.acss.components.acs.code;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface CodeRepository extends JpaRepository<CodeModel, Long> {
|
||||
Optional<CodeModel> findByCodeValue(Long codeValue);
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.displaynone.acss.components.acs.code.service;
|
||||
|
||||
import com.displaynone.acss.components.acs.code.CodeModel;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface CodeService {
|
||||
Optional<CodeModel> getCodeByValue(Long value);
|
||||
|
||||
CodeModel getCodeByValueStrict(Long value);
|
||||
|
||||
boolean isValid(Long code);
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.displaynone.acss.components.acs.code.service;
|
||||
|
||||
import com.displaynone.acss.components.acs.code.CodeModel;
|
||||
import com.displaynone.acss.components.acs.code.CodeRepository;
|
||||
import com.displaynone.acss.exception.generics.NotFoundHTTPException;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class CodeServiceImpl implements CodeService {
|
||||
private final CodeRepository codeRepository;
|
||||
|
||||
@Override
|
||||
public Optional<CodeModel> getCodeByValue(Long value) {
|
||||
return codeRepository.findByCodeValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeModel getCodeByValueStrict(Long value) {
|
||||
Optional<CodeModel> model = getCodeByValue(value);
|
||||
if (model.isEmpty()) throw new NotFoundHTTPException("Code not found");
|
||||
return model.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(Long code) {
|
||||
return getCodeByValue(code).isPresent();
|
||||
}
|
||||
}
|
@ -2,8 +2,6 @@ package com.displaynone.acss.components.auth;
|
||||
|
||||
import com.displaynone.acss.components.auth.internal_utils.JWTUtils;
|
||||
import com.displaynone.acss.components.auth.models.AuthTokenPair;
|
||||
import com.displaynone.acss.components.auth.models.user.UserDTO;
|
||||
import com.displaynone.acss.components.auth.models.user.UserMapper;
|
||||
import com.displaynone.acss.components.auth.models.user.UserModel;
|
||||
import com.displaynone.acss.components.auth.models.user.service.UserService;
|
||||
import com.displaynone.acss.exception.generics.UnauthorizedHTTPException;
|
||||
@ -31,18 +29,18 @@ public class AuthComponent implements UserDetailsService {
|
||||
this.userService = userService;
|
||||
}
|
||||
|
||||
private AuthTokenPair _generateTokenPair(@NonNull UserDetails user) {
|
||||
public AuthTokenPair _generateTokenPair(@NonNull UserDetails user) {
|
||||
String accessToken = jwtUtils.generateAccessToken(user);
|
||||
String refreshToken = jwtUtils.generateRefreshToken(user);
|
||||
|
||||
return new AuthTokenPair(accessToken, refreshToken);
|
||||
}
|
||||
|
||||
private Optional<UserModel> _findModelByLogin(@NonNull String login) {
|
||||
public Optional<UserModel> getUserByLogin(@NonNull String login) {
|
||||
return userService.findByLogin(login);
|
||||
}
|
||||
|
||||
private UserModel _findModelByLoginStrict(@NonNull String login) {
|
||||
public UserModel getUserByLoginStrict(@NonNull String login) {
|
||||
return userService.findByLoginStrict(login);
|
||||
}
|
||||
|
||||
@ -50,7 +48,7 @@ public class AuthComponent implements UserDetailsService {
|
||||
if (!jwtUtils.validateToken(accessToken)) throw new UnauthorizedHTTPException("Invalid access token");
|
||||
|
||||
String username = jwtUtils.getLogin(accessToken);
|
||||
UserModel userModel = _findModelByLoginStrict(username);
|
||||
UserModel userModel = getUserByLoginStrict(username);
|
||||
|
||||
return new UsernamePasswordAuthenticationToken(userModel, null, userModel.getAuthorities());
|
||||
}
|
||||
@ -60,22 +58,13 @@ public class AuthComponent implements UserDetailsService {
|
||||
|
||||
String login = jwtUtils.getLogin(refreshToken);
|
||||
System.out.println(login);
|
||||
UserModel userModel = _findModelByLoginStrict(login);
|
||||
UserModel userModel = getUserByLoginStrict(login);
|
||||
|
||||
return _generateTokenPair(userModel);
|
||||
}
|
||||
|
||||
public Optional<UserDTO> findByLogin(@NonNull String login) {
|
||||
Optional<UserModel> userModel = _findModelByLogin(login);
|
||||
return userModel.map(UserMapper::convertToDTO);
|
||||
}
|
||||
|
||||
public UserDTO findByLoginStrict(@NonNull String login) {
|
||||
return UserMapper.convertToDTO(userService.findByLoginStrict(login));
|
||||
}
|
||||
|
||||
public Pair<UserModel, AuthTokenPair> authenticate(@NonNull String login) {
|
||||
UserModel userModel = _findModelByLoginStrict(login);
|
||||
UserModel userModel = getUserByLoginStrict(login);
|
||||
return Pair.of(userModel, authenticate(userModel));
|
||||
}
|
||||
|
||||
@ -85,6 +74,6 @@ public class AuthComponent implements UserDetailsService {
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(@NonNull String username) throws UsernameNotFoundException {
|
||||
return _findModelByLoginStrict(username);
|
||||
return getUserByLoginStrict(username);
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +0,0 @@
|
||||
package com.displaynone.acss.components.auth.models.code;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
@Data
|
||||
public class CodeDTO {
|
||||
private Long id;
|
||||
private Long value;
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package com.displaynone.acss.components.auth.models.code.service;
|
||||
|
||||
import com.displaynone.acss.components.auth.models.code.CodeModel;
|
||||
|
||||
public interface CodeService {
|
||||
CodeModel getCodeByValue(Long value);
|
||||
|
||||
boolean isValid(Long code);
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package com.displaynone.acss.components.auth.models.code.service;
|
||||
|
||||
import com.displaynone.acss.components.auth.models.code.CodeModel;
|
||||
import com.displaynone.acss.components.auth.models.code.CodeRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class CodeServiceImpl implements CodeService {
|
||||
private final CodeRepository codeRepository;
|
||||
|
||||
@Override
|
||||
public CodeModel getCodeByValue(Long value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(Long code) {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,13 +1,24 @@
|
||||
package com.displaynone.acss.controllers.acs;
|
||||
|
||||
import com.displaynone.acss.components.acs.ACSComponent;
|
||||
import com.displaynone.acss.exception.generics.ForbiddenHTTPException;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/acs")
|
||||
@RequiredArgsConstructor
|
||||
public class ACSController {
|
||||
private final ACSComponent acsComponent;
|
||||
|
||||
@PostMapping("/open")
|
||||
public ResponseEntity<Void> open() {}
|
||||
public ResponseEntity<Void> open(@RequestBody OpenRB body) {
|
||||
Long code = body.getCode();
|
||||
if (!acsComponent.isValid(code)) throw new ForbiddenHTTPException("Invalid code");
|
||||
return ResponseEntity.ok(null);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
package com.displaynone.acss.controllers.acs;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class OpenRB {
|
||||
private Long code;
|
||||
}
|
@ -2,13 +2,13 @@ package com.displaynone.acss.controllers.auth;
|
||||
|
||||
import com.displaynone.acss.components.auth.AuthComponent;
|
||||
import com.displaynone.acss.components.auth.models.AuthTokenPair;
|
||||
import com.displaynone.acss.components.auth.models.user.UserDTO;
|
||||
import com.displaynone.acss.components.auth.models.user.UserModel;
|
||||
import com.displaynone.acss.exception.generics.BadRequestHTTPException;
|
||||
import com.displaynone.acss.exception.generics.NotFoundHTTPException;
|
||||
import com.displaynone.acss.exception.generics.UnauthorizedHTTPException;
|
||||
import com.displaynone.acss.utils.Pair;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
@ -17,17 +17,13 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/auth")
|
||||
@RequiredArgsConstructor
|
||||
public class AuthController {
|
||||
private final AuthComponent authComponent;
|
||||
|
||||
@Autowired
|
||||
public AuthController(AuthComponent authComponent) {
|
||||
this.authComponent = authComponent;
|
||||
}
|
||||
|
||||
@PostMapping("/login")
|
||||
public ResponseEntity<AuthTokenPair> login(@RequestBody LoginRequestBody loginRequest) {
|
||||
String login = loginRequest.getLogin();
|
||||
public ResponseEntity<AuthTokenPair> login(@RequestBody LoginRB body) {
|
||||
String login = body.getLogin();
|
||||
if (login == null) throw new BadRequestHTTPException("Login not specified");
|
||||
|
||||
Pair<UserModel, AuthTokenPair> authInfo;
|
||||
@ -42,8 +38,8 @@ public class AuthController {
|
||||
}
|
||||
|
||||
@PostMapping("/refresh")
|
||||
public ResponseEntity<?> refreshToken(@RequestBody TokenRefreshRequestBody request) {
|
||||
String requestRefreshToken = request.getRefreshToken();
|
||||
public ResponseEntity<?> refreshToken(@RequestBody TokenRefreshRB body) {
|
||||
String requestRefreshToken = body.getRefreshToken();
|
||||
if (requestRefreshToken == null) throw new BadRequestHTTPException("Refresh token not specified");
|
||||
|
||||
AuthTokenPair authTokenPair;
|
||||
|
@ -3,6 +3,6 @@ package com.displaynone.acss.controllers.auth;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class LoginRequestBody {
|
||||
public class LoginRB {
|
||||
private String login;
|
||||
}
|
@ -3,6 +3,6 @@ package com.displaynone.acss.controllers.auth;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class TokenRefreshRequestBody {
|
||||
public class TokenRefreshRB {
|
||||
public String refreshToken;
|
||||
}
|
@ -1,17 +1,23 @@
|
||||
package com.displaynone.acss.controllers.user;
|
||||
|
||||
import com.displaynone.acss.components.auth.AuthComponent;
|
||||
import com.displaynone.acss.components.auth.models.user.UserDTO;
|
||||
import com.displaynone.acss.components.auth.models.user.UserMapper;
|
||||
import com.displaynone.acss.components.auth.models.user.UserModel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/users")
|
||||
@RequiredArgsConstructor
|
||||
public class UserController {
|
||||
private final AuthComponent authComponent;
|
||||
|
||||
@GetMapping("/me")
|
||||
public ResponseEntity<UserDTO> getMe() {
|
||||
UserModel user = (UserModel) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||
@ -19,7 +25,8 @@ public class UserController {
|
||||
}
|
||||
|
||||
@GetMapping("/login/{login}")
|
||||
public ResponseEntity<UserDTO> getUserByLogin() {
|
||||
// TODO
|
||||
public ResponseEntity<UserDTO> getUserByLogin(@PathVariable String login) {
|
||||
UserModel user = authComponent.getUserByLoginStrict(login);
|
||||
return ResponseEntity.ok(UserMapper.convertToDTO(user));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
package com.displaynone.acss.exception.generics;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
|
||||
@ResponseStatus(HttpStatus.FORBIDDEN)
|
||||
public class ForbiddenHTTPException extends RuntimeException {
|
||||
public ForbiddenHTTPException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
@ -1,10 +1,7 @@
|
||||
package com.displaynone.acss.exception.handler;
|
||||
|
||||
import com.displaynone.acss.exception.*;
|
||||
import com.displaynone.acss.exception.generics.AlreadyExistsHTTPException;
|
||||
import com.displaynone.acss.exception.generics.BadRequestHTTPException;
|
||||
import com.displaynone.acss.exception.generics.NotFoundHTTPException;
|
||||
import com.displaynone.acss.exception.generics.UnauthorizedHTTPException;
|
||||
import com.displaynone.acss.exception.generics.*;
|
||||
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -17,6 +14,7 @@ import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.servlet.resource.NoResourceFoundException;
|
||||
|
||||
@RestControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
@ -73,4 +71,14 @@ public class GlobalExceptionHandler {
|
||||
|
||||
return buildErrorResponse(e, HttpStatus.UNAUTHORIZED, "Unauthorized: unexpected error occurred");
|
||||
}
|
||||
|
||||
@ExceptionHandler(NoResourceFoundException.class)
|
||||
public ResponseEntity<ErrorResponse> handleNoResourceFoundException(NoResourceFoundException e, WebRequest request) {
|
||||
return buildErrorResponse(e, HttpStatus.NOT_FOUND, null);
|
||||
}
|
||||
|
||||
@ExceptionHandler(ForbiddenHTTPException.class)
|
||||
public ResponseEntity<ErrorResponse> handleForbiddenHTTPException(ForbiddenHTTPException e, WebRequest request) {
|
||||
return buildErrorResponse(e, HttpStatus.FORBIDDEN, null);
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ public class WebSecurityConfig {
|
||||
.authorizeHttpRequests(authorizeRequests ->
|
||||
authorizeRequests
|
||||
.requestMatchers("/api/auth/**").permitAll()
|
||||
.requestMatchers("/api/users/login/**").hasAuthority("ROLE_ADMIN")
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
|
@ -9,7 +9,7 @@
|
||||
<column name="id" type="INTEGER" autoIncrement="true">
|
||||
<constraints primaryKey="true"/>
|
||||
</column>
|
||||
<column name="value" type="INTEGER">
|
||||
<column name="code_value" type="BIGINT">
|
||||
<constraints unique="true" nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
|
@ -1,5 +1,5 @@
|
||||
user_id;role_id
|
||||
1;1
|
||||
1;2
|
||||
2;2
|
||||
3;2
|
||||
4;1
|
||||
|
|
@ -1,3 +1,4 @@
|
||||
id;code_value
|
||||
1;1234567890123456789
|
||||
2;9223372036854775807
|
||||
3;1122334455667788990
|
||||
|
|
@ -8,8 +8,10 @@
|
||||
<include file="db/changelog/01/0002-roles.xml"/>
|
||||
<include file="db/changelog/01/0001-users.xml"/>
|
||||
<include file="db/changelog/01/0003-user_roles.xml"/>
|
||||
<include file="db/changelog/01/0004-codes.xml"/>
|
||||
|
||||
<include file="db/changelog/data/0002-roles-data.xml"/>
|
||||
<include file="db/changelog/data/0001-user-data.xml"/>
|
||||
<include file="db/changelog/data/0003-user_roles-data.xml"/>
|
||||
<include file="db/changelog/data/0004-codes-data.xml"/>
|
||||
</databaseChangeLog>
|
||||
|
Loading…
x
Reference in New Issue
Block a user