-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* build: actuator 추가 * feat: 세션 그룹을 저장하고 조회하는 기능 추가 * build: 세션 그룹 스키마 작성 * feat: 세션 그룹 조회, 생성, 삭제 기능 구현 * feat: 세션 그룹 객체 및 업데이트 메서드 추가 * refactor: 세션 생성 시 만료일 파라미터 삭제 * feat: HttpSession -> SessionGroup으로 변경 * build: flyway V7 작성 * fix: 세션 연장을 위한 `@Transactional` 추가 * refactor: 세션 커스텀 예외 생성 * chore: 테스트 컨벤션 수정 * refactor: 세션 만료 설정 추가 * chore: 메서드 명 및 컨벤션 수정
- Loading branch information
1 parent
52cd1ed
commit 5abeafc
Showing
20 changed files
with
663 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
backend/pium/src/main/java/com/official/pium/config/TimeConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.official.pium.config; | ||
|
||
import java.time.Clock; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
@Configuration | ||
public class TimeConfig { | ||
|
||
@Bean | ||
public Clock clock() { | ||
return Clock.systemDefaultZone(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 2 additions & 2 deletions
4
backend/pium/src/main/java/com/official/pium/controller/GlobalExceptionHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
98 changes: 98 additions & 0 deletions
98
backend/pium/src/main/java/com/official/pium/domain/SessionGroup.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package com.official.pium.domain; | ||
|
||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.Table; | ||
import jakarta.validation.constraints.NotBlank; | ||
import jakarta.validation.constraints.NotNull; | ||
import java.time.LocalDateTime; | ||
import java.time.temporal.ChronoUnit; | ||
import java.util.Objects; | ||
import lombok.AccessLevel; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import org.hibernate.proxy.HibernateProxy; | ||
|
||
@Entity | ||
@Getter | ||
@Table(name = "session_group") | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class SessionGroup extends BaseEntity { | ||
|
||
private static final int SESSION_EXTEND_DAYS = 7; | ||
private static final int MIN_EXPIRE_DAY = 1; | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
|
||
@NotBlank | ||
@Column(name = "session_id", nullable = false) | ||
private String sessionId; | ||
|
||
@NotBlank | ||
@Column(name = "session_key", nullable = false) | ||
private String sessionKey; | ||
|
||
@NotBlank | ||
@Column(name = "session_value", nullable = false) | ||
private String sessionValue; | ||
|
||
@NotNull | ||
@Column(name = "expire_time", nullable = false) | ||
private LocalDateTime expireTime; | ||
|
||
@Builder | ||
private SessionGroup(String sessionId, String sessionKey, String sessionValue, LocalDateTime expireTime) { | ||
this.sessionId = sessionId; | ||
this.sessionKey = sessionKey; | ||
this.sessionValue = sessionValue; | ||
this.expireTime = expireTime; | ||
} | ||
|
||
public boolean isExpired(LocalDateTime currentTime) { | ||
return expireTime.isBefore(currentTime); | ||
} | ||
|
||
public boolean canExtends(LocalDateTime currentTime) { | ||
return ChronoUnit.DAYS.between(currentTime, expireTime) < SESSION_EXTEND_DAYS; | ||
} | ||
|
||
public void extendExpireTime(long extendDay) { | ||
if (extendDay < MIN_EXPIRE_DAY) { | ||
throw new IllegalArgumentException("세션 연장 가능 일수는 음수가 될 수 없습니다."); | ||
} | ||
this.expireTime = this.expireTime.plusDays(extendDay); | ||
} | ||
|
||
@Override | ||
public final boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null) { | ||
return false; | ||
} | ||
Class<?> oEffectiveClass = | ||
o instanceof HibernateProxy ? ((HibernateProxy) o).getHibernateLazyInitializer().getPersistentClass() | ||
: o.getClass(); | ||
Class<?> thisEffectiveClass = | ||
this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer() | ||
.getPersistentClass() : this.getClass(); | ||
if (thisEffectiveClass != oEffectiveClass) { | ||
return false; | ||
} | ||
SessionGroup sessionGroup = (SessionGroup) o; | ||
return getId() != null && Objects.equals(getId(), sessionGroup.getId()); | ||
} | ||
|
||
@Override | ||
public final int hashCode() { | ||
return this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer() | ||
.getPersistentClass().hashCode() : getClass().hashCode(); | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
backend/pium/src/main/java/com/official/pium/exception/AuthenticationException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.official.pium.exception; | ||
|
||
public class AuthenticationException extends RuntimeException { | ||
|
||
public AuthenticationException(String message) { | ||
super(message); | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
backend/pium/src/main/java/com/official/pium/repository/SessionGroupRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.official.pium.repository; | ||
|
||
import com.official.pium.domain.SessionGroup; | ||
import java.util.Optional; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface SessionGroupRepository extends JpaRepository<SessionGroup, Long> { | ||
|
||
Optional<SessionGroup> findBySessionIdAndSessionKey(String sessionId, String sessionKey); | ||
} |
69 changes: 69 additions & 0 deletions
69
backend/pium/src/main/java/com/official/pium/service/SessionGroupService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package com.official.pium.service; | ||
|
||
import com.official.pium.domain.SessionGroup; | ||
import com.official.pium.exception.AuthenticationException; | ||
import com.official.pium.repository.SessionGroupRepository; | ||
import java.time.Clock; | ||
import java.time.LocalDateTime; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@Service | ||
@Transactional(readOnly = true) | ||
@RequiredArgsConstructor | ||
public class SessionGroupService { | ||
|
||
private static final int EXTEND_EXPIRED_DAY = 30; | ||
|
||
private final SessionGroupRepository sessionGroupRepository; | ||
private final Clock clock; | ||
|
||
@Transactional | ||
public String findOrExtendsBySessionIdAndKey(String sessionId, String key) { | ||
SessionGroup sessionGroup = sessionGroupRepository.findBySessionIdAndSessionKey(sessionId, key) | ||
.orElseThrow(() -> new AuthenticationException("일치하는 세션을 찾을 수 없습니다.")); | ||
|
||
LocalDateTime currentTime = LocalDateTime.now(clock); | ||
validateSession(sessionGroup, currentTime); | ||
extendsSession(sessionGroup, currentTime); | ||
return sessionGroup.getSessionValue(); | ||
} | ||
|
||
private void validateSession(SessionGroup sessionGroup, LocalDateTime currentTime) throws AuthenticationException { | ||
if (sessionGroup.isExpired(currentTime)) { | ||
sessionGroupRepository.delete(sessionGroup); | ||
throw new AuthenticationException("세션이 만료 되었습니다."); | ||
} | ||
} | ||
|
||
private void extendsSession(SessionGroup sessionGroup, LocalDateTime currentTime) { | ||
if (sessionGroup.canExtends(currentTime)) { | ||
sessionGroup.extendExpireTime(EXTEND_EXPIRED_DAY); | ||
} | ||
} | ||
|
||
@Transactional | ||
public void add(String sessionId, String key, String value) { | ||
sessionGroupRepository.findBySessionIdAndSessionKey(sessionId, key) | ||
.ifPresent(existsSessionGroup -> { | ||
throw new AuthenticationException("이미 존재하는 세션입니다. sessionId: " + sessionId); | ||
}); | ||
|
||
SessionGroup sessionGroup = SessionGroup.builder() | ||
.sessionId(sessionId) | ||
.sessionKey(key) | ||
.sessionValue(value) | ||
.expireTime(LocalDateTime.now().plusMinutes(EXTEND_EXPIRED_DAY)) | ||
.build(); | ||
sessionGroupRepository.save(sessionGroup); | ||
} | ||
|
||
@Transactional | ||
public void delete(String sessionId, String key) { | ||
SessionGroup sessionGroup = sessionGroupRepository.findBySessionIdAndSessionKey(sessionId, key) | ||
.orElseThrow(() -> new AuthenticationException("일치하는 세션을 찾을 수 없습니다.")); | ||
|
||
sessionGroupRepository.delete(sessionGroup); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
backend/pium/src/main/resources/db/migration/V7__session_group.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
CREATE TABLE IF NOT EXISTS session_group | ||
( | ||
id BIGINT AUTO_INCREMENT NOT NULL, | ||
session_id VARCHAR(255) NOT NULL, | ||
session_key VARCHAR(255) NOT NULL, | ||
session_value VARCHAR(255) NOT NULL, | ||
created_at DATETIME NOT NULL, | ||
updated_at DATETIME NOT NULL, | ||
expire_time DATETIME NOT NULL, | ||
PRIMARY KEY (id) | ||
); | ||
|
||
ALTER TABLE session_group | ||
ADD CONSTRAINT uniq_sessions UNIQUE(session_id, session_key); |
Oops, something went wrong.