Skip to content

Commit c9e49b7

Browse files
authored
Merge pull request #174 from gelecekbilimde/GBS-55/username-create
GBS-55 | Username Created
2 parents 45b40b4 + 4c51f2d commit c9e49b7

File tree

12 files changed

+114
-9
lines changed

12 files changed

+114
-9
lines changed

src/main/java/org/gelecekbilimde/scienceplatform/auth/model/request/RegisterRequest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import lombok.Getter;
99
import lombok.NoArgsConstructor;
1010
import lombok.Setter;
11+
import org.gelecekbilimde.scienceplatform.common.util.validation.Username;
1112
import org.gelecekbilimde.scienceplatform.user.model.enums.UserDegree;
1213
import org.gelecekbilimde.scienceplatform.user.model.enums.UserGender;
1314

@@ -28,6 +29,10 @@ public class RegisterRequest {
2829
@Size(min = 2, max = 25)
2930
private String lastname;
3031

32+
@NotBlank
33+
@Username
34+
private String username;
35+
3136
@NotBlank
3237
@Email
3338
@Size(min = 8, max = 255)

src/main/java/org/gelecekbilimde/scienceplatform/auth/service/impl/RegistrationServiceImpl.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.gelecekbilimde.scienceplatform.auth.model.request.VerifyRequest;
1313
import org.gelecekbilimde.scienceplatform.auth.port.RoleReadPort;
1414
import org.gelecekbilimde.scienceplatform.auth.service.RegistrationService;
15+
import org.gelecekbilimde.scienceplatform.user.exception.UsernameAlreadyTakenException;
1516
import org.gelecekbilimde.scienceplatform.user.model.User;
1617
import org.gelecekbilimde.scienceplatform.user.model.UserVerification;
1718
import org.gelecekbilimde.scienceplatform.user.model.enums.UserStatus;
@@ -48,9 +49,14 @@ public void register(RegisterRequest request) {
4849
Role role = roleReadPort.findByName(RoleName.USER)
4950
.orElseThrow(() -> new RoleNotFoundByNameException(RoleName.USER.name()));
5051

52+
if (userReadPort.existsByUsername(request.getUsername())) {
53+
throw new UsernameAlreadyTakenException(request.getUsername());
54+
}
55+
5156
User user = User.builder()
5257
.firstName(request.getFirstname())
5358
.lastName(request.getLastname())
59+
.username(request.getUsername().toLowerCase())
5460
.email(request.getEmail())
5561
.birthDate(request.getBirthDate())
5662
.biography(request.getBiography())
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.gelecekbilimde.scienceplatform.common.util.validation;
2+
3+
import jakarta.validation.Constraint;
4+
import jakarta.validation.Payload;
5+
6+
import java.lang.annotation.ElementType;
7+
import java.lang.annotation.Retention;
8+
import java.lang.annotation.RetentionPolicy;
9+
import java.lang.annotation.Target;
10+
11+
@Target(value = ElementType.FIELD)
12+
@Retention(RetentionPolicy.RUNTIME)
13+
@Constraint(validatedBy = UsernameValidator.class)
14+
public @interface Username {
15+
16+
String message() default "must be valid";
17+
18+
Class<?>[] groups() default {};
19+
20+
Class<? extends Payload>[] payload() default {};
21+
22+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package org.gelecekbilimde.scienceplatform.common.util.validation;
2+
3+
import jakarta.validation.ConstraintValidator;
4+
import jakarta.validation.ConstraintValidatorContext;
5+
import org.springframework.util.StringUtils;
6+
7+
class UsernameValidator implements ConstraintValidator<Username, String> {
8+
9+
private static final String USERNAME_REGEX = "^[a-zA-Z0-9]{3,20}$";
10+
11+
@Override
12+
public boolean isValid(String value, ConstraintValidatorContext context) {
13+
if (!StringUtils.hasText(value)) {
14+
return true;
15+
}
16+
17+
String lowerCasedValue = value.toLowerCase();
18+
19+
if (!value.trim().equals(value)) {
20+
context.disableDefaultConstraintViolation();
21+
context.buildConstraintViolationWithTemplate("name must not start or end with whitespace")
22+
.addConstraintViolation();
23+
return false;
24+
}
25+
26+
if (value.length() <= 3 || value.length() >= 20) {
27+
context.disableDefaultConstraintViolation();
28+
context.buildConstraintViolationWithTemplate("must be between 3 and 20 characters long")
29+
.addConstraintViolation();
30+
return false;
31+
}
32+
33+
if (!lowerCasedValue.matches(USERNAME_REGEX)) {
34+
context.disableDefaultConstraintViolation();
35+
context.buildConstraintViolationWithTemplate("must be alphanumeric")
36+
.addConstraintViolation();
37+
return false;
38+
}
39+
40+
return true;
41+
}
42+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.gelecekbilimde.scienceplatform.user.exception;
2+
3+
import org.gelecekbilimde.scienceplatform.common.exception.AbstractConflictException;
4+
5+
import java.io.Serial;
6+
7+
public final class UsernameAlreadyTakenException extends AbstractConflictException {
8+
9+
@Serial
10+
private static final long serialVersionUID = -3365493595680402581L;
11+
12+
public UsernameAlreadyTakenException(String username) {
13+
super(String.format("'%s' username already taken", username));
14+
}
15+
16+
}

src/main/java/org/gelecekbilimde/scienceplatform/user/model/User.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public class User extends BaseDomainModel {
2323
private String password;
2424
private String firstName;
2525
private String lastName;
26+
private String username;
2627
private String avatarPath;
2728
private String biography;
2829
private LocalDate birthDate;

src/main/java/org/gelecekbilimde/scienceplatform/user/model/entity/UserEntity.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ public class UserEntity extends BaseEntity {
5656
@Column(name = "last_name")
5757
private String lastName;
5858

59+
@Column(name = "username")
60+
private String username;
61+
5962
@Column(name = "avatar_path")
6063
private String avatar;
6164

src/main/java/org/gelecekbilimde/scienceplatform/user/port/UserReadPort.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ public interface UserReadPort {
1212

1313
boolean existsByEmail(String email);
1414

15+
boolean existsByUsername(String username);
1516
}

src/main/java/org/gelecekbilimde/scienceplatform/user/port/adapter/UserAdapter.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ public boolean existsByEmail(final String email) {
4343
}
4444

4545

46+
@Override
47+
public boolean existsByUsername(String username) {
48+
return userRepository.existsByUsername(username);
49+
}
50+
51+
4652
@Override
4753
public User save(User user) {
4854
final UserEntity userEntity = userToEntityMapper.map(user);

src/main/java/org/gelecekbilimde/scienceplatform/user/repository/UserRepository.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,6 @@ public interface UserRepository extends JpaRepository<UserEntity, String> {
1010
Optional<UserEntity> findByEmail(String email);
1111

1212
boolean existsByEmail(String email);
13+
14+
boolean existsByUsername(String username);
1315
}

0 commit comments

Comments
 (0)