Skip to content

Commit

Permalink
controller: UserController: Add API to delete self
Browse files Browse the repository at this point in the history
Signed-off-by: Shashank Verma <[email protected]>
  • Loading branch information
shank03 committed Oct 29, 2023
1 parent ef4c48e commit bab081d
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 0 deletions.
30 changes: 30 additions & 0 deletions src/main/kotlin/com/mnnit/moticlubs/controller/UserController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ import com.mnnit.moticlubs.dto.response.AdminUserDTO
import com.mnnit.moticlubs.service.FCMService
import com.mnnit.moticlubs.service.UserService
import com.mnnit.moticlubs.utils.Constants.BASE_PATH
import com.mnnit.moticlubs.utils.Constants.CAPTCHA_HEADER
import com.mnnit.moticlubs.utils.Constants.STAMP_HEADER
import com.mnnit.moticlubs.utils.Constants.USER_ID_CLAIM
import com.mnnit.moticlubs.utils.Constants.USER_ROUTE
import com.mnnit.moticlubs.utils.ResponseStamp
import com.mnnit.moticlubs.utils.ResponseStamp.invalidateStamp
import com.mnnit.moticlubs.utils.ServiceLogger
import com.mnnit.moticlubs.utils.UnauthorizedException
import com.mnnit.moticlubs.utils.apiWrapper
import com.mnnit.moticlubs.utils.invalidateStamp
import com.mnnit.moticlubs.utils.validateRequestBody
Expand All @@ -23,6 +25,7 @@ import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.tags.Tag
import org.springframework.http.ResponseEntity
import org.springframework.http.server.reactive.ServerHttpRequest
import org.springframework.web.bind.annotation.DeleteMapping
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.PostMapping
Expand Down Expand Up @@ -138,4 +141,31 @@ class UserController(
fcmService.updateFcm(FCM(it, dto.token))
}
.wrapError()

@DeleteMapping
@Operation(
summary = "Delete your own account",
description = "This API will delete your account and any actions (that includes posts, " +
"replies and as club admin) permanently. You need to enter your college G-Suite ID email in the captcha.",
)
fun deleteUser(@RequestHeader(CAPTCHA_HEADER) email: String): Mono<ResponseEntity<Void>> = pathAuthorization
.userAuthorization()
.flatMap { uid -> userService.getUserByUid(uid).map { Pair(uid, it) } }
.flatMap { (uid, user) ->
if (user.email == email) {
LOGGER.info("deleteUser: DELETE ACCOUNT [$uid]")
userService.deleteUser(uid)
} else {
Mono.error(UnauthorizedException("Please enter your email in the captcha"))
}
}
.invalidateStamp {
ResponseStamp.ADMIN.invalidateStamp()
ResponseStamp.MEMBER.invalidateStamp()
ResponseStamp.POST.invalidateStamp()
ResponseStamp.REPLY.invalidateStamp()
ResponseStamp.CHANNEL.invalidateStamp()
ResponseStamp.USER
}
.wrapError()
}
6 changes: 6 additions & 0 deletions src/main/kotlin/com/mnnit/moticlubs/service/UserService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,10 @@ class UserService(

@CacheEvict(cacheNames = ["user", "admins", "all_users", "members"], allEntries = true)
fun updateContact(uid: Long, contact: String): Mono<User> = userRepository.updateContact(uid, contact)

@CacheEvict(
cacheNames = ["user", "admins", "all_users", "members", "post", "replies", "all_channels"],
allEntries = true,
)
fun deleteUser(uid: Long) = userRepository.deleteById(uid)
}
1 change: 1 addition & 0 deletions src/main/kotlin/com/mnnit/moticlubs/utils/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.mnnit.moticlubs.utils

object Constants {
const val STAMP_HEADER = "X-Stamp-Value"
const val CAPTCHA_HEADER = "X-Captcha-Email"

const val BASE_PATH = "api/v1"

Expand Down
11 changes: 11 additions & 0 deletions src/main/kotlin/com/mnnit/moticlubs/utils/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@ fun <T> Mono<T>.invalidateStamp(
.body(it)
}

fun Mono<Void>.invalidateStamp(
getStampKey: () -> ResponseStamp.StampKey,
): Mono<ResponseEntity<Void>> = then(
Mono.fromCallable {
val updatedStamp = getStampKey().invalidateStamp()
ResponseEntity.ok()
.header(Constants.STAMP_HEADER, updatedStamp.toString())
.body(null)
},
)

/**
* Supposed to be called after any function of [com.mnnit.moticlubs.web.security.PathAuthorization]
*/
Expand Down

0 comments on commit bab081d

Please sign in to comment.