Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentExce

@Override
public String getName() {
return name;
return email;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,8 @@ public void init() {
};

ADMIN_URLS = new String[]{
"/" + apiPath + "/reservations/{id}",
"/" + apiPath + "/properties/{id}",
"/" + apiPath + "/categories/**",
"/" + apiPath + "/facilities/**",
"/" + apiPath + "/users/{id}",
"/" + apiPath + "/images/{id}"
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
package kattsyn.dev.rentplace.controllers;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.security.auth.message.AuthException;
import jakarta.servlet.http.HttpServletResponse;
import kattsyn.dev.rentplace.dtos.CodeRequest;
import kattsyn.dev.rentplace.dtos.JwtRequest;
import kattsyn.dev.rentplace.dtos.JwtResponse;
import kattsyn.dev.rentplace.dtos.RefreshJwtRequest;
import kattsyn.dev.rentplace.dtos.*;
import kattsyn.dev.rentplace.services.AuthService;
import kattsyn.dev.rentplace.services.VerificationCodeService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseCookie;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.Duration;

@RestController
@RequestMapping("${api.path}/auth")
@RequiredArgsConstructor
Expand Down Expand Up @@ -118,4 +111,12 @@ public ResponseEntity<JwtResponse> refresh(/*@CookieValue(name = "refreshToken")
.body(jwtResponse);
}


@GetMapping("/info")
@SecurityRequirement(name = "JWT")
@Operation(summary = "Получение информации о пользователе", description = "Возвращает информацию об авторизованном пользователе")
public UserDTO getUserInfo() throws AuthException {
return authService.getUserInfo();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
Expand All @@ -43,17 +44,18 @@ public class PropertyController {
@ApiResponse(responseCode = "413", description = "Превышен максимальный размер запроса"),
@ApiResponse(responseCode = "500", description = "Внутренняя ошибка сервера")
})
@PreAuthorize("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER')" )
@PreAuthorize("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER')")
@SecurityRequirement(name = "JWT")
public ResponseEntity<List<ImageDTO>> uploadMultipleImages(
@PathVariable @Parameter(description = "id объявления", example = "10") long id,
@Parameter(
description = "Массив файлов фотографий",
required = true,
content = @Content(mediaType = MediaType.MULTIPART_FORM_DATA_VALUE, schema = @Schema(type = "string", format = "binary"))
) @RequestPart("files") MultipartFile[] files) {

) @RequestPart("files") MultipartFile[] files,
Authentication authentication) {

propertyService.ownsPropertyOrAdmin(id, authentication.getName());
List<ImageDTO> savedImages = propertyService.uploadImages(files, id);

return ResponseEntity.ok(savedImages);
Expand Down Expand Up @@ -104,10 +106,11 @@ public ResponseEntity<PropertyDTO> findById(@Valid @PathVariable @Parameter(desc
@ApiResponse(responseCode = "422", description = "Ошибка валидации", content = @Content),
@ApiResponse(responseCode = "500", description = "Непредвиденная ошибка со стороны сервера", content = @Content)
})
@PreAuthorize("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER')" )
@PreAuthorize("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER')")
@SecurityRequirement(name = "JWT")
@PostMapping(path = "/", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<PropertyDTO> createPropertyWithImage(@Valid @ModelAttribute PropertyCreateEditDTO propertyCreateEditDTO) {
public ResponseEntity<PropertyDTO> createPropertyWithImage(@Valid @ModelAttribute PropertyCreateEditDTO propertyCreateEditDTO, Authentication authentication) {
propertyService.allowedToCreatePropertyOrAdmin(propertyCreateEditDTO, authentication.getName());
return new ResponseEntity<>(propertyService.createWithImages(propertyCreateEditDTO), HttpStatus.CREATED);
}

Expand All @@ -122,11 +125,13 @@ public ResponseEntity<PropertyDTO> createPropertyWithImage(@Valid @ModelAttribut
@ApiResponse(responseCode = "422", description = "Ошибка валидации", content = @Content),
@ApiResponse(responseCode = "500", description = "Непредвиденная ошибка со стороны сервера", content = @Content)
})
@PreAuthorize("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER')" )
@PreAuthorize("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER')")
@SecurityRequirement(name = "JWT")
@PatchMapping(path = "/{id}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<PropertyDTO> updateProperty(@Valid @PathVariable @Parameter(description = "id объявления", example = "1") long id,
@Valid @ModelAttribute PropertyCreateEditDTO propertyCreateEditDTO) {
@Valid @ModelAttribute PropertyCreateEditDTO propertyCreateEditDTO,
Authentication authentication) {
propertyService.ownsPropertyOrAdmin(id, authentication.getName());
return ResponseEntity.ok(propertyService.update(id, propertyCreateEditDTO));
}

Expand All @@ -141,11 +146,13 @@ public ResponseEntity<PropertyDTO> updateProperty(@Valid @PathVariable @Paramete
@ApiResponse(responseCode = "422", description = "Ошибка валидации", content = @Content),
@ApiResponse(responseCode = "500", description = "Непредвиденная ошибка со стороны сервера", content = @Content)
})
@PreAuthorize("hasAuthority('ROLE_ADMIN')" )
@PreAuthorize("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER')")
@SecurityRequirement(name = "JWT")
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteProperty(@Valid @PathVariable @Parameter(description = "id объявления", example = "10") long id) {
propertyService.deleteById(id);
public ResponseEntity<Void> deleteProperty(@Valid @PathVariable @Parameter(description = "id объявления", example = "10") long id, Authentication authentication) {
if (propertyService.ownsPropertyOrAdmin(id, authentication.getName())) {
propertyService.deleteById(id);
}
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

Expand Down Expand Up @@ -79,7 +80,9 @@ public ResponseEntity<ReservationDTO> getReservation(@PathVariable
@SecurityRequirement(name = "JWT")
@SecurityRequirement(name = "JWT")
@PostMapping(path = "/", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<ReservationDTO> createReservation(@Valid @ModelAttribute ReservationCreateEditDTO reservationCreateEditDTO) {
public ResponseEntity<ReservationDTO> createReservation(@Valid @ModelAttribute ReservationCreateEditDTO reservationCreateEditDTO,
Authentication authentication) {
reservationService.allowedToCreateReservationOrAdmin(reservationCreateEditDTO, authentication.getName());
return ResponseEntity.ok(reservationService.createReservation(reservationCreateEditDTO));
}

Expand Down Expand Up @@ -118,8 +121,10 @@ public ResponseEntity<ReservationDTO> updateReservation(@PathVariable @Parameter
@SecurityRequirement(name = "JWT")
public ResponseEntity<ReservationDTO> deleteReservation(
@PathVariable
@Valid @Parameter(description = "id бронирования", example = "1") long id
@Valid @Parameter(description = "id бронирования", example = "1") long id,
Authentication authentication
) {
reservationService.ownsReservationOrAdmin(id, authentication.getName());
return ResponseEntity.ok(reservationService.deleteById(id));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
Expand Down Expand Up @@ -51,8 +52,9 @@ public ResponseEntity<ImageDTO> uploadImage(
content = @Content(mediaType = MediaType.MULTIPART_FORM_DATA_VALUE)
) @RequestParam("file") MultipartFile file,
@PathVariable
@Parameter(description = "id пользователя", example = "10") long id) {

@Parameter(description = "id пользователя", example = "10") long id,
Authentication authentication) {
userService.allowedToEditUser(id, authentication.getName());
return ResponseEntity.ok(userService.uploadImage(file, id));
}

Expand Down Expand Up @@ -122,7 +124,9 @@ public ResponseEntity<UserDTO> createUser(@ModelAttribute @Valid UserCreateEditD
public ResponseEntity<UserDTO> updateUser(
@PathVariable
@Parameter(description = "id пользователя", example = "1") long id,
@ModelAttribute @Valid UserCreateEditDTO userCreateEditDTO) {
@ModelAttribute @Valid UserCreateEditDTO userCreateEditDTO,
Authentication authentication) {
userService.allowedToEditUser(id, authentication.getName());
return ResponseEntity.ok(userService.update(id, userCreateEditDTO));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package kattsyn.dev.rentplace.dtos;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Email;
import lombok.AllArgsConstructor;
import lombok.Getter;
Expand All @@ -13,6 +14,7 @@
public class CodeRequest {

@Email
@Schema(description = "Почта пользователя", example = "warshard1337@gmail.com")
private String email;

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class JwtRequest {

@Schema(description = "Почта пользователя", example = "warshard1337@gmail.com")
private String email;
@Schema(description = "Код, который пользователь получил на почту", example = "123456")
@Schema(description = "Код, который пользователь получил на почту", example = "12345")
private String code;

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package kattsyn.dev.rentplace.dtos;

import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand All @@ -12,10 +12,13 @@
@NoArgsConstructor
public class JwtResponse {

@Schema(example = "Bearer ")
private final String type = "Bearer ";
@Schema(example = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ3YXJzaGFyZDEzMzdAZ21haWwuY29tIiwiZXhwIjoxNzQ2MzA1ODEzLCJyb2xlIjoiUk9MRV9B211JTiIsIm5hbWUiOiJhZG1pbiJ9.4Rg7E39Y4baT9Eld_pkvH0D6S72eepmyd17Ch44K5Fikw32BSbXsnVq4EOnXJgXsQkmkhZrGDHZh-cSGg7pLPg")
private String accessToken;

//@JsonIgnore
@Schema(example = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ3YXJzaGFyZDEzMzdAZ21haWwuY29tIiwiZXhwIjoxNzQ2MzA1ODEzLCJyb2xlIjoiUk9MRV9Bda1JTiIsIm5hbWUiOiJhZG1pbiJ9.4Rg7E39Y4baT9Eld_pkvH0D6S72eepmydCLCh44K5FikwkdBSbXsnVq4EOnXJgXsQkmkhZrGDHZh-cSGg7pLPg")
private String refreshToken;

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import kattsyn.dev.rentplace.enums.Gender;
import kattsyn.dev.rentplace.enums.Role;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand All @@ -30,6 +31,8 @@ public class UserCreateEditDTO {
private String surname;
@Schema(description = "Пол пользователя. MALE или FEMALE")
private Gender gender;
@Schema(description = "Роль пользователя. ROLE_USER или ROLE_ADMIN")
private Role role;
@Schema(description = "Дата рождения пользователя", example = "2004-02-22")
private LocalDate birthDate;
@Schema(description = "email пользователя", example = "ivanivanov@gmail.com")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import kattsyn.dev.rentplace.enums.Gender;
import kattsyn.dev.rentplace.enums.Role;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand Down Expand Up @@ -33,6 +34,8 @@ public class UserDTO {
private String surname;
@Schema(description = "Пол пользователя. MALE или FEMALE")
private Gender gender;
@Schema(description = "Роль пользователя. ROLE_USER или ROLE_ADMIN")
private Role role;
@Schema(description = "Дата рождения пользователя", example = "2004-02-22")
private LocalDate birthDate;
@Schema(description = "email пользователя", example = "ivanivanov@gmail.com")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import lombok.*;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Entity
Expand Down Expand Up @@ -78,7 +77,7 @@ NOT PUBLISHED (не опубликовано) - объявление уже пр
private int maxGuests;

@Schema(description = "Владелец жилья")
@OneToOne(cascade = CascadeType.MERGE)
@ManyToOne(cascade = CascadeType.MERGE)
@JoinColumn(name = "owner_id", referencedColumnName = "user_id")
private User owner;

Expand Down Expand Up @@ -108,6 +107,4 @@ NOT PUBLISHED (не опубликовано) - объявление уже пр
)
private Set<Facility> facilities = new HashSet<>();

@OneToMany(mappedBy = "property")
private List<Reservation> reservations;
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ public class Reservation {
private long reservationId;

@ManyToOne
@JoinColumn(name = "property_id") // имя столбца в таблице reservations
@JoinColumn(name = "property_id")
private Property property;

@ManyToOne
@JoinColumn(name = "renter_id") // имя столбца в таблице reservations
@JoinColumn(name = "renter_id")
private User renter;

@Column(name = "start_date")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import lombok.*;

import java.time.LocalDate;
import java.util.List;

@Entity
@NoArgsConstructor
Expand Down Expand Up @@ -43,6 +42,4 @@ public class User {
@JoinColumn(name = "image_id")
private Image image;

@OneToMany(mappedBy = "renter")
private List<Reservation> reservations;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package kattsyn.dev.rentplace.exceptions;

import org.springframework.http.HttpStatus;

public class ForbiddenException extends AppException {

public ForbiddenException(String message) {
super(HttpStatus.FORBIDDEN.value(), "FORBIDDEN", message);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import kattsyn.dev.rentplace.auth.JwtAuthentication;
import kattsyn.dev.rentplace.dtos.JwtRequest;
import kattsyn.dev.rentplace.dtos.JwtResponse;
import kattsyn.dev.rentplace.dtos.UserDTO;

public interface AuthService {

Expand All @@ -15,4 +16,6 @@ public interface AuthService {

JwtAuthentication getAuthInfo();

UserDTO getUserInfo() throws AuthException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@

public interface PropertyService {

boolean ownsPropertyOrAdmin(long propertyId, String email);

boolean allowedToCreatePropertyOrAdmin(PropertyCreateEditDTO propertyCreateEditDTO, String email);

List<PropertyDTO> findAll();

PropertyDTO findById(long id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
@Service
public interface ReservationService {

boolean ownsReservationOrAdmin(long reservationId, String email);

boolean allowedToCreateReservationOrAdmin(ReservationCreateEditDTO reservationCreateEditDTO, String email);

Reservation getReservationById(long reservationId);

ReservationDTO getReservationDTOById(long reservationId);
Expand Down
Loading
Loading