Skip to content

Commit cadcee8

Browse files
Staging (#106)
1 parent abf03b4 commit cadcee8

15 files changed

Lines changed: 127 additions & 23 deletions

pom.xml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,25 @@
135135
<artifactId>jjwt-impl</artifactId>
136136
<version>0.11.5</version>
137137
</dependency>
138+
<dependency>
139+
<groupId>net.coobird</groupId>
140+
<artifactId>thumbnailator</artifactId>
141+
<version>0.4.20</version>
142+
</dependency>
143+
<dependency>
144+
<groupId>org.apache.commons</groupId>
145+
<artifactId>commons-lang3</artifactId>
146+
<version>3.14.0</version>
147+
</dependency>
148+
<dependency>
149+
<groupId>com.fasterxml.jackson.core</groupId>
150+
<artifactId>jackson-databind</artifactId>
151+
</dependency>
152+
<dependency>
153+
<groupId>com.fasterxml.jackson.core</groupId>
154+
<artifactId>jackson-databind</artifactId>
155+
<version>2.15.0</version>
156+
</dependency>
138157
<dependency>
139158
<groupId>io.jsonwebtoken</groupId>
140159
<artifactId>jjwt-jackson</artifactId>

src/main/java/com/back_alasso/BackendProjectTemplateApplication.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
package com.back_alasso;
22

33
import com.back_alasso.config.InitLogger;
4+
import com.fasterxml.jackson.core.StreamReadConstraints;
45
import org.springframework.boot.SpringApplication;
56
import org.springframework.boot.autoconfigure.SpringBootApplication;
7+
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
68
import org.springframework.context.ApplicationContext;
79
import org.springframework.context.annotation.Bean;
810
import org.springframework.web.client.RestTemplate;
911

1012
@SpringBootApplication
1113
public class BackendProjectTemplateApplication {
1214

15+
private final int ONE_HUNDRED_THOUSAND = 100_000_000;
16+
1317
public static void main(String[] args) {
18+
System.setProperty("spring.jackson.parser.allow-unquoted-field-names", "true");
1419
ApplicationContext context = SpringApplication.run(BackendProjectTemplateApplication.class, args);
1520
InitLogger logger = new InitLogger();
1621
logger.logCurrentEnvironment(context);
@@ -20,4 +25,12 @@ public static void main(String[] args) {
2025
public RestTemplate restTemplate() {
2126
return new RestTemplate();
2227
}
28+
29+
@Bean
30+
public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() {
31+
return builder ->
32+
builder.postConfigurer(mapper ->
33+
mapper.getFactory().setStreamReadConstraints(StreamReadConstraints.builder().maxStringLength(ONE_HUNDRED_THOUSAND).build())
34+
);
35+
}
2336
}

src/main/java/com/back_alasso/features/Activity/ActivityController.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ public ResponseEntity<List<ActivityResponseDTO>> getPastActivities(@Authenticati
4242
return ResponseEntity.ok(activities);
4343
}
4444

45+
@GetMapping("/draft")
46+
public ResponseEntity<List<ActivityResponseDTO>> getDraftActivities(@AuthenticationPrincipal UserDetails userDetails) {
47+
UUID authenticatedUserId = userService.getAuthenticatedUserId(userDetails);
48+
List<ActivityResponseDTO> activities = activityService.getDraftActivities(authenticatedUserId);
49+
return ResponseEntity.ok(activities);
50+
}
51+
4552
@GetMapping("/{activityId}")
4653
public ResponseEntity<ActivityResponseDTO> getActivityById(@AuthenticationPrincipal UserDetails userDetails, @PathVariable UUID activityId) {
4754
UUID authenticatedUserId = userService.getAuthenticatedUserId(userDetails);

src/main/java/com/back_alasso/features/Activity/ActivityRepository.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.back_alasso.features.Activity;
22

3+
import com.back_alasso.features.Activity.DTO.ActivityStatusEnumType;
34
import com.back_alasso.features.Voluntary.Voluntary;
45
import java.time.LocalDateTime;
56
import java.util.List;
@@ -44,6 +45,15 @@ public interface ActivityRepository extends JpaRepository<Activity, UUID> {
4445
)
4546
List<Activity> findAllFromNotBannedAssociationsAndPast(@Param("now") LocalDateTime now);
4647

48+
@Query(
49+
"""
50+
SELECT a
51+
FROM Activity a
52+
WHERE a.association.account_status <> 'BANNED' AND a.status = :status
53+
"""
54+
)
55+
List<Activity> findAllFromNotBannedAssociationsAndDraft(@Param("status") ActivityStatusEnumType status);
56+
4757
@Query(
4858
"""
4959
SELECT a

src/main/java/com/back_alasso/features/Activity/ActivityService.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.back_alasso.exception.ResourceNotFoundException;
44
import com.back_alasso.features.Activity.DTO.ActivityResponseDTO;
55
import com.back_alasso.features.Activity.DTO.ActivitySaveRequestDTO;
6+
import com.back_alasso.features.Activity.DTO.ActivityStatusEnumType;
67
import com.back_alasso.features.ActivityImage.ActivityImageService;
78
import com.back_alasso.features.ActivityTheme.ActivityThemeService;
89
import com.back_alasso.features.Address.Address;
@@ -62,6 +63,12 @@ public List<ActivityResponseDTO> getPastActivities(UUID authenticatedUserId) {
6263
return activities.stream().map(activity -> activityResponseMapper.fromEntityToDTO(activity, authenticatedUserId)).toList();
6364
}
6465

66+
public List<ActivityResponseDTO> getDraftActivities(UUID authenticatedUserId) {
67+
List<Activity> activities = activityRepository.findAllFromNotBannedAssociationsAndDraft(ActivityStatusEnumType.draft);
68+
69+
return activities.stream().map(activity -> activityResponseMapper.fromEntityToDTO(activity, authenticatedUserId)).toList();
70+
}
71+
6572
public ActivityResponseDTO getMappedActivityById(UUID authenticatedUserId, UUID activityId) {
6673
Activity activity = getActivityById(activityId);
6774

src/main/java/com/back_alasso/features/Activity/DTO/ActivitySaveRequestDTO.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.back_alasso.features.Image.DTO.ImageActivityCreationRequestDTO;
66
import com.back_alasso.features.Theme.ThemeNameEnumType;
77
import jakarta.validation.Valid;
8+
import jakarta.validation.constraints.Min;
89
import jakarta.validation.constraints.NotBlank;
910
import jakarta.validation.constraints.NotEmpty;
1011
import jakarta.validation.constraints.NotNull;
@@ -31,7 +32,8 @@ public class ActivitySaveRequestDTO {
3132
@NotBlank(groups = OnPublish.class)
3233
private String title;
3334

34-
@NotNull(groups = OnPublish.class)
35+
@NotNull(groups = OnPublish.class, message = "Le nombre de volontaires est obligatoire")
36+
@Min(groups = OnPublish.class, value = 1, message = "Le nombre de volontaires doit être supérieur à 0")
3537
private Long requestedVolunteers;
3638

3739
@NotNull(groups = OnPublish.class)

src/main/java/com/back_alasso/features/Association/AssociationService.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ public void uploadCover(UUID associationId, MultipartFile coverFile) {
133133
uploadAssociationImage(associationId, coverFile, ImageEnumType.PROFILE_ASSOCIATION);
134134
}
135135

136+
@Transactional
136137
private void uploadAssociationImage(UUID associationId, MultipartFile file, ImageEnumType type) {
137138
Association association = associationRepository.findById(associationId).orElseThrow(() -> new ResourceNotFoundException("Association not found"));
138139

src/main/java/com/back_alasso/features/Authentication/AuthController.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import jakarta.validation.Validator;
1818
import java.util.HashMap;
1919
import java.util.Map;
20+
import java.util.UUID;
2021
import lombok.RequiredArgsConstructor;
2122
import org.springframework.beans.factory.annotation.Autowired;
2223
import org.springframework.http.HttpStatus;
@@ -39,6 +40,16 @@ public class AuthController {
3940
private final AssociationLoginResponseMapper associationLoginResponseMapper;
4041
private final LoginRateLimitFilter loginRateLimitFilter;
4142

43+
@GetMapping("/token")
44+
public ResponseEntity<Map<String, Object>> getUserByToken(@AuthenticationPrincipal UserDetails userDetails) {
45+
UUID authenticatedUserId = userService.getAuthenticatedUserId(userDetails);
46+
User user = userService.findById(authenticatedUserId);
47+
48+
Map<String, Object> response = new HashMap<>();
49+
authService.addUserToResponse(user, response);
50+
return ResponseEntity.ok(response);
51+
}
52+
4253
@PostMapping("/register/voluntary")
4354
public ResponseEntity<Boolean> register(@Valid @RequestBody VoluntaryRegistrationDTO voluntaryRegistrationDTO) {
4455
userService.checkUserExists(voluntaryRegistrationDTO.email());
@@ -48,7 +59,7 @@ public ResponseEntity<Boolean> register(@Valid @RequestBody VoluntaryRegistratio
4859
}
4960

5061
@PostMapping("/register/association")
51-
public ResponseEntity<Boolean> register(@RequestBody AssociationRegistrationDTO associationRegistrationDTO) {
62+
public ResponseEntity<Boolean> register(@Valid @RequestBody AssociationRegistrationDTO associationRegistrationDTO) {
5263
validator.validate(associationRegistrationDTO, OnPublish.class);
5364

5465
userService.checkUserExists(associationRegistrationDTO.email());

src/main/java/com/back_alasso/features/Authentication/ValidationConstants.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ public class ValidationConstants {
77
public static final int MIN_PASSWORD_LENGTH = 8;
88
public static final String SIRET_REGEX = "^\\d{14}$";
99
public static final String PASSWORD_REGEX = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*()_\\-+=\\[\\]{};':\"\\\\|,.<>/?]).{8,}$";
10-
public static final String PHONE_REGEX = "^(\\+33|0)[1-9](\\d{2}){4}$";
10+
public static final String PHONE_REGEX = "^(|(?:\\+33|0)[1-9](\\d{2}){4})$";
1111
}

src/main/java/com/back_alasso/features/Image/ImageService.java

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,18 @@
22

33
import com.back_alasso.exception.ResourceNotFoundException;
44
import com.back_alasso.features.Image.DTO.ImageActivityCreationRequestDTO;
5+
import java.awt.image.BufferedImage;
6+
import java.io.ByteArrayInputStream;
7+
import java.io.ByteArrayOutputStream;
58
import java.io.IOException;
69
import java.util.ArrayList;
710
import java.util.Base64;
811
import java.util.Collections;
912
import java.util.List;
1013
import java.util.UUID;
14+
import javax.imageio.ImageIO;
1115
import lombok.RequiredArgsConstructor;
16+
import net.coobird.thumbnailator.Thumbnails;
1217
import org.apache.commons.lang3.StringUtils;
1318
import org.springframework.stereotype.Service;
1419
import org.springframework.web.multipart.MultipartFile;
@@ -18,6 +23,27 @@
1823
public class ImageService {
1924

2025
private final ImageRepository imageRepository;
26+
private final double ZERO_POINT_SIX = 0.6;
27+
private final double ONE = 1.0;
28+
29+
private byte[] compressImage(byte[] originalBytes, double targetQuality, double scale) throws IOException {
30+
ByteArrayInputStream inputStream = new ByteArrayInputStream(originalBytes);
31+
BufferedImage originalImage = ImageIO.read(inputStream);
32+
33+
if (originalImage == null) {
34+
throw new IOException("Impossible de lire l'image");
35+
}
36+
37+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
38+
39+
Thumbnails.of(originalImage)
40+
.scale(scale) // ex: 1.0 garde la taille, <1.0 réduit
41+
.outputQuality(targetQuality) // qualité JPEG/WebP (0.0 à 1.0)
42+
.outputFormat("jpeg")
43+
.toOutputStream(outputStream);
44+
45+
return outputStream.toByteArray();
46+
}
2147

2248
public List<Image> processImages(List<ImageActivityCreationRequestDTO> imageDTOs) {
2349
if (imageDTOs == null || imageDTOs.isEmpty()) return Collections.emptyList();
@@ -36,11 +62,17 @@ public List<Image> processImages(List<ImageActivityCreationRequestDTO> imageDTOs
3662
}
3763
byte[] imageData = Base64.getDecoder().decode(base64);
3864

39-
Image image = new Image();
40-
image.setData(imageData);
41-
image.setType(ImageEnumType.ACTIVITY);
42-
image.setUrl("");
43-
newImages.add(image);
65+
try {
66+
byte[] compressed = compressImage(imageData, ZERO_POINT_SIX, ONE);
67+
68+
Image image = new Image();
69+
image.setData(compressed);
70+
image.setType(ImageEnumType.ACTIVITY);
71+
image.setUrl("");
72+
newImages.add(image);
73+
} catch (IOException e) {
74+
throw new RuntimeException("Erreur lors de la compression de l'image", e);
75+
}
4476
}
4577
}
4678

@@ -56,12 +88,16 @@ public Image uploadImage(MultipartFile file, ImageEnumType type, String folder)
5688

5789
validateExtension(extension);
5890

91+
byte[] originalData = file.getBytes();
92+
93+
byte[] compressedData = compressImage(originalData, ZERO_POINT_SIX, ONE);
94+
5995
String cleanedFilename = cleanFilename(originalFilename != null ? originalFilename : type.name().toLowerCase());
6096
String uniqueFilename = UUID.randomUUID() + "_" + cleanedFilename;
6197
String url = "/images/" + folder + "/" + uniqueFilename;
6298

6399
Image image = new Image();
64-
image.setData(file.getBytes());
100+
image.setData(compressedData);
65101
image.setType(type);
66102
image.setFilename(uniqueFilename);
67103
image.setFormat(extension);

0 commit comments

Comments
 (0)