diff --git a/collabstack-be/app/build.gradle b/collabstack-be/app/build.gradle index 0b4aa0c..58caa9c 100644 --- a/collabstack-be/app/build.gradle +++ b/collabstack-be/app/build.gradle @@ -36,6 +36,7 @@ dependencies { implementation('org.apache.httpcomponents:httpcore') implementation('org.apache.httpcomponents:httpclient') implementation("com.auth0:java-jwt:$jwt_version") + testImplementation("org.springframework.security:spring-security-test"); } test { diff --git a/collabstack-be/app/src/main/java/net/collabstack/app/CollabStackApp.java b/collabstack-be/app/src/main/java/net/collabstack/app/CollabStackApp.java index f2cd63e..7316999 100644 --- a/collabstack-be/app/src/main/java/net/collabstack/app/CollabStackApp.java +++ b/collabstack-be/app/src/main/java/net/collabstack/app/CollabStackApp.java @@ -11,5 +11,4 @@ public class CollabStackApp { public static void main(final String[] args) { SpringApplication.run(CollabStackApp.class, args); } - } diff --git a/collabstack-be/app/src/main/java/net/collabstack/app/letter/LetterController.java b/collabstack-be/app/src/main/java/net/collabstack/app/letter/LetterController.java new file mode 100644 index 0000000..a640855 --- /dev/null +++ b/collabstack-be/app/src/main/java/net/collabstack/app/letter/LetterController.java @@ -0,0 +1,78 @@ +package net.collabstack.app.letter; + +import java.util.List; +import java.util.stream.Collectors; + +import javax.validation.Valid; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotNull; + +import org.springframework.http.HttpStatus; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import net.collabstack.app.letter.domain.Letter; +import net.collabstack.app.letter.dto.LetterPinningRequest; +import net.collabstack.app.letter.dto.LetterResponse; +import net.collabstack.app.letter.dto.LetterSaveRequest; +import net.collabstack.common.CommonResponse; +import net.collabstack.common.ResultCode; +import net.collabstack.security.annotation.AuthenticatedUser; +import net.collabstack.security.member.SecurityMember; + +import lombok.RequiredArgsConstructor; + +@RestController +@RequestMapping("/v1/letters") +@RequiredArgsConstructor +@Validated +public class LetterController { + + private final LetterService letterService; + + @GetMapping("/{ownerEmail}") + public CommonResponse> getLetters( + @PathVariable("ownerEmail") @Email final String ownerEmail) { + final List letters = letterService.getLetters(ownerEmail); + final List letterResponses = letters.stream() + .map(LetterResponse::from) + .collect(Collectors.toList()); + return CommonResponse.success(ResultCode.OK, "letters", letterResponses); + } + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public CommonResponse saveLetter( + @RequestBody @Valid final LetterSaveRequest letterSaveRequest) { + final Letter savedLetter = letterService.saveLetter(letterSaveRequest); + final LetterResponse letterResponse = LetterResponse.from(savedLetter); + return CommonResponse.success(ResultCode.CREATED, "saved", letterResponse); + } + + @PutMapping("/pins") + public CommonResponse pinning( + @AuthenticatedUser @NotNull final SecurityMember authenticatedUser, + @RequestBody @Valid final LetterPinningRequest letterPinningRequest) { + final Letter pinnedLetter = + letterService.setPinned(authenticatedUser.getUsername(), letterPinningRequest); + final LetterResponse letterResponse = LetterResponse.from(pinnedLetter); + return CommonResponse.success(ResultCode.OK, "pinning", letterResponse); + } + + @GetMapping("/{ownerEmail}/pins") + public CommonResponse> getPinnedLetters( + @PathVariable("ownerEmail") @Email final String ownerEmail) { + final List pinnedLetters = letterService.getPinnedLetters(ownerEmail); + final List letterResponses = pinnedLetters.stream() + .map(LetterResponse::from) + .collect(Collectors.toList()); + return CommonResponse.success(ResultCode.OK, "pinned letters", letterResponses); + } +} diff --git a/collabstack-be/app/src/main/java/net/collabstack/app/letter/LetterService.java b/collabstack-be/app/src/main/java/net/collabstack/app/letter/LetterService.java new file mode 100644 index 0000000..27d613c --- /dev/null +++ b/collabstack-be/app/src/main/java/net/collabstack/app/letter/LetterService.java @@ -0,0 +1,76 @@ +package net.collabstack.app.letter; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import net.collabstack.app.letter.domain.Letter; +import net.collabstack.app.letter.domain.LetterRepository; +import net.collabstack.app.letter.dto.LetterPinningRequest; +import net.collabstack.app.letter.dto.LetterSaveRequest; +import net.collabstack.app.letter.exception.LetterNotFoundException; +import net.collabstack.app.letter.exception.PinAlreadyFullException; +import net.collabstack.app.member.MemberService; +import net.collabstack.app.member.domain.Member; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class LetterService { + + private final static int MAX_PINNING_COUNT = 4; + + private final LetterRepository letterRepository; + private final MemberService memberService; + + @Transactional(readOnly = true) + public List getLetters(final String ownerId) { + return letterRepository.findByOwner_email(ownerId); + } + + @Transactional + public Letter saveLetter(final LetterSaveRequest letterSaveRequest) { + final Member recommender = memberService.getMember(letterSaveRequest.getRecommenderEmail()); + final Member owner = memberService.getMember(letterSaveRequest.getOwnerEmail()); + final Letter letter = Letter.toLetter(make -> { + make.setLetterTitle(letterSaveRequest.getLetterTitle()); + make.setContent(letterSaveRequest.getLetterContent()); + make.setOwner(owner); + make.setRecommender(recommender); + make.setPinned(false); + make.setStar(0); + make.setCreateDate(LocalDateTime.now()); + return make; + }); + return letterRepository.save(letter); + } + + @Transactional(readOnly = true) + final List getPinnedLetters(final String ownerEmail) { + return letterRepository.findByOwner_emailAndIsPinned(ownerEmail, true); + } + + @Transactional + public Letter setPinned(final String ownerEmail, final LetterPinningRequest pinningRequest) { + final List letters = letterRepository.findByOwner_email(ownerEmail); + final long pinningCount = letters.stream() + .filter(Letter::isPinned) + .count(); + if (pinningCount >= MAX_PINNING_COUNT) { + throw new PinAlreadyFullException(ownerEmail, "이미 지정된 최대 pinned 개수에 도달하였습니다 (핀 지정갯수 4)"); + } + final Optional letterOptional = letters.stream() + .filter( + letter -> letter.getOwner().getEmail().equals(ownerEmail) + && letter.getId().compareTo(pinningRequest.getLetterId()) == 0) + .findFirst(); + letterOptional.ifPresent(letter -> letter.setPinned(pinningRequest.getIsPinning())); + return letterOptional.orElseThrow(() -> new LetterNotFoundException(pinningRequest.getLetterId(), + ownerEmail, + "추천서를 찾을 수 없습니다.")); + } +} diff --git a/collabstack-be/app/src/main/java/net/collabstack/app/letter/domain/Letter.java b/collabstack-be/app/src/main/java/net/collabstack/app/letter/domain/Letter.java new file mode 100644 index 0000000..83efb6b --- /dev/null +++ b/collabstack-be/app/src/main/java/net/collabstack/app/letter/domain/Letter.java @@ -0,0 +1,54 @@ +package net.collabstack.app.letter.domain; + +import java.time.LocalDateTime; +import java.util.function.Function; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + +import org.springframework.data.annotation.CreatedDate; + +import net.collabstack.app.member.domain.Member; + +import lombok.Data; + +@Entity +@Data +public class Letter { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(length = 30, nullable = false) + private String letterTitle; + + @Column(length = 300, nullable = false) + private String content; + + @Column + private Integer star; + + private boolean isPinned; + + @CreatedDate + private LocalDateTime createDate; + + @ManyToOne + @JoinColumn(name = "recommenderEmail") + private Member recommender; + + @ManyToOne + @JoinColumn(name = "ownerEmail") + private Member owner; + + public static Letter toLetter(final Function function) { + final Letter letter = new Letter(); + return function.apply(letter); + } +} diff --git a/collabstack-be/app/src/main/java/net/collabstack/app/letter/domain/LetterRepository.java b/collabstack-be/app/src/main/java/net/collabstack/app/letter/domain/LetterRepository.java new file mode 100644 index 0000000..32f329e --- /dev/null +++ b/collabstack-be/app/src/main/java/net/collabstack/app/letter/domain/LetterRepository.java @@ -0,0 +1,14 @@ +package net.collabstack.app.letter.domain; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface LetterRepository extends JpaRepository { + + int countByOwnerEmailAndIsPinned(final String ownerEmail, final boolean isPinned); + + List findByOwner_emailAndIsPinned(final String ownerEmail, final boolean isPinned); + + List findByOwner_email(final String ownerEmail); +} diff --git a/collabstack-be/app/src/main/java/net/collabstack/app/letter/dto/LetterPinningRequest.java b/collabstack-be/app/src/main/java/net/collabstack/app/letter/dto/LetterPinningRequest.java new file mode 100644 index 0000000..e9991dd --- /dev/null +++ b/collabstack-be/app/src/main/java/net/collabstack/app/letter/dto/LetterPinningRequest.java @@ -0,0 +1,17 @@ +package net.collabstack.app.letter.dto; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +import lombok.Data; + +@Data +public class LetterPinningRequest { + + @NotNull + @Min(1) + private Long letterId; + + @NotNull + private Boolean isPinning; +} diff --git a/collabstack-be/app/src/main/java/net/collabstack/app/letter/dto/LetterResponse.java b/collabstack-be/app/src/main/java/net/collabstack/app/letter/dto/LetterResponse.java new file mode 100644 index 0000000..bdf47c5 --- /dev/null +++ b/collabstack-be/app/src/main/java/net/collabstack/app/letter/dto/LetterResponse.java @@ -0,0 +1,36 @@ +package net.collabstack.app.letter.dto; + +import java.util.Date; + +import net.collabstack.app.letter.domain.Letter; +import net.collabstack.app.letter.util.DateUtil; + +import lombok.Data; + +@Data +public class LetterResponse { + + private Long id; + private String letterTitle; + private String letterContent; + private Integer star; + private boolean isPinned; + /** + * 생성일을 좀더 정확하게 표현합니다. + * e.g) 1 hours ago, 1 years ago + * */ + private String creationDate; + private String recommenderName; + + public static LetterResponse from(final Letter letter) { + final LetterResponse letterResponse = new LetterResponse(); + letterResponse.setId(letter.getId()); + letterResponse.setLetterTitle(letter.getLetterTitle()); + letterResponse.setLetterContent(letter.getContent()); + letterResponse.setStar(letter.getStar()); + letterResponse.setPinned(letter.isPinned()); + letterResponse.setCreationDate(DateUtil.toStandingTypeDate(new Date(), letter.getCreateDate())); + letterResponse.setRecommenderName(letter.getRecommender().getName()); + return letterResponse; + } +} diff --git a/collabstack-be/app/src/main/java/net/collabstack/app/letter/dto/LetterSaveRequest.java b/collabstack-be/app/src/main/java/net/collabstack/app/letter/dto/LetterSaveRequest.java new file mode 100644 index 0000000..87d578c --- /dev/null +++ b/collabstack-be/app/src/main/java/net/collabstack/app/letter/dto/LetterSaveRequest.java @@ -0,0 +1,25 @@ +package net.collabstack.app.letter.dto; + +import javax.validation.constraints.Email; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import lombok.Data; + +@Data +public class LetterSaveRequest { + + @Size(min = 5, max = 30) + private String letterTitle; + + @Size(min = 30, max = 300) + private String letterContent; + + @Email + @NotNull + private String recommenderEmail; + + @Email + @NotNull + private String ownerEmail; +} diff --git a/collabstack-be/app/src/main/java/net/collabstack/app/letter/exception/LetterExceptionHandler.java b/collabstack-be/app/src/main/java/net/collabstack/app/letter/exception/LetterExceptionHandler.java new file mode 100644 index 0000000..00b6243 --- /dev/null +++ b/collabstack-be/app/src/main/java/net/collabstack/app/letter/exception/LetterExceptionHandler.java @@ -0,0 +1,30 @@ +package net.collabstack.app.letter.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import net.collabstack.common.CommonResponse; +import net.collabstack.common.ResultCode; + +@RestControllerAdvice +public class LetterExceptionHandler { + + @ExceptionHandler(PinAlreadyFullException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public CommonResponse pinAlreadyFullExceptionHandler( + final PinAlreadyFullException exception) { + return CommonResponse.failure( + ResultCode.BAD_REQUEST, exception.getMessage(), exception.getOwnerEmail()); + } + + @ExceptionHandler(LetterNotFoundException.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + public CommonResponse letterNotFoundException( + final LetterNotFoundException exception) { + return CommonResponse.failure( + ResultCode.NOT_FOUND, exception.getLetterId() + " " + exception.getMessage(), + exception.getOwnerEmail()); + } +} diff --git a/collabstack-be/app/src/main/java/net/collabstack/app/letter/exception/LetterNotFoundException.java b/collabstack-be/app/src/main/java/net/collabstack/app/letter/exception/LetterNotFoundException.java new file mode 100644 index 0000000..1d62099 --- /dev/null +++ b/collabstack-be/app/src/main/java/net/collabstack/app/letter/exception/LetterNotFoundException.java @@ -0,0 +1,16 @@ +package net.collabstack.app.letter.exception; + +import lombok.Getter; + +@Getter +public class LetterNotFoundException extends RuntimeException { + + private final Long letterId; + private final String ownerEmail; + + public LetterNotFoundException(final Long letterId, final String ownerEmail, final String message) { + super(message); + this.letterId = letterId; + this.ownerEmail = ownerEmail; + } +} diff --git a/collabstack-be/app/src/main/java/net/collabstack/app/letter/exception/PinAlreadyFullException.java b/collabstack-be/app/src/main/java/net/collabstack/app/letter/exception/PinAlreadyFullException.java new file mode 100644 index 0000000..a05f23c --- /dev/null +++ b/collabstack-be/app/src/main/java/net/collabstack/app/letter/exception/PinAlreadyFullException.java @@ -0,0 +1,14 @@ +package net.collabstack.app.letter.exception; + +import lombok.Data; + +@Data +public class PinAlreadyFullException extends RuntimeException { + + private String ownerEmail; + + public PinAlreadyFullException(final String ownerEmail, final String message) { + super(message); + this.ownerEmail = ownerEmail; + } +} diff --git a/collabstack-be/app/src/main/java/net/collabstack/app/letter/util/DateUtil.java b/collabstack-be/app/src/main/java/net/collabstack/app/letter/util/DateUtil.java new file mode 100644 index 0000000..61ac3c0 --- /dev/null +++ b/collabstack-be/app/src/main/java/net/collabstack/app/letter/util/DateUtil.java @@ -0,0 +1,36 @@ +package net.collabstack.app.letter.util; + +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.util.Date; + +public class DateUtil { + + public static String toStandingTypeDate(final Date now, final LocalDateTime creationDate) { + final long nowTimeMills = now.getTime(); + final long creationDateTimeMills = Timestamp.valueOf(creationDate).getTime(); + long gap = (nowTimeMills - creationDateTimeMills) / 1000; + + if (gap < 60) { + return gap + " seconds ago"; + } + gap /= 60; + if (gap < 60) { + return gap + " minutes ago"; + } + gap /= 60; + if (gap < 24) { + return gap + " hours ago"; + } + gap /= 24; + if (gap < 31) { + return gap + " days ago"; + } + gap /= 30; + if (gap < 12) { + return gap + " months ago"; + } + gap /= 12; + return gap + " years ago"; + } +} diff --git a/collabstack-be/app/src/main/java/net/collabstack/app/member/MemberResolverImpl.java b/collabstack-be/app/src/main/java/net/collabstack/app/member/MemberResolverImpl.java index 2cfe0db..ac9b4a0 100644 --- a/collabstack-be/app/src/main/java/net/collabstack/app/member/MemberResolverImpl.java +++ b/collabstack-be/app/src/main/java/net/collabstack/app/member/MemberResolverImpl.java @@ -25,7 +25,6 @@ public SecurityMember resolveMember(final String id) { final Member member = memberService.getMember(id); return new SecurityMember<>(id, member.getName(), - false, List.of(new SimpleGrantedAuthority("Member"))); } } diff --git a/collabstack-be/app/src/test/java/net/collabstack/app/letter/LetterControllerTest.java b/collabstack-be/app/src/test/java/net/collabstack/app/letter/LetterControllerTest.java new file mode 100644 index 0000000..aa9f040 --- /dev/null +++ b/collabstack-be/app/src/test/java/net/collabstack/app/letter/LetterControllerTest.java @@ -0,0 +1,42 @@ +package net.collabstack.app.letter; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; + +import net.collabstack.app.letter.dto.LetterPinningRequest; + +import com.fasterxml.jackson.databind.ObjectMapper; + +@SpringBootTest +@AutoConfigureMockMvc +@EnableConfigurationProperties +@ActiveProfiles(profiles = "test") +class LetterControllerTest { + + @Autowired + ObjectMapper objectMapper; + + @Autowired + MockMvc mockMvc; + + @Test + void getPinnedLettersTest() throws Exception { + final String email = "wsnam0507@gmail.com"; + + final ResultActions resultActions = mockMvc.perform(get("/v1/" + email + "/pins")); + + resultActions.andDo(print()) + .andExpect(status().isBadRequest()); + } +} \ No newline at end of file diff --git a/collabstack-be/app/src/test/java/net/collabstack/app/letter/util/DateUtilTest.java b/collabstack-be/app/src/test/java/net/collabstack/app/letter/util/DateUtilTest.java new file mode 100644 index 0000000..e1ea1b2 --- /dev/null +++ b/collabstack-be/app/src/test/java/net/collabstack/app/letter/util/DateUtilTest.java @@ -0,0 +1,94 @@ +package net.collabstack.app.letter.util; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.LocalDateTime; +import java.util.Date; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class DateUtilTest { + + @Test + void toStandingTypeDateSecondTest() { + LocalDateTime now = LocalDateTime.now(); + now = now.minusSeconds(20); + + final String standingTypeString = DateUtil.toStandingTypeDate(new Date(), now); + + assertThat(standingTypeString).isEqualTo("20 seconds ago"); + } + + @Test + void toStandingTypeDateMinuteTest() { + LocalDateTime now = LocalDateTime.now(); + now = now.minusMinutes(12); + + final String standingTypeString = DateUtil.toStandingTypeDate(new Date(), now); + + assertThat(standingTypeString).isEqualTo("12 minutes ago"); + } + + @Test + void toStandingTypeDateHoursTest() { + LocalDateTime now = LocalDateTime.now(); + now = now.minusHours(23); + + final String standingTypeString = DateUtil.toStandingTypeDate(new Date(), now); + + assertThat(standingTypeString).isEqualTo("23 hours ago"); + } + + @Test + void toStandingTypeDateDaysTest() { + LocalDateTime now = LocalDateTime.now(); + now = now.minusDays(29); + + final String standingTypeString = DateUtil.toStandingTypeDate(new Date(), now); + + assertThat(standingTypeString).isEqualTo("29 days ago"); + } + + @Test + void toStandingTypeDateMonthsTest() { + LocalDateTime now = LocalDateTime.now(); + now = now.minusMonths(11); + + final String standingTypeString = DateUtil.toStandingTypeDate(new Date(), now); + + assertThat(standingTypeString).isEqualTo("11 months ago"); + } + + @Test + void toStandingTypeDateYearsTest() { + LocalDateTime now = LocalDateTime.now(); + now = now.minusYears(3); + + final String standingTypeString = DateUtil.toStandingTypeDate(new Date(), now); + + assertThat(standingTypeString).isEqualTo("3 years ago"); + } + + @Test + @DisplayName("62초 뒤일경우") + void toStandingTypeDateTest_after62sec() { + LocalDateTime now = LocalDateTime.now(); + now = now.minusSeconds(62); + + final String standingTypeString = DateUtil.toStandingTypeDate(new Date(), now); + + assertThat(standingTypeString).isEqualTo("1 minutes ago"); + } + + @Test + @DisplayName("32일 뒤일경우") + void toStandingTypeDateTest_after32days() { + LocalDateTime now = LocalDateTime.now(); + now = now.minusDays(32); + + final String standingTypeString = DateUtil.toStandingTypeDate(new Date(), now); + + assertThat(standingTypeString).isEqualTo("1 months ago"); + } +} \ No newline at end of file diff --git a/collabstack-be/security/src/main/java/net/collabstack/security/SecurityConfig.java b/collabstack-be/security/src/main/java/net/collabstack/security/SecurityConfig.java index 3f34e9a..8afbedf 100644 --- a/collabstack-be/security/src/main/java/net/collabstack/security/SecurityConfig.java +++ b/collabstack-be/security/src/main/java/net/collabstack/security/SecurityConfig.java @@ -46,19 +46,22 @@ public SecurityFilterChain securityFilterChain(final HttpSecurity http) throws E http.formLogin().disable(); http.logout().disable(); http.httpBasic().disable(); + http.headers().frameOptions().sameOrigin(); http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); http .authorizeRequests() .antMatchers(HttpMethod.POST, "/v1/login").permitAll() // TODO: 추후에 인증 필터 거치도록 변경해야합니다. .antMatchers(HttpMethod.GET, "/v1/member/*").permitAll() + .antMatchers(HttpMethod.GET, "/v1/letters/*").permitAll() + .antMatchers(HttpMethod.POST, "/v1/letters/*").permitAll() .and().authorizeRequests() .antMatchers( "/favicon.ico", "/h2-console/**", "/hello", "/error" - ).hasAnyRole() + ).permitAll() .and() .authorizeRequests().anyRequest().hasRole("Member") .and() @@ -84,6 +87,7 @@ CorsConfigurationSource corsConfigurationSource() { corsConfiguration.addAllowedOrigin("https://collabstack.net"); corsConfiguration.addAllowedOrigin("https://www.collabstack.net"); corsConfiguration.addAllowedOrigin("http://localhost:8700"); + corsConfiguration.addAllowedOrigin("http://localhost:8080"); corsConfiguration.addAllowedMethod("*"); corsConfiguration.addAllowedHeader("*"); corsConfiguration.setAllowCredentials(true); diff --git a/collabstack-be/security/src/main/java/net/collabstack/security/annotation/AuthenticatedUser.java b/collabstack-be/security/src/main/java/net/collabstack/security/annotation/AuthenticatedUser.java new file mode 100644 index 0000000..95ae366 --- /dev/null +++ b/collabstack-be/security/src/main/java/net/collabstack/security/annotation/AuthenticatedUser.java @@ -0,0 +1,14 @@ +package net.collabstack.security.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.security.core.annotation.AuthenticationPrincipal; + +@Target({ ElementType.PARAMETER, ElementType.ANNOTATION_TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@AuthenticationPrincipal +public @interface AuthenticatedUser { +} diff --git a/collabstack-be/security/src/main/java/net/collabstack/security/filter/PreJwtAuthenticationProvider.java b/collabstack-be/security/src/main/java/net/collabstack/security/filter/PreJwtAuthenticationProvider.java index adf9c66..c32352a 100644 --- a/collabstack-be/security/src/main/java/net/collabstack/security/filter/PreJwtAuthenticationProvider.java +++ b/collabstack-be/security/src/main/java/net/collabstack/security/filter/PreJwtAuthenticationProvider.java @@ -34,7 +34,7 @@ public Authentication authenticate(final Authentication authentication) throws A if (token == null) { final SecurityMember anonymous = new SecurityMember<>( - null, "anonymous", false, anonymousRoles); + null, "anonymous", anonymousRoles); return new PreAuthenticatedAuthenticationToken(anonymousRoles, "", anonymousRoles); } final String id = jwtProvider.decrypt(token, "id", String.class); diff --git a/collabstack-be/security/src/main/java/net/collabstack/security/member/SecurityMember.java b/collabstack-be/security/src/main/java/net/collabstack/security/member/SecurityMember.java index 8a42b32..4ba619f 100644 --- a/collabstack-be/security/src/main/java/net/collabstack/security/member/SecurityMember.java +++ b/collabstack-be/security/src/main/java/net/collabstack/security/member/SecurityMember.java @@ -3,49 +3,13 @@ import java.util.Collection; import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; import lombok.Data; @Data -public class SecurityMember implements UserDetails { +public class SecurityMember { private final T id; private final String username; - private final boolean isAccountNonExpired; private final Collection authorities; - - @Override - public Collection getAuthorities() { - return authorities; - } - - public String getUsername() { - return username; - } - - @Override - public boolean isAccountNonExpired() { - return isAccountNonExpired; - } - - @Override - public boolean isAccountNonLocked() { - return true; - } - - @Override - public boolean isCredentialsNonExpired() { - return isAccountNonExpired; - } - - @Override - public boolean isEnabled() { - return true; - } - - @Override - public String getPassword() { - return null; - } }