-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
984 additions
and
968 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
405 changes: 204 additions & 201 deletions
405
src/main/java/com/moabam/api/application/auth/AuthorizationService.java
Large diffs are not rendered by default.
Oops, something went wrong.
80 changes: 41 additions & 39 deletions
80
src/main/java/com/moabam/api/application/auth/JwtAuthenticationService.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 |
---|---|---|
@@ -1,57 +1,59 @@ | ||
package com.moabam.api.application.auth; | ||
|
||
import java.nio.charset.StandardCharsets; | ||
import java.security.Key; | ||
|
||
import org.json.JSONObject; | ||
import org.springframework.stereotype.Service; | ||
|
||
import com.moabam.api.application.auth.mapper.AuthorizationMapper; | ||
import com.moabam.api.domain.member.Role; | ||
import com.moabam.global.auth.model.PublicClaim; | ||
import com.moabam.global.config.TokenConfig; | ||
import com.moabam.global.error.exception.UnauthorizedException; | ||
import com.moabam.global.error.model.ErrorMessage; | ||
|
||
import io.jsonwebtoken.ExpiredJwtException; | ||
import io.jsonwebtoken.Jwts; | ||
import io.jsonwebtoken.io.Decoders; | ||
import lombok.RequiredArgsConstructor; | ||
import org.json.JSONObject; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.nio.charset.StandardCharsets; | ||
import java.security.Key; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class JwtAuthenticationService { | ||
|
||
private final TokenConfig tokenConfig; | ||
|
||
public boolean isTokenExpire(String token, Role role) { | ||
try { | ||
Key key = getSecret(role); | ||
|
||
Jwts.parserBuilder() | ||
.setSigningKey(key) | ||
.build() | ||
.parseClaimsJws(token); | ||
return false; | ||
} catch (ExpiredJwtException expiredJwtException) { | ||
return true; | ||
} catch (Exception exception) { | ||
throw new UnauthorizedException(ErrorMessage.AUTHENTICATE_FAIL); | ||
} | ||
} | ||
|
||
private Key getSecret(Role role) { | ||
if (role.equals(Role.ADMIN)) { | ||
return tokenConfig.getAdminKey(); | ||
} | ||
|
||
return tokenConfig.getKey(); | ||
} | ||
|
||
public PublicClaim parseClaim(String token) { | ||
String claims = token.split("\\.")[1]; | ||
byte[] claimsBytes = Decoders.BASE64URL.decode(claims); | ||
String decodedClaims = new String(claimsBytes, StandardCharsets.UTF_8); | ||
JSONObject jsonObject = new JSONObject(decodedClaims); | ||
|
||
return AuthorizationMapper.toPublicClaim(jsonObject); | ||
} | ||
private final TokenConfig tokenConfig; | ||
|
||
public boolean isTokenExpire(String token, Role role) { | ||
try { | ||
Key key = getSecret(role); | ||
|
||
Jwts.parserBuilder() | ||
.setSigningKey(key) | ||
.build() | ||
.parseClaimsJws(token); | ||
return false; | ||
} catch (ExpiredJwtException expiredJwtException) { | ||
return true; | ||
} catch (Exception exception) { | ||
throw new UnauthorizedException(ErrorMessage.AUTHENTICATE_FAIL); | ||
} | ||
} | ||
|
||
private Key getSecret(Role role) { | ||
if (role.equals(Role.ADMIN)) { | ||
return tokenConfig.getAdminKey(); | ||
} | ||
|
||
return tokenConfig.getKey(); | ||
} | ||
|
||
public PublicClaim parseClaim(String token) { | ||
String claims = token.split("\\.")[1]; | ||
byte[] claimsBytes = Decoders.BASE64URL.decode(claims); | ||
String decodedClaims = new String(claimsBytes, StandardCharsets.UTF_8); | ||
JSONObject jsonObject = new JSONObject(decodedClaims); | ||
|
||
return AuthorizationMapper.toPublicClaim(jsonObject); | ||
} | ||
} |
51 changes: 24 additions & 27 deletions
51
src/main/java/com/moabam/api/application/ranking/RankingMapper.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 |
---|---|---|
@@ -1,42 +1,39 @@ | ||
package com.moabam.api.application.ranking; | ||
|
||
import java.util.List; | ||
|
||
import com.moabam.api.dto.ranking.RankingInfo; | ||
import com.moabam.api.dto.ranking.TopRankingInfo; | ||
import com.moabam.api.dto.ranking.TopRankingResponse; | ||
import com.moabam.api.dto.ranking.UpdateRanking; | ||
|
||
import lombok.AccessLevel; | ||
import lombok.NoArgsConstructor; | ||
|
||
import java.util.List; | ||
|
||
@NoArgsConstructor(access = AccessLevel.PRIVATE) | ||
public class RankingMapper { | ||
|
||
public static TopRankingInfo topRankingResponse(int rank, long score, RankingInfo rankInfo) { | ||
return TopRankingInfo.builder() | ||
.rank(rank) | ||
.score(score) | ||
.nickname(rankInfo.nickname()) | ||
.image(rankInfo.image()) | ||
.memberId(rankInfo.memberId()) | ||
.build(); | ||
} | ||
public static TopRankingInfo topRankingResponse(int rank, long score, RankingInfo rankInfo) { | ||
return TopRankingInfo.builder() | ||
.rank(rank) | ||
.score(score) | ||
.nickname(rankInfo.nickname()) | ||
.image(rankInfo.image()) | ||
.memberId(rankInfo.memberId()) | ||
.build(); | ||
} | ||
|
||
public static TopRankingInfo topRankingResponse(int rank, UpdateRanking updateRanking) { | ||
return TopRankingInfo.builder() | ||
.rank(rank + 1) | ||
.score(updateRanking.score()) | ||
.nickname(updateRanking.rankingInfo().nickname()) | ||
.image(updateRanking.rankingInfo().image()) | ||
.memberId(updateRanking.rankingInfo().memberId()) | ||
.build(); | ||
} | ||
public static TopRankingInfo topRankingResponse(int rank, UpdateRanking updateRanking) { | ||
return TopRankingInfo.builder() | ||
.rank(rank + 1) | ||
.score(updateRanking.score()) | ||
.nickname(updateRanking.rankingInfo().nickname()) | ||
.image(updateRanking.rankingInfo().image()) | ||
.memberId(updateRanking.rankingInfo().memberId()) | ||
.build(); | ||
} | ||
|
||
public static TopRankingResponse topRankingResponses(TopRankingInfo myRanking, | ||
List<TopRankingInfo> topRankings) { | ||
return TopRankingResponse.builder() | ||
.topRankings(topRankings) | ||
.myRanking(myRanking) | ||
.build(); | ||
} | ||
public static TopRankingResponse topRankingResponses(TopRankingInfo myRanking, List<TopRankingInfo> topRankings) { | ||
return TopRankingResponse.builder().topRankings(topRankings).myRanking(myRanking).build(); | ||
} | ||
} |
95 changes: 48 additions & 47 deletions
95
src/main/java/com/moabam/api/application/ranking/RankingService.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 |
---|---|---|
@@ -1,74 +1,75 @@ | ||
package com.moabam.api.application.ranking; | ||
|
||
import static java.util.Objects.*; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Set; | ||
|
||
import org.springframework.data.redis.core.ZSetOperations; | ||
import org.springframework.stereotype.Service; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.moabam.api.dto.ranking.RankingInfo; | ||
import com.moabam.api.dto.ranking.TopRankingInfo; | ||
import com.moabam.api.dto.ranking.TopRankingResponse; | ||
import com.moabam.api.dto.ranking.UpdateRanking; | ||
import com.moabam.api.infrastructure.redis.ZSetRedisRepository; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.data.redis.core.ZSetOperations; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Set; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class RankingService { | ||
|
||
private static final String RANKING = "Ranking"; | ||
private static final int START_INDEX = 0; | ||
private static final int LIMIT_INDEX = 9; | ||
private static final String RANKING = "Ranking"; | ||
private static final int START_INDEX = 0; | ||
private static final int LIMIT_INDEX = 9; | ||
|
||
private final ObjectMapper objectMapper; | ||
private final ZSetRedisRepository zSetRedisRepository; | ||
private final ObjectMapper objectMapper; | ||
private final ZSetRedisRepository zSetRedisRepository; | ||
|
||
public void addRanking(RankingInfo rankingInfo, Long totalCertifyCount) { | ||
zSetRedisRepository.add(RANKING, rankingInfo, totalCertifyCount); | ||
} | ||
public void addRanking(RankingInfo rankingInfo, Long totalCertifyCount) { | ||
zSetRedisRepository.add(RANKING, rankingInfo, totalCertifyCount); | ||
} | ||
|
||
public void updateScores(List<UpdateRanking> updateRankings) { | ||
updateRankings.forEach(updateRanking -> | ||
zSetRedisRepository.add(RANKING, updateRanking.rankingInfo(), updateRanking.score())); | ||
} | ||
public void updateScores(List<UpdateRanking> updateRankings) { | ||
updateRankings.forEach( | ||
updateRanking -> zSetRedisRepository.add(RANKING, updateRanking.rankingInfo(), updateRanking.score())); | ||
} | ||
|
||
public void changeInfos(RankingInfo before, RankingInfo after) { | ||
zSetRedisRepository.changeMember(RANKING, before, after); | ||
} | ||
public void changeInfos(RankingInfo before, RankingInfo after) { | ||
zSetRedisRepository.changeMember(RANKING, before, after); | ||
} | ||
|
||
public void removeRanking(RankingInfo rankingInfo) { | ||
zSetRedisRepository.delete(RANKING, rankingInfo); | ||
} | ||
public void removeRanking(RankingInfo rankingInfo) { | ||
zSetRedisRepository.delete(RANKING, rankingInfo); | ||
} | ||
|
||
public TopRankingResponse getMemberRanking(UpdateRanking myRankingInfo) { | ||
List<TopRankingInfo> topRankings = getTopRankings(); | ||
Long myRanking = zSetRedisRepository.reverseRank(RANKING, myRankingInfo.rankingInfo()); | ||
TopRankingInfo myRankingInfoResponse = | ||
RankingMapper.topRankingResponse(myRanking.intValue(), myRankingInfo); | ||
public TopRankingResponse getMemberRanking(UpdateRanking myRankingInfo) { | ||
List<TopRankingInfo> topRankings = getTopRankings(); | ||
Long myRanking = zSetRedisRepository.reverseRank(RANKING, myRankingInfo.rankingInfo()); | ||
TopRankingInfo myRankingInfoResponse = RankingMapper.topRankingResponse(myRanking.intValue(), myRankingInfo); | ||
|
||
return RankingMapper.topRankingResponses(myRankingInfoResponse, topRankings); | ||
} | ||
return RankingMapper.topRankingResponses(myRankingInfoResponse, topRankings); | ||
} | ||
|
||
private List<TopRankingInfo> getTopRankings() { | ||
Set<ZSetOperations.TypedTuple<Object>> topRankings = | ||
zSetRedisRepository.rangeJson(RANKING, START_INDEX, LIMIT_INDEX); | ||
private List<TopRankingInfo> getTopRankings() { | ||
Set<ZSetOperations.TypedTuple<Object>> topRankings = zSetRedisRepository.rangeJson(RANKING, START_INDEX, | ||
LIMIT_INDEX); | ||
|
||
Set<Long> scoreSet = new HashSet<>(); | ||
List<TopRankingInfo> topRankingInfo = new ArrayList<>(); | ||
Set<Long> scoreSet = new HashSet<>(); | ||
List<TopRankingInfo> topRankingInfo = new ArrayList<>(); | ||
|
||
for (ZSetOperations.TypedTuple<Object> topRanking : topRankings) { | ||
long score = requireNonNull(topRanking.getScore()).longValue(); | ||
scoreSet.add(score); | ||
for (ZSetOperations.TypedTuple<Object> topRanking : topRankings) { | ||
long score = requireNonNull(topRanking.getScore()).longValue(); | ||
scoreSet.add(score); | ||
|
||
RankingInfo rankingInfo = objectMapper.convertValue(topRanking.getValue(), RankingInfo.class); | ||
topRankingInfo.add(RankingMapper.topRankingResponse(scoreSet.size(), score, rankingInfo)); | ||
} | ||
RankingInfo rankingInfo = objectMapper.convertValue(topRanking.getValue(), RankingInfo.class); | ||
topRankingInfo.add(RankingMapper.topRankingResponse(scoreSet.size(), score, rankingInfo)); | ||
} | ||
|
||
return topRankingInfo; | ||
} | ||
return topRankingInfo; | ||
} | ||
} |
51 changes: 26 additions & 25 deletions
51
src/main/java/com/moabam/api/domain/auth/repository/TokenRepository.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 |
---|---|---|
@@ -1,42 +1,43 @@ | ||
package com.moabam.api.domain.auth.repository; | ||
|
||
import com.moabam.api.domain.member.Role; | ||
import com.moabam.api.dto.auth.TokenSaveValue; | ||
import com.moabam.api.infrastructure.redis.HashRedisRepository; | ||
import java.time.Duration; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.stereotype.Repository; | ||
|
||
import java.time.Duration; | ||
import com.moabam.api.domain.member.Role; | ||
import com.moabam.api.dto.auth.TokenSaveValue; | ||
import com.moabam.api.infrastructure.redis.HashRedisRepository; | ||
|
||
@Repository | ||
public class TokenRepository { | ||
|
||
private static final int EXPIRE_DAYS = 14; | ||
private static final int EXPIRE_DAYS = 14; | ||
|
||
private final HashRedisRepository hashRedisRepository; | ||
private final HashRedisRepository hashRedisRepository; | ||
|
||
@Autowired | ||
public TokenRepository(HashRedisRepository hashRedisRepository) { | ||
this.hashRedisRepository = hashRedisRepository; | ||
} | ||
@Autowired | ||
public TokenRepository(HashRedisRepository hashRedisRepository) { | ||
this.hashRedisRepository = hashRedisRepository; | ||
} | ||
|
||
public void saveToken(Long memberId, TokenSaveValue tokenSaveRequest, Role role) { | ||
String tokenKey = parseTokenKey(memberId, role); | ||
public void saveToken(Long memberId, TokenSaveValue tokenSaveRequest, Role role) { | ||
String tokenKey = parseTokenKey(memberId, role); | ||
|
||
hashRedisRepository.save(tokenKey, tokenSaveRequest, Duration.ofDays(EXPIRE_DAYS)); | ||
} | ||
hashRedisRepository.save(tokenKey, tokenSaveRequest, Duration.ofDays(EXPIRE_DAYS)); | ||
} | ||
|
||
public TokenSaveValue getTokenSaveValue(Long memberId, Role role) { | ||
String tokenKey = parseTokenKey(memberId, role); | ||
return (TokenSaveValue) hashRedisRepository.get(tokenKey); | ||
} | ||
public TokenSaveValue getTokenSaveValue(Long memberId, Role role) { | ||
String tokenKey = parseTokenKey(memberId, role); | ||
return (TokenSaveValue)hashRedisRepository.get(tokenKey); | ||
} | ||
|
||
public void delete(Long memberId, Role role) { | ||
String tokenKey = parseTokenKey(memberId, role); | ||
hashRedisRepository.delete(tokenKey); | ||
} | ||
public void delete(Long memberId, Role role) { | ||
String tokenKey = parseTokenKey(memberId, role); | ||
hashRedisRepository.delete(tokenKey); | ||
} | ||
|
||
private String parseTokenKey(Long memberId, Role role) { | ||
return role.name() + "_" + memberId; | ||
} | ||
private String parseTokenKey(Long memberId, Role role) { | ||
return role.name() + "_" + memberId; | ||
} | ||
} |
Oops, something went wrong.