-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #687 from woowacourse-teams/develop
release: v1.6.0
- Loading branch information
Showing
68 changed files
with
1,568 additions
and
262 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
50 changes: 50 additions & 0 deletions
50
back/src/main/java/com/woowacourse/teatime/auth/config/RedisConfig.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,50 @@ | ||
package com.woowacourse.teatime.auth.config; | ||
|
||
import java.time.Duration; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.cache.CacheManager; | ||
import org.springframework.cache.annotation.EnableCaching; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.data.redis.cache.RedisCacheConfiguration; | ||
import org.springframework.data.redis.cache.RedisCacheManager.RedisCacheManagerBuilder; | ||
import org.springframework.data.redis.connection.RedisConnectionFactory; | ||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; | ||
import org.springframework.data.redis.core.RedisTemplate; | ||
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; | ||
|
||
@Configuration | ||
@EnableCaching | ||
@EnableRedisRepositories | ||
public class RedisConfig { | ||
|
||
@Value("${spring.redis.host}") | ||
private String host; | ||
|
||
@Value("${spring.redis.port}") | ||
private int port; | ||
|
||
@Value("${refresh-token.expire-length}") | ||
private Long expireLength; | ||
|
||
@Bean | ||
public RedisConnectionFactory redisConnectionFactory() { | ||
return new LettuceConnectionFactory(host, port); | ||
} | ||
|
||
@Bean | ||
public RedisTemplate<?, ?> redisTemplate() { | ||
RedisTemplate<byte[], byte[]> redisTemplate = new RedisTemplate<>(); | ||
redisTemplate.setConnectionFactory(redisConnectionFactory()); | ||
return redisTemplate; | ||
} | ||
|
||
@Bean | ||
public CacheManager cacheManager() { | ||
RedisCacheManagerBuilder builder = RedisCacheManagerBuilder.fromConnectionFactory(redisConnectionFactory()); | ||
RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig() | ||
.entryTtl(Duration.ofSeconds(expireLength)); | ||
builder.cacheDefaults(configuration); | ||
return builder.build(); | ||
} | ||
} |
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
12 changes: 12 additions & 0 deletions
12
back/src/main/java/com/woowacourse/teatime/auth/controller/dto/GenerateTokenDto.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,12 @@ | ||
package com.woowacourse.teatime.auth.controller.dto; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
@AllArgsConstructor | ||
public class GenerateTokenDto { | ||
|
||
private String accessToken; | ||
private String refreshToken; | ||
} |
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
...src/main/java/com/woowacourse/teatime/auth/controller/dto/RefreshAccessTokenResponse.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.woowacourse.teatime.auth.controller.dto; | ||
|
||
import lombok.AccessLevel; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PRIVATE) | ||
@AllArgsConstructor | ||
public class RefreshAccessTokenResponse { | ||
|
||
private String accessToken; | ||
} |
16 changes: 16 additions & 0 deletions
16
back/src/main/java/com/woowacourse/teatime/auth/controller/dto/UserAuthDto.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,16 @@ | ||
package com.woowacourse.teatime.auth.controller.dto; | ||
|
||
import com.woowacourse.teatime.teatime.domain.Role; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
@AllArgsConstructor | ||
public class UserAuthDto { | ||
|
||
private String accessToken; | ||
private String refreshToken; | ||
private Role role; | ||
private String image; | ||
private String name; | ||
} |
26 changes: 26 additions & 0 deletions
26
back/src/main/java/com/woowacourse/teatime/auth/domain/UserAuthInfo.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,26 @@ | ||
package com.woowacourse.teatime.auth.domain; | ||
|
||
import lombok.AccessLevel; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import org.springframework.data.annotation.Id; | ||
import org.springframework.data.redis.core.RedisHash; | ||
|
||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PRIVATE) | ||
@AllArgsConstructor | ||
@RedisHash(value = "refreshToken", timeToLive = 1209600) | ||
public class UserAuthInfo { | ||
|
||
@Id | ||
private String refreshToken; | ||
private String accessToken; | ||
private Long userId; | ||
private String role; | ||
|
||
public boolean isSameToken(String refreshToken, String accessToken) { | ||
return this.refreshToken.equals(refreshToken) | ||
&& this.accessToken.equals(accessToken); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
back/src/main/java/com/woowacourse/teatime/auth/exception/WrongTokenException.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,12 @@ | ||
package com.woowacourse.teatime.auth.exception; | ||
|
||
import com.woowacourse.teatime.exception.BadRequestException; | ||
|
||
public class WrongTokenException extends BadRequestException { | ||
|
||
private static final String ERROR_MESSAGE = "토큰이 잘못되었습니다."; | ||
|
||
public WrongTokenException() { | ||
super(ERROR_MESSAGE); | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
...rc/main/java/com/woowacourse/teatime/auth/infrastructure/ResponseCookieTokenProvider.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,29 @@ | ||
package com.woowacourse.teatime.auth.infrastructure; | ||
|
||
import javax.servlet.http.HttpServletResponse; | ||
import org.eclipse.jetty.http.HttpCookie.SameSite; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.http.ResponseCookie; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class ResponseCookieTokenProvider { | ||
|
||
private final Long expireLength; | ||
|
||
public ResponseCookieTokenProvider(@Value("${refresh-token.expire-length}") String expireLength) { | ||
this.expireLength = Long.parseLong(expireLength); | ||
} | ||
|
||
public void setCookie(HttpServletResponse response, String refreshToken) { | ||
ResponseCookie cookie = ResponseCookie.from("refreshToken", refreshToken) | ||
.maxAge(expireLength) | ||
.path("/") | ||
.secure(true) | ||
.sameSite(SameSite.NONE.name()) | ||
.httpOnly(true) | ||
.build(); | ||
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString()); | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
back/src/main/java/com/woowacourse/teatime/auth/repository/UserAuthInfoRepository.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,7 @@ | ||
package com.woowacourse.teatime.auth.repository; | ||
|
||
import com.woowacourse.teatime.auth.domain.UserAuthInfo; | ||
import org.springframework.data.repository.CrudRepository; | ||
|
||
public interface UserAuthInfoRepository extends CrudRepository<UserAuthInfo, String> { | ||
} |
125 changes: 125 additions & 0 deletions
125
back/src/main/java/com/woowacourse/teatime/auth/service/LoginService.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,125 @@ | ||
package com.woowacourse.teatime.auth.service; | ||
|
||
|
||
import static com.woowacourse.teatime.teatime.domain.Role.COACH; | ||
import static com.woowacourse.teatime.teatime.domain.Role.CREW; | ||
|
||
import com.woowacourse.teatime.auth.controller.dto.LoginRequest; | ||
import com.woowacourse.teatime.auth.controller.dto.UserAuthDto; | ||
import com.woowacourse.teatime.auth.domain.UserAuthInfo; | ||
import com.woowacourse.teatime.auth.infrastructure.JwtTokenProvider; | ||
import com.woowacourse.teatime.auth.infrastructure.OpenIdAuth; | ||
import com.woowacourse.teatime.teatime.controller.dto.request.SheetQuestionUpdateRequest; | ||
import com.woowacourse.teatime.teatime.domain.Coach; | ||
import com.woowacourse.teatime.teatime.domain.Crew; | ||
import com.woowacourse.teatime.teatime.repository.CoachRepository; | ||
import com.woowacourse.teatime.teatime.repository.CrewRepository; | ||
import com.woowacourse.teatime.teatime.service.QuestionService; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.UUID; | ||
import java.util.stream.Collectors; | ||
import lombok.RequiredArgsConstructor; | ||
import org.apache.commons.lang3.StringUtils; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@RequiredArgsConstructor | ||
@Transactional | ||
@Service | ||
public class LoginService { | ||
|
||
private static final String COACH_EMAIL_DOMAIN = "woowahan"; | ||
private static final String DEFAULT_QUESTION_1 = "이번 면담을 통해 논의하고 싶은 내용"; | ||
private static final String DEFAULT_QUESTION_2 = "최근에 자신이 긍정적으로 보는 시도와 변화"; | ||
private static final String DEFAULT_QUESTION_3 = "이번 면담을 통해 생기기를 원하는 변화"; | ||
|
||
private final OpenIdAuth openIdAuth; | ||
private final CrewRepository crewRepository; | ||
private final CoachRepository coachRepository; | ||
private final QuestionService questionService; | ||
private final UserAuthService userAuthService; | ||
private final JwtTokenProvider jwtTokenProvider; | ||
|
||
@Value("${coaches}") | ||
private List<String> emails; | ||
|
||
public UserAuthDto login(LoginRequest loginRequest) { | ||
String code = loginRequest.getCode(); | ||
String accessToken = openIdAuth.getAccessToken(code); | ||
UserInfoDto userInfo = openIdAuth.getUserInfo(accessToken); | ||
return getLoginResponse(userInfo); | ||
} | ||
|
||
private UserAuthDto getLoginResponse(UserInfoDto userInfo) { | ||
String email = userInfo.getEmail(); | ||
String emailDomain = StringUtils.substringBetween(email, "@", "."); | ||
|
||
List<String> emails = getEmails(); | ||
if (COACH_EMAIL_DOMAIN.equals(emailDomain) || emails.contains(email)) { | ||
return getCoachLoginResponse(userInfo); | ||
} | ||
return getCrewLoginResponse(userInfo); | ||
} | ||
|
||
private List<String> getEmails() { | ||
return emails.stream() | ||
.map(String::trim) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
private UserAuthDto getCoachLoginResponse(UserInfoDto userInfo) { | ||
Coach coach = coachRepository.findByEmail(userInfo.getEmail()) | ||
.orElseGet(() -> saveCoachAndDefaultQuestions(userInfo)); | ||
coach.setSlackId(userInfo.getSlackId()); | ||
coach.setImage(userInfo.getImage()); | ||
|
||
Map<String, Object> claims = Map.of("id", coach.getId(), "role", COACH); | ||
String accessToken = jwtTokenProvider.createToken(claims); | ||
String refreshToken = UUID.randomUUID().toString(); | ||
userAuthService.save(new UserAuthInfo(refreshToken, accessToken, coach.getId(), COACH.name())); | ||
return new UserAuthDto(accessToken, refreshToken, COACH, coach.getImage(), coach.getName()); | ||
} | ||
|
||
@NotNull | ||
private Coach saveCoachAndDefaultQuestions(UserInfoDto userInfo) { | ||
Coach coach = coachRepository.save(new Coach( | ||
userInfo.getSlackId(), | ||
userInfo.getName(), | ||
userInfo.getEmail(), | ||
userInfo.getImage())); | ||
|
||
List<SheetQuestionUpdateRequest> defaultQuestionDtos = List.of( | ||
new SheetQuestionUpdateRequest(1, DEFAULT_QUESTION_1, true), | ||
new SheetQuestionUpdateRequest(2, DEFAULT_QUESTION_2, true), | ||
new SheetQuestionUpdateRequest(3, DEFAULT_QUESTION_3, true)); | ||
|
||
questionService.update(coach.getId(), defaultQuestionDtos); | ||
return coach; | ||
} | ||
|
||
private UserAuthDto getCrewLoginResponse(UserInfoDto userInfo) { | ||
Crew crew = crewRepository.findByEmail(userInfo.getEmail()) | ||
.orElseGet(() -> saveCrew(userInfo)); | ||
crew.setSlackId(userInfo.getSlackId()); | ||
crew.setImage(userInfo.getImage()); | ||
|
||
Map<String, Object> claims = Map.of("id", crew.getId(), "role", CREW); | ||
String accessToken = jwtTokenProvider.createToken(claims); | ||
String refreshToken = UUID.randomUUID().toString(); | ||
userAuthService.save(new UserAuthInfo(refreshToken, accessToken, crew.getId(), CREW.name())); | ||
return new UserAuthDto(accessToken, refreshToken, CREW, crew.getImage(), crew.getName()); | ||
} | ||
|
||
@NotNull | ||
private Crew saveCrew(UserInfoDto userInfo) { | ||
Crew newCrew = new Crew( | ||
userInfo.getSlackId(), | ||
userInfo.getName(), | ||
userInfo.getEmail(), | ||
userInfo.getImage()); | ||
return crewRepository.save(newCrew); | ||
} | ||
} |
Oops, something went wrong.