Skip to content

Commit 0b644c8

Browse files
committed
feat: add internationalization
1 parent eb8a5ff commit 0b644c8

37 files changed

+518
-457
lines changed

src/main/java/com/github/throyer/common/springboot/configurations/SpringSecurityConfiguration.java

+27-52
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import com.github.throyer.common.springboot.domain.session.service.SessionService;
44
import com.github.throyer.common.springboot.middlewares.AuthorizationMiddleware;
55
import org.springframework.beans.factory.annotation.Autowired;
6-
import org.springframework.beans.factory.annotation.Value;
76
import org.springframework.context.annotation.Bean;
87
import org.springframework.context.annotation.Configuration;
98
import org.springframework.core.annotation.Order;
@@ -14,7 +13,6 @@
1413
import org.springframework.security.config.annotation.web.builders.WebSecurity;
1514
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
1615
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
17-
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
1816
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
1917
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
2018
import org.springframework.stereotype.Component;
@@ -30,58 +28,45 @@
3028
@EnableWebSecurity
3129
@EnableGlobalMethodSecurity(prePostEnabled = true)
3230
public class SpringSecurityConfiguration {
33-
34-
@Autowired
35-
private SessionService sessionService;
3631

37-
@Autowired
38-
private BCryptPasswordEncoder encoder;
32+
private final SessionService sessionService;
33+
private final AuthorizationMiddleware filter;
3934

4035
@Autowired
41-
private AuthorizationMiddleware filter;
42-
43-
private static String SECRET;
44-
45-
public SpringSecurityConfiguration(@Value("${token.secret}") String secret) {
46-
SpringSecurityConfiguration.SECRET = secret;
36+
public SpringSecurityConfiguration(
37+
SessionService sessionService,
38+
AuthorizationMiddleware filter
39+
) {
40+
this.sessionService = sessionService;
41+
this.filter = filter;
4742
}
4843

4944
@Order(1)
5045
@Configuration
5146
public class Api extends WebSecurityConfigurerAdapter {
52-
47+
5348
@Override
5449
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
5550
auth.userDetailsService(sessionService)
56-
.passwordEncoder(encoder);
51+
.passwordEncoder(PASSWORD_ENCODER);
5752
}
58-
53+
5954
@Override
6055
protected void configure(HttpSecurity http) throws Exception {
6156
http
6257
.antMatcher("/api/**")
6358
.authorizeRequests()
64-
.antMatchers(
65-
GET,
66-
"/api",
67-
"/api/documentation/**"
68-
)
59+
.antMatchers(GET, "/api", "/api/documentation/**")
6960
.permitAll()
70-
.antMatchers(
71-
POST,
72-
"/api/users",
73-
"/api/sessions/**",
74-
"/api/recoveries/**",
75-
"/api/documentation/**"
76-
)
61+
.antMatchers(POST, "/api/users", "/api/sessions/**", "/api/recoveries/**", "/api/documentation/**")
7762
.permitAll()
7863
.anyRequest()
7964
.authenticated()
8065
.and()
8166
.csrf()
8267
.disable()
83-
.exceptionHandling()
84-
.authenticationEntryPoint((request, response, exception) -> forbidden(response))
68+
.exceptionHandling()
69+
.authenticationEntryPoint((request, response, exception) -> forbidden(response))
8570
.and()
8671
.sessionManagement()
8772
.sessionCreationPolicy(STATELESS)
@@ -90,50 +75,40 @@ protected void configure(HttpSecurity http) throws Exception {
9075
.cors()
9176
.configurationSource(request -> new CorsConfiguration().applyPermitDefaultValues());
9277
}
93-
78+
9479
@Override
95-
public void configure(WebSecurity web) throws Exception {
80+
public void configure(WebSecurity web) {
9681
web
9782
.ignoring()
9883
.antMatchers(STATIC_FILES);
9984
}
100-
85+
10186
@Bean
10287
@Override
10388
protected AuthenticationManager authenticationManager() throws Exception {
10489
return super.authenticationManager();
10590
}
10691
}
107-
92+
10893
@Order(2)
10994
@Configuration
11095
public class App extends WebSecurityConfigurerAdapter {
11196
@Override
11297
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
11398
auth.
11499
userDetailsService(sessionService)
115-
.passwordEncoder(encoder);
100+
.passwordEncoder(PASSWORD_ENCODER);
116101
}
117-
102+
118103
@Override
119104
protected void configure(HttpSecurity http) throws Exception {
120-
105+
121106
http
122107
.antMatcher("/app/**")
123108
.authorizeRequests()
124-
.antMatchers(
125-
GET,
126-
LOGIN_URL,
127-
"/app",
128-
"/app/register",
129-
"/app/recovery/**"
130-
)
109+
.antMatchers(GET, LOGIN_URL, "/app", "/app/register", "/app/recovery/**")
131110
.permitAll()
132-
.antMatchers(
133-
POST,
134-
"/app/register",
135-
"/app/recovery/**"
136-
)
111+
.antMatchers(POST, "/app/register", "/app/recovery/**")
137112
.permitAll()
138113
.anyRequest()
139114
.authenticated()
@@ -146,11 +121,11 @@ protected void configure(HttpSecurity http) throws Exception {
146121
.defaultSuccessUrl(HOME_URL)
147122
.usernameParameter(USERNAME_PARAMETER)
148123
.passwordParameter(PASSWORD_PARAMETER)
149-
.and()
124+
.and()
150125
.rememberMe()
151-
.key(SECRET)
126+
.key(TOKEN_SECRET)
152127
.tokenValiditySeconds(DAY_MILLISECONDS)
153-
.and()
128+
.and()
154129
.logout()
155130
.deleteCookies(SESSION_COOKIE_NAME)
156131
.logoutRequestMatcher(new AntPathRequestMatcher(LOGOUT_URL))

src/main/java/com/github/throyer/common/springboot/configurations/SpringWebConfiguration.java

-5
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,6 @@ public void addCorsMappings(CorsRegistry registry) {
5151
.allowedHeaders("*");
5252
}
5353

54-
@Bean
55-
public BCryptPasswordEncoder passwordEncoder() {
56-
return new BCryptPasswordEncoder();
57-
}
58-
5954
@Bean
6055
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
6156
return new SecurityEvaluationContextExtension();

src/main/java/com/github/throyer/common/springboot/controllers/api/UsersController.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
import com.github.throyer.common.springboot.domain.pagination.model.Page;
1010
import com.github.throyer.common.springboot.domain.user.service.FindUserService;
1111
import com.github.throyer.common.springboot.domain.user.service.RemoveUserService;
12-
import com.github.throyer.common.springboot.domain.user.model.CreateUserProps;
12+
import com.github.throyer.common.springboot.domain.user.form.CreateUserProps;
1313
import com.github.throyer.common.springboot.domain.user.service.CreateUserService;
14-
import com.github.throyer.common.springboot.domain.user.model.UpdateUserProps;
14+
import com.github.throyer.common.springboot.domain.user.form.UpdateUserProps;
1515
import com.github.throyer.common.springboot.domain.user.service.FindUserByIdService;
1616
import com.github.throyer.common.springboot.domain.user.service.UpdateUserService;
1717
import com.github.throyer.common.springboot.domain.user.model.UserDetails;

src/main/java/com/github/throyer/common/springboot/controllers/app/RegisterController.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import static com.github.throyer.common.springboot.domain.toast.Type.SUCCESS;
44
import static com.github.throyer.common.springboot.utils.Responses.validateAndUpdateModel;
55

6-
import com.github.throyer.common.springboot.domain.user.model.CreateUserProps;
6+
import com.github.throyer.common.springboot.domain.user.form.CreateUserProps;
77
import com.github.throyer.common.springboot.domain.user.service.CreateUserService;
88
import com.github.throyer.common.springboot.domain.toast.Toasts;
99

src/main/java/com/github/throyer/common/springboot/domain/mail/exceptions/EmailNotUniqueException.java

-36
This file was deleted.

src/main/java/com/github/throyer/common/springboot/domain/mail/validation/EmailValidations.java

+10-7
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
package com.github.throyer.common.springboot.domain.mail.validation;
22

3-
import com.github.throyer.common.springboot.domain.mail.exceptions.EmailNotUniqueException;
43
import com.github.throyer.common.springboot.domain.mail.model.Addressable;
54
import com.github.throyer.common.springboot.domain.user.repository.UserRepository;
5+
import com.github.throyer.common.springboot.errors.exceptions.BadRequestException;
6+
import com.github.throyer.common.springboot.errors.model.ValidationError;
67
import org.springframework.beans.factory.annotation.Autowired;
78
import org.springframework.stereotype.Component;
89
import org.springframework.validation.BindingResult;
910
import org.springframework.validation.ObjectError;
1011

11-
import static com.github.throyer.common.springboot.utils.Constants.MAIL.*;
12+
import java.util.List;
13+
14+
import static com.github.throyer.common.springboot.utils.Constants.MESSAGES.EMAIL_ALREADY_USED_MESSAGE;
15+
import static com.github.throyer.common.springboot.utils.Messages.message;
1216

1317
@Component
1418
public class EmailValidations {
@@ -22,18 +26,17 @@ public EmailValidations(UserRepository repository) {
2226

2327
public static void validateEmailUniqueness(Addressable entity) {
2428
if (repository.existsByEmail(entity.getEmail())) {
25-
throw new EmailNotUniqueException(EMAIL_ERROR);
29+
throw new BadRequestException(List.of(new ValidationError("email", message(EMAIL_ALREADY_USED_MESSAGE))));
2630
}
2731
}
2832

2933
public static void validateEmailUniqueness(Addressable entity, BindingResult result) {
3034
if (repository.existsByEmail(entity.getEmail())) {
31-
result.addError(new ObjectError(EMAIL_FIELD, EMAIL_ALREADY_USED_MESSAGE));
35+
result.addError(new ObjectError("email", message(EMAIL_ALREADY_USED_MESSAGE)));
3236
}
3337
}
3438

3539
public static void validateEmailUniquenessOnModify(Addressable newEntity, Addressable actualEntity) {
36-
3740
var newEmail = newEntity.getEmail();
3841
var actualEmail = actualEntity.getEmail();
3942

@@ -42,7 +45,7 @@ public static void validateEmailUniquenessOnModify(Addressable newEntity, Addres
4245
var emailAlreadyUsed = repository.existsByEmail(newEmail);
4346

4447
if (changedEmail && emailAlreadyUsed) {
45-
throw new EmailNotUniqueException(EMAIL_ERROR);
48+
throw new BadRequestException(List.of(new ValidationError("email", message(EMAIL_ALREADY_USED_MESSAGE))));
4649
}
4750
}
4851

@@ -60,7 +63,7 @@ public static void validateEmailUniquenessOnModify(
6063
var emailAlreadyUsed = repository.existsByEmail(newEmail);
6164

6265
if (changedEmail && emailAlreadyUsed) {
63-
result.addError(new ObjectError(EMAIL_FIELD, EMAIL_ALREADY_USED_MESSAGE));
66+
result.addError(new ObjectError("email", message(EMAIL_ALREADY_USED_MESSAGE)));
6467
}
6568
}
6669
}

src/main/java/com/github/throyer/common/springboot/domain/pagination/model/Page.java

+10-21
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
package com.github.throyer.common.springboot.domain.pagination.model;
22

3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
import lombok.Getter;
5+
36
import static com.github.throyer.common.springboot.utils.JsonUtils.toJson;
47
import java.util.Collection;
8+
import java.util.List;
59

10+
@Getter
11+
@Schema(requiredProperties = {"content", "page", "size", "totalPages", "totalElements"})
612
public class Page<T> {
713
private final Collection<T> content;
814
private final Integer page;
@@ -26,27 +32,6 @@ public Page(Collection<T> content, Integer page, Integer size, Long count) {
2632
this.totalElements = count;
2733
}
2834

29-
30-
public Collection<T> getContent() {
31-
return content;
32-
}
33-
34-
public Integer getPage() {
35-
return page;
36-
}
37-
38-
public Integer getSize() {
39-
return size;
40-
}
41-
42-
public Long getTotalElements() {
43-
return totalElements;
44-
}
45-
46-
public Integer getTotalPages() {
47-
return totalPages;
48-
}
49-
5035
public static <T> Page<T> of(org.springframework.data.domain.Page<T> page) {
5136
return new Page<>(page);
5237
}
@@ -55,6 +40,10 @@ public static <T> Page<T> of(Collection<T> content, Integer page, Integer size,
5540
return new Page<>(content, page, size, count);
5641
}
5742

43+
public static <T> Page<T> empty() {
44+
return new Page<>(List.of(), 0, 0, 0L);
45+
}
46+
5847
@Override
5948
public String toString() {
6049
return toJson(this);
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,19 @@
11
package com.github.throyer.common.springboot.domain.recovery.model;
22

3+
import lombok.Getter;
4+
import lombok.Setter;
5+
36
import javax.validation.constraints.Email;
47
import javax.validation.constraints.NotEmpty;
5-
import javax.validation.constraints.NotNull;
68

9+
@Getter
10+
@Setter
711
public class RecoveryConfirm {
812

9-
@Email
10-
@NotNull
11-
@NotEmpty
13+
@Email(message = "{recovery.email.is-valid}")
14+
@NotEmpty(message = "{recovery.email.not-empty}")
1215
private String email;
1316

14-
@Email
15-
@NotNull
16-
@NotEmpty
17+
@NotEmpty(message = "{recovery.code.not-empty}")
1718
private String code;
18-
19-
public String getEmail() {
20-
return email;
21-
}
22-
23-
public void setEmail(String email) {
24-
this.email = email;
25-
}
26-
27-
public String getCode() {
28-
return code;
29-
}
30-
31-
public void setCode(String code) {
32-
this.code = code;
33-
}
3419
}

0 commit comments

Comments
 (0)