diff --git a/server/README.md b/server/README.md deleted file mode 100644 index 76ac08dd..00000000 --- a/server/README.md +++ /dev/null @@ -1 +0,0 @@ -# Server diff --git a/server/edusync/.gitignore b/server/edusync/.gitignore deleted file mode 100644 index c2065bc2..00000000 --- a/server/edusync/.gitignore +++ /dev/null @@ -1,37 +0,0 @@ -HELP.md -.gradle -build/ -!gradle/wrapper/gradle-wrapper.jar -!**/src/main/**/build/ -!**/src/test/**/build/ - -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache -bin/ -!**/src/main/**/bin/ -!**/src/test/**/bin/ - -### IntelliJ IDEA ### -.idea -*.iws -*.iml -*.ipr -out/ -!**/src/main/**/out/ -!**/src/test/**/out/ - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ - -### VS Code ### -.vscode/ diff --git a/server/edusync/background_run_app.sh b/server/edusync/background_run_app.sh deleted file mode 100644 index 1d1b19cd..00000000 --- a/server/edusync/background_run_app.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -# Build the project -./gradlew bootJar -x test - -# Run the app.jar file in the /build/libs directory -nohup java -jar build/libs/app.jar --spring.profiles.active=server &>/dev/null & disown \ No newline at end of file diff --git a/server/edusync/build.gradle b/server/edusync/build.gradle deleted file mode 100644 index 5bf9a631..00000000 --- a/server/edusync/build.gradle +++ /dev/null @@ -1,86 +0,0 @@ -plugins { - id 'java' - id 'org.springframework.boot' version '2.7.10' - id 'io.spring.dependency-management' version '1.0.15.RELEASE' - id "org.asciidoctor.jvm.convert" version "3.3.2" // .adoc 파일 확장자를 가지는 AsciiDoc 문서를 생성해주는 Asciidoctor를 사용하기 위한 플러그인 추가 - id 'war' -} - -ext { // API 문서 스니핏이 생성될 경로를 지정 - set('snippetsDir', file("build/generated-snippets")) -} - -group = 'com.seb33' -version = '0.0.1-SNAPSHOT' -sourceCompatibility = '11' - -configurations { - asciidoctorExtensions - compileOnly { - extendsFrom annotationProcessor - } -} - -repositories { - mavenCentral() -} - -dependencies { - testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' // spring-restdocs-core와 spring-restdocs-mockmvc 의존 라이브러리 추가 - asciidoctorExtensions 'org.springframework.restdocs:spring-restdocs-asciidoctor' // asciidoctorExtensions 그룹에 spring-restdocs-asciidoctor 의존 라이브러리를 추가 - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' - implementation 'org.springframework.boot:spring-boot-starter-security' - implementation 'org.springframework.boot:spring-boot-starter-web' - compileOnly 'org.projectlombok:lombok' - developmentOnly 'org.springframework.boot:spring-boot-devtools' - runtimeOnly 'com.mysql:mysql-connector-j' - annotationProcessor 'org.projectlombok:lombok' - testImplementation 'org.springframework.boot:spring-boot-starter-test' - testImplementation 'org.springframework.security:spring-security-test' - - implementation 'org.springframework.boot:spring-boot-starter-validation' // 유효성검사용 라이브러리 추가 - - implementation 'org.mapstruct:mapstruct:1.5.2.Final' // mapstruct - annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.2.Final' - implementation 'org.springframework.boot:spring-boot-starter-mail' // 이메일 전송용 - - implementation 'com.google.code.gson:gson' // (dto를) json으로 쉽게 바꿔주는 util 라이브러리 - - implementation 'io.jsonwebtoken:jjwt-api:0.11.5' // JWT 기능을 위한 jjwt 라이브러리 - runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' - runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' - - implementation 'org.jsoup:jsoup:1.14.2' -} - -tasks.named('test') { -// outputs.dir snippetsDir - useJUnitPlatform() -} - -tasks.named('asciidoctor') { // :asciidoctor task 실행 시 - configurations "asciidoctorExtensions" // Asciidoctor 기능을 사용하기 위해 :asciidoctor task에 asciidoctorExtensions 을 설정 - inputs.dir snippetsDir - dependsOn test -} - -// :build 실행 전에 실행되는 task -task copyDocument(type: Copy) { - dependsOn asciidoctor // [:asciidoctor]가 실행된 후에 task가 실행 되도록 의존성을 설정 - from file("${asciidoctor.outputDir}") // "build/docs/asciidoc/" 경로에 생성되는 index.html을 copy - into file("src/main/resources/static/docs") // 괄호안 경로에 복사한 index.html을 추가 -} - -build { - dependsOn copyDocument // :build task가 실행되기 전에 :copyDocument task가 먼저 수행 되도록 의존성 설정 -} - -// 애플리케이션 실행 파일이 생성하는 :bootJar task 설정 -bootJar { - archiveFileName = 'app.jar' // 애플리케이션 이름 짧게 만들기 - dependsOn copyDocument // :bootJar task 실행 전에 :copyDocument task가 실행 되도록 의존성을 설정 - from ("${asciidoctor.outputDir}") { - into 'static/docs' // Asciidoctor 실행으로 생성되는 index.html 파일을 jar 파일 안에 추가 - } // jar 파일에 index.html을 추가해 줌으로써 웹 브라우저에서 접속(http://localhost:8080/docs/index.html) 후, API 문서를 확인할 수 있게 된다. -} diff --git a/server/edusync/gradle/wrapper/gradle-wrapper.jar b/server/edusync/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 249e5832..00000000 Binary files a/server/edusync/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/server/edusync/gradle/wrapper/gradle-wrapper.properties b/server/edusync/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 774fae87..00000000 --- a/server/edusync/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/server/edusync/gradlew b/server/edusync/gradlew deleted file mode 100644 index a69d9cb6..00000000 --- a/server/edusync/gradlew +++ /dev/null @@ -1,240 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/server/edusync/gradlew.bat b/server/edusync/gradlew.bat deleted file mode 100644 index f127cfd4..00000000 --- a/server/edusync/gradlew.bat +++ /dev/null @@ -1,91 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/server/edusync/run_app.sh b/server/edusync/run_app.sh deleted file mode 100644 index 88974771..00000000 --- a/server/edusync/run_app.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -# Build the project -./gradlew bootJar -x test - -# Run the app.jar file in the /build/libs directory -java -jar build/libs/app.jar --spring.profiles.active=server diff --git a/server/edusync/settings.gradle b/server/edusync/settings.gradle deleted file mode 100644 index 86585926..00000000 --- a/server/edusync/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'edusync' diff --git a/server/edusync/src/main/java/com/codestates/edusync/EdusyncApplication.java b/server/edusync/src/main/java/com/codestates/edusync/EdusyncApplication.java deleted file mode 100644 index eb98356f..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/EdusyncApplication.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.codestates.edusync; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class EdusyncApplication { - - public static void main(String[] args) { - SpringApplication.run(EdusyncApplication.class, args); - } - -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/audit/Auditable.java b/server/edusync/src/main/java/com/codestates/edusync/audit/Auditable.java deleted file mode 100644 index 20fe7481..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/audit/Auditable.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.codestates.edusync.audit; - -import lombok.Getter; -import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.annotation.LastModifiedDate; -import org.springframework.data.jpa.domain.support.AuditingEntityListener; - -import javax.persistence.Column; -import javax.persistence.EntityListeners; -import javax.persistence.MappedSuperclass; -import java.time.LocalDateTime; - -@Getter -@MappedSuperclass -@EntityListeners(AuditingEntityListener.class) -public abstract class Auditable { - @CreatedDate // Entity 생성시간 자동 저장 - @Column(name = "created_at", updatable = false) - private LocalDateTime createdAt; - - @LastModifiedDate // 조회한 Entity의 값을 변경할 때 시간 자동 저장(수정) - private LocalDateTime modifiedAt; -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/audit/utils/ErrorResponder.java b/server/edusync/src/main/java/com/codestates/edusync/audit/utils/ErrorResponder.java deleted file mode 100644 index a0a366bb..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/audit/utils/ErrorResponder.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.codestates.edusync.audit.utils; - -import com.codestates.edusync.response.ErrorResponse; -import com.google.gson.Gson; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; - -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -public class ErrorResponder { - public static void sendErrorResponse(HttpServletResponse response, HttpStatus status, String message) throws IOException { - Gson gson = new Gson(); - ErrorResponse errorResponse = ErrorResponse.of(status, message); - response.setContentType(MediaType.APPLICATION_JSON_VALUE); // 응답의 컨텐츠 타입을 JSON으로 설정 - response.setStatus(status.value()); // status 작성 - response.getWriter().write(gson.toJson(errorResponse, ErrorResponse.class)); // response body 부분 작성 - } - - -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/auth/dto/LoginDto.java b/server/edusync/src/main/java/com/codestates/edusync/auth/dto/LoginDto.java deleted file mode 100644 index fdcafbf4..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/auth/dto/LoginDto.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.codestates.edusync.auth.dto; - -import lombok.Getter; - -@Getter -public class LoginDto { - private String email; - private String password; -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/auth/filter/JwtAuthenticationFilter.java b/server/edusync/src/main/java/com/codestates/edusync/auth/filter/JwtAuthenticationFilter.java deleted file mode 100644 index c7cdbe51..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/auth/filter/JwtAuthenticationFilter.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.codestates.edusync.auth.filter; - -import com.codestates.edusync.auth.dto.LoginDto; -import com.codestates.edusync.auth.jwt.JwtTokenizer; -import com.codestates.edusync.member.entity.Member; -import com.fasterxml.jackson.databind.ObjectMapper; -import lombok.SneakyThrows; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -// 로그인 인증 요청을 처리하는 Custom Security Filter 구현 -public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter { // 디폴트 Security Filter인 UsernamePasswordAuthenticationFilter를 확장해서 구현 - private final AuthenticationManager authenticationManager; - // DI 받은 AuthenticationManager는 로그인 인증 정보(Username/Password)를 전달받아 UserDetailsService와 인터랙션 한 뒤 인증 여부를 판단 - private final JwtTokenizer jwtTokenizer; - // DI 받은 JwtTokenizer는 클라이언트가 인증에 성공할 경우, JWT를 생성 및 발급하는 역할 - - public JwtAuthenticationFilter(AuthenticationManager authenticationManager, JwtTokenizer jwtTokenizer) { - this.authenticationManager = authenticationManager; - this.jwtTokenizer = jwtTokenizer; - } - - @SneakyThrows // 예외처리 무시 - @Override - public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) { // 인증을 시도하는 로직을 구현 - ObjectMapper objectMapper = new ObjectMapper(); - LoginDto loginDto = objectMapper.readValue(request.getInputStream(), LoginDto.class); // 역직렬화(Deserialization) - - UsernamePasswordAuthenticationToken authenticationToken = - new UsernamePasswordAuthenticationToken(loginDto.getEmail(), loginDto.getPassword()); // Username과 Password 정보를 포함한 UsernamePasswordAuthenticationToken 생성 - - return authenticationManager.authenticate(authenticationToken); // UsernamePasswordAuthenticationToken을 AuthenticationManager에게 전달하면서 인증 처리를 위임 - } - - // 인증에 성공할 경우 (Spring Security에서 자동으로) 호출되는 메서드 - @Override - protected void successfulAuthentication(HttpServletRequest request, - HttpServletResponse response, - FilterChain chain, - Authentication authResult) throws ServletException, IOException { - Member member = (Member) authResult.getPrincipal(); // 인증 정보로 Member 엔티티 객체 만들기 - - String accessToken = delegateAccessToken(member); // Access Token 생성 - String refreshToken = delegateRefreshToken(member); // Refresh Token 생성 - - response.setHeader("Authorization", "Bearer " + accessToken); // 클리이언트한테 Access Token 보내주기 (이후에 클라이언트 측에서 백엔드 애플리케이션 측에 요청을 보낼 때마다 request header에 추가해서 클라이언트 측의 자격을 증명하는데 사용) - response.setHeader("Refresh", "Bearer " + refreshToken); // 클리이언트한테 Refresh Token 보내주기 - - this.getSuccessHandler().onAuthenticationSuccess(request, response, authResult); // MemberAuthenticationSuccessHandler의 onAuthenticationSuccess() 메서드 호출 - // 인증 성공 후에 할 동작을 설정해둔걸 불러와서 수행 - // 인증 실패 할 경우 MemberAuthenticationFailureHandler클래스의 onAuthenticationFailure() 메서드는 코드 추가 없이도 알아서 호출된다. - } - - // Access Token을 생성하는 구체적인 로직 - private String delegateAccessToken(Member member) { - Map claims = new HashMap<>(); - claims.put("email", member.getEmail()); - claims.put("roles", member.getRoles()); - claims.put("nickName", member.getNickName()); - - String subject = member.getEmail(); - Date expiration = jwtTokenizer.getTokenExpiration(jwtTokenizer.getAccessTokenExpirationMinutes()); - - String base64EncodedSecretKey = jwtTokenizer.encodeBase64SecretKey(jwtTokenizer.getSecretKey()); - - String accessToken = jwtTokenizer.generateAccessToken(claims, subject, expiration, base64EncodedSecretKey); - - return accessToken; - } - - // Refresh Token을 생성하는 구체적인 로직 - private String delegateRefreshToken(Member member) { - String subject = member.getEmail(); - Date expiration = jwtTokenizer.getTokenExpiration(jwtTokenizer.getRefreshTokenExpirationMinutes()); - String base64EncodedSecretKey = jwtTokenizer.encodeBase64SecretKey(jwtTokenizer.getSecretKey()); - - String refreshToken = jwtTokenizer.generateRefreshToken(subject, expiration, base64EncodedSecretKey); - - return refreshToken; - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/auth/filter/JwtVerificationFilter.java b/server/edusync/src/main/java/com/codestates/edusync/auth/filter/JwtVerificationFilter.java deleted file mode 100644 index 09ccaf13..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/auth/filter/JwtVerificationFilter.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.codestates.edusync.auth.filter; - -import com.codestates.edusync.auth.jwt.JwtTokenizer; -import com.codestates.edusync.auth.utils.CustomAuthorityUtils; -import io.jsonwebtoken.ExpiredJwtException; -import io.jsonwebtoken.MalformedJwtException; -import io.jsonwebtoken.security.SignatureException; -import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.web.filter.OncePerRequestFilter; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.List; -import java.util.Map; - -import static com.codestates.edusync.audit.utils.ErrorResponder.sendErrorResponse; - -// JWT 검증 필터 구현 클래스 -// 클라이언트 측에서 전송된 request header에 포함된 JWT에 대해 검증 작업을 수행하는 코드 -@RequiredArgsConstructor -public class JwtVerificationFilter extends OncePerRequestFilter { // OncePerRequestFilter 상속받아서 request 당 단 한 번만 수행 - private final JwtTokenizer jwtTokenizer; // JWT를 검증하고 Claims(토큰에 포함된 정보)를 얻는 데 사용 - private final CustomAuthorityUtils authorityUtils; // JWT 검증에 성공하면 Authentication 객체에 채울 사용자의 권한을 생성하는 데 사용 - - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { - try { - Map claims = verifyJws(request); // JWT 검증 - setAuthenticationToContext(claims); // SecurityContext에 검증된 정보 저장 - filterChain.doFilter(request, response); // 인증이 성공한 경우 다음 필터 호출 - } catch (SignatureException se) { - sendErrorResponse(response, HttpStatus.valueOf(401), "The token information is incorrect."); // 토큰 정보가 잘못되었을 경우 401 응답 반환 - } catch (MalformedJwtException me){ - sendErrorResponse(response, HttpStatus.valueOf(401), "JWT strings must contain exactly 2 period characters"); // 토큰 정보가 잘못되었을 경우 401 응답 반환 - } catch (ExpiredJwtException ee) { - sendErrorResponse(response, HttpStatus.valueOf(401), "The token has expired."); // JWT가 만료된 경우 401 응답 반환 - } catch (Exception e) { -// sendErrorResponse(response, HttpStatus.valueOf(401), "The token information is incorrect."); - request.setAttribute("exception", e); // 토큰의 길이가 짧으면 다른 오류를 발생시켜서 주석처리 함 - filterChain.doFilter(request, response); - } - } - - // 특정 조건에 부합하면(true이면) 해당 Filter의 동작을 수행하지 않고 다음 Filter로 건너뛰도록 해주는 메서드인 OncePerRequestFilter의 shouldNotFilter()를 오버라이드 - @Override - protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException { - String authorization = request.getHeader("Authorization"); - - return authorization == null; // header의 값이 null이면 해당 Filter(토큰 검증)의 동작을 수행하지 않도록 정의 - // JWT가 Authorization header에 포함되지 않았다면 JWT 자격증명이 필요하지 않은 리소스에 대한 요청이라고 판단하고 다음(Next) Filter로 처리를 넘기는 것 - } - - private Map verifyJws(HttpServletRequest request) { // JWT를 검증하는데 사용되는 메서드 - if(!request.getHeader("Authorization").startsWith("Bearer ")) { - throw new SignatureException(""); - } - String jws = request.getHeader("Authorization").replace("Bearer ", ""); // "Bearer" 부분을 제거해서 JWT(accessToken) 얻기 - String base64EncodedSecretKey = jwtTokenizer.encodeBase64SecretKey(jwtTokenizer.getSecretKey()); // JWT 서명(Signature)을 검증하기 위한 Secret Key 얻기 - Map claims = jwtTokenizer.getClaims(jws, base64EncodedSecretKey).getBody(); // Claims를 파싱 // 여기서 오류가 발생하면 SignatureException 발생 - - return claims; // Claims가 정상적으로 파싱이 되면 서명 검증에 성공한거다. - } - - private void setAuthenticationToContext(Map claims) { // Authentication 객체를 SecurityContext에 저장하기 위한 메서드 - String username = (String) claims.get("email"); // 파싱한 Claims에서 username 얻기 - List authorities = authorityUtils.createAuthorities((List)claims.get("roles")); // Claims에서 권한 정보 얻기 - Authentication authentication = new UsernamePasswordAuthenticationToken(username, null, authorities); // 이미 앞에서 인증된 Authentication객체를 생성하는데 비밀번호는 불필요하니까 null입력 - SecurityContextHolder.getContext().setAuthentication(authentication); // SecurityContext에 Authentication 객체를 저장 - } - -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/auth/handler/MemberAccessDeniedHandler.java b/server/edusync/src/main/java/com/codestates/edusync/auth/handler/MemberAccessDeniedHandler.java deleted file mode 100644 index 45f8ecc0..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/auth/handler/MemberAccessDeniedHandler.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.codestates.edusync.auth.handler; - -import com.codestates.edusync.audit.utils.ErrorResponder; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.HttpStatus; -import org.springframework.security.access.AccessDeniedException; -import org.springframework.security.web.access.AccessDeniedHandler; -import org.springframework.stereotype.Component; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -// 인증에는 성공했지만 해당 리소스에 대한 권한이 없으면 호출되는 핸들러 -@Slf4j -@Component -public class MemberAccessDeniedHandler implements AccessDeniedHandler { - @Override - public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { - ErrorResponder.sendErrorResponse(response, HttpStatus.FORBIDDEN, "The member does not have permission to access the requested resource."); // 클라이언트한테 응답 - log.warn("Forbidden error happened: {}", accessDeniedException.getMessage()); // 발생한 예외 log로 남기기 - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/auth/handler/MemberAuthenticationEntryPoint.java b/server/edusync/src/main/java/com/codestates/edusync/auth/handler/MemberAuthenticationEntryPoint.java deleted file mode 100644 index f0b1f670..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/auth/handler/MemberAuthenticationEntryPoint.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.codestates.edusync.auth.handler; - -import com.codestates.edusync.audit.utils.ErrorResponder; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.HttpStatus; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.AuthenticationEntryPoint; -import org.springframework.stereotype.Component; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -// AuthenticationException(인증오류)이 발생할 때 호출되는 핸들러 같은 역할 -@Slf4j -@Component -public class MemberAuthenticationEntryPoint implements AuthenticationEntryPoint { - @Override // 인증 요청이 실패했을 때 호출되는 메서드 - public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { - Exception exception = (Exception) request.getAttribute("exception"); // 어떤 오류인지 exception에 할당 (필터에서 저장했던 request의 Attribute 중 exception) - ErrorResponder.sendErrorResponse(response, HttpStatus.UNAUTHORIZED, "Authentication error occurred."); // 클라이언트에게 401 응답 보내기 - - logExceptionMessage(authException, exception); // (인증 과정에서 발생한 예외 정보 or 요청 객체에서 얻어온 예외 정보) log로 남기기 - } - - private void logExceptionMessage(AuthenticationException authException, Exception exception) { - String message = exception != null ? exception.getMessage() : authException.getMessage(); // exception이 null이 아니면 전자, null이면 후자를 message에 할당 - log.warn("Unauthorized error happened: {}", message); - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/auth/handler/MemberAuthenticationFailureHandler.java b/server/edusync/src/main/java/com/codestates/edusync/auth/handler/MemberAuthenticationFailureHandler.java deleted file mode 100644 index 903ff42f..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/auth/handler/MemberAuthenticationFailureHandler.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.codestates.edusync.auth.handler; - -import com.codestates.edusync.audit.utils.ErrorResponder; -import com.codestates.edusync.response.ErrorResponse; -import com.google.gson.Gson; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.web.authentication.AuthenticationFailureHandler; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -@Slf4j -public class MemberAuthenticationFailureHandler implements AuthenticationFailureHandler { // 로그인 인증 실패 시, 추가 작업을 할 수 있는 클래스 - @Override - public void onAuthenticationFailure(HttpServletRequest request, - HttpServletResponse response, - AuthenticationException exception) throws IOException { - // 인증 실패 시, 에러 로그를 기록하거나 error response를 전송할 수 있다. - log.error("# Authentication failed: {}", exception.getMessage()); - - ErrorResponder.sendErrorResponse(response, HttpStatus.UNAUTHORIZED, "Please check your email and password again."); - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/auth/handler/MemberAuthenticationSuccessHandler.java b/server/edusync/src/main/java/com/codestates/edusync/auth/handler/MemberAuthenticationSuccessHandler.java deleted file mode 100644 index 76512c43..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/auth/handler/MemberAuthenticationSuccessHandler.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.codestates.edusync.auth.handler; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.security.core.Authentication; -import org.springframework.security.web.authentication.AuthenticationSuccessHandler; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; - -@Slf4j -public class MemberAuthenticationSuccessHandler implements AuthenticationSuccessHandler { // 로그인 인증 성공 시 추가 작업을 할 수 있는 클래스 - @Override - public void onAuthenticationSuccess(HttpServletRequest request, - HttpServletResponse response, - Authentication authentication) throws IOException { - log.info("# Authenticated successfully!"); - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/auth/handler/OAuth2MemberSuccessHandler.java b/server/edusync/src/main/java/com/codestates/edusync/auth/handler/OAuth2MemberSuccessHandler.java deleted file mode 100644 index 4e62e56e..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/auth/handler/OAuth2MemberSuccessHandler.java +++ /dev/null @@ -1,169 +0,0 @@ -package com.codestates.edusync.auth.handler; - -import com.codestates.edusync.auth.jwt.JwtTokenizer; -import com.codestates.edusync.auth.utils.CustomAuthorityUtils; -import com.codestates.edusync.exception.BusinessLogicException; -import com.codestates.edusync.exception.ExceptionCode; -import com.codestates.edusync.member.entity.Member; -import com.codestates.edusync.member.repository.MemberRepository; -import lombok.extern.slf4j.Slf4j; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; -import org.springframework.security.oauth2.core.user.OAuth2User; -import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; -import org.springframework.stereotype.Component; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.util.UriComponentsBuilder; -import org.springframework.security.core.authority.SimpleGrantedAuthority; - - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.net.URI; -import java.util.*; -import java.util.stream.Collectors; - -// OAuth 2 인증 후, Frontend 애플리케이션 쪽으로 JWT를 전송하는 역할 -@Slf4j -@Component -public class OAuth2MemberSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { - private final JwtTokenizer jwtTokenizer; - private final CustomAuthorityUtils authorityUtils; - private final MemberRepository memberRepository; - - public OAuth2MemberSuccessHandler(JwtTokenizer jwtTokenizer, - CustomAuthorityUtils authorityUtils, MemberRepository memberRepository) { - this.jwtTokenizer = jwtTokenizer; - this.authorityUtils = authorityUtils; - this.memberRepository = memberRepository; - } - - @Override - public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { - var oAuth2User = (OAuth2User)authentication.getPrincipal(); -// String email = String.valueOf(oAuth2User.getAttributes().get("email")); // OAuth2User 객체로부터 Resource Owner의 이메일 주소를 얻기 -// String nickName = String.valueOf(oAuth2User.getAttributes().get("name")); // 이름을 얻기 -// String profileImage = String.valueOf(oAuth2User.getAttributes().get("picture")); // 프로필 이미지 URL을 얻기 - - OAuth2AuthenticationToken authToken = (OAuth2AuthenticationToken) authentication; - String providerType = authToken.getAuthorizedClientRegistrationId(); - - String email; - String nickName; - String profileImage; - - if ("google".equals(providerType)) { - email = String.valueOf(oAuth2User.getAttributes().get("email")); - nickName = String.valueOf(oAuth2User.getAttributes().get("name")); - profileImage = String.valueOf(oAuth2User.getAttributes().get("picture")); - } else if ("kakao".equals(providerType)) { - Map attributes = oAuth2User.getAttributes(); - Map kakaoAccount = (Map) attributes.get("kakao_account"); - email = (String) kakaoAccount.get("email"); - Map profile = (Map) kakaoAccount.get("profile"); - nickName = (String) profile.get("nickname"); - profileImage = (String) profile.get("profile_image_url"); - } else if ("naver".equals(providerType)) { - Map attributes = oAuth2User.getAttributes(); - Map response2 = (Map) attributes.get("response"); - email = (String) response2.get("email"); - nickName = (String) response2.get("name"); - profileImage = (String) response2.get("profile_image"); - } else { - throw new IllegalArgumentException("Unsupported provider: " + providerType); - } - - Optional optionalMember = memberRepository.findByEmail(email); - - Member member; - if (optionalMember.isEmpty()) { // 이메일이 저장되어 있지 않은 경우 - member = saveMember(email, nickName, profileImage); // Resource Owner의 정보를 DB에 저장 - } else { - member = optionalMember.get(); - } - - redirect(request, response, member); // Access Token과 Refresh Token을 생성해서 Frontend 애플리케이션에 전달하기 위해 Redirect - } - - private Member saveMember(String email, String nickname, String profileImage) { - memberRepository.findByEmail(email).ifPresent(it -> - {throw new BusinessLogicException(ExceptionCode.MEMBER_EXISTS, String.format("%s is duplicated 버그발생! OAuth2 핸들러 검사하시오.", email)); - }); - Member member = new Member(); - member.setEmail(email); - member.setNickName(nickname); - member.setProfileImage(profileImage); - List roles = authorityUtils.createRoles(email); - member.setRoles(roles); - Member savedMember = memberRepository.save(member); - - return savedMember; - } - - private void redirect(HttpServletRequest request, HttpServletResponse response, Member member) throws IOException { - String accessToken = delegateAccessToken(member); // JWT Access Token 생성 - String refreshToken = delegateRefreshToken(member.getEmail()); // Refresh Token 생성 - - response.setHeader("Authorization", "Bearer " + accessToken); // 클리이언트한테 Access Token 보내주기 (이후에 클라이언트 측에서 백엔드 애플리케이션 측에 요청을 보낼 때마다 request header에 추가해서 클라이언트 측의 자격을 증명하는데 사용) - response.setHeader("Refresh", "Bearer " + refreshToken); // 클리이언트한테 Refresh Token 보내주기 - - String uri = createURI(accessToken, refreshToken).toString(); // Access Token과 Refresh Token을 포함한 URL을 생성 - getRedirectStrategy().sendRedirect(request, response, uri); // Frontend 애플리케이션 쪽으로 리다이렉트 - - log.info("# Authenticated successfully!"); - - // response 헤더 정보 로그 출력 - for (String headerName : response.getHeaderNames()) { - log.info(headerName + ": " + response.getHeader(headerName)); - } - } - - private String delegateAccessToken(Member member) { // Todo 코드의 중복 어떻게 해결할까? - Map claims = new HashMap<>(); - claims.put("email", member.getEmail()); - claims.put("nickName", member.getNickName()); - claims.put("roles", member.getRoles()); - - String subject = member.getEmail(); - - Date expiration = jwtTokenizer.getTokenExpiration(jwtTokenizer.getAccessTokenExpirationMinutes()); - - String base64EncodedSecretKey = jwtTokenizer.encodeBase64SecretKey(jwtTokenizer.getSecretKey()); - - String accessToken = jwtTokenizer.generateAccessToken(claims, subject, expiration, base64EncodedSecretKey); - - return accessToken; - } - - private String delegateRefreshToken(String username) { - String subject = username; - Date expiration = jwtTokenizer.getTokenExpiration(jwtTokenizer.getRefreshTokenExpirationMinutes()); - String base64EncodedSecretKey = jwtTokenizer.encodeBase64SecretKey(jwtTokenizer.getSecretKey()); - - String refreshToken = jwtTokenizer.generateRefreshToken(subject, expiration, base64EncodedSecretKey); - - return refreshToken; - } - - private URI createURI(String accessToken, String refreshToken) { - MultiValueMap queryParams = new LinkedMultiValueMap<>(); - queryParams.add("access_token", accessToken); - queryParams.add("refresh_token", refreshToken); - - return UriComponentsBuilder - .newInstance() - .scheme("http") - .host("localhost") // Todo 리액트 서버 도메인 주소 입력 - .port(8080) - .queryParams(queryParams) - .build() - .toUri(); - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/auth/jwt/JwtTokenizer.java b/server/edusync/src/main/java/com/codestates/edusync/auth/jwt/JwtTokenizer.java deleted file mode 100644 index 9a3424ad..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/auth/jwt/JwtTokenizer.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.codestates.edusync.auth.jwt; - -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.Jws; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.io.Decoders; -import io.jsonwebtoken.io.Encoders; -import io.jsonwebtoken.security.Keys; -import lombok.Getter; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -import java.nio.charset.StandardCharsets; -import java.security.Key; -import java.util.Calendar; -import java.util.Date; -import java.util.Map; - -@Component // Bean 등록 -public class JwtTokenizer { // JWT(JSON Web Token)를 생성하고 검증하는 역할을 수행하는 클래스 - @Getter - @Value("${jwt.key}") - private String secretKey; // JWT 생성 및 검증 시 사용되는 Secret Key 정보 - - @Getter - @Value("${jwt.access-token-expiration-minutes}") - private int accessTokenExpirationMinutes; // Access Token에 대한 만료 시간 정보 - - @Getter - @Value("${jwt.refresh-token-expiration-minutes}") - private int refreshTokenExpirationMinutes; // Refresh Token에 대한 만료 시간 정보 - - public String encodeBase64SecretKey(String secretKey) { - return Encoders.BASE64.encode(secretKey.getBytes(StandardCharsets.UTF_8)); - } - - public String generateAccessToken(Map claims, - String subject, - Date expiration, - String base64EncodedSecretKey) { - Key key = getKeyFromBase64EncodedKey(base64EncodedSecretKey); - - return Jwts.builder() - .setClaims(claims) - .setSubject(subject) - .setIssuedAt(Calendar.getInstance().getTime()) - .setExpiration(expiration) - .signWith(key) - .compact(); - } - - public String generateRefreshToken(String subject, Date expiration, String base64EncodedSecretKey) { - Key key = getKeyFromBase64EncodedKey(base64EncodedSecretKey); - - return Jwts.builder() - .setSubject(subject) - .setIssuedAt(Calendar.getInstance().getTime()) - .setExpiration(expiration) - .signWith(key) - .compact(); - } - - public Jws getClaims(String jws, String base64EncodedSecretKey) { - Key key = getKeyFromBase64EncodedKey(base64EncodedSecretKey); // base64로 인코딩된 Secret Key를 디코딩하여 Key 객체 얻기 - - Jws claims = Jwts.parserBuilder()// JwtParserBuilder 인스턴스를 생성해서 JWT 파싱에 필요한 설정을 지정 - .setSigningKey(key) // 서명 검증에 사용할 시크릿키를 설정 - .build() // JwtParser 객체 생성 - .parseClaimsJws(jws); // 입력으로 받은 JWT 토큰 문자열을 파싱+key와 비교해 검증 - return claims; // 클레임(토큰 데이터)을 포함하는 Jws 객체를 반환 - } - - public void verifySignature(String jws, String base64EncodedSecretKey) { - Key key = getKeyFromBase64EncodedKey(base64EncodedSecretKey); - - Jwts.parserBuilder() - .setSigningKey(key) - .build() - .parseClaimsJws(jws); - } - - public Date getTokenExpiration(int expirationMinutes) { - Calendar calendar = Calendar.getInstance(); - calendar.add(Calendar.MINUTE, expirationMinutes); - Date expiration = calendar.getTime(); - - return expiration; - } - - private Key getKeyFromBase64EncodedKey(String base64EncodedSecretKey) { - byte[] keyBytes = Decoders.BASE64.decode(base64EncodedSecretKey); - Key key = Keys.hmacShaKeyFor(keyBytes); - - return key; - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/auth/refresh/RefreshController.java b/server/edusync/src/main/java/com/codestates/edusync/auth/refresh/RefreshController.java deleted file mode 100644 index 941d7559..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/auth/refresh/RefreshController.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.codestates.edusync.auth.refresh; - -import com.codestates.edusync.auth.jwt.JwtTokenizer; -import com.codestates.edusync.member.entity.Member; -import com.codestates.edusync.member.repository.MemberRepository; -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.Jws; -import io.jsonwebtoken.JwtException; -import lombok.AllArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import javax.servlet.http.HttpServletRequest; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -@RestController -@RequestMapping("/refresh") -@AllArgsConstructor -public class RefreshController { - private final JwtTokenizer jwtTokenizer; - private final MemberRepository memberRepository; - @PostMapping - public ResponseEntity refreshAccessToken(HttpServletRequest request) { // 리프레쉬 토큰 받으면 엑세스 토큰 재발급 - String refreshTokenHeader = request.getHeader("Refresh"); - if (refreshTokenHeader != null && refreshTokenHeader.startsWith("Bearer ")) { - String refreshToken = refreshTokenHeader.substring(7); - try { - Jws claims = jwtTokenizer.getClaims(refreshToken, jwtTokenizer.encodeBase64SecretKey(jwtTokenizer.getSecretKey())); - - String email = claims.getBody().getSubject(); - Optional optionalMember = memberRepository.findByEmail(email); - - if (optionalMember.isPresent()) { - Member member = optionalMember.get(); - String accessToken = delegateAccessToken(member); - - return ResponseEntity.ok().header("Authorization", "Bearer " + accessToken).body("Access token refreshed"); - } else { - return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid member email"); - } - } catch (JwtException e) { - return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid refresh token"); - } - } else { - return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Missing refresh token"); - } - } - - private String delegateAccessToken(Member member) { // 코드의 중복...찝찝하다. - Map claims = new HashMap<>(); - claims.put("email", member.getEmail()); - claims.put("roles", member.getRoles()); - claims.put("nickName", member.getNickName()); - - String subject = member.getEmail(); - Date expiration = jwtTokenizer.getTokenExpiration(jwtTokenizer.getAccessTokenExpirationMinutes()); - - String base64EncodedSecretKey = jwtTokenizer.encodeBase64SecretKey(jwtTokenizer.getSecretKey()); - - String accessToken = jwtTokenizer.generateAccessToken(claims, subject, expiration, base64EncodedSecretKey); - - return accessToken; - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/auth/userdetails/MemberDetailsService.java b/server/edusync/src/main/java/com/codestates/edusync/auth/userdetails/MemberDetailsService.java deleted file mode 100644 index 4498cc6d..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/auth/userdetails/MemberDetailsService.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.codestates.edusync.auth.userdetails; - -import com.codestates.edusync.auth.utils.CustomAuthorityUtils; -import com.codestates.edusync.exception.BusinessLogicException; -import com.codestates.edusync.exception.ExceptionCode; -import com.codestates.edusync.member.entity.Member; -import com.codestates.edusync.member.repository.MemberRepository; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.stereotype.Component; - -import java.util.Collection; -import java.util.Optional; - -@Component -public class MemberDetailsService implements UserDetailsService { - - private final MemberRepository memberRepository; - private final CustomAuthorityUtils authorityUtils; - - public MemberDetailsService(MemberRepository memberRepository, CustomAuthorityUtils authorityUtils) { - this.memberRepository = memberRepository; - this.authorityUtils = authorityUtils; - } - - - @Override - public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { - Optional optionalMember = memberRepository.findByEmail(email); - Member findMember = optionalMember.orElseThrow(() -> new BusinessLogicException(ExceptionCode.MEMBER_NOT_FOUND)); - - return new MemberDetails(findMember); - } - - private final class MemberDetails extends Member implements UserDetails { - MemberDetails(Member member) { - setId(member.getId()); - setEmail(member.getEmail()); - setPassword(member.getPassword()); - setNickName(member.getNickName()); - setRoles(member.getRoles()); - } - - @Override - public Collection getAuthorities() { - return authorityUtils.createAuthorities(this.getRoles()); - } - - @Override - public String getUsername() { - return getEmail(); - } - - @Override - public boolean isAccountNonExpired() { - return true; - } - - @Override - public boolean isAccountNonLocked() { - return true; - } - - @Override - public boolean isCredentialsNonExpired() { - return true; - } - - @Override - public boolean isEnabled() { - return true; - } - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/auth/utils/CustomAuthorityUtils.java b/server/edusync/src/main/java/com/codestates/edusync/auth/utils/CustomAuthorityUtils.java deleted file mode 100644 index 0706e383..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/auth/utils/CustomAuthorityUtils.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.codestates.edusync.auth.utils; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.AuthorityUtils; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.stereotype.Component; - -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; - -@Component -public class CustomAuthorityUtils { // 사용자 권한 부여, 확인을 위한 클래스 - @Value("${mail.address.admin}") // yml에 정의해 둔 관리자 이메일 가져오는거 - private String adminMailAddress; - - private final List ADMIN_ROLES = AuthorityUtils.createAuthorityList("ROLE_ADMIN", "ROLE_USER"); - private final List USER_ROLES = AuthorityUtils.createAuthorityList("ROLE_USER"); - private final List ADMIN_ROLES_STRING = List.of("ADMIN", "USER"); - private final List USER_ROLES_STRING = List.of("USER"); - - // 메모리 상의 Role을 기반으로 권한 정보 생성. - public List createAuthorities(String email) { - if (email.equals(adminMailAddress)) { - return ADMIN_ROLES; - } - return USER_ROLES; - } - - // DB에 저장된 Role을 기반으로 권한 정보 생성 - public List createAuthorities(List roles) { - List authorities = roles.stream() - .map(role -> new SimpleGrantedAuthority("ROLE_" + role)) - .collect(Collectors.toList()); - return authorities; - } - - // DB 저장 용 - public List createRoles(String email) { - if (email.equals(adminMailAddress)) { - return ADMIN_ROLES_STRING; - } - return USER_ROLES_STRING; - } - - // 관리자 확인용 - public boolean isAdmin(UserDetails userDetails) { - Collection authorities = userDetails.getAuthorities(); - - return authorities.stream() - .anyMatch(authority -> authority.getAuthority().equals("ROLE_ADMIN")); - } -} - - diff --git a/server/edusync/src/main/java/com/codestates/edusync/config/SecurityConfiguration.java b/server/edusync/src/main/java/com/codestates/edusync/config/SecurityConfiguration.java deleted file mode 100644 index 5a26f176..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/config/SecurityConfiguration.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.codestates.edusync.config; - -import com.codestates.edusync.auth.filter.JwtAuthenticationFilter; -import com.codestates.edusync.auth.filter.JwtVerificationFilter; -import com.codestates.edusync.auth.handler.*; -import com.codestates.edusync.auth.jwt.JwtTokenizer; -import com.codestates.edusync.auth.utils.CustomAuthorityUtils; -import lombok.RequiredArgsConstructor; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; -import org.springframework.security.config.http.SessionCreationPolicy; -import org.springframework.security.crypto.factory.PasswordEncoderFactories; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter; -import org.springframework.security.web.SecurityFilterChain; -import org.springframework.web.cors.CorsConfiguration; -import org.springframework.web.cors.CorsConfigurationSource; -import org.springframework.web.cors.UrlBasedCorsConfigurationSource; - -import java.util.Arrays; - -import static org.springframework.security.config.Customizer.withDefaults; - -@Configuration -@RequiredArgsConstructor -@EnableWebSecurity // Spring Security를 사용하기 위한 필수 설정들을 자동으로 등록 -@EnableGlobalMethodSecurity(prePostEnabled = true) // 메소드 보안 기능 활성화 -public class SecurityConfiguration { - private final JwtTokenizer jwtTokenizer; - private final CustomAuthorityUtils authorityUtils; - private final OAuth2MemberSuccessHandler oAuth2MemberSuccessHandler; - - @Bean - public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http - .csrf().disable() // CSRF공격에 대한 Spring Security에 대한 설정을 비활성화 - .cors(withDefaults()) // CORS 설정 추가 (corsConfigurationSource라는 이름으로 등록된 Bean을 이용) - .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 세션을 생성하지 않도록 설정 - .and() - .formLogin().disable() // 폼 로그인 방식을 비활성화 - .httpBasic().disable() // HTTP Basic 인증 방식을 비활성화 - .exceptionHandling() - .authenticationEntryPoint(new MemberAuthenticationEntryPoint()) // 인증오류가 발생할 때 처리해주는 핸들러 호출 - .accessDeniedHandler(new MemberAccessDeniedHandler()) // 인증에는 성공했지만 해당 리소스에 대한 권한이 없을 때 처리해주는 핸들러 호출 - .and() - .apply(new CustomFilterConfigurer()) // Custom Configurer 적용 - .and() - .authorizeHttpRequests(authorize -> authorize - .anyRequest().permitAll() // 모든 HTTP request 요청에 대해서 접근 허용 - ) - .oauth2Login() - .successHandler(oAuth2MemberSuccessHandler); // OAuth 2 인증이 성공한 뒤 실행되는 핸들러를 추가 -// .userInfoEndpoint() // OAuth2 로그인 성공 이후 사용자 정보를 가져올 때 설정을 저장 -// .userService(oauth2Service); // OAuth2 로그인 성공 시, 후작업을 진행할 UserService 인터페이스 구현체 등록 - return http.build(); - } - - @Bean - public PasswordEncoder passwordEncoder() { - return PasswordEncoderFactories.createDelegatingPasswordEncoder(); // PasswordEncoder Bean 객체 생성 - } - - - // CORS 정책 설정하는 방법 - @Bean - CorsConfigurationSource corsConfigurationSource() { // CorsConfigurationSource Bean 생성을 통해 구체적인 CORS 정책을 설정 - CorsConfiguration configuration = new CorsConfiguration(); - configuration.setAllowedOriginPatterns(Arrays.asList("*")); - configuration.setAllowedMethods(Arrays.asList("GET","POST", "PATCH", "DELETE", "OPTIONS")); // 파라미터로 지정한 HTTP Method에 대한 HTTP 통신을 허용 - configuration.setAllowedHeaders(Arrays.asList("*")); - configuration.setExposedHeaders(Arrays.asList("*")); - configuration.addAllowedHeader("*"); - configuration.setAllowCredentials(Boolean.valueOf(true)); // 토큰인증방식 이용할거니까 프론트측에서 Credentials true 가능하게 허용 - - UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); // CorsConfigurationSource 인터페이스의 구현 클래스인 UrlBasedCorsConfigurationSource 클래스의 객체를 생성 - source.registerCorsConfiguration("/**", configuration); // 모든 URL에 앞에서 구성한 CORS 정책(CorsConfiguration)을 적용 - return source; - } - - // Custom Configurer 클래스 (JwtAuthenticationFilter를 등록하는 역할) - public class CustomFilterConfigurer extends AbstractHttpConfigurer { // AbstractHttpConfigurer를 상속해서 Custom Configurer를 구현할 수 있다. - @Override - public void configure(HttpSecurity builder) throws Exception { // configure() 메서드를 오버라이드해서 Configuration을 커스터마이징 - AuthenticationManager authenticationManager = builder.getSharedObject(AuthenticationManager.class); // AuthenticationManager 객체 가져오기 - - JwtAuthenticationFilter jwtAuthenticationFilter = new JwtAuthenticationFilter(authenticationManager, jwtTokenizer); // JwtAuthenticationFilter를 생성하면서 JwtAuthenticationFilter에서 사용되는 AuthenticationManager와 JwtTokenizer를 DI - jwtAuthenticationFilter.setFilterProcessesUrl("/members/login"); // setFilterProcessesUrl() 메서드를 통해 디폴트 request URL인 “/login”을 “/members/login”으로 변경 - jwtAuthenticationFilter.setAuthenticationSuccessHandler(new MemberAuthenticationSuccessHandler()); // 인증 성공시 사용할 객체 등록 - jwtAuthenticationFilter.setAuthenticationFailureHandler(new MemberAuthenticationFailureHandler()); // 인증 실패시 사용할 객체 등록 - - JwtVerificationFilter jwtVerificationFilter = new JwtVerificationFilter(jwtTokenizer, authorityUtils); // JwtVerificationFilter의 인스턴스를 생성하면서 JwtVerificationFilter에서 사용되는 객체들을 생성자로 DI - - builder.addFilter(jwtAuthenticationFilter) // addFilter() 메서드를 통해 JwtAuthenticationFilter를 Spring Security Filter Chain에 추가 - .addFilterAfter(jwtVerificationFilter, JwtAuthenticationFilter.class) // JwtVerificationFilter는 JwtAuthenticationFilter에서 로그인 인증에 성공한 후 발급 받은 JWT가 클라이언트의 request header(Authorization 헤더)에 포함되어 있을 경우에만 동작한다. - .addFilterAfter(jwtVerificationFilter, OAuth2LoginAuthenticationFilter.class); - } - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/dto/MultiResponseDto.java b/server/edusync/src/main/java/com/codestates/edusync/dto/MultiResponseDto.java deleted file mode 100644 index 60b2d717..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/dto/MultiResponseDto.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.codestates.edusync.dto; - -import lombok.Getter; -import org.springframework.data.domain.Page; - -import java.util.List; - -@Getter -public class MultiResponseDto { - private List data; - private PageInfo pageInfo; - - public MultiResponseDto(List data, Page page) { - this.data = data; - this.pageInfo = new PageInfo(page.getNumber() + 1, - page.getSize(), page.getTotalElements(), page.getTotalPages()); - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/dto/PageInfo.java b/server/edusync/src/main/java/com/codestates/edusync/dto/PageInfo.java deleted file mode 100644 index 367aad6a..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/dto/PageInfo.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.codestates.edusync.dto; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@AllArgsConstructor -@Getter -public class PageInfo { - private int page; - private int size; - private long totalElements; - private int totalPages; -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/exception/BusinessLogicException.java b/server/edusync/src/main/java/com/codestates/edusync/exception/BusinessLogicException.java deleted file mode 100644 index 7fb12b6a..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/exception/BusinessLogicException.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.codestates.edusync.exception; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@Getter -@AllArgsConstructor -public class BusinessLogicException extends RuntimeException{ - - private ExceptionCode exceptionCode; - private String message; - - public BusinessLogicException(ExceptionCode exceptionCode){ - this.exceptionCode = exceptionCode; - this.message = null; - } - - - @Override - public String getMessage(){ - if(message == null){ - return exceptionCode.getMessage(); - } - - return String.format("%s. %s,", exceptionCode.getMessage(), message); - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/exception/ExceptionCode.java b/server/edusync/src/main/java/com/codestates/edusync/exception/ExceptionCode.java deleted file mode 100644 index 2029e85e..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/exception/ExceptionCode.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.codestates.edusync.exception; - -import lombok.Getter; - -public enum ExceptionCode { - - DUPLICATED_EMAIL(409, "이메일을 찾을수 없습니다."), - MEMBER_EXISTS(409, "이메일이 이미 존재"), - MEMBER_NOT_FOUND(404, "멤버를 찾을수 없습니다."), - INTERNAL_SERVER_ERROR(500, "내부 서버 오류"), - INVALID_PERMISSION(403, "권한이 유효하지 않습니다."), - INACTIVE_MEMBER(403, "탈퇴한 회원입니다."), - INVALID_TOKEN(401, "유효하지 않은 토큰입니다."), - STUDYGROUP_NOT_FOUND(404, "스터디를 찾을 수 없습니다."), - STUDYGROUP_POST_COMMENT_NOT_FOUND(404, "댓글을 찾을 수 없습니다."), - STUDYGROUP_POST_COMMENT_NOT_ALLOWED(403, "댓글은 본인과 스터디장만 삭제할 수 있습니다."), - STUDYGROUP_POST_COMMENT_ALLOWED_ONLY_FOR_LEADER(403, "스터디장에게만 있는 권한입니다."), - STUDYGROUP_POST_COMMENT_NOT_MATCHED(400, "해당 댓글은 해당 스터디 모집글에 존재하지 않습니다. 댓글의 식별자와 스터디 모집글의 식별자를 확인해주세요!"), - TIME_SCHEDULE_NOT_FOUND(404, "일정이 존재하지 않습니다."), - ; - - @Getter - private int status; - @Getter - private String message; - - ExceptionCode(int status, String message) { - this.status = status; - this.message = message; - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/exception/Response/Response.java b/server/edusync/src/main/java/com/codestates/edusync/exception/Response/Response.java deleted file mode 100644 index 103892c0..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/exception/Response/Response.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.codestates.edusync.exception.Response; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@Getter -@AllArgsConstructor -public class Response { - - private String resultCode; - private T result; - - public static Response error(String errorCode) { - return new Response<>(errorCode, null); - } - - public static Response success() { - return new Response("SUCCESS", null); - } - - public static Response success(T result) { - return new Response<>("SUCCESS", result); - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/infodto/timeschedule/dto/TimeScheduleInfoDto.java b/server/edusync/src/main/java/com/codestates/edusync/infodto/timeschedule/dto/TimeScheduleInfoDto.java deleted file mode 100644 index 1a546dba..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/infodto/timeschedule/dto/TimeScheduleInfoDto.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.codestates.edusync.infodto.timeschedule.dto; - -import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import java.sql.Timestamp; - -@NoArgsConstructor -@Getter -@Setter -public class TimeScheduleInfoDto { - @JsonFormat(pattern = "MM-dd HH:mm", timezone = "Asia/Seoul") - private Timestamp start; - - @JsonFormat(pattern = "MM-dd HH:mm", timezone = "Asia/Seoul") - private Timestamp end; -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/infodto/timeschedule/dto/TimeScheduleResponseDto.java b/server/edusync/src/main/java/com/codestates/edusync/infodto/timeschedule/dto/TimeScheduleResponseDto.java deleted file mode 100644 index eb310f23..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/infodto/timeschedule/dto/TimeScheduleResponseDto.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.codestates.edusync.infodto.timeschedule.dto; - -import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import java.sql.Timestamp; - -@NoArgsConstructor -@Getter -@Setter -public class TimeScheduleResponseDto { - private Long id; - - private String studygroupName; - private String platform; - - private TimeScheduleDto timeScheduleInfo; - private CalendarInfoDto calendarInfo; - - @NoArgsConstructor - @Getter - @Setter - public static class CalendarInfoDto { - @JsonFormat(pattern = "MM-dd", timezone = "Asia/Seoul") - private Timestamp start; - - @JsonFormat(pattern = "MM-dd", timezone = "Asia/Seoul") - private Timestamp end; - } - - @NoArgsConstructor - @Getter - @Setter - public static class TimeScheduleDto { - @JsonFormat(pattern = "MM-dd HH:mm", timezone = "Asia/Seoul") - private Timestamp start; - - @JsonFormat(pattern = "MM-dd HH:mm", timezone = "Asia/Seoul") - private Timestamp end; - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/infodto/timeschedule/dto/TimeScheduleSingleResponseDto.java b/server/edusync/src/main/java/com/codestates/edusync/infodto/timeschedule/dto/TimeScheduleSingleResponseDto.java deleted file mode 100644 index 5a1cea5d..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/infodto/timeschedule/dto/TimeScheduleSingleResponseDto.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.codestates.edusync.infodto.timeschedule.dto; - -import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import java.sql.Timestamp; - -@NoArgsConstructor -@Getter -@Setter -public class TimeScheduleSingleResponseDto { - private Long id; - - @JsonFormat(pattern = "MM-dd HH:mm", timezone = "Asia/Seoul") - private Timestamp startTime; - - @JsonFormat(pattern = "MM-dd HH:mm", timezone = "Asia/Seoul") - private Timestamp endTime; -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/infodto/timeschedule/entity/TimeSchedule.java b/server/edusync/src/main/java/com/codestates/edusync/infodto/timeschedule/entity/TimeSchedule.java deleted file mode 100644 index d104a566..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/infodto/timeschedule/entity/TimeSchedule.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.codestates.edusync.infodto.timeschedule.entity; - -import com.codestates.edusync.audit.Auditable; -import com.codestates.edusync.member.entity.Member; -import com.codestates.edusync.study.studygroup.entity.Studygroup; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import javax.persistence.*; -import java.sql.Timestamp; - -import static javax.persistence.CascadeType.*; -import static javax.persistence.FetchType.LAZY; - -@NoArgsConstructor -@Getter -@Setter -@Entity -public class TimeSchedule extends Auditable { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(length = 100) - private String title; - - @Column(length = 200) - private String content; - - @Column - private Timestamp start; - @Column - private Timestamp end; - - @ManyToOne(fetch = LAZY, cascade = {PERSIST, MERGE, REMOVE}) - @JoinColumn(name = "studygroup_id") - private Studygroup studygroup; - - @ManyToOne(fetch = LAZY, cascade = {PERSIST, MERGE, REMOVE}) - @JoinColumn(name = "member_id") - private Member member; - - - /** - *

