diff --git a/src/main/kotlin/com/msg/gauth/domain/auth/presentation/AuthController.kt b/src/main/kotlin/com/msg/gauth/domain/auth/presentation/AuthController.kt index 3fa3d839..2ee93381 100644 --- a/src/main/kotlin/com/msg/gauth/domain/auth/presentation/AuthController.kt +++ b/src/main/kotlin/com/msg/gauth/domain/auth/presentation/AuthController.kt @@ -6,10 +6,12 @@ import com.msg.gauth.domain.auth.presentation.dto.response.RefreshResponseDto import com.msg.gauth.domain.auth.presentation.dto.response.SigninResponseDto import com.msg.gauth.domain.auth.services.* import com.msg.gauth.domain.auth.presentation.dto.request.PasswordInitReqDto +import com.msg.gauth.domain.auth.presentation.dto.response.SignupImageResDto import com.msg.gauth.domain.auth.services.InitPasswordService import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.* +import org.springframework.web.multipart.MultipartFile import javax.validation.Valid @RestController @@ -19,7 +21,8 @@ class AuthController( private val logoutService: LogoutService, private val signInService: SignInService, private val signUpService: SignUpService, - private val initPasswordService: InitPasswordService + private val initPasswordService: InitPasswordService, + private val signupImageUploadService: SignupImageUploadService, ) { @PatchMapping fun refresh(@RequestHeader("RefreshToken") refreshToken: String): ResponseEntity = @@ -42,6 +45,10 @@ class AuthController( return ResponseEntity(HttpStatus.CREATED) } + @PatchMapping("/image") + fun uploadSignupImage(@RequestPart("image") image: MultipartFile, @RequestPart("imageUrl") previousUrl: String?): ResponseEntity = + ResponseEntity.ok(signupImageUploadService.execute(image, previousUrl)) + @PatchMapping("/password/initialize") fun initPassword(@Valid @RequestBody passwordInitReqDto: PasswordInitReqDto): ResponseEntity { diff --git a/src/main/kotlin/com/msg/gauth/domain/auth/presentation/dto/request/SignupRequestDto.kt b/src/main/kotlin/com/msg/gauth/domain/auth/presentation/dto/request/SignupRequestDto.kt index 77db4bbf..e666138e 100644 --- a/src/main/kotlin/com/msg/gauth/domain/auth/presentation/dto/request/SignupRequestDto.kt +++ b/src/main/kotlin/com/msg/gauth/domain/auth/presentation/dto/request/SignupRequestDto.kt @@ -14,7 +14,9 @@ data class SignUpDto( @field:NotBlank @field:Pattern(regexp = "^(?=.*[A-Za-z])(?=.*[0-9])(?=.*[\$@\$!%*#?&])[A-Za-z[0-9]\$@\$!%*#?&]{8,20}$") - val password: String + val password: String, + + val profileUrl: String?, ) { fun toEntity(password: String): User = User( @@ -22,6 +24,6 @@ data class SignUpDto( password = password, roles = mutableListOf(UserRole.ROLE_STUDENT), state = UserState.PENDING, - profileUrl = null, + profileUrl = profileUrl, ) } \ No newline at end of file diff --git a/src/main/kotlin/com/msg/gauth/domain/auth/presentation/dto/response/SignupImageResDto.kt b/src/main/kotlin/com/msg/gauth/domain/auth/presentation/dto/response/SignupImageResDto.kt new file mode 100644 index 00000000..d3f194c6 --- /dev/null +++ b/src/main/kotlin/com/msg/gauth/domain/auth/presentation/dto/response/SignupImageResDto.kt @@ -0,0 +1,5 @@ +package com.msg.gauth.domain.auth.presentation.dto.response + +data class SignupImageResDto( + val imageUrl: String, +) \ No newline at end of file diff --git a/src/main/kotlin/com/msg/gauth/domain/auth/services/SignupImageUploadService.kt b/src/main/kotlin/com/msg/gauth/domain/auth/services/SignupImageUploadService.kt new file mode 100644 index 00000000..4aab18fd --- /dev/null +++ b/src/main/kotlin/com/msg/gauth/domain/auth/services/SignupImageUploadService.kt @@ -0,0 +1,17 @@ +package com.msg.gauth.domain.auth.services + +import com.msg.gauth.domain.auth.presentation.dto.response.SignupImageResDto +import com.msg.gauth.global.aws.s3.S3Util +import org.springframework.stereotype.Service +import org.springframework.web.multipart.MultipartFile + +@Service +class SignupImageUploadService( + private val s3Util: S3Util, +){ + fun execute(image: MultipartFile, previousUrl: String?): SignupImageResDto{ + if(previousUrl != null) + s3Util.deleteImage(previousUrl) + return SignupImageResDto(s3Util.upload(image)) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/msg/gauth/domain/user/presentation/UserController.kt b/src/main/kotlin/com/msg/gauth/domain/user/presentation/UserController.kt index ce8f108f..1fde2b06 100644 --- a/src/main/kotlin/com/msg/gauth/domain/user/presentation/UserController.kt +++ b/src/main/kotlin/com/msg/gauth/domain/user/presentation/UserController.kt @@ -4,11 +4,7 @@ import com.msg.gauth.domain.user.presentation.dto.request.PasswordChangeReqDto import com.msg.gauth.domain.user.services.ChangePasswordService import com.msg.gauth.domain.user.services.UploadProfileService import org.springframework.http.ResponseEntity -import org.springframework.web.bind.annotation.PatchMapping -import org.springframework.web.bind.annotation.RequestBody -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RequestParam -import org.springframework.web.bind.annotation.RestController +import org.springframework.web.bind.annotation.* import org.springframework.web.multipart.MultipartFile import javax.validation.Valid @@ -25,7 +21,7 @@ class UserController( } @PatchMapping("/image") - fun uploadProfile(@RequestParam("image") image: MultipartFile): ResponseEntity{ + fun uploadProfile(@RequestPart("image") image: MultipartFile): ResponseEntity{ uploadProfileService.execute(image) return ResponseEntity.noContent().build() } diff --git a/src/main/kotlin/com/msg/gauth/global/aws/s3/S3Util.kt b/src/main/kotlin/com/msg/gauth/global/aws/s3/S3Util.kt index 37dfbbf8..3b76bd13 100644 --- a/src/main/kotlin/com/msg/gauth/global/aws/s3/S3Util.kt +++ b/src/main/kotlin/com/msg/gauth/global/aws/s3/S3Util.kt @@ -20,4 +20,9 @@ class S3Util( amazonS3.putObject(bucket, profileName, file.inputStream, metadata) return amazonS3.getUrl(bucket, profileName).toString() } + + fun deleteImage(url: String){ + val key = url.split("/")[3] + amazonS3.deleteObject(bucket, key) + } } \ No newline at end of file diff --git a/src/main/kotlin/com/msg/gauth/global/security/SecurityConfig.kt b/src/main/kotlin/com/msg/gauth/global/security/SecurityConfig.kt index ffbe82d6..8f647ce0 100644 --- a/src/main/kotlin/com/msg/gauth/global/security/SecurityConfig.kt +++ b/src/main/kotlin/com/msg/gauth/global/security/SecurityConfig.kt @@ -1,7 +1,6 @@ package com.msg.gauth.global.security import com.fasterxml.jackson.databind.ObjectMapper -import com.msg.gauth.domain.user.enums.UserRole import com.msg.gauth.global.security.config.FilterConfig import com.msg.gauth.global.security.jwt.JwtTokenProvider import org.springframework.context.annotation.Bean @@ -15,7 +14,6 @@ import org.springframework.security.crypto.password.PasswordEncoder import org.springframework.security.web.SecurityFilterChain import org.springframework.security.web.util.matcher.RequestMatcher import org.springframework.web.cors.CorsUtils -import javax.servlet.http.HttpServletRequest @Configuration @EnableWebSecurity @@ -45,6 +43,8 @@ class SecurityConfig( .antMatchers(HttpMethod.DELETE, "/auth").authenticated() .antMatchers(HttpMethod.POST, "/auth/signup").permitAll() .antMatchers(HttpMethod.PATCH, "/auth/password/initialize").permitAll() + .antMatchers(HttpMethod.PATCH, "/auth/image").permitAll() + .antMatchers(HttpMethod.DELETE, "/auth/image").permitAll() // Email .antMatchers(HttpMethod.POST, "/email").permitAll()