Skip to content

Commit

Permalink
refactor #77 : update RegisterMember API logic
Browse files Browse the repository at this point in the history
- Modified RegisterMember API to accommodate the separation of member and account entities.
- Updated data handling and validation processes to align with the new structure.
- Made minimal changes to the login API to ensure basic functionality; further logic improvements are needed.
  • Loading branch information
seonpilKim committed Oct 9, 2024
1 parent 7485a23 commit 684baa4
Show file tree
Hide file tree
Showing 33 changed files with 386 additions and 192 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.titi.titi_auth.adapter.out.persistence;

import org.springframework.stereotype.Component;

import lombok.RequiredArgsConstructor;

import com.titi.titi_auth.application.port.out.persistence.SaveAccountPort;
import com.titi.titi_auth.data.jpa.entity.AccountEntity;
import com.titi.titi_auth.data.jpa.entity.mapper.EntityMapper;
import com.titi.titi_auth.data.jpa.repository.AccountEntityRepository;
import com.titi.titi_auth.domain.Account;

@Component
@RequiredArgsConstructor
public class SaveAccountPortAdapter implements SaveAccountPort {

private final AccountEntityRepository accountEntityRepository;

@Override
public Account invoke(Account account) {
if (account.id() != null) {
throw new IllegalArgumentException("account.id() must be null.");
}
final AccountEntity accountEntity = accountEntityRepository.save(EntityMapper.INSTANCE.toEntity(account));
return EntityMapper.INSTANCE.toDomain(accountEntity);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.titi.titi_auth.application.port.in;

import lombok.Builder;

public interface CreateAccountUseCase {

Result invoke(Command command);

@Builder
record Command(
String username,
String encodedEncryptedPassword
) {

}

@Builder
record Result(
Long accountId
) {

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.titi.titi_auth.application.port.out.persistence;

import com.titi.titi_auth.domain.Account;

public interface SaveAccountPort {

Account invoke(Account account);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.titi.titi_auth.application.service;

import java.nio.charset.StandardCharsets;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import lombok.RequiredArgsConstructor;

import com.titi.titi_auth.application.port.in.CreateAccountUseCase;
import com.titi.titi_auth.application.port.out.persistence.FindAccountPort;
import com.titi.titi_auth.application.port.out.persistence.SaveAccountPort;
import com.titi.titi_auth.common.TiTiAuthBusinessCodes;
import com.titi.titi_auth.common.TiTiAuthException;
import com.titi.titi_auth.domain.Account;
import com.titi.titi_auth.domain.AccountStatus;
import com.titi.titi_auth.domain.Authority;
import com.titi.titi_auth.domain.EncodedEncryptedPassword;

@Service
@RequiredArgsConstructor
public class CreateAccountService implements CreateAccountUseCase {

private final PasswordEncoder passwordEncoder;
private final FindAccountPort findAccountPort;
private final SaveAccountPort saveAccountPort;
@Value("${crypto.secret-key}")
private String secretKey;

@Override
public Result invoke(Command command) {
this.validateUsername(command.username());
final String rawPassword = EncodedEncryptedPassword.builder()
.value(command.encodedEncryptedPassword())
.build()
.getRawPassword(this.secretKey.getBytes(StandardCharsets.UTF_8));
final String encodedEncryptedPassword = this.passwordEncoder.encode(rawPassword);
final Account account = this.saveAccountPort.invoke(
Account.builder()
.username(command.username())
.encodedEncryptedPassword(encodedEncryptedPassword)
.accountStatus(AccountStatus.ACTIVATED)
.authority(Authority.MEMBER)
.build()
);
return Result.builder()
.accountId(account.id())
.build();
}

private void validateUsername(String username) {
final Account account = Account.builder().username(username).build();
if (this.findAccountPort.invoke(account).isPresent()) {
throw new TiTiAuthException(TiTiAuthBusinessCodes.UNAVAILABLE_USERNAME);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public enum TiTiAuthBusinessCodes {

GENERATE_AUTH_CODE_FAILURE(500, "AU7000", "Failed to generate and transmit the authentication code. Please try again later."),
VERIFY_AUTH_CODE_FAILURE(500, "AU7001", "Authentication code verification failed. Please try again later."),
UNAVAILABLE_USERNAME(400, "AU7002", "The username is unavailable."),
CACHE_SERVER_ERROR(500, "AU9000", "Cache server error. Please try again later"),
;

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/titi/titi_auth/domain/Account.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
public record Account(
Long id,
String username,
String password,
String encodedEncryptedPassword,
Authority authority,
AccountStatus accountStatus
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.titi.titi_user.domain.member;
package com.titi.titi_auth.domain;

import java.nio.charset.StandardCharsets;
import java.util.Base64;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
import lombok.Builder;
import lombok.RequiredArgsConstructor;

import com.titi.titi_auth.domain.EncodedEncryptedPassword;
import com.titi.titi_common_lib.util.HttpRequestHeaderParser;
import com.titi.titi_user.application.port.in.LoginUseCase;
import com.titi.titi_user.common.TiTiUserBusinessCodes;
import com.titi.titi_user.domain.member.EncodedEncryptedPassword;

@RestController
@RequiredArgsConstructor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

import com.titi.titi_user.application.port.in.RegisterMemberUseCase;
import com.titi.titi_user.common.TiTiUserBusinessCodes;
import com.titi.titi_user.domain.member.EncodedEncryptedPassword;

@RestController
@RequiredArgsConstructor
Expand All @@ -31,7 +30,7 @@ public ResponseEntity<RegisterMemberResponseBody> registerMember(@Valid @Request
this.registerMemberUseCase.invoke(
RegisterMemberUseCase.Command.builder()
.username(requestBody.username())
.encodedEncryptedPassword(EncodedEncryptedPassword.builder().value(requestBody.encodedEncryptedPassword()).build())
.encodedEncryptedPassword(requestBody.encodedEncryptedPassword())
.nickname(requestBody.nickname())
.authToken(requestBody.authToken())
.build()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.titi.titi_user.adapter.out.auth;

import org.springframework.stereotype.Component;

import lombok.RequiredArgsConstructor;

import com.titi.exception.TiTiException;
import com.titi.titi_auth.application.port.in.CreateAccountUseCase;
import com.titi.titi_user.application.port.out.auth.CreateAccountPort;
import com.titi.titi_user.common.TiTiUserBusinessCodes;
import com.titi.titi_user.common.TiTiUserException;

@Component
@RequiredArgsConstructor
public class CreateAccountPortAdapter implements CreateAccountPort {

private final CreateAccountUseCase createAccountUseCase;

@Override
public Result invoke(Command command) {
try {
final CreateAccountUseCase.Result createAccountResult = this.createAccountUseCase.invoke(
CreateAccountUseCase.Command.builder()
.username(command.username())
.encodedEncryptedPassword(command.encodedEncryptedPassword())
.build()
);
return Result.builder()
.accountId(createAccountResult.accountId())
.build();
} catch (TiTiException e) {
throw new TiTiUserException(TiTiUserBusinessCodes.UNAVAILABLE_USERNAME);
}
}

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.titi.titi_user.adapter.out.internal;
package com.titi.titi_user.adapter.out.auth;

import org.springframework.stereotype.Component;

import lombok.RequiredArgsConstructor;

import com.titi.titi_auth.application.port.in.GenerateAccessTokenUseCase;
import com.titi.titi_user.application.port.out.internal.GenerateAccessTokenPort;
import com.titi.titi_user.application.port.out.auth.GenerateAccessTokenPort;

@Component
@RequiredArgsConstructor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import lombok.Builder;

import com.titi.titi_user.domain.member.EncodedEncryptedPassword;
import com.titi.titi_auth.domain.EncodedEncryptedPassword;

public interface LoginUseCase {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import com.titi.titi_crypto_lib.util.HashingUtils;
import com.titi.titi_user.common.TiTiUserBusinessCodes;
import com.titi.titi_user.common.TiTiUserException;
import com.titi.titi_user.domain.member.EncodedEncryptedPassword;

public interface RegisterMemberUseCase {

Expand All @@ -14,7 +13,7 @@ public interface RegisterMemberUseCase {
@Builder
record Command(
String username,
EncodedEncryptedPassword encodedEncryptedPassword,
String encodedEncryptedPassword,
String nickname,
String authToken
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.titi.titi_user.application.port.out.auth;

import lombok.Builder;

public interface CreateAccountPort {

Result invoke(Command command);

@Builder
record Command(
String username,
String encodedEncryptedPassword
) {

}

@Builder
record Result(
Long accountId
) {

}

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.titi.titi_user.application.port.out.internal;
package com.titi.titi_user.application.port.out.auth;

import lombok.Builder;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import lombok.RequiredArgsConstructor;

import com.titi.titi_user.application.port.in.LoginUseCase;
import com.titi.titi_user.application.port.out.internal.GenerateAccessTokenPort;
import com.titi.titi_user.application.port.out.auth.GenerateAccessTokenPort;
import com.titi.titi_user.application.port.out.persistence.FindMemberPort;
import com.titi.titi_user.application.port.out.persistence.UpdateDeviceLastAccessPort;
import com.titi.titi_user.common.TiTiUserBusinessCodes;
Expand All @@ -33,10 +33,10 @@ class LoginService implements LoginUseCase {
@Override
@Transactional
public Result invoke(Command command) {
final Member member = this.findMemberPort.invoke(Member.builder().username(command.username()).build())
final Member member = this.findMemberPort.invoke(Member.builder()/*.username(command.username())*/.build())
.orElseThrow(() -> new TiTiUserException(TiTiUserBusinessCodes.LOGIN_FAILURE_MISMATCHED_MEMBER_INFORMATION));
final String rawPassword = command.encodedEncryptedPassword().getRawPassword(this.secretKey.getBytes());
this.validatePassword(rawPassword, member);
/*this.validatePassword(rawPassword, member);*/

final String generatedDeviceId = command.deviceId() == null ? UUID.randomUUID().toString() : null;
final Device device = Device.builder()
Expand All @@ -62,10 +62,10 @@ public Result invoke(Command command) {
.build();
}

private void validatePassword(String rawPassword, Member member) {
/*private void validatePassword(String rawPassword, Member member) {
if (!this.passwordEncoder.matches(rawPassword, member.password())) {
throw new TiTiUserException(TiTiUserBusinessCodes.LOGIN_FAILURE_MISMATCHED_MEMBER_INFORMATION);
}
}
}*/

}
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
package com.titi.titi_user.application.service;

import java.nio.charset.StandardCharsets;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;

import com.titi.titi_common_lib.util.JwtUtils;
import com.titi.titi_user.application.common.constant.UserConstants;
import com.titi.titi_user.application.port.in.RegisterMemberUseCase;
import com.titi.titi_user.application.port.out.persistence.FindMemberPort;
import com.titi.titi_user.application.port.out.auth.CreateAccountPort;
import com.titi.titi_user.application.port.out.persistence.SaveMemberPort;
import com.titi.titi_user.common.TiTiUserBusinessCodes;
import com.titi.titi_user.common.TiTiUserException;
import com.titi.titi_user.domain.member.AccountStatus;
import com.titi.titi_user.domain.member.Authority;
import com.titi.titi_user.domain.member.Member;
import com.titi.titi_user.domain.member.MembershipType;
import com.titi.titi_user.domain.member.ProfileImage;
Expand All @@ -25,38 +20,29 @@
@RequiredArgsConstructor
class RegisterMemberService implements RegisterMemberUseCase {

private final PasswordEncoder passwordEncoder;
private final JwtUtils jwtUtils;
private final FindMemberPort findMemberPort;
private final SaveMemberPort saveMemberPort;
@Value("${crypto.secret-key}")
private String secretKey;
private final CreateAccountPort createAccountPort;

@Override
@Transactional
public void invoke(Command command) {
this.validateAuthToken(command);
this.validateUsername(command.username());
final String rawPassword = command.encodedEncryptedPassword().getRawPassword(this.secretKey.getBytes(StandardCharsets.UTF_8));
final String encryptedPassword = this.passwordEncoder.encode(rawPassword);
final CreateAccountPort.Result createAccountResult = this.createAccountPort.invoke(
CreateAccountPort.Command.builder()
.username(command.username())
.encodedEncryptedPassword(command.encodedEncryptedPassword())
.build()
);
final Member member = Member.builder()
.username(command.username())
.password(encryptedPassword)
.accountId(createAccountResult.accountId())
.nickname(command.nickname())
.profileImage(ProfileImage.defaultInstance())
.membershipType(MembershipType.NORMAL)
.accountStatus(AccountStatus.ACTIVATED)
.authority(Authority.MEMBER)
.build();
this.saveMemberPort.invoke(member);
}

private void validateUsername(String username) {
final Member member = Member.builder().username(username).build();
if (this.findMemberPort.invoke(member).isPresent()) {
throw new TiTiUserException(TiTiUserBusinessCodes.REGISTER_MEMBER_FAILURE_ALREADY_EXISTS_USERNAME);
}
}

private void validateAuthToken(Command command) {
try {
final String authKey = this.jwtUtils.getPayloads(command.authToken(), UserConstants.AUTH_TOKEN).getSubject();
Expand Down
Loading

0 comments on commit 684baa4

Please sign in to comment.