양방향 매핑을 위한 메서드

- * 기존 연결을 끊고, 새로 관계를 연결한다.
- * 양방향 매핑 시 순환참조 가능성이 있으므로, 반대쪽에서 사용하면 절대 안됨
- * 참고: {@link TimeSchedule#setStudygroupOneWay(Studygroup)} - * @param studygroup 양방향 매핑을 위한 객체 - */ - public void setStudygroup(Studygroup studygroup) { - if (studygroup == null) { - throw new IllegalArgumentException("Studygroup cannot be null"); - } - - if(this.studygroup != null) { - this.studygroup.getTimeSchedules().remove(this); - } - this.studygroup = studygroup; - this.studygroup.getTimeSchedules().add(this); - } - - /** - *

양방향 매핑 중 순환 방지용으로 단방향으로만 추가하는 메서드

- * @param studygroup 관계를 끊는 경우 null 가능 - */ - public void setStudygroupOneWay(Studygroup studygroup) { - this.studygroup = studygroup; - } - - - /** - *

양방향 매핑을 위한 메서드

- * 기존 연결을 끊고, 새로 관계를 연결한다.
- * 양방향 매핑 시 순환참조 가능성이 있으므로, 반대쪽에서 사용하면 절대 안됨
- * 참고: {@link TimeSchedule#setMemberOneWay(Member)} - * @param member 양방향 매핑을 위한 객체 - */ - public void setMember(Member member) { - if (member == null) { - throw new IllegalArgumentException("Member cannot be null"); - } - - if(this.member != null) { - this.member.getTimeSchedules().remove(this); - } - this.member = member; - this.member.getTimeSchedules().add(this); - } - - /** - *

양방향 매핑 중 순환 방지용으로 단방향으로만 추가하는 메서드

- * @param member 관계를 끊는 경우 null 가능 - */ - public void setMemberOneWay(Member member) { - this.member = member; - } - -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/member/controller/MemberController.java b/server/edusync/src/main/java/com/codestates/edusync/member/controller/MemberController.java deleted file mode 100644 index a99b333c..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/member/controller/MemberController.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.codestates.edusync.member.controller; - -import com.codestates.edusync.dto.MultiResponseDto; -import com.codestates.edusync.member.dto.MemberDto; -import com.codestates.edusync.member.dto.MemberJoinResponseDto; -import com.codestates.edusync.member.entity.Member; -import com.codestates.edusync.member.mapper.MemberMapper; -import com.codestates.edusync.member.service.MemberService; -import com.codestates.edusync.util.UriCreator; -import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Page; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.core.Authentication; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.validation.Valid; -import javax.validation.constraints.Positive; -import java.net.URI; -import java.util.List; - -@AllArgsConstructor -@RestController -@RequestMapping("/members") -@Validated // 유효성 검사용 -@Slf4j -public class MemberController { - private final MemberService memberService; - private final MemberMapper memberMapper; - - @PostMapping - public ResponseEntity postMember(@Valid @RequestBody MemberDto.Post requestBody) { - Member member = memberMapper.memberPostToMember(requestBody); - Member createMember = memberService.createMember(member); - MemberJoinResponseDto responseDto = memberMapper.memberToMemberResponse(createMember); - - URI location = UriCreator.createUri("/members", createMember.getId()); - HttpHeaders headers = new HttpHeaders(); - headers.setLocation(location); - - return new ResponseEntity(responseDto, headers, HttpStatus.CREATED); - } - - @PatchMapping("/{member-id}") // 케법 케이스 (url 경로에서 주로 사용하는 방식 => 필드값은 카멜케이스로 작성하니까 구분을 위해 사용) - public ResponseEntity patchMember( - @PathVariable("member-id") @Positive Long memberId, - @Valid @RequestBody MemberDto.Patch requestBody, - Authentication authentication) { - requestBody.setId(memberId); - Member updateMember = memberService.updateMember(memberMapper.memberPatchToMember(requestBody), memberId, authentication.getName()); - MemberJoinResponseDto responseDto = memberMapper.memberToMemberResponse(updateMember); - - return new ResponseEntity(responseDto, HttpStatus.OK); - } - - @GetMapping("/{member-id}") - public ResponseEntity getMember( - @PathVariable("member-id") @Positive Long memberId) { - Member member = memberService.findMember(memberId); - MemberJoinResponseDto responseDto = memberMapper.memberToMemberResponse(member); - return new ResponseEntity(responseDto, HttpStatus.OK); - } - - @GetMapping - public ResponseEntity getMembers(@Positive @RequestParam int page, - @Positive @RequestParam int size) { - Page pageMembers = memberService.findMembers(page - 1, size); - List members = pageMembers.getContent(); - return new ResponseEntity<>( - new MultiResponseDto<>(memberMapper.membersToMemberResponses(members), - pageMembers), - HttpStatus.OK); - } - - @DeleteMapping("/{member-id}") - public ResponseEntity deleteMember( - @PathVariable("member-id") @Positive Long memberId, - Authentication authentication) { - memberService.deleteMember(memberId, authentication.getName()); - - return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } - - @PatchMapping("/{member-id}/profile-image") - public ResponseEntity updateProfileImage( - @PathVariable("member-id") @Positive Long memberId, - @RequestBody MemberDto.ProfileImage requestBody, - Authentication authentication) { - Member member = memberService.findMember(memberId); - member.setProfileImage(requestBody.getProfileImage()); - Member updatedMember = memberService.updateMember(member, memberId, authentication.getName()); - MemberJoinResponseDto responseDto = memberMapper.memberToMemberResponse(updatedMember); - return new ResponseEntity(responseDto, HttpStatus.OK); - } - - @PatchMapping("/{member-id}/detail") - public ResponseEntity updateDetail(@PathVariable("member-id") @Positive Long memberId, - @RequestBody MemberDto.Detail requestBody, - Authentication authentication){ - Member updatedMember = memberService.updateDetail(memberId, requestBody, authentication.getName()); - MemberJoinResponseDto responseDto = memberMapper.memberToMemberResponse(updatedMember); - return new ResponseEntity(responseDto, HttpStatus.OK); - } - - @GetMapping("/{member-id}/password") - public ResponseEntity checkPassword( - @PathVariable("member-id") @Positive Long memberId, - @RequestBody MemberDto.CheckPassword requestBody, - Authentication authentication) { - boolean isPasswordCorrect = memberService.checkPassword(memberId, requestBody.getPassword(), authentication.getName()); - if (isPasswordCorrect) { - return new ResponseEntity<>(HttpStatus.OK); - } else { - return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); - } - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/member/dto/MemberDto.java b/server/edusync/src/main/java/com/codestates/edusync/member/dto/MemberDto.java deleted file mode 100644 index b401bf1f..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/member/dto/MemberDto.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.codestates.edusync.member.dto; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import javax.validation.constraints.Email; -import javax.validation.constraints.NotBlank; - -public class MemberDto { - @Getter - @NoArgsConstructor - public static class Post{ - @Email(message = "올바른 이메일 형태가 아닙니다.") - private String email; - @NotBlank(message = "비밀번호는 공백이 아니어야 합니다.") - private String password; - private String nickName; - } - - @Getter - @NoArgsConstructor - public static class Patch { - private long id; - private String nickName; - private String password; // 비번 변경 요청시 비밀번호 입력하도록 나중에 기능 추가 - - public void setId(long id) { - this.id = id; - } - } - - @Getter - @NoArgsConstructor - @AllArgsConstructor - public static class ProfileImage { - private String profileImage; - } - - @Getter - @NoArgsConstructor - public static class Detail{ - private String withMe; - private String aboutMe; - } - - @Getter - @NoArgsConstructor - public static class CheckPassword{ - private String password; - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/member/dto/MemberJoinResponseDto.java b/server/edusync/src/main/java/com/codestates/edusync/member/dto/MemberJoinResponseDto.java deleted file mode 100644 index fc0e2e72..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/member/dto/MemberJoinResponseDto.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.codestates.edusync.member.dto; - -import com.codestates.edusync.member.entity.Member; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import java.util.List; - -@AllArgsConstructor -@NoArgsConstructor -@Setter -@Getter -public class MemberJoinResponseDto { - private long id; - private String email; - private String profileImage; - private String nickName; - private String aboutMe; - private String withMe; - private Member.MemberStatus memberStatus; - private List roles; -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/member/dto/MemberResponseDto.java b/server/edusync/src/main/java/com/codestates/edusync/member/dto/MemberResponseDto.java deleted file mode 100644 index ab2da207..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/member/dto/MemberResponseDto.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.codestates.edusync.member.dto; - -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -@NoArgsConstructor -@Getter -@Setter -public class MemberResponseDto { - private Long id; - - private String nickName; - private String email; - private String grade; - - private String aboutMe; - private String withMe; -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/member/entity/Member.java b/server/edusync/src/main/java/com/codestates/edusync/member/entity/Member.java deleted file mode 100644 index 7f1aa12a..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/member/entity/Member.java +++ /dev/null @@ -1,180 +0,0 @@ -package com.codestates.edusync.member.entity; - -import com.codestates.edusync.audit.Auditable; -import com.codestates.edusync.infodto.timeschedule.entity.TimeSchedule; -import com.codestates.edusync.study.postcomment.entity.StudygroupPostComment; -import com.codestates.edusync.study.studygroup.entity.Studygroup; -import com.codestates.edusync.study.studygroupjoin.entity.StudygroupJoin; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import javax.persistence.*; -import java.util.ArrayList; -import java.util.List; - -import static javax.persistence.CascadeType.*; -import static javax.persistence.FetchType.*; - -@NoArgsConstructor -@Getter -@Setter -@Entity -public class Member extends Auditable { - @Id // 식별자 등록 - @GeneratedValue(strategy = GenerationType.IDENTITY) // 식별자를 자동으로 생성 - private Long id; - @Column(nullable = false, updatable = true, unique = true) - private String nickName; - @Column(nullable = false, updatable = false, unique = true) - private String email; - @Column(length = 2147483647) // fixme : 길이 제한 걸릴 경우 length = -1 이나 columnDefinition = "TEXT" 타입 고려 - private String profileImage; - private String password; - @Column(length = 50) - private String grade; - - public Member(Long id, String nickName, String email, String profileImage) { // 테스트코드 작성용 생성자 - this.id = id; - this.nickName = nickName; - this.email = email; - this.profileImage = profileImage; - } - - @ElementCollection(fetch = FetchType.EAGER) // 별도의 테이블로 생성해서 저장 // 권한 여러개 설정할거면 나중에 바꾸기 (String roles 지우고 관련 메서드 체크!) - private List roles = new ArrayList<>(); // 권한 테이블 - private String withMe; - private String aboutMe; - @Enumerated(value = EnumType.STRING) - @Column(length = 20, nullable = false) - private MemberStatus memberStatus = MemberStatus.MEMBER_ACTIVE; - - public enum MemberStatus { - MEMBER_ACTIVE("활동중"), - MEMBER_SLEEP("휴면 상태"), - MEMBER_QUIT("탈퇴 상태"); - - @Getter - private String status; - - MemberStatus(String status) { - this.status = status; - } - } - - @OneToMany(mappedBy = "leaderMember", cascade = {PERSIST, MERGE}, fetch = LAZY) - private List studygroupsAsLeader = new ArrayList<>(); - - private Provider provider = Provider.LOCAL; - - public enum Provider { - LOCAL("기본 회원"), - GOOGLE("구글 연동 회원"), - KAKAO("카카오 연동 회원"), - NAVER("네이버 연동 회원"); - - @Getter - private String provider; - - Provider(String provider) { - this.provider = provider; - } - } - - @OneToMany(mappedBy = "member", cascade = {PERSIST, MERGE, REMOVE}, fetch = LAZY) - private List studygroupJoins = new ArrayList<>(); - - @OneToMany(mappedBy = "member", cascade = {PERSIST, MERGE, REMOVE}, fetch = LAZY) - private List timeSchedules = new ArrayList<>(); - - @OneToMany(mappedBy = "member", cascade = {PERSIST, MERGE, REMOVE}, fetch = LAZY) - private List studygroupPostComments = new ArrayList<>(); - - /** - *

양방향 매핑을 위한 One To Many 쪽의 Setter 설정

- * 기존에 연결되어있던 관계를 끊고, 양쪽 객체를 새로 연결해준다. - * @param studygroupsAsLeader 새로 매핑할 객체의 리스트( 시간표 ) - */ - public void setStudygroupsAsLeader(List studygroupsAsLeader) { - if (studygroupsAsLeader == null) { - throw new IllegalArgumentException("studygroup As Leader List cannot be null"); - } - - if (this.studygroupsAsLeader != null) { - for (Studygroup studygroup : this.studygroupsAsLeader) { - studygroup.setLeaderMemberOneWay(null); - } - } - - this.studygroupsAsLeader = studygroupsAsLeader; - for (Studygroup studygroup : this.studygroupsAsLeader) { - studygroup.setLeaderMemberOneWay(this); - } - } - - /** - *

양방향 매핑을 위한 One To Many 쪽의 Setter 설정

- * 기존에 연결되어있던 관계를 끊고, 양쪽 객체를 새로 연결해준다. - * @param studygroupJoins 새로 매핑할 객체의 리스트( 시간표 ) - */ - public void setStudygroupJoin(List studygroupJoins) { - if (studygroupJoins == null) { - throw new IllegalArgumentException("Studygroup Join List cannot be null"); - } - - if (this.studygroupJoins != null) { - for (StudygroupJoin studygroupJoin : this.studygroupJoins) { - studygroupJoin.setMemberOneWay(null); - } - } - - this.studygroupJoins = studygroupJoins; - for (StudygroupJoin studygroupJoin : this.studygroupJoins) { - studygroupJoin.setMemberOneWay(this); - } - } - - /** - *

양방향 매핑을 위한 One To Many 쪽의 Setter 설정

- * 기존에 연결되어있던 관계를 끊고, 양쪽 객체를 새로 연결해준다. - * @param timeSchedules 새로 매핑할 객체의 리스트( 시간표 ) - */ - public void setTimeSchedule(List timeSchedules) { - if (timeSchedules == null) { - throw new IllegalArgumentException("TimeSchedule List cannot be null"); - } - - if (this.timeSchedules != null) { - for (TimeSchedule timeSchedule : this.timeSchedules) { - timeSchedule.setMemberOneWay(null); - } - } - - this.timeSchedules = timeSchedules; - for (TimeSchedule timeSchedule : this.timeSchedules) { - timeSchedule.setMemberOneWay(this); - } - } - - /** - *

양방향 매핑을 위한 One To Many 쪽의 Setter 설정

- * 기존에 연결되어있던 관계를 끊고, 양쪽 객체를 새로 연결해준다. - * @param studygroupPostComments 새로 매핑할 객체의 리스트( 시간표 ) - */ - public void setStudygroupPostComment(List studygroupPostComments) { - if (studygroupPostComments == null) { - throw new IllegalArgumentException("StudygroupPostComment List cannot be null"); - } - - if (this.studygroupPostComments != null) { - for (StudygroupPostComment studygroupPostComment : this.studygroupPostComments) { - studygroupPostComment.setMemberOneWay(null); - } - } - - this.studygroupPostComments = studygroupPostComments; - for (StudygroupPostComment studygroupPostComment : this.studygroupPostComments) { - studygroupPostComment.setMemberOneWay(this); - } - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/member/mapper/MemberMapper.java b/server/edusync/src/main/java/com/codestates/edusync/member/mapper/MemberMapper.java deleted file mode 100644 index 868ae862..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/member/mapper/MemberMapper.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.codestates.edusync.member.mapper; - -import com.codestates.edusync.member.dto.MemberDto; -import com.codestates.edusync.member.dto.MemberJoinResponseDto; -import com.codestates.edusync.member.entity.Member; -import org.mapstruct.Mapper; -import org.mapstruct.ReportingPolicy; - -import java.util.List; - -@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) // unmappedTargetPolicy = ReportingPolicy.IGNORE // Todo 테스트 끝나면 추가 -public interface MemberMapper { - Member memberPostToMember(MemberDto.Post requestBody); - Member memberPatchToMember(MemberDto.Patch requestBody); - MemberJoinResponseDto memberToMemberResponse(Member member); - List membersToMemberResponses(List members); -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/member/repository/MemberRepository.java b/server/edusync/src/main/java/com/codestates/edusync/member/repository/MemberRepository.java deleted file mode 100644 index e44d36b6..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/member/repository/MemberRepository.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.codestates.edusync.member.repository; - -import com.codestates.edusync.member.entity.Member; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.Optional; - -public interface MemberRepository extends JpaRepository { - Optional findByEmail(String email); // 예시로 일단 만들었음 뭘 기준으로 member를 찾을지 의논 -} - diff --git a/server/edusync/src/main/java/com/codestates/edusync/member/service/MemberService.java b/server/edusync/src/main/java/com/codestates/edusync/member/service/MemberService.java deleted file mode 100644 index 1576ebb7..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/member/service/MemberService.java +++ /dev/null @@ -1,186 +0,0 @@ -package com.codestates.edusync.member.service; - -import com.codestates.edusync.auth.utils.CustomAuthorityUtils; -import com.codestates.edusync.exception.BusinessLogicException; -import com.codestates.edusync.exception.ExceptionCode; -import com.codestates.edusync.member.dto.MemberDto; -import com.codestates.edusync.member.entity.Member; -import com.codestates.edusync.member.repository.MemberRepository; -import com.codestates.edusync.util.VerifyMember; -import lombok.AllArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Sort; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.oauth2.core.user.OAuth2User; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Isolation; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Optional; - -@AllArgsConstructor -@Transactional -@Service -public class MemberService implements VerifyMember { - private final MemberRepository memberRepository; - private final PasswordEncoder passwordEncoder; - private final CustomAuthorityUtils authorityUtils; - - public Member createMember(Member member) { - verifyExistsEmail(member.getEmail()); - - String encryptedPassword = passwordEncoder.encode(member.getPassword()); - member.setPassword(encryptedPassword); - - List roles = authorityUtils.createRoles(member.getEmail()); - member.setRoles(roles); - member.setAboutMe(""); // FE 요청으로 추가 (null -> 빈문자열) - member.setWithMe(""); - - if (member.getProfileImage() == null || member.getProfileImage().isEmpty()) { - member.setProfileImage("https://avatars.githubusercontent.com/u/120456261?v=4"); - } - - Member savedMember = memberRepository.save(member); - - return savedMember; - } - - @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE) - public Member updateMember(Member member, Long memberId, String email) { - sameMemberTest(memberId, email); - - Member findMember = findVerifiedMember(member.getId()); - verifyMemberIsActive(findMember); - - Optional.ofNullable(member.getNickName()) - .ifPresent(name -> findMember.setNickName(name)); - Optional.ofNullable(member.getPassword()) - .ifPresent(password -> { - if (!password.isEmpty()) { - findMember.setPassword(password); - } - }); - Optional.ofNullable(member.getProfileImage()) - .ifPresent(image -> findMember.setProfileImage(image)); - Optional.ofNullable(member.getWithMe()) - .ifPresent(withMe -> findMember.setWithMe(withMe)); - Optional.ofNullable(member.getAboutMe()) - .ifPresent(aboutMe -> findMember.setAboutMe(aboutMe)); - return memberRepository.save(findMember); - } - - @Transactional(readOnly = true) - public Member findMember(Long memberId) { - return findVerifiedMember(memberId); - } - - public Page findMembers(int page, int size) { - return memberRepository.findAll(PageRequest.of(page, size, - Sort.by("id").descending())); - } - - public void deleteMember(Long memberId, String email) { - sameMemberTest(memberId, email); - Member findMember = findVerifiedMember(memberId); - verifyMemberIsActive(findMember); - String newEmail = "del_" + memberId + "_" + findMember.getEmail(); - - findMember.setMemberStatus(Member.MemberStatus.MEMBER_QUIT); - findMember.setEmail(newEmail); - - memberRepository.save(findMember); - } - - public Member updateDetail(Long memberId, MemberDto.Detail requestBody, String token){ - Member member = findVerifiedMember(memberId); - verifyMemberIsActive(member); - - if (requestBody.getWithMe() != null) { - member.setWithMe(requestBody.getWithMe()); - } - if (requestBody.getAboutMe() != null) { - member.setAboutMe(requestBody.getAboutMe()); - } - - return updateMember(member, memberId, token); - } - - public boolean checkPassword(Long memberId, String password, String email){ - sameMemberTest(memberId, email); - - Member member = memberRepository.findByEmail(email).get(); - return passwordEncoder.matches(password, member.getPassword()); - } - - @Transactional(readOnly = true) - public Member findVerifiedMember(Long memberId) { - Optional optionalMember = - memberRepository.findById(memberId); - - Member findMember = - optionalMember.orElseThrow(() -> - new BusinessLogicException(ExceptionCode.MEMBER_NOT_FOUND, String.format("%d번 회원을 찾을 수 없습니다.", memberId))); - verifyMemberIsActive(findMember); - - return findMember; - } - - private void verifyExistsEmail(String email) { - Optional member = memberRepository.findByEmail(email); - if (member.isPresent()) - throw new BusinessLogicException(ExceptionCode.MEMBER_EXISTS, String.format("%s는 이미 가입한 이메일입니다.", email)); - } - - public void sameMemberTest(Long memberId, String email){ - Member findMember = findVerifiedMember(memberId); - - if(email == null || email.isEmpty()){ - throw new BusinessLogicException(ExceptionCode.DUPLICATED_EMAIL, String.format("이메일을 찾을 수 없습니다. 올바른 토큰이 아닐 확률이 높습니다.")); - }else if(!email.equals(findMember.getEmail())){ - throw new BusinessLogicException(ExceptionCode.INVALID_PERMISSION, String.format("유저(%s)가 권한을 가지고 있지 않습니다. 사용자(%s) 정보를 수정할 수 없습니다.", email, findMember.getEmail())); - } - } - - public void verifyMemberIsActive(Member member) { - if (member.getMemberStatus() != Member.MemberStatus.MEMBER_ACTIVE) { - throw new BusinessLogicException(ExceptionCode.INACTIVE_MEMBER, - String.format("멤버(%s)는 활성화되지 않았습니다. 해당 요청을 처리할 수 없습니다.", member.getEmail())); - } - } - - /** - *

현재 로그인 된 사용자의 정보를 리턴해주는 메서드

- * @return 접속 중인 Member 의 정보 - */ - public Member findVerifyMemberWhoLoggedIn() { - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - String email = authentication.getPrincipal().toString(); - - return findVerifiedMember(email); - } - - /** - *

email 을 이용해서 회원을 검색하는 메서드

- * email 로 회원 검색 후 검증하여 리턴해준다. - * @param email - * @return - */ - @Transactional(readOnly = true) - public Member findVerifiedMember(String email) { - Optional optionalMember = - memberRepository.findByEmail(email); - - Member findMember = - optionalMember.orElseThrow(() -> - new BusinessLogicException(ExceptionCode.MEMBER_NOT_FOUND, String.format("%s 회원을 찾을 수 없습니다.", email))); - verifyMemberIsActive(findMember); - - return findMember; - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/response/ErrorResponse.java b/server/edusync/src/main/java/com/codestates/edusync/response/ErrorResponse.java deleted file mode 100644 index cec0d966..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/response/ErrorResponse.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.codestates.edusync.response; - -import com.codestates.edusync.exception.ExceptionCode; -import lombok.Getter; -import org.springframework.http.HttpStatus; -import org.springframework.validation.BindingResult; - -import javax.validation.ConstraintViolation; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -@Getter -public class ErrorResponse { - private int status; - private String message; - private List fieldErrors; - private List violationErrors; - - public ErrorResponse(int status, String message) { - this.status = status; - this.message = message; - } - - private ErrorResponse(final List fieldErrors, - final List violationErrors) { - this.fieldErrors = fieldErrors; - this.violationErrors = violationErrors; - } - - public static ErrorResponse of(BindingResult bindingResult) { - return new ErrorResponse(FieldError.of(bindingResult), null); - } - - public static ErrorResponse of(Set> violations) { - return new ErrorResponse(null, ConstraintViolationError.of(violations)); - } - - public static ErrorResponse of(ExceptionCode exceptionCode) { - return new ErrorResponse(exceptionCode.getStatus(), exceptionCode.getMessage()); - } - - public static ErrorResponse of(HttpStatus httpStatus) { - return new ErrorResponse(httpStatus.value(), httpStatus.getReasonPhrase()); - } - - public static ErrorResponse of(HttpStatus httpStatus, String message) { - return new ErrorResponse(httpStatus.value(), message); - } - - @Getter - public static class FieldError { - private String field; - private Object rejectedValue; - private String reason; - - private FieldError(String field, Object rejectedValue, String reason) { - this.field = field; - this.rejectedValue = rejectedValue; - this.reason = reason; - } - - public static List of(BindingResult bindingResult) { - final List fieldErrors = - bindingResult.getFieldErrors(); - return fieldErrors.stream() - .map(error -> new FieldError( - error.getField(), - error.getRejectedValue() == null ? - "" : error.getRejectedValue().toString(), - error.getDefaultMessage())) - .collect(Collectors.toList()); - } - } - - @Getter - public static class ConstraintViolationError { - private String propertyPath; - private Object rejectedValue; - private String reason; - - private ConstraintViolationError(String propertyPath, Object rejectedValue, - String reason) { - this.propertyPath = propertyPath; - this.rejectedValue = rejectedValue; - this.reason = reason; - } - - public static List of( - Set> constraintViolations) { - return constraintViolations.stream() - .map(constraintViolation -> new ConstraintViolationError( - constraintViolation.getPropertyPath().toString(), - constraintViolation.getInvalidValue().toString(), - constraintViolation.getMessage() - )).collect(Collectors.toList()); - } - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/searchtag/controller/SearchTagController.java b/server/edusync/src/main/java/com/codestates/edusync/searchtag/controller/SearchTagController.java deleted file mode 100644 index a534574c..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/searchtag/controller/SearchTagController.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.codestates.edusync.searchtag.controller; - -import com.codestates.edusync.searchtag.dto.SearchTagResponseDto; -import com.codestates.edusync.searchtag.entity.SearchTag; -import com.codestates.edusync.searchtag.mapper.SearchTagMapper; -import com.codestates.edusync.searchtag.service.SearchTagService; -import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import java.util.List; - -@RequiredArgsConstructor -@Validated -@RestController -public class SearchTagController { - private final SearchTagService searchTagService; - private final SearchTagMapper mapper; - - private static final String DEFAULT_SEARCH_TAG_URL = "/search"; - - /** - * key(카테고리) 와 value(태그) 의 쌍을 응답한다. - * @return - */ - @GetMapping(DEFAULT_SEARCH_TAG_URL + "/all") - public ResponseEntity getSearchTags() { - List tags = searchTagService.getAllSearchTagList(); - - return new ResponseEntity<>( - mapper.searchTagsToSearchTagResponseDto(tags), - HttpStatus.OK - ); - } - - /** - * key(카테고리)를 요청받아서 value(태그)들만 리턴한다. - * @param key - * @return - */ - @GetMapping(DEFAULT_SEARCH_TAG_URL) - public ResponseEntity getSearchTags(@RequestParam("key") String key) { - List tags = searchTagService.getSearchTagList(key); - - return new ResponseEntity<>( - mapper.searchTagsToSearchTagResponseDto(tags), - HttpStatus.OK - ); - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/searchtag/dto/SearchTagResponseDto.java b/server/edusync/src/main/java/com/codestates/edusync/searchtag/dto/SearchTagResponseDto.java deleted file mode 100644 index 2266b339..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/searchtag/dto/SearchTagResponseDto.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.codestates.edusync.searchtag.dto; - -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import java.util.HashMap; -import java.util.List; - -@NoArgsConstructor -@Getter -@Setter -public class SearchTagResponseDto { - private HashMap tags; -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/searchtag/entity/SearchTag.java b/server/edusync/src/main/java/com/codestates/edusync/searchtag/entity/SearchTag.java deleted file mode 100644 index ffdf81f1..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/searchtag/entity/SearchTag.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.codestates.edusync.searchtag.entity; - -import com.codestates.edusync.study.studygroup.entity.Studygroup; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import javax.persistence.*; - -import static javax.persistence.CascadeType.*; -import static javax.persistence.FetchType.*; - -@NoArgsConstructor -@Getter -@Setter -@Entity -public class SearchTag { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(length = 20) - private String tagKey; - - @Column(length = 100) - private String tagValue; - - @ManyToOne - @JoinColumn(name = "studygroup_id") - private Studygroup studygroup; - - - /** - *

양방향 매핑을 위한 메서드

- * 기존 연결을 끊고, 새로 관계를 연결한다.
- * 양방향 매핑 시 순환참조 가능성이 있으므로, 반대쪽에서 사용하면 절대 안됨
- * 참고: {@link SearchTag#setStudygroupOneWay(Studygroup)} - * @param studygroup 양방향 매핑을 위한 객체 - */ - public void setStudygroup(Studygroup studygroup) { - if (studygroup == null) { - throw new IllegalArgumentException("Studygroup cannot be null"); - } - - if(this.studygroup != null) { - this.studygroup.getSearchTags().remove(this); - } - this.studygroup = studygroup; - this.studygroup.getSearchTags().add(this); - } - - /** - *

양방향 매핑 중 순환 방지용으로 단방향으로만 추가하는 메서드

- * @param studygroup 관계를 끊는 경우 null 가능 - */ - public void setStudygroupOneWay(Studygroup studygroup) { - this.studygroup = studygroup; - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/searchtag/mapper/SearchTagMapper.java b/server/edusync/src/main/java/com/codestates/edusync/searchtag/mapper/SearchTagMapper.java deleted file mode 100644 index 34f9753e..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/searchtag/mapper/SearchTagMapper.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.codestates.edusync.searchtag.mapper; - -import com.codestates.edusync.searchtag.dto.SearchTagResponseDto; -import com.codestates.edusync.searchtag.entity.SearchTag; -import org.mapstruct.Mapper; - -import java.util.HashMap; -import java.util.List; - -@Mapper(componentModel = "spring") -public interface SearchTagMapper { - - default SearchTagResponseDto searchTagsToSearchTagResponseDto(List tags) { - SearchTagResponseDto result = new SearchTagResponseDto(); - HashMap resultTags = new HashMap<>(); - - tags.forEach(tag -> resultTags.put(tag.getTagKey(), tag.getTagValue())); - result.setTags(resultTags); - - return result; - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/searchtag/repository/SearchTagRepository.java b/server/edusync/src/main/java/com/codestates/edusync/searchtag/repository/SearchTagRepository.java deleted file mode 100644 index 877f3b7b..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/searchtag/repository/SearchTagRepository.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.codestates.edusync.searchtag.repository; - -import com.codestates.edusync.searchtag.entity.SearchTag; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.List; - -public interface SearchTagRepository extends JpaRepository { - - List findByTagKey(String key); -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/searchtag/service/SearchTagService.java b/server/edusync/src/main/java/com/codestates/edusync/searchtag/service/SearchTagService.java deleted file mode 100644 index 3bcc92fe..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/searchtag/service/SearchTagService.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.codestates.edusync.searchtag.service; - -import com.codestates.edusync.searchtag.entity.SearchTag; -import com.codestates.edusync.searchtag.repository.SearchTagRepository; -import com.codestates.edusync.searchtag.utils.SearchTagManager; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -import java.util.List; - -@RequiredArgsConstructor -@Service -public class SearchTagService implements SearchTagManager { - private final SearchTagRepository searchTagRepository; - - @Override - public List getSearchTagList(String key) { - return searchTagRepository.findByTagKey(key); - } - - @Override - public List getAllSearchTagList() { - return searchTagRepository.findAll(); - } - - @Override - public List createSearchTags(List tags) { - return searchTagRepository.saveAll(tags); - } - - @Override - public void deleteSearchTags(List tags) { - searchTagRepository.deleteAll(tags); - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/searchtag/utils/SearchTagManager.java b/server/edusync/src/main/java/com/codestates/edusync/searchtag/utils/SearchTagManager.java deleted file mode 100644 index 45ffa429..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/searchtag/utils/SearchTagManager.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.codestates.edusync.searchtag.utils; - -import com.codestates.edusync.searchtag.entity.SearchTag; - -import java.util.List; - -public interface SearchTagManager { - /** - *

key(카테고리)를 받아 해당 key 에 대한 value(태그)의 리스트를 반환해준다

- * 403 forbidden 로그인을 하지 않은 경우
- * 404 not found 해당 key 에 대한 값이 하나도 존재하지 않을 경우
- * @param key 검색에 사용할 key(카테고리) - * @return key(카테고리)에 해당하는 value(태그)의 목록 전부 - */ - List getSearchTagList(String key); - - /** - *

모든 key(카테고리)와 value(태그)의 쌍을 리스트로 반환해준다

- * 403 forbidden 로그인을 하지 않은 경우
- * 404 not found 해당 key 에 대한 값이 하나도 존재하지 않을 경우
- * @param key 검색에 사용할 key(카테고리) - * @return key(카테고리)에 해당하는 value(태그)의 목록 전부 - */ - List getAllSearchTagList(); - - /** - *

searchTag 의 목록을 입력받아, DB 에 생성한다

- * @param tags key(카테고리), value(태그) 의 목록 - */ - List createSearchTags(List tags); - - /** - *

searchTag 의 목록을 입력받아, DB 에서 삭제한다

- * 403 forbidden 로그인을 하지 않은 경우
- * 403 forbidden 해당 스터디의 리더가 아닌 경우
- * 404 not found 해당 key 와 value 로 이루어진 목록이 하나도 존재하지 않는 경우
- * @param tags - */ - void deleteSearchTags(List tags); -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/classmate/entity/Classmate.java b/server/edusync/src/main/java/com/codestates/edusync/study/classmate/entity/Classmate.java deleted file mode 100644 index e69de29b..00000000 diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/classmate/controller/CalendarClassmateController.java b/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/classmate/controller/CalendarClassmateController.java deleted file mode 100644 index 554f8e76..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/classmate/controller/CalendarClassmateController.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.codestates.edusync.study.plancalendar.classmate.controller; - -import com.codestates.edusync.study.plancalendar.studygroup.dto.CalendarDto; -import com.codestates.edusync.study.plancalendar.classmate.mapper.CalendarClassmateMapper; -import com.codestates.edusync.study.plancalendar.classmate.service.CalendarClassmateService; -import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.validation.Valid; -import javax.validation.constraints.Positive; - -@RequiredArgsConstructor -@Validated -@RestController -public class CalendarClassmateController { - private final CalendarClassmateService calendarClassmateService; - private final CalendarClassmateMapper mapper; - - private static final String DEFAULT_CALENDAR_URL = "/calendar"; - - @PatchMapping(DEFAULT_CALENDAR_URL + "/{calendar-id}/classmate") - public ResponseEntity patchCalendarClassmate(@PathVariable("calendar-id") @Positive Long calendarId, - @Valid @RequestBody CalendarDto.Patch patchDto) { - - return new ResponseEntity<>(HttpStatus.ACCEPTED); - } - - @DeleteMapping(DEFAULT_CALENDAR_URL + "/{calendar-id}/classmate") - public ResponseEntity deleteCalendarClassmate(@PathVariable("calendar-id") @Positive Long calendarId) { - - return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/classmate/dto/CalendarClassmateDto.java b/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/classmate/dto/CalendarClassmateDto.java deleted file mode 100644 index 0dce871f..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/classmate/dto/CalendarClassmateDto.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.codestates.edusync.study.plancalendar.classmate.dto; - -import com.codestates.edusync.infodto.timeschedule.entity.TimeSchedule; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import javax.validation.constraints.NotNull; -import java.util.List; - -public class CalendarClassmateDto { - - @NoArgsConstructor - @Getter - public static class Post { - @NotNull - private List timeSchedules; - } - - @NoArgsConstructor - @Getter - @Setter - public static class Patch { - @NotNull - private List timeSchedules; - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/classmate/dto/CalendarClassmateResponseDto.java b/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/classmate/dto/CalendarClassmateResponseDto.java deleted file mode 100644 index 120adf0d..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/classmate/dto/CalendarClassmateResponseDto.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.codestates.edusync.study.plancalendar.classmate.dto; - -import com.codestates.edusync.infodto.timeschedule.dto.TimeScheduleResponseDto; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import java.util.List; - -@NoArgsConstructor -@Getter -@Setter -public class CalendarClassmateResponseDto { - private Long id; - - private List timeSchedules; -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/classmate/mapper/CalendarClassmateMapper.java b/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/classmate/mapper/CalendarClassmateMapper.java deleted file mode 100644 index 57e710e6..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/classmate/mapper/CalendarClassmateMapper.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.codestates.edusync.study.plancalendar.classmate.mapper; - -import com.codestates.edusync.study.plancalendar.studygroup.dto.CalendarDto; -import com.codestates.edusync.study.studygroup.entity.Studygroup; -import org.mapstruct.Mapper; - -@Mapper(componentModel = "spring") -public interface CalendarClassmateMapper { - -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/classmate/service/CalendarClassmateService.java b/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/classmate/service/CalendarClassmateService.java deleted file mode 100644 index 2ed0a1d9..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/classmate/service/CalendarClassmateService.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.codestates.edusync.study.plancalendar.classmate.service; - -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@RequiredArgsConstructor -@Service -public class CalendarClassmateService { - -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/dto/MultiEventResponseDto.java b/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/dto/MultiEventResponseDto.java deleted file mode 100644 index 0779bce6..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/dto/MultiEventResponseDto.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.codestates.edusync.study.plancalendar.dto; - -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import java.util.List; - -@NoArgsConstructor -@Getter -@Setter -public class MultiEventResponseDto { - private List events; -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/controller/CalendarStudygroupController.java b/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/controller/CalendarStudygroupController.java deleted file mode 100644 index c7ab902e..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/controller/CalendarStudygroupController.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.codestates.edusync.study.plancalendar.studygroup.controller; - -import com.codestates.edusync.infodto.timeschedule.dto.TimeScheduleResponseDto; -import com.codestates.edusync.infodto.timeschedule.entity.TimeSchedule; -import com.codestates.edusync.study.plancalendar.studygroup.dto.CalendarDto; -import com.codestates.edusync.study.plancalendar.studygroup.mapper.CalendarStudygroupMapper; -import com.codestates.edusync.study.plancalendar.studygroup.service.CalendarStudygroupService; -import com.codestates.edusync.study.studygroup.entity.Studygroup; -import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.validation.Valid; -import javax.validation.constraints.Positive; -import java.util.List; - -@RequiredArgsConstructor -@Validated -@RestController -public class CalendarStudygroupController { - private final CalendarStudygroupService calendarStudygroupService; - private final CalendarStudygroupMapper mapper; - - private static final String DEFAULT_STUDYGROUP_URL = "/studygroup"; - private static final String DEFAULT_TIME_SCHEDULE_URL = "/timeSchedule"; - - @PostMapping(DEFAULT_STUDYGROUP_URL + "/{studygroup-id}") - public ResponseEntity postCalendarStudygroup(@PathVariable("studygroup-id") @Positive Long studygroupId, - @Valid @RequestBody CalendarDto.Post postDto) { - calendarStudygroupService.createTimeSchedulesForStudygroup( - studygroupId, - mapper.timeSchedulePostDtoListToTimeScheduleList(postDto.getTimeSchedules()) - ); - - return new ResponseEntity<>(HttpStatus.CREATED); - } - - @PatchMapping(DEFAULT_STUDYGROUP_URL + "/{studygroup-id}" + DEFAULT_TIME_SCHEDULE_URL + "/{timeschedule-id}") - public ResponseEntity patchCalendarStudygroup(@PathVariable("studygroup-id") @Positive Long studygroupId, - @PathVariable("timeschedule-id") @Positive Long timeScheduleId, - @Valid @RequestBody CalendarDto.Patch patchDto) { - calendarStudygroupService.updateStudygroupTimeSchedule( - studygroupId, timeScheduleId, - mapper.timeSchedulePatchDtoToTimeSchedule(patchDto) - ); - - return new ResponseEntity<>(HttpStatus.ACCEPTED); - } - - @GetMapping(DEFAULT_STUDYGROUP_URL + "/{studygroup-id}" + DEFAULT_TIME_SCHEDULE_URL + "s") - public ResponseEntity getAllTimeScheduleOfStudygroup(@PathVariable("studygroup-id") @Positive Long studygroupId) { - - List findTimeSchedules = - calendarStudygroupService.getTimeSchedulesByStudygroupId(studygroupId); - - List responseDtos = - mapper.timeScheduleListToTimeScheduleResponseDto(findTimeSchedules); - - return new ResponseEntity<>(responseDtos, HttpStatus.OK); - } - - @GetMapping(DEFAULT_STUDYGROUP_URL + "/{studygroup-id}" + DEFAULT_TIME_SCHEDULE_URL + "/{timeschedule-id}") - public ResponseEntity getTimeScheduleOfStudygroup(@PathVariable("studygroup-id") @Positive Long studygroupId, - @PathVariable("timeschedule-id") @Positive Long timeScheduleId) { - TimeSchedule findTimeSchedule = - calendarStudygroupService.getSingleTimeScheduleById(studygroupId, timeScheduleId); - - TimeScheduleResponseDto responseDto = - mapper.timeScheduleToTimeScheduleResponseDto(findTimeSchedule); - - return new ResponseEntity<>(responseDto, HttpStatus.OK); - } - - @DeleteMapping(DEFAULT_STUDYGROUP_URL + "/{studygroup-id}" + DEFAULT_TIME_SCHEDULE_URL + "/{timeschedule-id}") - public ResponseEntity deleteCalendarStudygroup(@PathVariable("studygroup-id") @Positive Long studygroupId, - @PathVariable("timeschedule-id") @Positive Long timeScheduleId) { - calendarStudygroupService.deleteTimeScheduleByTimeScheduleId(studygroupId, timeScheduleId); - - return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/dto/CalendarDto.java b/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/dto/CalendarDto.java deleted file mode 100644 index 4a26ce4b..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/dto/CalendarDto.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.codestates.edusync.study.plancalendar.studygroup.dto; - -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import org.springframework.lang.Nullable; - -import javax.validation.constraints.NotNull; -import java.sql.Timestamp; -import java.util.List; - -public class CalendarDto { - - @NoArgsConstructor - @Getter - public static class Post { - @NotNull - private List timeSchedules; - } - - @NoArgsConstructor - @Getter - @Setter - public static class Patch { - @NotNull - private TimeScheduleDto.Patch timeSchedule; - } - - public static class TimeScheduleDto { - - @NoArgsConstructor - @Getter - @Setter - public static class Post { - @NotNull - private String title; - - @Nullable - private String content; - - @NotNull - private Timestamp start; - - @NotNull - private Timestamp end; - } - - @NoArgsConstructor - @Getter - @Setter - public static class Patch { - private Long id; - private String title; - private String content; - private Timestamp start; - private Timestamp end; - } - - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/dto/CalendarResponseDto.java b/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/dto/CalendarResponseDto.java deleted file mode 100644 index cdf0ab13..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/dto/CalendarResponseDto.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.codestates.edusync.study.plancalendar.studygroup.dto; - -import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import java.sql.Timestamp; -import java.util.HashMap; -import java.util.Map; - -@NoArgsConstructor -@Getter -@Setter -public class CalendarResponseDto { - private Long id; - private Long groupId; - - private String title; - private Boolean allDay; - - @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss", timezone = "Asia/Seoul") - private Timestamp start; - @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss", timezone = "Asia/Seoul") - private Timestamp end; - - private String description; - private Boolean overlap; - - private Map extendedProps = new HashMap<>(); - - private String color; -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/dto/CalendarStudygroupResponseDto.java b/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/dto/CalendarStudygroupResponseDto.java deleted file mode 100644 index be6a42cc..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/dto/CalendarStudygroupResponseDto.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.codestates.edusync.study.plancalendar.studygroup.dto; - -import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import java.sql.Timestamp; -import java.util.HashMap; -import java.util.Map; - -@NoArgsConstructor -@Getter -@Setter -public class CalendarStudygroupResponseDto { - private Long id; - private Long groupId; - - private String title; - private Boolean allDay; - - @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss", timezone = "Asia/Seoul") - private Timestamp start; - @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss", timezone = "Asia/Seoul") - private Timestamp end; - - private String description; - private Boolean overlap; - - private Map extendedProps = new HashMap<>(); - - private String color; -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/mapper/CalendarStudygroupMapper.java b/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/mapper/CalendarStudygroupMapper.java deleted file mode 100644 index eba0ab17..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/mapper/CalendarStudygroupMapper.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.codestates.edusync.study.plancalendar.studygroup.mapper; - -import com.codestates.edusync.infodto.timeschedule.dto.TimeScheduleResponseDto; -import com.codestates.edusync.infodto.timeschedule.entity.TimeSchedule; -import com.codestates.edusync.study.plancalendar.studygroup.dto.CalendarDto; -import com.codestates.edusync.study.studygroup.entity.Studygroup; -import org.mapstruct.Mapper; - -import java.util.List; - -@Mapper(componentModel = "spring") -public interface CalendarStudygroupMapper { - - List timeSchedulePostDtoListToTimeScheduleList(List timeSchedules); - TimeSchedule timeSchedulePatchDtoToTimeSchedule(CalendarDto.Patch patchDto); - - List timeScheduleListToTimeScheduleResponseDto(List timeSchedules); - - default TimeScheduleResponseDto timeScheduleToTimeScheduleResponseDto(TimeSchedule ts) { - TimeScheduleResponseDto result = new TimeScheduleResponseDto(); - result.setId(ts.getId()); - result.setStudygroupName(ts.getStudygroup().getStudyName()); - result.setPlatform(ts.getStudygroup().getPlatform()); - - TimeScheduleResponseDto.TimeScheduleDto resultTimeScheduleInfo = new TimeScheduleResponseDto.TimeScheduleDto(); - resultTimeScheduleInfo.setStart(ts.getStart()); - resultTimeScheduleInfo.setEnd(ts.getEnd()); - result.setTimeScheduleInfo(resultTimeScheduleInfo); - - TimeScheduleResponseDto.CalendarInfoDto resultCalendarInfo = new TimeScheduleResponseDto.CalendarInfoDto(); - resultCalendarInfo.setStart(ts.getStudygroup().getStudyPeriodStart()); - resultCalendarInfo.setEnd(ts.getStudygroup().getStudyPeriodEnd()); - result.setCalendarInfo(resultCalendarInfo); - - return result; - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/repository/CalendarStudygroupRepository.java b/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/repository/CalendarStudygroupRepository.java deleted file mode 100644 index c73c0cc7..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/repository/CalendarStudygroupRepository.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.codestates.edusync.study.plancalendar.studygroup.repository; - -import com.codestates.edusync.infodto.timeschedule.entity.TimeSchedule; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.List; - -public interface CalendarStudygroupRepository extends JpaRepository { - - List findAllByStudygroupId(Long studygroupId); -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/service/CalendarStudygroupService.java b/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/service/CalendarStudygroupService.java deleted file mode 100644 index b1577554..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/service/CalendarStudygroupService.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.codestates.edusync.study.plancalendar.studygroup.service; - -import com.codestates.edusync.exception.BusinessLogicException; -import com.codestates.edusync.infodto.timeschedule.entity.TimeSchedule; -import com.codestates.edusync.study.plancalendar.studygroup.repository.CalendarStudygroupRepository; -import com.codestates.edusync.study.plancalendar.studygroup.utils.CalendarStudygroupManager; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.Optional; - -import static com.codestates.edusync.exception.ExceptionCode.STUDYGROUP_POST_COMMENT_NOT_FOUND; -import static com.codestates.edusync.exception.ExceptionCode.TIME_SCHEDULE_NOT_FOUND; - -@RequiredArgsConstructor -@Service -public class CalendarStudygroupService implements CalendarStudygroupManager { - private final CalendarStudygroupRepository calendarStudygroupRepository; - @Override - public void createTimeSchedulesForStudygroup(Long studyGroupId, - List timeSchedules) { - // FIXME: 2023-05-11: 스터디 그룹 머지하면 적용. 지금은 동작 하지 않는다! -// Studygroup findStudygroup = studygroupService.findVerifyStudygroup(studygroupId); -// -// timeSchedules.forEach(ts -> { -// ts.setStudygroup(findStudygroup); -// ts.setTitle(findStudygroup.getStudyName()); -// ts.setContent((findStudygroup.getPlatform())); -// } ); - calendarStudygroupRepository.saveAll(timeSchedules); - } - - @Override - public void createTimeSchedulesOfAllMember(Long studygroupId, - List timeSchedules) { - // TODO: 2023-05-11 나중에 구현할거임 ! ADV - } - - @Override - public void updateStudygroupTimeSchedule(Long studygroupId, Long timeScheduleId, - TimeSchedule timeSchedule) { - TimeSchedule findTimeSchedule = findVerifyTimeSchedule(timeScheduleId); - - Optional.ofNullable(timeSchedule.getTitle()).ifPresent(findTimeSchedule::setTitle); - Optional.ofNullable(timeSchedule.getContent()).ifPresent(findTimeSchedule::setContent); - Optional.ofNullable(timeSchedule.getStart()).ifPresent(findTimeSchedule::setStart); - Optional.ofNullable(timeSchedule.getEnd()).ifPresent(findTimeSchedule::setEnd); - - calendarStudygroupRepository.save(findTimeSchedule); - } - - @Override - public List getTimeSchedulesByStudygroupId(Long studygroupId) { - return calendarStudygroupRepository.findAllByStudygroupId(studygroupId); - } - - @Override - public TimeSchedule getSingleTimeScheduleById(Long studygroupId, Long timeScheduleId) { - return findVerifyTimeSchedule(timeScheduleId); - } - - @Override - public void deleteAllTimeSchedulesByStudygroupId(Long studygroupId) { - List findTimeSchedules = calendarStudygroupRepository.findAllByStudygroupId(studygroupId); - - calendarStudygroupRepository.deleteAll(findTimeSchedules); - } - - @Override - public void deleteTimeScheduleByTimeScheduleId(Long studygroupId, Long timeScheduleId) { - TimeSchedule findTimeSchedule = findVerifyTimeSchedule(timeScheduleId); - - calendarStudygroupRepository.delete(findTimeSchedule); - } - - @Override - public void deleteTimeScheduleWithSameTimeOfMember(Long studygroupId, Long timeScheduleId) { - // TODO: 2023-05-11 ADV 에서 구현할거임 !!! - } - - /** - *

일정 조회

- * 일정 식별자에 해당하는 일정이 존재하는지 확인
- * 404 Not Found 일정이 존재하지 않음 !
- * @param timeScheduleId - * @return - */ - private TimeSchedule findVerifyTimeSchedule(Long timeScheduleId) { - return calendarStudygroupRepository.findById(timeScheduleId) - .orElseThrow( () -> - new BusinessLogicException(TIME_SCHEDULE_NOT_FOUND) - ); - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/utils/CalendarStudygroupManager.java b/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/utils/CalendarStudygroupManager.java deleted file mode 100644 index 0e76ef92..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/plancalendar/studygroup/utils/CalendarStudygroupManager.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.codestates.edusync.study.plancalendar.studygroup.utils; - -import com.codestates.edusync.infodto.timeschedule.entity.TimeSchedule; - -import java.util.List; - -public interface CalendarStudygroupManager { - - /** - *

스터디 그룹 일정 리스트를 생성한다

- * 일정 리스트를 입력 받아, Time Schedule 을 생성 한다.
- * 각각의 Time Schedule 은 해당 스터디 그룹의 일정과 연결 된다.
- * 스터디 그룹만의 캘린더에는 member 식별자 컬럼을 매핑하지 않는다.
- * @param studyGroupId 스터디 그룹의 식별자 - * @param timeSchedules 일정 리스트 - */ - void createTimeSchedulesForStudygroup(Long studygroupId, List timeSchedules); - - /** - *

스터디 맴버의 캘린더에 일정 리스트를 생성한다

- * 일정 리스트를 입력 받아, Time Schedule 을 생성 한다.
- * 각각의 Time Schedule 은 해당 스터디 그룹에 속해 있는 스터디 원들의 일정과 연결 된다.
- * 스터디 그룹에 속한 스터디 맴버의 일정에는 studygroup 식별자 컬럼과 member 식별자 컬럼을 전부 매핑한다.
- * @param studyGroupId 스터디 그룹의 식별자 - * @param timeSchedules 일정 리스트 - */ - void createTimeSchedulesOfAllMember(Long studygroupId, List timeSchedules); - - /** - *

하나의 일정을 수정한다.

- * Time Schedule Id 에 해당하는 일정의 내용을 수정한다
- * studygroup Id 는 유효성 검증용
- * @param studygroupId 스터디 그룹의 식별자 - * @param timeScheduleId 일정의 식별자 - * @param timeSchedule 변경할 일정 내용 - */ - void updateStudygroupTimeSchedule(Long studygroupId, Long timeScheduleId, TimeSchedule timeSchedule); - - /** - *

스터디 그룹에 해당하는 일정 리스트를 조회한다

- * 스터디 그룹의 식별자에 해당하는 일정 리스트를 조회한다. - * @param studygroupId - * @return - */ - List getTimeSchedulesByStudygroupId(Long studygroupId); - - - /** - *

하나의 일정을 조회한다

- * 스터디 그룹에 속하는 일정 하나를 조회한다. - * @param studygroupId 스터디 그룹의 식별자 - * @param timeScheduleId 일정의 식별자 - * @return - */ - TimeSchedule getSingleTimeScheduleById(Long studygroupId, Long timeScheduleId); - - /** - *

모든 스터디 맴버와 스터디 그룹의 일정을 삭제한다

- * 해당 스터디 그룹에 속한 맴버의 일정 리스트를 전부 삭제한다. - * @param studygroupId studygroup 의 식별자 - */ - void deleteAllTimeSchedulesByStudygroupId(Long studygroupId); - - /** - *

스터디 그룹의 해당 일정을 삭제한다

- * 해당 스터디에 속한 일정의 식별자에 해당하는 일정을 삭제한다. - * @param studygroupId studygroup 의 식별자 - * @param timeScheduleId timeSchedule 의 식별자 - */ - void deleteTimeScheduleByTimeScheduleId(Long studygroupId, Long timeScheduleId); - - /** - *

스터디 그룹의 일정과 스터디 그룹에 속한 맴버의 동일한 시간의 일정을 삭제한다.

- * 해당 스터디 그룹의 일정도 삭제하고,
- * 스터디 그룹에 속한 맴버의 동일한 시간의 일정을 전부 삭제한다.
- * @param studygroupId - * @param timeScheduleId - */ - void deleteTimeScheduleWithSameTimeOfMember(Long studygroupId, Long timeScheduleId); -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/controller/StudygroupPostCommentController.java b/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/controller/StudygroupPostCommentController.java deleted file mode 100644 index 2c5e92f0..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/controller/StudygroupPostCommentController.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.codestates.edusync.study.postcomment.controller; - -import com.codestates.edusync.study.postcomment.dto.StudygroupPostCommentDto; -import com.codestates.edusync.study.postcomment.entity.StudygroupPostComment; -import com.codestates.edusync.study.postcomment.mapper.StudygroupPostCommentMapper; -import com.codestates.edusync.study.postcomment.service.StudygroupPostCommentService; -import com.codestates.edusync.util.UriCreator; -import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.validation.Valid; -import javax.validation.constraints.Positive; -import java.net.URI; -import java.util.List; - -@RequiredArgsConstructor -@Validated -@RestController -public class StudygroupPostCommentController { - private final StudygroupPostCommentService studygroupPostCommentService; - private final StudygroupPostCommentMapper mapper; - - private static final String DEFAULT_STUDYGROUP_URL = "/studygroup"; - private static final String DEFAULT_STUDYGROUP_POST_COMMENT_URL = "/comment"; - - /** - * 댓글을 등록한다. - * @param studygroupId - * @param postDto - * @return - */ - @PostMapping(DEFAULT_STUDYGROUP_URL + "/{studygroup-id}" + DEFAULT_STUDYGROUP_POST_COMMENT_URL) - public ResponseEntity postStudygroupPostComment(@PathVariable("studygroup-id") @Positive Long studygroupId, - @Valid @RequestBody StudygroupPostCommentDto.Post postDto) { - StudygroupPostComment createdStudygroupPostComment = - studygroupPostCommentService.createStudygroupPostComment( - studygroupId, - mapper.studygroupPostCommentPostDtoToStudygroupPostComment(postDto) - ); - - URI location = UriCreator.createUri( - UriCreator.createUri(DEFAULT_STUDYGROUP_URL, studygroupId) + - DEFAULT_STUDYGROUP_POST_COMMENT_URL, createdStudygroupPostComment.getId()); - - return new ResponseEntity<>(location, HttpStatus.CREATED); - } - - /** - * 댓글을 수정한다. - * @param studygroupId - * @param commentId - * @param patchDto - * @return - */ - @PatchMapping(DEFAULT_STUDYGROUP_URL + "/{studygroup-id}" + DEFAULT_STUDYGROUP_POST_COMMENT_URL + "/{comment-id}") - public ResponseEntity patchStudygroupPostComment(@PathVariable("studygroup-id") @Positive Long studygroupId, - @PathVariable("comment-id") @Positive Long commentId, - @Valid @RequestBody StudygroupPostCommentDto.Patch patchDto) { - StudygroupPostComment updatedStudygroupPostComment = - studygroupPostCommentService.updateStudygroupPostComment( - studygroupId, commentId, - mapper.studygroupPostCommentPatchDtoToStudygroupPostComment(patchDto) - ); - - return new ResponseEntity<>(HttpStatus.OK); - } - - /** - * 댓글들을 전부 조회한다 - * @param studygroupId - * @return - */ - @GetMapping(DEFAULT_STUDYGROUP_URL + "/{studygroup-id}" + DEFAULT_STUDYGROUP_POST_COMMENT_URL + "s") - public ResponseEntity getStudygroupPostComment(@PathVariable("studygroup-id") @Positive Long studygroupId) { - List findComments = studygroupPostCommentService.getAllStudygroupPostComments(studygroupId); - - return new ResponseEntity<>( - mapper.studygroupPostCommentToStudygroupPostCommentResponseDtos(findComments), - HttpStatus.OK - ); - } - - /** - * 댓글을 삭제한다 - * @param studygroupId - * @param commentId - * @return - */ - @DeleteMapping(DEFAULT_STUDYGROUP_URL + "/{studygroup-id}" + DEFAULT_STUDYGROUP_POST_COMMENT_URL + "/{comment-id}") - public ResponseEntity deleteStudygroupPostComment(@PathVariable("studygroup-id") @Positive Long studygroupId, - @PathVariable("comment-id") @Positive Long commentId) { - - studygroupPostCommentService.deleteStudygroupPostComment(studygroupId, commentId); - - return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } - - /** - * 스터디 모집글에 있는 댓글들을 전부 삭제한다 - * @param studygroupId - * @return - */ - @DeleteMapping(DEFAULT_STUDYGROUP_URL + "/{studygroup-id}/all") - public ResponseEntity deleteAllStudygroupPostComment(@PathVariable("studygroup-id") @Positive Long studygroupId) { - - studygroupPostCommentService.deleteAllStudygroupPostCommentByStudygroupId(studygroupId); - - return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/dto/StudygroupPostCommentDto.java b/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/dto/StudygroupPostCommentDto.java deleted file mode 100644 index 3f6349b5..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/dto/StudygroupPostCommentDto.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.codestates.edusync.study.postcomment.dto; - -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import javax.validation.constraints.NotNull; - -public class StudygroupPostCommentDto { - - @NoArgsConstructor - @Getter - public static class Post { - @NotNull - private String content; - } - - @NoArgsConstructor - @Getter - @Setter - public static class Patch { - private Long id; - - private String content; - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/dto/StudygroupPostCommentResponseDto.java b/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/dto/StudygroupPostCommentResponseDto.java deleted file mode 100644 index 5e351f0a..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/dto/StudygroupPostCommentResponseDto.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.codestates.edusync.study.postcomment.dto; - -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -@NoArgsConstructor -@Getter -@Setter -public class StudygroupPostCommentResponseDto { - private Long commentId; - private Long studygroupId; - private Long memberId; - private String content; -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/entity/StudygroupPostComment.java b/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/entity/StudygroupPostComment.java deleted file mode 100644 index 769a2ad8..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/entity/StudygroupPostComment.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.codestates.edusync.study.postcomment.entity; - -import com.codestates.edusync.audit.Auditable; -import com.codestates.edusync.member.entity.Member; -import com.codestates.edusync.study.studygroup.entity.Studygroup; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import javax.persistence.*; - -import static javax.persistence.FetchType.*; - -@NoArgsConstructor -@Getter -@Setter -@Entity -@Table(name = "studygroup_post_comment") -public class StudygroupPostComment extends Auditable { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(length = 200) - private String content; - - @ManyToOne(fetch = LAZY) - @JoinColumn(name = "studygroup_id") - private Studygroup studygroup; - - @ManyToOne(fetch = LAZY) - @JoinColumn(name = "member_id") - private Member member; - - - /** - *

양방향 매핑을 위한 메서드

- * 기존 연결을 끊고, 새로 관계를 연결한다.
- * 양방향 매핑 시 순환참조 가능성이 있으므로, 반대쪽에서 사용하면 절대 안됨
- * 참고: {@link StudygroupPostComment#setStudygroupOneWay(Studygroup)} - * @param studygroup 양방향 매핑을 위한 객체 - */ - public void setStudygroup(Studygroup studygroup) { - if (studygroup == null) { - throw new IllegalArgumentException("Studygroup cannot be null"); - } - - if(this.studygroup != null) { - this.studygroup.getStudygroupPostComments().remove(this); - } - this.studygroup = studygroup; - this.studygroup.getStudygroupPostComments().add(this); - } - - /** - *

양방향 매핑 중 순환 방지용으로 단방향으로만 추가하는 메서드

- * @param studygroup 관계를 끊는 경우 null 가능 - */ - public void setStudygroupOneWay(Studygroup studygroup) { - this.studygroup = studygroup; - } - - - /** - *

양방향 매핑을 위한 메서드

- * 기존 연결을 끊고, 새로 관계를 연결한다.
- * 양방향 매핑 시 순환참조 가능성이 있으므로, 반대쪽에서 사용하면 절대 안됨
- * 참고: {@link StudygroupPostComment#setMemberOneWay(Member)} - * @param member 양방향 매핑을 위한 객체 - */ - public void setMember(Member member) { - if (member == null) { - throw new IllegalArgumentException("Member cannot be null"); - } - - if(this.member != null) { - this.member.getStudygroupPostComments().remove(this); - } - this.member = member; - this.member.getStudygroupPostComments().add(this); - } - - /** - *

양방향 매핑 중 순환 방지용으로 단방향으로만 추가하는 메서드

- * @param member 관계를 끊는 경우 null 가능 - */ - public void setMemberOneWay(Member member) { - this.member = member; - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/mapper/StudygroupPostCommentMapper.java b/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/mapper/StudygroupPostCommentMapper.java deleted file mode 100644 index 7f5574d2..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/mapper/StudygroupPostCommentMapper.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.codestates.edusync.study.postcomment.mapper; - -import com.codestates.edusync.study.postcomment.dto.StudygroupPostCommentDto; -import com.codestates.edusync.study.postcomment.dto.StudygroupPostCommentResponseDto; -import com.codestates.edusync.study.postcomment.entity.StudygroupPostComment; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; - -import java.util.List; - -@Mapper(componentModel = "spring") -public interface StudygroupPostCommentMapper { - StudygroupPostComment studygroupPostCommentPostDtoToStudygroupPostComment(StudygroupPostCommentDto.Post postDto); - StudygroupPostComment studygroupPostCommentPatchDtoToStudygroupPostComment(StudygroupPostCommentDto.Patch patchDto); - - @Mapping(source = "id", target = "commentId") - @Mapping(source = "studygroup.id", target = "studygroupId") - @Mapping(source = "member.id", target = "memberId") - List studygroupPostCommentToStudygroupPostCommentResponseDtos(List comment); -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/repository/StudygroupPostCommentRepository.java b/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/repository/StudygroupPostCommentRepository.java deleted file mode 100644 index 74f687e4..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/repository/StudygroupPostCommentRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.codestates.edusync.study.postcomment.repository; - -import com.codestates.edusync.study.postcomment.entity.StudygroupPostComment; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.List; - -public interface StudygroupPostCommentRepository extends JpaRepository { - - List findAllByStudygroupId(Long studygroupId); - - void deleteAllByStudygroupId(Long studygroupId); -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/service/StudygroupPostCommentService.java b/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/service/StudygroupPostCommentService.java deleted file mode 100644 index 12a6eb4e..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/service/StudygroupPostCommentService.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.codestates.edusync.study.postcomment.service; - -import com.codestates.edusync.exception.BusinessLogicException; -import com.codestates.edusync.member.entity.Member; -import com.codestates.edusync.member.service.MemberService; -import com.codestates.edusync.study.postcomment.entity.StudygroupPostComment; -import com.codestates.edusync.study.postcomment.repository.StudygroupPostCommentRepository; -import com.codestates.edusync.study.postcomment.utils.StudygroupPostCommentManager; -import com.codestates.edusync.study.studygroup.service.StudygroupService; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.Optional; - -import static com.codestates.edusync.exception.ExceptionCode.*; - -@RequiredArgsConstructor -@Service -public class StudygroupPostCommentService implements StudygroupPostCommentManager { - private final StudygroupPostCommentRepository studygroupPostCommentRepository; - private final MemberService memberService; - private final StudygroupService studygroupService; - - @Override - public StudygroupPostComment createStudygroupPostComment(Long studygroupId, - StudygroupPostComment comment) { - Member findMember = memberService.findVerifyMemberWhoLoggedIn(); - comment.setMember(findMember); - - // FIXME: 2023-05-11: 스터디 그룹 머지하면 적용. 지금은 동작 하지 않는다! -// Studygroup findStudygroup = studygroupService.findVerifyStudygroup(studygroupId); -// comment.setStudygroup(findStudygroup); - - // 이것도 동작하지않음. 엔티티에 빈값이 있어서 ! - return studygroupPostCommentRepository.save(comment); - } - - @Override - public StudygroupPostComment updateStudygroupPostComment(Long studygroupId, Long commentId, - StudygroupPostComment patchComment) { - Member findMember = memberService.findVerifyMemberWhoLoggedIn(); - StudygroupPostComment findComment = findVerifyStudygroupPostComment(commentId); - - verifyStudygroupPostComment(findMember.getId(), studygroupId, findComment); - - Optional.ofNullable(patchComment.getContent()) - .ifPresent(findComment::setContent); - - return studygroupPostCommentRepository.save(findComment); - } - - /** - *

댓글 조회

- * 댓글 식별자에 해당하는 댓글이 존재하는지 확인
- * 404 Not Found 댓글이 존재하지 않음 !
- * @param commentId - * @return - */ - private StudygroupPostComment findVerifyStudygroupPostComment(Long commentId) { - return studygroupPostCommentRepository.findById(commentId) - .orElseThrow( () -> - new BusinessLogicException(STUDYGROUP_POST_COMMENT_NOT_FOUND) - ); - } - - /** - *

댓글의 유효성 검증

- * 400 Not matched 요청받은 스터디 모집글의 식별자와, 코멘트의 스터디 식별자가 일치하지 않음
- * 403 Not Allowed 스터디 장이 아니고, 본인이 쓴 글이 아닐 때는 forbidden
- * @param memberId - * @param studygroupId - * @param comment - */ - private void verifyStudygroupPostComment(Long memberId, Long studygroupId, - StudygroupPostComment comment) { - if( comment.getStudygroup().getId() != studygroupId ) { - throw new BusinessLogicException(STUDYGROUP_POST_COMMENT_NOT_MATCHED); - } - - if( comment.getStudygroup().getLeaderMember().getId() != memberId && - comment.getMember().getId() != memberId ) { - throw new BusinessLogicException(STUDYGROUP_POST_COMMENT_NOT_ALLOWED); - } - } - - private void verifyStudygroupMemberLeader(Long memberId, - StudygroupPostComment comment) { - if( comment.getStudygroup().getLeaderMember().getId() != memberId ) { - throw new BusinessLogicException(STUDYGROUP_POST_COMMENT_ALLOWED_ONLY_FOR_LEADER); - } - } - - @Override - public List getAllStudygroupPostComments(Long studygroupId) { - return studygroupPostCommentRepository.findAllByStudygroupId(studygroupId); - } - - @Override - public void deleteStudygroupPostComment(Long studygroupId, Long commentId) { - Member findMember = memberService.findVerifyMemberWhoLoggedIn(); - StudygroupPostComment findComment = findVerifyStudygroupPostComment(commentId); - - verifyStudygroupPostComment(findMember.getId(), studygroupId, findComment); - - studygroupPostCommentRepository.delete(findComment); - } - - @Override - public void deleteAllStudygroupPostCommentByStudygroupId(Long studygroupId) { - Member findMember = memberService.findVerifyMemberWhoLoggedIn(); - // FIXME: 2023-05-11 : 머지 후 작업 필요 -// Studygroup findStudygroup = studygroupService.findVerifyStudygroup(studygroupId); -// -// verifyStudygroupMemberLeader(findMember.getId(), findStudygroup); - - studygroupPostCommentRepository.deleteAllByStudygroupId(studygroupId); - } - -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/utils/StudygroupPostCommentManager.java b/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/utils/StudygroupPostCommentManager.java deleted file mode 100644 index c5877a45..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/postcomment/utils/StudygroupPostCommentManager.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.codestates.edusync.study.postcomment.utils; - -import com.codestates.edusync.study.postcomment.entity.StudygroupPostComment; - -import java.util.List; - -public interface StudygroupPostCommentManager { - - /** - *

댓글을 생성한다

- * 해당 스터디 그룹에 댓글을 생성한다.
- * @param studygroupId 스터디 그룹 식별자 - * @param comment 댓글 - */ - StudygroupPostComment createStudygroupPostComment(Long studygroupId, StudygroupPostComment comment); - - /** - *

댓글을 수정한다

- * 해당 스터디 그룹의 댓글을 수정한다.
- * @param studygroupId 스터디 그룹 식별자 - * @param commentId 댓글 식별자 - * @param comment 댓글 - */ - StudygroupPostComment updateStudygroupPostComment(Long studygroupId, Long commentId, StudygroupPostComment comment); - - /** - *

댓글들을 전부 조회한다

- * 해당 스터디 모집글의 댓글을 전부 조회한다.
- * @param studygroupId 스터디 모집글 식별자 - * @return 스터디 모집글의 댓글 리스트 - */ - List getAllStudygroupPostComments(Long studygroupId); - - /** - *

스터디 모질글의 댓글을 삭제한다

- * 해당 스터디 모집글의 댓글 하나를 삭제한다.
- * @param studygroupId - * @param studygroupPostCommentId - */ - void deleteStudygroupPostComment(Long studygroupId, Long studygroupPostCommentId); - - /** - *

스터디 모집글의 댓글을 전부 삭제한다

- * 해당 스터디 모집글에 있는 모든 댓글을 삭제한다.
- * @param studygroupId - */ - void deleteAllStudygroupPostCommentByStudygroupId(Long studygroupId); -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/controller/StudygroupController.java b/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/controller/StudygroupController.java deleted file mode 100644 index 745b1521..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/controller/StudygroupController.java +++ /dev/null @@ -1,151 +0,0 @@ -package com.codestates.edusync.study.studygroup.controller; - -import com.codestates.edusync.dto.MultiResponseDto; -import com.codestates.edusync.study.studygroup.dto.StudygroupDto; -import com.codestates.edusync.study.studygroup.dto.StudygroupResponseDto; -import com.codestates.edusync.study.studygroup.entity.Studygroup; -import com.codestates.edusync.study.studygroup.mapper.StudygroupMapper; -import com.codestates.edusync.study.studygroup.service.StudygroupService; -import com.codestates.edusync.util.UriCreator; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.validation.Valid; -import javax.validation.constraints.Positive; -import java.net.URI; -import java.util.List; - -@RequiredArgsConstructor -@Validated -@RestController -public class StudygroupController { - private static final String STUDYGROUP_DEFAULT_URI = "/studygroup"; - private final StudygroupMapper mapper; - private final StudygroupService service; - - /** - * 스터디 모집 & 등록 - * @param postDto - * @return - */ - @PostMapping(STUDYGROUP_DEFAULT_URI) - public ResponseEntity postStudygroup(@Valid @RequestBody StudygroupDto.Post postDto) { - - Studygroup studygroup = mapper.StudygroupDtoPostToStudygroup(postDto); - studygroup = service.createStudygruop(studygroup); - URI location = UriCreator.createUri(STUDYGROUP_DEFAULT_URI, studygroup.getId()); - - return ResponseEntity.created(location).build(); - } - - /** - * 스터디 모집 & 수정 - * @param patchDto - * @return - * @throws Exception - */ - @PatchMapping(STUDYGROUP_DEFAULT_URI) - public ResponseEntity patchStudygroup(@Valid @RequestBody StudygroupDto.Patch patchDto) { - - Studygroup studygroup = mapper.StudygroupDtoPatchToStudygroup(patchDto); - studygroup = service.updateStudygroup(studygroup); - - URI location = UriCreator.createUri(STUDYGROUP_DEFAULT_URI, studygroup.getId()); - HttpHeaders headers = new HttpHeaders(); - headers.setLocation(location); - - return new ResponseEntity<>(headers, HttpStatus.OK); - } - - /** - * 스터디 모집 상태 수정(모집중 - 모집완료) - * @param studygroupId - * @return - */ - @PatchMapping(STUDYGROUP_DEFAULT_URI + "/{studygroup-id}") - public ResponseEntity patchStudygroupStatus(@PathVariable("studygroup-id") @Positive Long studygroupId) { - - service.updateStatusStudygroup(studygroupId); - - URI location = UriCreator.createUri(STUDYGROUP_DEFAULT_URI, studygroupId); - HttpHeaders headers = new HttpHeaders(); - headers.setLocation(location); - - return new ResponseEntity<>(headers, HttpStatus.OK); - } - - /** - * 스터디 조회 - * @param studygroupId - * @return - */ - @GetMapping(STUDYGROUP_DEFAULT_URI + "/{studygroup-id}") - public ResponseEntity getStudygroupDetail(@PathVariable("studygroup-id") @Positive Long studygroupId) { - - Studygroup studygroup = service.findStudygroup(studygroupId); - StudygroupResponseDto responseDto = mapper.StudygroupToStudygroupResponseDto(studygroup); - - return ResponseEntity.ok(responseDto); - } - - /** - * 스터디 리스트 - * @param page - * @param size - * @return - */ - @GetMapping(STUDYGROUP_DEFAULT_URI + "s") - public ResponseEntity getStudygroupPage(@RequestParam("page") @Positive Integer page, - @RequestParam("size") @Positive Integer size){ - - Page studygroupPage = service.findStudygroups(page-1, size); - List studygroupList = studygroupPage.getContent(); - List responseDtoList = - mapper.StudygroupListToStudygroupResponseDtoList(studygroupList); - - return ResponseEntity.ok(new MultiResponseDto<>(responseDtoList,studygroupPage)); - } - - /** - * 스터디 삭제 - * @param studygroupId - * @return - */ - @DeleteMapping(STUDYGROUP_DEFAULT_URI + "/{studygroup-id}") - public ResponseEntity deleteStudygroup(@PathVariable("studygroup-id") @Positive Long studygroupId) { - service.deleteStudygroup(studygroupId); - return ResponseEntity.noContent().build(); - } - - // FIXME: 2023-05-10 끝나고 생각 -// /** -// * 스터디 멤버 강퇴 -// * @param studygroupId -// * @param classmateId -// * @return -// */ -// @DeleteMapping(STUDYGROUP_DEFAULT_URI + "/{studygroup-id}/classmate/{classmate-id}/kickout") -// public ResponseEntity deleteStudygroupkick(@PathVariable("studygroup-id") @Positive Long studygroupId, -// @PathVariable("classmate-id") @Positive Long classmateId) { -// -// return new ResponseEntity(HttpStatus.NO_CONTENT); -// } -// -// /** -// * 스터디 자진 탈퇴 -// * @param studygroupId -// * @param classmateId -// * @return -// */ -// @DeleteMapping(STUDYGROUP_DEFAULT_URI + "/{studygroup-id}/classmate/{classmate-id}") -// public ResponseEntity deleteStudygroup(@PathVariable("studygroup-id") @Positive Long studygroupId, -// @PathVariable("classmate-id") @Positive Long classmateId) { -// -// return new ResponseEntity(HttpStatus.NO_CONTENT); -// } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/dto/StudygroupDto.java b/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/dto/StudygroupDto.java deleted file mode 100644 index 976da8c8..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/dto/StudygroupDto.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.codestates.edusync.study.studygroup.dto; - -import com.codestates.edusync.searchtag.entity.SearchTag; -import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Positive; -import java.sql.Timestamp; -import java.util.List; - -public class StudygroupDto { - - @NoArgsConstructor - @Getter - @Setter - public static class Post { - @NotNull - private String studyName; - - @NotNull - @JsonFormat(pattern = "yyyy.MM.dd") - private Timestamp studyPeriodStart; - - @NotNull - @JsonFormat(pattern = "yyyy.MM.dd") - private Timestamp studyPeriodEnd; - - private List daysOfWeek; - - @NotNull - @JsonFormat(pattern = "HH:mm", timezone = "Asia/Seoul") - private Timestamp studyTimeStart; - - @NotNull - @JsonFormat(pattern = "HH:mm", timezone = "Asia/Seoul") - private Timestamp studyTimeEnd; - - @Positive - private Integer memberCountMin; - - @Positive - private Integer memberCountMax; - - @NotNull - private String platform; - - @NotNull - private String introduction; - - private List tags; - } - - @NoArgsConstructor - @Getter - @Setter - public static class Patch { - @NotNull - private Long id; - - private String studyName; - - @JsonFormat(pattern = "yyyy.MM.dd") - private Timestamp studyPeriodStart; - - @JsonFormat(pattern = "yyyy.MM.dd") - private Timestamp studyPeriodEnd; - - private List daysOfWeek; - - @JsonFormat(pattern = "HH:mm", timezone = "Asia/Seoul") - private Timestamp studyTimeStart; - - @JsonFormat(pattern = "HH:mm", timezone = "Asia/Seoul") - private Timestamp studyTimeEnd; - - @Positive - private Integer memberCountMin; - - @Positive - private Integer memberCountMax; - - private String platform; - - private String introduction; - - private List tags; - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/dto/StudygroupResponseDto.java b/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/dto/StudygroupResponseDto.java deleted file mode 100644 index 2f2d1082..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/dto/StudygroupResponseDto.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.codestates.edusync.study.studygroup.dto; - -import com.codestates.edusync.searchtag.entity.SearchTag; -import com.codestates.edusync.study.studygroupjoin.dto.ClassmateResponseDto; -import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import org.apache.tomcat.jni.Time; - -import javax.validation.constraints.NotNull; -import java.sql.Timestamp; -import java.util.List; - -@NoArgsConstructor -@Getter -@Setter -public class StudygroupResponseDto { - private Long id; - private String studyName; - @JsonFormat(pattern = "yyyy.MM.dd") - private Timestamp studyPeriodStart; - @JsonFormat(pattern = "yyyy.MM.dd") - private Timestamp studyPeriodEnd; - private String daysOfWeek; - @JsonFormat(pattern = "HH:mm", timezone = "Asia/Seoul") - private Timestamp studyTimeStart; - @JsonFormat(pattern = "HH:mm", timezone = "Asia/Seoul") - private Timestamp studyTimeEnd; - private Integer memberCountMin; - private Integer memberCountMax; - private String platform; - private String introduction; - private Boolean requited; - private List tags; - private StudyLeader leader; - - @NoArgsConstructor - @Getter - @Setter - public static class StudyLeader { - private Long id; - private String nickName; - } - - /** - * 스터디 조회 - */ - @NoArgsConstructor - @Getter - @Setter - public static class DtoList { - private Long id; - private String title; - //private - } - - /** - * 스터디 조회 시, 태그 - */ - @NoArgsConstructor - @Getter - @Setter - public static class TagDto { - private String key; - private String value; - } - -// private Count count; -// -// @NoArgsConstructor -// @Getter -// @Setter -// public static class Count { -// private Integer waiter; -// private Integer classmate; -// private Integer comment; -// private Integer tag; -// } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/entity/Studygroup.java b/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/entity/Studygroup.java deleted file mode 100644 index db8cfe8b..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/entity/Studygroup.java +++ /dev/null @@ -1,208 +0,0 @@ -package com.codestates.edusync.study.studygroup.entity; - -import com.codestates.edusync.audit.Auditable; -import com.codestates.edusync.infodto.timeschedule.entity.TimeSchedule; -import com.codestates.edusync.member.entity.Member; -import com.codestates.edusync.study.postcomment.entity.StudygroupPostComment; -import com.codestates.edusync.study.studygroupjoin.entity.StudygroupJoin; -import com.codestates.edusync.searchtag.entity.SearchTag; -import com.fasterxml.jackson.annotation.JsonFormat; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import javax.persistence.*; - -import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.List; - -import static javax.persistence.CascadeType.*; -import static javax.persistence.FetchType.*; - -@NoArgsConstructor -@Getter -@Setter -@Entity -public class Studygroup extends Auditable { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(length = 50, nullable = false) - private String studyName; - - @Column(length = -1, name = "studygroup_image") - private String studygroupImage; - - @Column(length = 200) - private String address; - - @Column(length = 50, name = "days_of_week") - private String daysOfWeek; - - @Column(name = "study_period_start") - @JsonFormat(pattern = "yyyy.MM.dd") - private Timestamp studyPeriodStart; - - @Column(name = "study_period_end") - @JsonFormat(pattern = "yyyy.MM.dd") - private Timestamp studyPeriodEnd; - - @Column(name = "study_time_start") - @JsonFormat(pattern = "HH:mm", timezone = "Asia/Seoul") - private Timestamp studyTimeStart; - - @Column(name = "study_time_end") - @JsonFormat(pattern = "HH:mm", timezone = "Asia/Seoul") - private Timestamp studyTimeEnd; - - @OneToMany(mappedBy = "studygroup", fetch = LAZY) - private List timeSchedules = new ArrayList<>(); - - @Column(nullable = false, columnDefinition = "TEXT") - private String introduction; - - @Column - private Integer memberCountMin; - - @Column - private Integer memberCountMax; - - @Column(length = 50, nullable = false) - private String platform; - - @Column - private Boolean is_requited; - - @ManyToOne(cascade = {PERSIST, MERGE}, fetch = EAGER) - @JoinColumn(name = "leader_member_id") - private Member leaderMember; - - @OneToMany(mappedBy = "studygroup", fetch = LAZY) - private List studygroupJoins = new ArrayList<>(); - - @OneToMany(mappedBy = "studygroup", cascade = {REMOVE}, fetch = LAZY) - private List studygroupPostComments = new ArrayList<>(); - - @OneToMany(mappedBy = "studygroup", cascade = {PERSIST, MERGE, REMOVE}, fetch = LAZY) - private List searchTags = new ArrayList<>(); - - - /** - *

양방향 매핑을 위한 One To Many 쪽의 Setter 설정

- * 기존에 연결되어있던 관계를 끊고, 양쪽 객체를 새로 연결해준다. - * @param timeSchedules 새로 매핑할 객체의 리스트( 시간표 ) - */ - public void setTimeSchedules(List timeSchedules) { - if (timeSchedules == null) { - throw new IllegalArgumentException("TimeSchedule List cannot be null"); - } - - if (this.timeSchedules != null) { - for (TimeSchedule timeSchedule : this.timeSchedules) { - timeSchedule.setStudygroupOneWay(null); - } - } - - this.timeSchedules = timeSchedules; - for (TimeSchedule timeSchedule : this.timeSchedules) { - timeSchedule.setStudygroupOneWay(this); - } - } - - - /** - *

양방향 매핑을 위한 메서드

- * 기존 연결을 끊고, 새로 관계를 연결한다.
- * 양방향 매핑 시 순환참조 가능성이 있으므로, 반대쪽에서 사용하면 절대 안됨
- * 참고: {@link Studygroup#setLeaderMemberOneWay(Member)} - * @param leaderMember 양방향 매핑을 위한 객체 - */ - public void setLeaderMember(Member leaderMember) { - if (leaderMember == null) { - throw new IllegalArgumentException("Leader Member cannot be null"); - } - - if(this.leaderMember != null) { - this.leaderMember.getStudygroupsAsLeader().remove(this); - } - this.leaderMember = leaderMember; - this.leaderMember.getStudygroupsAsLeader().add(this); - } - - /** - *

양방향 매핑 중 순환 방지용으로 단방향으로만 추가하는 메서드

- * @param leaderMember 관계를 끊는 경우 null 가능 - */ - public void setLeaderMemberOneWay(Member leaderMember) { - this.leaderMember = leaderMember; - } - - /** - *

양방향 매핑을 위한 One To Many 쪽의 Setter 설정

- * 기존에 연결되어있던 관계를 끊고, 양쪽 객체를 새로 연결해준다. - * @param studygroupJoins 새로 매핑할 객체의 리스트( 시간표 ) - */ - public void setStudygroupJoins(List studygroupJoins) { - if (studygroupJoins == null) { - throw new IllegalArgumentException("StudygroupJoin List cannot be null"); - } - - if (this.studygroupJoins != null) { - for (StudygroupJoin studygroupJoin : this.studygroupJoins) { - studygroupJoin.setStudygroupOneWay(null); - } - } - - this.studygroupJoins = studygroupJoins; - for (StudygroupJoin studygroupJoin : this.studygroupJoins) { - studygroupJoin.setStudygroupOneWay(this); - } - } - - /** - *

양방향 매핑을 위한 One To Many 쪽의 Setter 설정

- * 기존에 연결되어있던 관계를 끊고, 양쪽 객체를 새로 연결해준다. - * @param studygroupPostComments 새로 매핑할 객체의 리스트( 시간표 ) - */ - public void setStudygroupPostComments(List studygroupPostComments) { - if (studygroupPostComments == null) { - throw new IllegalArgumentException("StudygroupPostComment List cannot be null"); - } - - if (this.studygroupPostComments != null) { - for (StudygroupPostComment studygroupPostComment : this.studygroupPostComments) { - studygroupPostComment.setStudygroupOneWay(null); - } - } - - this.studygroupPostComments = studygroupPostComments; - for (StudygroupPostComment studygroupPostComment : this.studygroupPostComments) { - studygroupPostComment.setStudygroupOneWay(this); - } - } - - - /** - *

양방향 매핑을 위한 One To Many 쪽의 Setter 설정

- * 기존에 연결되어있던 관계를 끊고, 양쪽 객체를 새로 연결해준다. - * @param searchTags 새로 매핑할 객체의 리스트( 시간표 ) - */ - public void setSearchTags(List searchTags) { - if (searchTags == null) { - throw new IllegalArgumentException("Search Tag List cannot be null"); - } - - if (this.searchTags != null) { - for (SearchTag searchTag : this.searchTags) { - searchTag.setStudygroupOneWay(null); - } - } - - this.searchTags = searchTags; - for (SearchTag searchTag : this.searchTags) { - searchTag.setStudygroupOneWay(this); - } - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/mapper/StudygroupMapper.java b/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/mapper/StudygroupMapper.java deleted file mode 100644 index b5d88d00..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/mapper/StudygroupMapper.java +++ /dev/null @@ -1,140 +0,0 @@ -package com.codestates.edusync.study.studygroup.mapper; - -import com.codestates.edusync.exception.BusinessLogicException; -import com.codestates.edusync.exception.ExceptionCode; -import com.codestates.edusync.member.entity.Member; -import com.codestates.edusync.searchtag.dto.SearchTagResponseDto; -import com.codestates.edusync.searchtag.entity.SearchTag; -import com.codestates.edusync.study.studygroup.dto.StudygroupDto; -import com.codestates.edusync.study.studygroup.dto.StudygroupResponseDto; -import com.codestates.edusync.study.studygroup.entity.Studygroup; -import org.mapstruct.Mapper; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -@Mapper(componentModel = "spring") -public interface StudygroupMapper { - /** - * 스터드 등록 시, Request Body 로 받아 Studygroup 객체로 매핑 - * @param studygroupDto - * @return - * @throws Exception - */ - default Studygroup StudygroupDtoPostToStudygroup(StudygroupDto.Post studygroupDto){ - Studygroup studygroup = new Studygroup(); - studygroup.setStudyName(studygroupDto.getStudyName()); - studygroup.setDaysOfWeek(studygroupDto.getDaysOfWeek().toString()); - studygroup.setStudyPeriodStart(studygroupDto.getStudyPeriodStart()); - studygroup.setStudyPeriodEnd(studygroupDto.getStudyPeriodEnd()); - studygroup.setStudyTimeStart(studygroupDto.getStudyTimeStart()); - studygroup.setStudyTimeEnd(studygroupDto.getStudyTimeEnd()); - studygroup.setIntroduction(studygroupDto.getIntroduction()); - studygroup.setMemberCountMin(studygroupDto.getMemberCountMin()); - studygroup.setMemberCountMax(studygroupDto.getMemberCountMax()); - studygroup.setPlatform(studygroupDto.getPlatform()); - studygroup.setIs_requited(false); - studygroup.setSearchTags(studygroupDto.getTags()); - return studygroup; - } - - /** - * 스터디 조회 시, Studygroup 객체를 ResponseDto 로 매핑 - * @param studygroup - * @return - * @throws Exception - */ - default StudygroupResponseDto StudygroupToStudygroupResponseDto(Studygroup studygroup){ - List tags = new ArrayList<>(); - for (SearchTag st : studygroup.getSearchTags()) { - StudygroupResponseDto.TagDto tag = new StudygroupResponseDto.TagDto(); - tag.setKey(st.getTagKey()); - tag.setValue(st.getTagValue()); - tags.add(tag); - } - StudygroupResponseDto responseDto = new StudygroupResponseDto(); - responseDto.setId(studygroup.getId()); - responseDto.setStudyName(studygroup.getStudyName()); - responseDto.setStudyPeriodStart(studygroup.getStudyPeriodStart()); - responseDto.setStudyPeriodEnd(studygroup.getStudyPeriodEnd()); - responseDto.setDaysOfWeek(studygroup.getDaysOfWeek()); - responseDto.setStudyTimeStart(studygroup.getStudyTimeStart()); - responseDto.setStudyTimeEnd(studygroup.getStudyTimeEnd()); - responseDto.setMemberCountMin(studygroup.getMemberCountMin()); - responseDto.setMemberCountMax(studygroup.getMemberCountMax()); - responseDto.setPlatform(studygroup.getPlatform()); - responseDto.setIntroduction(studygroup.getIntroduction()); - responseDto.setRequited(studygroup.getIs_requited()); - responseDto.setTags(tags); - responseDto.setLeader(memberToStudyLeader(studygroup.getLeaderMember())); - return responseDto; - } - - /** - * 스터디 조회 시, 스터디 리더 정보 매핑 - * @param member - * @return - * @throws Exception - */ - default StudygroupResponseDto.StudyLeader memberToStudyLeader(Member member){ - if (member == null) throw new BusinessLogicException(ExceptionCode.MEMBER_NOT_FOUND); - StudygroupResponseDto.StudyLeader leader = new StudygroupResponseDto.StudyLeader(); - leader.setId(member.getId()); - leader.setNickName(member.getNickName()); - return leader; - } - - /** - * 스터디 수정 시, 스터디 객체로 매핑 - * @param studygroupDto - * @return - * @throws Exception - */ - default Studygroup StudygroupDtoPatchToStudygroup(StudygroupDto.Patch studygroupDto){ - Studygroup studygroup = new Studygroup(); - studygroup.setId(studygroupDto.getId()); - studygroup.setStudyName(studygroupDto.getStudyName()); - studygroup.setDaysOfWeek(studygroupDto.getDaysOfWeek().toString()); - studygroup.setStudyPeriodStart(studygroupDto.getStudyPeriodStart()); - studygroup.setStudyPeriodEnd(studygroupDto.getStudyPeriodEnd()); - studygroup.setStudyTimeStart(studygroupDto.getStudyTimeStart()); - studygroup.setStudyTimeEnd(studygroupDto.getStudyTimeEnd()); - studygroup.setIntroduction(studygroupDto.getIntroduction()); - studygroup.setMemberCountMin(studygroupDto.getMemberCountMin()); - studygroup.setMemberCountMax(studygroupDto.getMemberCountMax()); - studygroup.setPlatform(studygroupDto.getPlatform()); - studygroup.setSearchTags(studygroupDto.getTags()); - return studygroup; - } - - /** - * 스터디 리스트 조회 - * @param studygroups - * @return - */ - default List StudygroupListToStudygroupResponseDtoList(List studygroups){ - List respnseDtoList = new ArrayList<>(studygroups.size()); - Iterator studygroupIterator = studygroups.iterator(); - - while(studygroupIterator.hasNext()) { - StudygroupResponseDto.DtoList responseDto = - StudygroupsToStudygroupResponseDtoList((Studygroup) studygroupIterator.next()); - respnseDtoList.add(responseDto); - } - - return respnseDtoList; - } - - /** - * 스터디 리스트 조회 시, 각 스터디를 ResponseDto 로 매핑 - * @param studygroup - * @return - */ - default StudygroupResponseDto.DtoList StudygroupsToStudygroupResponseDtoList(Studygroup studygroup){ - StudygroupResponseDto.DtoList dtoList = new StudygroupResponseDto.DtoList(); - dtoList.setId(studygroup.getId()); - dtoList.setTitle(studygroup.getStudyName()); - return dtoList; - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/repository/StudygroupRepository.java b/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/repository/StudygroupRepository.java deleted file mode 100644 index c7974df4..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/repository/StudygroupRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.codestates.edusync.study.studygroup.repository; - -import com.codestates.edusync.study.studygroup.entity.Studygroup; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface StudygroupRepository extends JpaRepository { - -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/service/StudygroupService.java b/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/service/StudygroupService.java deleted file mode 100644 index e8aa9e24..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/service/StudygroupService.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.codestates.edusync.study.studygroup.service; - -import com.codestates.edusync.exception.BusinessLogicException; -import com.codestates.edusync.exception.ExceptionCode; -import com.codestates.edusync.member.entity.Member; -import com.codestates.edusync.member.service.MemberService; -import com.codestates.edusync.searchtag.service.SearchTagService; -import com.codestates.edusync.study.studygroup.entity.Studygroup; -import com.codestates.edusync.study.studygroup.repository.StudygroupRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Sort; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Optional; - -@RequiredArgsConstructor -@Transactional -@Service -public class StudygroupService { - private final StudygroupRepository repository; - private final MemberService memberService; - private final SearchTagService searchTagService; - - /** - * 스터디 등록 - * 스터디 리더등록을 위한 Member 조회에 대한 의존성 분리 필요해 보임 - * @param studygroup - * @return - */ - public Studygroup createStudygruop(Studygroup studygroup) { - Member member = memberService.findVerifyMemberWhoLoggedIn(); - studygroup.setLeaderMember(member); - studygroup.setSearchTags(searchTagService.createSearchTags(studygroup.getSearchTags())); - return repository.save(studygroup); - } - - /** - * 스터디 정보 수정 - * @param studygroup - * @return - */ - public Studygroup updateStudygroup(Studygroup studygroup) { - Studygroup findStudygroup = findStudygroup(studygroup.getId()); - Member member = memberService.findVerifyMemberWhoLoggedIn(); - - if (findStudygroup.getLeaderMember().getEmail().equals(member.getEmail())) { - Optional.ofNullable(studygroup.getStudyName()).ifPresent(findStudygroup::setStudyName); - Optional.ofNullable(studygroup.getDaysOfWeek()).ifPresent(findStudygroup::setDaysOfWeek); - Optional.ofNullable(studygroup.getStudyPeriodStart()).ifPresent(findStudygroup::setStudyPeriodStart); - Optional.ofNullable(studygroup.getStudyPeriodEnd()).ifPresent(findStudygroup::setStudyPeriodEnd); - Optional.ofNullable(studygroup.getStudyTimeStart()).ifPresent(findStudygroup::setStudyTimeStart); - Optional.ofNullable(studygroup.getStudyTimeEnd()).ifPresent(findStudygroup::setStudyTimeEnd); - Optional.ofNullable(studygroup.getIntroduction()).ifPresent(findStudygroup::setIntroduction); - Optional.ofNullable(studygroup.getMemberCountMin()).ifPresent(findStudygroup::setMemberCountMin); - Optional.ofNullable(studygroup.getMemberCountMax()).ifPresent(findStudygroup::setMemberCountMax); - Optional.ofNullable(studygroup.getPlatform()).ifPresent(findStudygroup::setPlatform); - Optional.ofNullable(studygroup.getSearchTags()).ifPresent(findStudygroup::setSearchTags); - } else throw new BusinessLogicException(ExceptionCode.INVALID_PERMISSION); - - return repository.save(findStudygroup); - } - - /** - * 스터디 모집 상태 수정 - * @param studygroupId - */ - public void updateStatusStudygroup(Long studygroupId) { - Studygroup findStudygroup = findStudygroup(studygroupId); - Member member = memberService.findVerifyMemberWhoLoggedIn(); - - if (findStudygroup.getLeaderMember().getEmail().equals(member.getEmail())) { - boolean requited = findStudygroup.getIs_requited(); - if (requited) requited = false; - else requited = true; - findStudygroup.setIs_requited(requited); - } else throw new BusinessLogicException(ExceptionCode.INVALID_PERMISSION); - - repository.save(findStudygroup); - } - - /** - * 스터디 조회 - * @param studygroupId - * @return - */ - public Studygroup findStudygroup(Long studygroupId) { - Studygroup findStudygroup = repository.findById(studygroupId) - .orElseThrow(() -> new BusinessLogicException(ExceptionCode.STUDYGROUP_NOT_FOUND)); - return findStudygroup; - } - - /** - * 스터디 리스트 조회 - * @param page - * @param size - * @return - */ - public Page findStudygroups(Integer page, Integer size) { - return repository.findAll(PageRequest.of(page, size, Sort.by("id").descending())); - } - - /** - * 스터디 삭제 - * @param studygroupId - * @throws Exception - */ - public void deleteStudygroup(Long studygroupId){ - Studygroup findStudygroup = findStudygroup(studygroupId); - Member member = memberService.findVerifyMemberWhoLoggedIn(); - - if (findStudygroup.getLeaderMember().getEmail().equals(member.getEmail())) { - repository.deleteById(studygroupId); - } else throw new BusinessLogicException(ExceptionCode.INVALID_PERMISSION); - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/utils/StudygroupManager.java b/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/utils/StudygroupManager.java deleted file mode 100644 index 36c7665d..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/studygroup/utils/StudygroupManager.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.codestates.edusync.study.studygroup.utils; - -public interface StudygroupManager { - -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/studygroupjoin/controller/StudygroupJoinController.java b/server/edusync/src/main/java/com/codestates/edusync/study/studygroupjoin/controller/StudygroupJoinController.java deleted file mode 100644 index 8310f853..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/studygroupjoin/controller/StudygroupJoinController.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.codestates.edusync.study.studygroupjoin.controller; - -import com.codestates.edusync.study.studygroupjoin.service.StudygroupJoinService; -import com.codestates.edusync.util.UriCreator; -import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.validation.constraints.Positive; -import java.net.URI; - -@RequiredArgsConstructor -@Validated -@RestController -public class StudygroupJoinController { - private final StudygroupJoinService studygroupJoinService; - private static final String DEFAULT_STUDYGROUP_URL = "/studygroup"; - private static final String DEFAULT_CLASSMATE_URL = "/classmate"; - private static final String DEFAULT_CANDIDATE_URL = "/candidate"; - - - /** - * 스터디 그룹에 가입 신청한다. - * @param studygroupId - * @return - */ - @PostMapping(DEFAULT_STUDYGROUP_URL + "/{studygroup-id}" + DEFAULT_CANDIDATE_URL) - public ResponseEntity postClassmateOnCandidated(@PathVariable("studygroup-id") @Positive Long studygroupId) { - long candidatedId = 1L; // fixme: 임시로 만들어둠 - - URI location = UriCreator.createUri( - UriCreator.createUri(DEFAULT_STUDYGROUP_URL, studygroupId) + - DEFAULT_CANDIDATE_URL, candidatedId); // FIXME: 2023-05-08 테스트 해봐야함 !!! - - return new ResponseEntity<>(location, HttpStatus.CREATED); - } - - /** - * 가입 승인한다. (스터디장) - * @param studygroupId - * @param candidateId - * @return - */ - @PostMapping(DEFAULT_STUDYGROUP_URL + "/{studygroup-id}" + DEFAULT_CANDIDATE_URL + "/{candidate-id}/approve") - public ResponseEntity approveCandidatedMember(@PathVariable("studygroup-id") @Positive Long studygroupId, - @PathVariable("candidate-id") @Positive Long candidateId) { - - return new ResponseEntity<>(HttpStatus.ACCEPTED); - } - - /** - * 가입 거부한다. (스터디장) - * @param studygroupId - * @param candidateId - * @return - */ - @DeleteMapping(DEFAULT_STUDYGROUP_URL + "/{studygroup-id}" + DEFAULT_CANDIDATE_URL + "/{candidate-id}/reject") - public ResponseEntity rejectCandidatedMember(@PathVariable("studygroup-id") @Positive Long studygroupId, - @PathVariable("candidate-id") @Positive Long candidateId) { - - return new ResponseEntity<>(HttpStatus.ACCEPTED); - } - - /** - * 본인이 직접 가입 신청을 철회한다 - * @param studygroupId - * @param candidateId - * @return - */ - @DeleteMapping(DEFAULT_STUDYGROUP_URL + "/{studygroup-id}" + DEFAULT_CANDIDATE_URL + "/{candidate-id}") - public ResponseEntity deleteCandidatedMember(@PathVariable("studygroup-id") @Positive Long studygroupId, - @PathVariable("candidate-id") @Positive Long candidateId) { - - return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/studygroupjoin/dto/ClassmateResponseDto.java b/server/edusync/src/main/java/com/codestates/edusync/study/studygroupjoin/dto/ClassmateResponseDto.java deleted file mode 100644 index c2b446db..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/studygroupjoin/dto/ClassmateResponseDto.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.codestates.edusync.study.studygroupjoin.dto; - -import com.codestates.edusync.member.dto.MemberResponseDto; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -@NoArgsConstructor -@Getter -@Setter -public class ClassmateResponseDto { - - private Long id; - private String address; - private MemberResponseDto member; - private Count count; - - @NoArgsConstructor - @Getter - @Setter - public static class Count { - private Integer studygroupAsLeader; - private Integer studygroup; - private Integer comment; - private Integer tag; - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/studygroupjoin/entity/StudygroupJoin.java b/server/edusync/src/main/java/com/codestates/edusync/study/studygroupjoin/entity/StudygroupJoin.java deleted file mode 100644 index 1cdd01bf..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/studygroupjoin/entity/StudygroupJoin.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.codestates.edusync.study.studygroupjoin.entity; - -import com.codestates.edusync.member.entity.Member; -import com.codestates.edusync.study.studygroup.entity.Studygroup; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -import javax.persistence.*; - -import static javax.persistence.FetchType.*; - -@NoArgsConstructor -@Getter -@Setter -@Entity -public class StudygroupJoin { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(name = "is_approved") - private Boolean isApproved = false; - - @ManyToOne(fetch = EAGER) - @JoinColumn(name = "studygroup_join_member_id") - private Member member; - - @ManyToOne(fetch = EAGER) - @JoinColumn(name = "studygroup_join_studygroup_id") - private Studygroup studygroup; - - - /** - *

양방향 매핑을 위한 메서드

- * 기존 연결을 끊고, 새로 관계를 연결한다.
- * 양방향 매핑 시 순환참조 가능성이 있으므로, 반대쪽에서 사용하면 절대 안됨
- * 참고: {@link StudygroupJoin#setStudygroupOneWay(Studygroup)} - * @param studygroup 양방향 매핑을 위한 인자 - */ - public void setStudygroup(Studygroup studygroup) { - if (studygroup == null) { - throw new IllegalArgumentException("Studygroup cannot be null"); - } - - if(this.studygroup != null) { - this.studygroup.getStudygroupJoins().remove(this); - } - this.studygroup = studygroup; - this.studygroup.getStudygroupJoins().add(this); - } - - /** - *

양방향 매핑 중 순환 방지용으로 단방향으로만 추가하는 메서드

- * @param studygroup 관계를 끊는 경우 null 가능 - */ - public void setStudygroupOneWay(Studygroup studygroup) { - this.studygroup = studygroup; - } - - /** - *

양방향 매핑을 위한 메서드

- * 기존 연결을 끊고, 새로 관계를 연결한다.
- * 양방향 매핑 시 순환참조 가능성이 있으므로, 반대쪽에서 사용하면 절대 안됨
- * 참고: {@link StudygroupJoin#setStudygroupOneWay(Studygroup)} - * @param member 양방향 매핑을 위한 인자 - */ - public void setMember(Member member) { - if (member == null) { - throw new IllegalArgumentException("Member cannot be null"); - } - - if(this.member != null) { - this.member.getStudygroupJoins().remove(this); - } - this.member = member; - this.member.getStudygroupJoins().add(this); - } - - /** - *

양방향 매핑 중 순환 방지용으로 단방향으로만 추가하는 메서드

- * @param member 관계를 끊는 경우 null 가능 - */ - public void setMemberOneWay(Member member) { - this.member = member; - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/studygroupjoin/mapper/StudygroupJoinMapper.java b/server/edusync/src/main/java/com/codestates/edusync/study/studygroupjoin/mapper/StudygroupJoinMapper.java deleted file mode 100644 index 8bb4ad86..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/studygroupjoin/mapper/StudygroupJoinMapper.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.codestates.edusync.study.studygroupjoin.mapper; - -import org.mapstruct.Mapper; - -@Mapper(componentModel = "spring") -public interface StudygroupJoinMapper { - -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/studygroupjoin/repository/StudygroupJoinRepository.java b/server/edusync/src/main/java/com/codestates/edusync/study/studygroupjoin/repository/StudygroupJoinRepository.java deleted file mode 100644 index 37914d8e..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/studygroupjoin/repository/StudygroupJoinRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.codestates.edusync.study.studygroupjoin.repository; - -import com.codestates.edusync.study.studygroupjoin.entity.StudygroupJoin; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface StudygroupJoinRepository extends JpaRepository { - -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/studygroupjoin/service/StudygroupJoinService.java b/server/edusync/src/main/java/com/codestates/edusync/study/studygroupjoin/service/StudygroupJoinService.java deleted file mode 100644 index aad2488c..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/studygroupjoin/service/StudygroupJoinService.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.codestates.edusync.study.studygroupjoin.service; - -import com.codestates.edusync.study.studygroupjoin.repository.StudygroupJoinRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@RequiredArgsConstructor -@Service -public class StudygroupJoinService { - private final StudygroupJoinRepository studygroupJoinRepository; - -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/study/studygroupjoin/utils/StudygroupJoinManager.java b/server/edusync/src/main/java/com/codestates/edusync/study/studygroupjoin/utils/StudygroupJoinManager.java deleted file mode 100644 index d9c99eec..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/study/studygroupjoin/utils/StudygroupJoinManager.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.codestates.edusync.study.studygroupjoin.utils; - -import com.codestates.edusync.study.studygroup.entity.Studygroup; - -public interface StudygroupJoinManager { - /** - *

스터디에 가입 신청을 한다

- * 403 forbidden 로그인을 하지 않은 경우, 권한이 없음
- * 404 not found 스터디를 찾을 수 없음
- * 409 already exist in this studygroup 이미 스터디그룹에 가입되어있는 경우
- * @param studygroupId - * @param classmateId - * @return - */ - Studygroup signUpToStudygroup(Long studygroupId, Long classmateId); - - - /** - *

스터디장이 가입 신청을 승인한다

- * 403 forbidden - * @param studygroupId - * @param classmateId - * @return - */ - Studygroup approveSignUpFromStudyLeader(Long studygroupId, Long classmateId); - - /** - *

스터디장이 가입 신청을 거절한다

- * 403 forbidden 가입신청 거절을 위한 권한이 없음
- * - * @param studygroupId - * @param studygroupJoinId - */ - void rejectByStudyLeader(Long studygroupId, Long studygroupJoinId); - - /** - *

스터디에 가입을 신청한 스터디원이 가입신청을 철회한다.

- * @param studygroupJoinId - */ - void cancelSubscription(Long studygroupJoinId); - - /** - * 스터디 그룹이 존재하는지 확인 - * @param studygroupId - */ - void verifyStudygroup(Long studygroupId); - - /** - * 이미 동일 스터디에 동일 클래스메이트가 신청을 한 경우의 예외처리 - * @param studygroupId - * @param classmateId - */ - void verifyExistCandidate(Long studygroupId, Long classmateId); -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/util/JwtUtil.java b/server/edusync/src/main/java/com/codestates/edusync/util/JwtUtil.java deleted file mode 100644 index e69de29b..00000000 diff --git a/server/edusync/src/main/java/com/codestates/edusync/util/UriCreator.java b/server/edusync/src/main/java/com/codestates/edusync/util/UriCreator.java deleted file mode 100644 index 83ac75d1..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/util/UriCreator.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.codestates.edusync.util; - -import org.springframework.web.util.UriComponentsBuilder; - -import java.net.URI; - -public class UriCreator { - public static URI createUri(String defaultUrl, long resourceId) { - return UriComponentsBuilder - .newInstance() - .path(defaultUrl + "/{resource-id}") - .buildAndExpand(resourceId) - .toUri(); - } -} diff --git a/server/edusync/src/main/java/com/codestates/edusync/util/VerifyMember.java b/server/edusync/src/main/java/com/codestates/edusync/util/VerifyMember.java deleted file mode 100644 index 4d0a2b3a..00000000 --- a/server/edusync/src/main/java/com/codestates/edusync/util/VerifyMember.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.codestates.edusync.util; - -import com.codestates.edusync.member.entity.Member; - -public interface VerifyMember { - Member findVerifiedMember(Long memberId); - void verifyMemberIsActive(Member member); - void sameMemberTest(Long memberId, String token); -} diff --git a/server/edusync/src/main/resources/application-server.yml b/server/edusync/src/main/resources/application-server.yml deleted file mode 100644 index dd465ae5..00000000 --- a/server/edusync/src/main/resources/application-server.yml +++ /dev/null @@ -1,49 +0,0 @@ -logging: - level: - org: - springframework: - web: debug - org.springframework.web.servlet: debug - org.hibernate.type.descriptor.sql.BasicBinder: trace - -spring: - datasource: - driver-class-name: com.mysql.cj.jdbc.Driver - url : ${RDS_DATABASE_URL} - username: ${RDS_DATABASE_USERNAME} - password: ${RDS_DATABASE_PASSWORD} - mvc: - pathmatch: - matching-strategy: ant_path_matcher - log-request-details: true - jpa: - defer-datasource-initialization: true - hibernate.ddl-auto: update - open-in-view: false - show-sql: true - properties: - hibernate: - format_sql: true - default_batch_fetch_size: 100 - highlight_sql: true - color-codes: true - type: - descriptor: - sql: trace - security: - oauth2: - client: - registration: - google: - client-id: 90423476142-0p4j9mmj540elt7qgg5udb7hsiog7hi2.apps.googleusercontent.com - clientSecret: ${GoogleClientSecret} - scope: - - email - - profile -mail: - address: - admin: ${ADMIN_MAIL} -jwt: - key: ${JWT_SECRET_KEY} - access-token-expiration-minutes: 30 - refresh-token-expiration-minutes: 420 \ No newline at end of file diff --git a/server/edusync/src/main/resources/application.yml b/server/edusync/src/main/resources/application.yml deleted file mode 100644 index 8b25ac4b..00000000 --- a/server/edusync/src/main/resources/application.yml +++ /dev/null @@ -1,73 +0,0 @@ -logging: - level: - org: - springframework: - web: debug -# security: debug - org.springframework.web.servlet: debug - org.hibernate.type.descriptor.sql.BasicBinder: trace - -spring: - datasource: - driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://localhost:3306/edusync?serverTimezone=Asia/Seoul - username: root - password: ${localDBPassword} - mvc: - pathmatch: - matching-strategy: ant_path_matcher - log-request-details: true -# sql: -# init: -# mode: always - jpa: - defer-datasource-initialization: true - open-in-view: false - show-sql: true - properties: - hibernate: - format_sql: true - default_batch_fetch_size: 100 - highlight_sql: true - color-codes: true - type: - descriptor: - sql: trace - security: - oauth2: - client: - registration: - google: - client-id: 90423476142-0p4j9mmj540elt7qgg5udb7hsiog7hi2.apps.googleusercontent.com - clientSecret: ${GoogleClientSecret} - scope: - - email - - profile - kakao: - client-id: ${KakaoClientId} - client-secret: ${KakaoClientSecret} - client-authentication-method: POST - authorization-grant-type: authorization_code - client-name: Kakao - provider: kakao - redirect-uri: "http://localhost:8080/login/oauth2/code/kakao" - scope: - - profile_nickname - - profile_image - - account_email - provider: - kakao: - authorization-uri: https://kauth.kakao.com/oauth/authorize - token-uri: https://kauth.kakao.com/oauth/token - user-info-uri: https://kapi.kakao.com/v2/user/me - user-name-attribute: id -mail: - address: - admin: admin@gmail.com -jwt: - key: ${JWT_SECRET_KEY} - access-token-expiration-minutes: 30 - refresh-token-expiration-minutes: 420 - -server: - port: 8080 diff --git a/server/edusync/src/main/resources/schema.sql b/server/edusync/src/main/resources/schema.sql deleted file mode 100644 index a965af7b..00000000 --- a/server/edusync/src/main/resources/schema.sql +++ /dev/null @@ -1,132 +0,0 @@ -create table if not exists member -( - id bigint auto_increment, - email varchar(100), - nick_name varchar(100), - profile_image blob, - password varchar(100), - address varchar(200), - grade varchar(50), - about_me TEXT, - with_me TEXT, - member_status varchar(50), - provider varchar(50), - modified_at timestamp, - created_at timestamp, - - constraint pk_member_id primary key (id), - constraint uk_member_email unique (email), - constraint uk_member_nick_name unique (nick_name) -); - -create table if not exists member_roles -( - member_id bigint not null, - roles varchar(30) -); - -create table if not exists studygroup_join -( - id bigint auto_increment, - is_approved boolean default false, - - member_id bigint, - studygroup_id bigint, - - constraint pk_studygroup_join_id primary key (id) -); - -create table if not exists studygroup -( - id bigint auto_increment, - study_name varchar(50), - studygroup_image blob, - address varchar(200), - days_of_week varchar(50), - study_period_start varchar(100), - study_period_end varchar(100), - study_time_start varchar(100), - study_time_end varchar(100), - introduction TEXT, - member_count_min int, - member_count_max int, - platform varchar(50), - is_requited boolean, - modified_at timestamp, - created_at timestamp, - - leader_member_id bigint, - - constraint pk_studygroup_id primary key (id) -); - -create table if not exists search_tag -( - id bigint auto_increment, - tag_key varchar(20), - tag_value varchar(100), - - studygroup_id bigint, - - constraint pk_search_tag_id primary key (id) -); - -create table if not exists studygroup_post_comment -( - id bigint auto_increment, - content varchar(200), - modified_at timestamp, - created_at timestamp, - - studygroup_id bigint, - member_id bigint, - - constraint pk_studygroup_post_comment_id primary key (id) -); - -create table if not exists time_schedule -( - id bigint auto_increment, - title varchar(100), - content varchar(200), - start_time timestamp, - end_time timestamp, - - member_id bigint, - studygroup_id bigint, - - constraint pk_time_schedule_id primary key (id) -); - -alter table member_roles - add constraint fk_member_roles_member_id - foreign key (member_id) references member (id); - -alter table studygroup_post_comment - add constraint fk_studygroup_post_comment_member_id - foreign key (member_id) references member (id); -alter table studygroup_post_comment - add constraint fk_studygroup_post_comment_studygroup_id - foreign key (studygroup_id) references studygroup (id); - -alter table studygroup_join - add constraint fk_studygroup_join_member_id - foreign key (member_id) references member (id); -alter table studygroup_join - add constraint fk_studygroup_join_studygroup_id - foreign key (studygroup_id) references studygroup (id); - -alter table search_tag - add constraint fk_search_tag_studygroup_id - foreign key (studygroup_id) references studygroup (id); - -alter table time_schedule - add constraint fk_time_schedule_member_id - foreign key (member_id) references member (id); -alter table time_schedule - add constraint fk_time_schedule_studygroup_id - foreign key (studygroup_id) references studygroup (id); - -alter table studygroup - add constraint fk_studygroup_leader_member_id - foreign key (leader_member_id) references member (id); \ No newline at end of file diff --git a/server/edusync/src/test/java/com/codestates/edusync/EdusyncApplicationTests.java b/server/edusync/src/test/java/com/codestates/edusync/EdusyncApplicationTests.java deleted file mode 100644 index ff467459..00000000 --- a/server/edusync/src/test/java/com/codestates/edusync/EdusyncApplicationTests.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.codestates.edusync; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class EdusyncApplicationTests { - -// @Test -// void contextLoads() { -// } - -} diff --git a/server/edusync/stop8080.sh b/server/edusync/stop8080.sh deleted file mode 100644 index bed9807b..00000000 --- a/server/edusync/stop8080.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -# Find the process running on port 8080 and get its process ID (PID) -pid=$(lsof -ti :8080) - -# If a process is found, kill it -if [ -n "$pid" ]; then - echo "Killing process on port 8080 with PID: $pid" - kill $pid - echo "Process killed." -else - echo "No process found running on port 8080." -fi \ No newline at end of file