Skip to content

Commit

Permalink
refactor: setting swagger in auth package
Browse files Browse the repository at this point in the history
  • Loading branch information
ShulV committed Nov 7, 2023
1 parent 7367e78 commit 1a57df6
Show file tree
Hide file tree
Showing 12 changed files with 125 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
import io.jsonwebtoken.JwtException;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
Expand All @@ -40,7 +43,16 @@ public class AuthenticationController {

@Operation(
summary = "Регистрация",
description = "Зарегистрироваться (с проверкой данных на валидность)."
description = "Зарегистрироваться (с проверкой данных на валидность).",
responses = {
@ApiResponse(responseCode = "201", description = "Пользователь успешно зарегистрирован",
content = { @Content(mediaType = "application/json",
schema = @Schema(implementation = RegisterResponse.class)) }
),
@ApiResponse(responseCode = "400", description = "Пользователь не был зарегистрирован",
content = { @Content(mediaType = "application/json",
schema = @Schema(implementation = RegisterErrorResponse.class)) }
)}
)
@PostMapping(value="/register")
public ResponseEntity<RegisterResponse> register(
Expand All @@ -55,7 +67,16 @@ public ResponseEntity<RegisterResponse> register(

@Operation(
summary = "Аутентификация",
description = "Аутентифицироваться по логину и паролю"
description = "Аутентифицироваться по логину и паролю",
responses = {
@ApiResponse(responseCode = "200", description = "Аутентификация прошла успешно",
content = { @Content(mediaType = "application/json",
schema = @Schema(implementation = AuthenticationResponse.class)) }
),
@ApiResponse(responseCode = "401", description = "Пользователь не был аутентифицирован " +
"(из-за неверного пароля или логина)", content = { @Content(mediaType = "application/json",
schema = @Schema(implementation = ErrorMessageResponse.class)) }
)}
)
@PostMapping(value="/authenticate")
public ResponseEntity<AuthenticationResponse> authenticate(
Expand All @@ -66,7 +87,17 @@ public ResponseEntity<AuthenticationResponse> authenticate(

@Operation(
summary = "Получение новых токенов",
description = "Получение новых access и refresh токенов пользователя"
description = "Получение новых access и refresh токенов пользователя",
responses = {
@ApiResponse(responseCode = "200", description = "Новые токены получены успешно",
content = { @Content(mediaType = "application/json",
schema = @Schema(implementation = RegisterResponse.class)) }
),
@ApiResponse(responseCode = "401", description = "Новые токены не были получены, " +
"т.к. refreshToken не прошел проверку на валидность или истёк",
content = { @Content(mediaType = "application/json",
schema = @Schema(implementation = RegisterErrorResponse.class)) }
)}
)
@PostMapping(value="/refresh-token")
public ResponseEntity<AuthenticationResponse> refreshToken(
Expand All @@ -78,7 +109,17 @@ public ResponseEntity<AuthenticationResponse> refreshToken(

@Operation(
summary = "Выход из учетной записи",
description = "Выход из текущей (одной) учетной записи пользователя"
description = "Выход из текущей (одной) учетной записи пользователя",
responses = {
@ApiResponse(responseCode = "200", description = "Успешный выход из аккаунта",
content = { @Content(mediaType = "application/json",
schema = @Schema(implementation = LogoutMessageResponse.class)) }
),
@ApiResponse(responseCode = "401", description = "Выход из аккаунта не удался, " +
"т.к. refreshToken не прошел проверку на валидность или истёк",
content = { @Content(mediaType = "application/json",
schema = @Schema(implementation = ErrorMessageResponse.class)) }
)}
)
@DeleteMapping(value = "/logout")
public ResponseEntity<LogoutMessageResponse> logout(
Expand All @@ -90,7 +131,17 @@ public ResponseEntity<LogoutMessageResponse> logout(

@Operation(
summary = "Выход из всех учетных записей",
description = "Выход из всех учетных записей пользователя"
description = "Выход из всех учетных записей пользователя",
responses = {
@ApiResponse(responseCode = "200", description = "Успешный выход из аккаунта",
content = { @Content(mediaType = "application/json",
schema = @Schema(implementation = LogoutMessageResponse.class)) }
),
@ApiResponse(responseCode = "401", description = "Выход из аккаунта не удался, " +
"т.к. refreshToken не прошел проверку на валидность или истёк",
content = { @Content(mediaType = "application/json",
schema = @Schema(implementation = ErrorMessageResponse.class)) }
)}
)
@DeleteMapping(value = "/logout-all")
public ResponseEntity<LogoutMessageResponse> logoutAll(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.shulpov.spots_app.authentication_management.requests;

import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
Expand All @@ -15,8 +16,11 @@
@AllArgsConstructor
@NoArgsConstructor
public class AuthenticationRequest {
@JsonProperty("email")
@NotEmpty
@Schema(description = "Логин (почта пользователя)", example = "alex_green@gmail.com")
private String email;
@JsonProperty("password")

@NotEmpty
@Schema(description = "Пароль пользователя", example = "password")
private String password;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.shulpov.spots_app.authentication_management.requests;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
Expand All @@ -18,20 +19,29 @@
@AllArgsConstructor
@NoArgsConstructor
public class RegisterRequest {
@Schema(description = "Имя пользователя", example = "Alex")
@NotEmpty(message = "Имя не должен быть пустым")
@Size(min = 2, max = 30, message = "Длина имени должна быть от 2 до 30 символов")
private String name;
@NotNull(message = "Email не должен быть пустой")

@Schema(description = "Почта пользователя", example = "alex_green@gmail.com")
@NotEmpty(message = "Email не должен быть пустой")
@Email(message = "Email должен быть валидным")
@Size(min = 5, max = 50, message = "Длина почты должна быть от 5 до 50 символов")
private String email;

@Schema(description = "Номер телефона пользователя", example = "89005553535")
@NotEmpty(message = "Номер не должен быть пустым")
@Pattern(regexp = "^\\+?[0-9\\-\\s()]*$", message = "Неверный формат номера телефона")
private String phoneNumber;

@Schema(description = "Дата рождения пользователя", example = "2000-07-15")
@NotNull(message = "Дата дня рождения не должна быть пустой")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birthday;
@NotNull(message = "Пароль не должен быть пустой")

@Schema(description = "Пароль пользователя", example = "password")
@NotEmpty(message = "Пароль не должен быть пустой")
@Size(min = 6, max = 50, message = "Длина пароля должна быть от 6 до 50 символов")
private String password;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.shulpov.spots_app.authentication_management.responses;

import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;

/**
Expand All @@ -13,10 +14,20 @@
@AllArgsConstructor
@NoArgsConstructor
public class AuthenticationResponse {
@Schema(description = "Id пользователя", example = "1")
@JsonProperty("id")
private Long userId;

@Schema(description = "Access-токен пользователя",
example = "eyJhbGciOiJIUzI1NiJ9.eyJhdXRob3JpdGllcyI6W3siYXV0aG9yaXR5IjoiUk9MRV9VU0VSIn1dLCJjcmVhdGluZ0Rhd" +
"GUiOjE2OTkyNTU3NzUyMzQsInVzZXJuYW1lIjoiYWxleF9ncmVlbkBnbWFpbC5jb20iLCJzdWIiOiJhbGV4X2dyZWVuQGdtY" +
"WlsLmNvbSIsImlhdCI6MTY5OTI1NTc3NSwiZXhwIjoxNjk5MzQyMTc1fQ.km9y4BK3I1p7c4FbqSOmYzbGAIo-W_jHOAgY_MUKkAg")
@JsonProperty("access_token")
private String accessToken;

@Schema(description = "Refresh-токен пользователя",
example = "eyJhbGciOiJIUzI1NiJ9.eyJjcmVhdGluZ0RhdGUiOjE2OTkyNTU3NzUyODAsInN1YiI6ImFsZXhfZ3JlZW5AZ21haWwuY" +
"29tIiwiaWF0IjoxNjk5MjU1Nzc1LCJleHAiOjE2OTk4NjA1NzV9.AErZPqLTbVykO11Ro16c_BmvSiCPJuglNRpcPybi7sY")
@JsonProperty("refresh_token")
private String refreshToken;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.shulpov.spots_app.authentication_management.responses;

import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;

@Setter
Expand All @@ -9,9 +10,14 @@
@AllArgsConstructor
@NoArgsConstructor
public class LogoutMessageResponse {
@Schema(description = "Сообщение о выходе из аккаунта", example = "Successful logout")
private String message;

@Schema(description = "Id пользователя", example = "1")
@JsonProperty("id")
private Long userId;

@Schema(description = "Количество закрытых сессий", example = "1")
@JsonProperty("closed_session_number")
private long closedSessionNumber;
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.shulpov.spots_app.authentication_management.responses;

import com.shulpov.spots_app.responses.ValidationErrorResponse;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class RegisterErrorResponse extends ValidationErrorResponse {
@Schema(description = "Сообщение о ошибке", example = "Регистрация не удалась")
private String message;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.shulpov.spots_app.authentication_management.responses;

import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
Expand All @@ -14,10 +15,20 @@
@AllArgsConstructor
@NoArgsConstructor
public class RegisterResponse {
@Schema(description = "Id пользователя", example = "1")
@JsonProperty("id")
private Long userId;

@Schema(description = "Access-токен пользователя",
example = "eyJhbGciOiJIUzI1NiJ9.eyJhdXRob3JpdGllcyI6W3siYXV0aG9yaXR5IjoiUk9MRV9VU0VSIn1dLCJjcmVhdGluZ0Rhd" +
"GUiOjE2OTkyNTU3NzUyMzQsInVzZXJuYW1lIjoiYWxleF9ncmVlbkBnbWFpbC5jb20iLCJzdWIiOiJhbGV4X2dyZWVuQGdtY" +
"WlsLmNvbSIsImlhdCI6MTY5OTI1NTc3NSwiZXhwIjoxNjk5MzQyMTc1fQ.km9y4BK3I1p7c4FbqSOmYzbGAIo-W_jHOAgY_MUKkAg")
@JsonProperty("access_token")
private String accessToken;

@Schema(description = "Refresh-токен пользователя",
example = "eyJhbGciOiJIUzI1NiJ9.eyJjcmVhdGluZ0RhdGUiOjE2OTkyNTU3NzUyODAsInN1YiI6ImFsZXhfZ3JlZW5AZ21haWwuY" +
"29tIiwiaWF0IjoxNjk5MjU1Nzc1LCJleHAiOjE2OTk4NjA1NzV9.AErZPqLTbVykO11Ro16c_BmvSiCPJuglNRpcPybi7sY")
@JsonProperty("refresh_token")
private String refreshToken;
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public RegisterResponse register(RegisterRequest request, BindingResult errors)
.build();
userValidator.validate(user, errors);
if(errors.hasErrors()) {
throw new RegisterErrorException("Регистрация не удалась.", errors.getFieldErrors());
throw new RegisterErrorException("Регистрация не удалась", errors.getFieldErrors());
}
User savedUser = userRepository.save(user);
String accessToken = jwtService.generateAccessToken(user);
Expand Down Expand Up @@ -88,7 +88,7 @@ public AuthenticationResponse authenticate(AuthenticationRequest request) throws
//authenticated
Optional<User> userOpt = userRepository.findByEmail(email);
if(userOpt.isEmpty()) {
throw new BadCredentialsException("User with email='" + email + "' not found");
throw new BadCredentialsException("Пользователь с email='" + email + "' не найден");
}
User user = userOpt.get();
String newAccessToken = jwtService.generateAccessToken(user);
Expand Down Expand Up @@ -185,7 +185,7 @@ public LogoutMessageResponse logout(String refreshTokenHeader) throws JwtExcepti
return LogoutMessageResponse.builder()
.closedSessionNumber(1L)
.userId(token.getUser().getId())
.message("Successful logout")
.message("Успешных выход из аккаунта")
.build();
}

Expand All @@ -200,7 +200,7 @@ public LogoutMessageResponse logoutAll(String refreshTokenHeader) throws JwtExce
return LogoutMessageResponse.builder()
.closedSessionNumber(count)
.userId(token.getUser().getId())
.message("Successful logout")
.message("Успешный выход из аккаунта на всех устройствах")
.build();
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.shulpov.spots_app.authentication_management.tokens;

import com.shulpov.spots_app.users.models.User;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.*;
import lombok.*;

Expand All @@ -12,13 +13,18 @@
@Entity
@Table(name = "tokens")
public class Token {
@Schema(description = "Id токена в БД", example = "1")
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long id;

@Schema(description = "Значение токена",
example = "eyJhbGciOiJIUzI1NiJ9.eyJjcmVhdGluZ0RhdGUiOjE2OTkyNTU3NzUyODAsInN1YiI6ImFsZXhfZ3JlZW5AZ21haWwuY" +
"29tIiwiaWF0IjoxNjk5MjU1Nzc1LCJleHAiOjE2OTk4NjA1NzV9.AErZPqLTbVykO11Ro16c_BmvSiCPJuglNRpcPybi7sY")
@Column(unique = true)
public String value;

@Schema(description = "Тип токена (используется только REFRESH)", example = "REFRESH")
@Enumerated(EnumType.STRING)
public TokenType tokenType;

Expand Down
6 changes: 6 additions & 0 deletions src/main/java/com/shulpov/spots_app/dto/FieldErrorDto.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.shulpov.spots_app.dto;

import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
Expand All @@ -15,10 +16,15 @@
@AllArgsConstructor
@NoArgsConstructor
public class FieldErrorDto {
@Schema(description = "Сообщение об ошибке", example = "Email должен быть валидным")
@JsonProperty("error_message")
private String defaultMessage;

@Schema(description = "Название поля, на котором вызвана ошибка", example = "email")
@JsonProperty("field")
private String field;

@Schema(description = "Переданное неверное значение поля", example = "kek.mail.ru")
@JsonProperty("rejected_value")
private String rejectedValue;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.shulpov.spots_app.responses;

import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
Expand All @@ -14,6 +15,7 @@
@AllArgsConstructor
@NoArgsConstructor
public class ErrorMessageResponse {
@Schema(description = "Сообщение об ошибке", example = "Пользователь с email='vova@mail.ru' не найден")
@JsonProperty("errorMessage")
private String errorMessage;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.fasterxml.jackson.annotation.JsonProperty;
import com.shulpov.spots_app.dto.FieldErrorDto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;

import java.util.List;
Expand All @@ -16,6 +17,7 @@
@AllArgsConstructor
@NoArgsConstructor
public class ValidationErrorResponse {
@Schema(description = "Массив ошибок, связанных с определенными полями")
@JsonProperty("errors")
private List<FieldErrorDto> errorDtoList;
}

0 comments on commit 1a57df6

Please sign in to comment.