Remove converter for Citizen
Add receiveOrBadRequest
This commit is contained in:
@@ -44,14 +44,6 @@ val converters: ConverterDeclaration = {
|
||||
|
||||
// TODO remove converters of entities
|
||||
|
||||
convert<Citizen> {
|
||||
decode { values, _ ->
|
||||
val id = values.singleOrNull()?.let { UUID.fromString(it) }
|
||||
?: throw InternalError("Cannot convert $values to UUID")
|
||||
get<CitizenRepository>().findById(id) ?: throw NotFoundException("Citizen $values not found")
|
||||
}
|
||||
}
|
||||
|
||||
convert<OpinionChoice> {
|
||||
decode { values, _ ->
|
||||
val id = values.singleOrNull()?.let { UUID.fromString(it) }
|
||||
|
||||
@@ -6,42 +6,39 @@ import fr.dcproject.component.auth.citizen
|
||||
import fr.dcproject.component.auth.citizenOrNull
|
||||
import fr.dcproject.component.citizen.Citizen
|
||||
import fr.dcproject.component.citizen.CitizenAccessControl
|
||||
import fr.dcproject.component.citizen.CitizenRef
|
||||
import fr.dcproject.security.assert
|
||||
import fr.dcproject.utils.receiveOrBadRequest
|
||||
import io.ktor.application.call
|
||||
import io.ktor.auth.UserPasswordCredential
|
||||
import io.ktor.features.BadRequestException
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.locations.Location
|
||||
import io.ktor.locations.put
|
||||
import io.ktor.request.receive
|
||||
import io.ktor.request.receiveOrNull
|
||||
import io.ktor.response.respond
|
||||
import io.ktor.routing.Route
|
||||
import java.util.UUID
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object ChangeMyPassword {
|
||||
@Location("/citizens/{citizen}/password/change")
|
||||
class ChangePasswordCitizenRequest(val citizen: Citizen) {
|
||||
class ChangePasswordCitizenRequest(citizen: UUID) {
|
||||
val citizen = CitizenRef(citizen)
|
||||
data class Input(val oldPassword: String, val newPassword: String)
|
||||
}
|
||||
|
||||
fun Route.changeMyPassword(ac: CitizenAccessControl, userRepository: UserRepository) {
|
||||
put<ChangePasswordCitizenRequest> {
|
||||
ac.assert { canChangePassword(it.citizen, citizenOrNull) }
|
||||
try {
|
||||
val content = call.receive<ChangePasswordCitizenRequest.Input>()
|
||||
val currentUser = userRepository.findByCredentials(UserPasswordCredential(citizen.user.username, content.oldPassword))
|
||||
val user = it.citizen.user
|
||||
if (currentUser == null || currentUser.id != user.id) {
|
||||
call.respond(HttpStatusCode.BadRequest, "Bad password")
|
||||
} else {
|
||||
user.plainPassword = content.newPassword
|
||||
userRepository.changePassword(user)
|
||||
val content = call.receiveOrBadRequest<ChangePasswordCitizenRequest.Input>()
|
||||
userRepository.findByCredentials(UserPasswordCredential(citizen.user.username, content.oldPassword)) ?: throw BadRequestException("Bad Password")
|
||||
citizen.user.plainPassword = content.newPassword
|
||||
userRepository.changePassword(citizen.user)
|
||||
|
||||
call.respond(HttpStatusCode.Created)
|
||||
}
|
||||
} catch (e: MissingKotlinParameterException) {
|
||||
call.respond(HttpStatusCode.BadRequest, "Request format is not correct")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,22 +3,29 @@ package fr.dcproject.component.citizen.routes
|
||||
import fr.dcproject.component.auth.citizenOrNull
|
||||
import fr.dcproject.component.citizen.Citizen
|
||||
import fr.dcproject.component.citizen.CitizenAccessControl
|
||||
import fr.dcproject.component.citizen.CitizenRef
|
||||
import fr.dcproject.component.citizen.CitizenRepository
|
||||
import fr.dcproject.security.assert
|
||||
import io.ktor.application.call
|
||||
import io.ktor.features.NotFoundException
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.locations.Location
|
||||
import io.ktor.locations.get
|
||||
import io.ktor.response.respond
|
||||
import io.ktor.routing.Route
|
||||
import java.util.UUID
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object GetOneCitizen {
|
||||
@Location("/citizens/{citizen}")
|
||||
class CitizenRequest(val citizen: Citizen)
|
||||
class CitizenRequest(citizen: UUID) {
|
||||
val citizen = CitizenRef(citizen)
|
||||
}
|
||||
|
||||
fun Route.getOneCitizen(ac: CitizenAccessControl) {
|
||||
fun Route.getOneCitizen(ac: CitizenAccessControl, citizenRepository: CitizenRepository) {
|
||||
get<CitizenRequest> {
|
||||
ac.assert { canView(it.citizen, citizenOrNull) }
|
||||
val citizen = citizenRepository.findById(it.citizen.id) ?: throw NotFoundException("Citizen not found ${it.citizen.id}")
|
||||
ac.assert { canView(citizen, citizenOrNull) }
|
||||
|
||||
call.respond(it.citizen)
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import org.koin.ktor.ext.get
|
||||
fun Routing.installCitizenRoutes() {
|
||||
authenticate(optional = true) {
|
||||
findCitizen(get(), get())
|
||||
getOneCitizen(get())
|
||||
getOneCitizen(get(), get())
|
||||
getCurrentCitizen(get())
|
||||
changeMyPassword(get(), get())
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package fr.dcproject.component.comment.article.routes
|
||||
|
||||
import fr.dcproject.component.auth.citizenOrNull
|
||||
import fr.dcproject.component.citizen.Citizen
|
||||
import fr.dcproject.component.citizen.CitizenRef
|
||||
import fr.dcproject.component.comment.article.CommentArticleRepository
|
||||
import fr.dcproject.component.comment.generic.CommentAccessControl
|
||||
import fr.dcproject.security.assert
|
||||
@@ -11,11 +12,14 @@ import io.ktor.locations.Location
|
||||
import io.ktor.locations.get
|
||||
import io.ktor.response.respond
|
||||
import io.ktor.routing.Route
|
||||
import java.util.UUID
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object GetCitizenArticleComments {
|
||||
@Location("/citizens/{citizen}/comments/articles")
|
||||
class CitizenCommentArticleRequest(val citizen: Citizen)
|
||||
class CitizenCommentArticleRequest(citizen: UUID) {
|
||||
val citizen = CitizenRef(citizen)
|
||||
}
|
||||
|
||||
fun Route.getCitizenArticleComments(repo: CommentArticleRepository, ac: CommentAccessControl) {
|
||||
get<CitizenCommentArticleRequest> {
|
||||
|
||||
@@ -2,6 +2,7 @@ package fr.dcproject.component.comment.constitution.routes
|
||||
|
||||
import fr.dcproject.component.auth.citizenOrNull
|
||||
import fr.dcproject.component.citizen.Citizen
|
||||
import fr.dcproject.component.citizen.CitizenRef
|
||||
import fr.dcproject.component.comment.constitution.CommentConstitutionRepository
|
||||
import fr.dcproject.component.comment.generic.CommentAccessControl
|
||||
import fr.dcproject.security.assert
|
||||
@@ -11,11 +12,14 @@ import io.ktor.locations.Location
|
||||
import io.ktor.locations.get
|
||||
import io.ktor.response.respond
|
||||
import io.ktor.routing.Route
|
||||
import java.util.UUID
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object GetCitizenCommentConstitution {
|
||||
@Location("/citizens/{citizen}/comments/constitutions")
|
||||
class GetCitizenCommentConstitutionRequest(val citizen: Citizen)
|
||||
class GetCitizenCommentConstitutionRequest(citizen: UUID) {
|
||||
val citizen = CitizenRef(citizen)
|
||||
}
|
||||
|
||||
fun Route.getCitizenCommentConstitution(repo: CommentConstitutionRepository, ac: CommentAccessControl) {
|
||||
get<GetCitizenCommentConstitutionRequest> {
|
||||
|
||||
@@ -2,6 +2,7 @@ package fr.dcproject.component.follow.routes.article
|
||||
|
||||
import fr.dcproject.component.auth.citizenOrNull
|
||||
import fr.dcproject.component.citizen.Citizen
|
||||
import fr.dcproject.component.citizen.CitizenRef
|
||||
import fr.dcproject.component.follow.FollowAccessControl
|
||||
import fr.dcproject.component.follow.FollowArticleRepository
|
||||
import fr.dcproject.security.assert
|
||||
@@ -11,11 +12,14 @@ import io.ktor.locations.Location
|
||||
import io.ktor.locations.get
|
||||
import io.ktor.response.respond
|
||||
import io.ktor.routing.Route
|
||||
import java.util.UUID
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object GetMyFollowsArticle {
|
||||
@Location("/citizens/{citizen}/follows/articles")
|
||||
class CitizenFollowArticleRequest(val citizen: Citizen)
|
||||
class CitizenFollowArticleRequest(citizen: UUID) {
|
||||
val citizen = CitizenRef(citizen)
|
||||
}
|
||||
|
||||
fun Route.getMyFollowsArticle(repo: FollowArticleRepository, ac: FollowAccessControl) {
|
||||
get<CitizenFollowArticleRequest> {
|
||||
|
||||
@@ -3,6 +3,7 @@ package fr.dcproject.component.opinion
|
||||
import com.fasterxml.jackson.core.type.TypeReference
|
||||
import fr.dcproject.common.entity.TargetRef
|
||||
import fr.dcproject.component.article.ArticleRef
|
||||
import fr.dcproject.component.citizen.CitizenI
|
||||
import fr.dcproject.component.opinion.entity.OpinionForUpdate
|
||||
import fr.postgresjson.connexion.Paginated
|
||||
import fr.postgresjson.connexion.Requester
|
||||
@@ -75,7 +76,7 @@ abstract class OpinionRepository<T : TargetRef>(requester: Requester) : OpinionC
|
||||
* Find opinions of one citizen filtered by target ids
|
||||
*/
|
||||
fun findCitizenOpinionsByTargets(
|
||||
citizen: CitizenEntity,
|
||||
citizen: CitizenI,
|
||||
targets: List<UUID>
|
||||
): List<OpinionEntity<T>> {
|
||||
val typeReference = object : TypeReference<List<OpinionEntity<T>>>() {}
|
||||
|
||||
@@ -2,6 +2,7 @@ package fr.dcproject.component.opinion.routes
|
||||
|
||||
import fr.dcproject.component.article.ArticleRef
|
||||
import fr.dcproject.component.auth.citizenOrNull
|
||||
import fr.dcproject.component.citizen.CitizenRef
|
||||
import fr.dcproject.component.opinion.OpinionAccessControl
|
||||
import fr.dcproject.component.opinion.entity.Opinion
|
||||
import fr.dcproject.security.assert
|
||||
@@ -23,7 +24,8 @@ object GetCitizenOpinions {
|
||||
* Get all Opinion of citizen on targets by target ids
|
||||
*/
|
||||
@Location("/citizens/{citizen}/opinions")
|
||||
class CitizenOpinions(val citizen: CitizenEntity, id: List<String>) : KoinComponent {
|
||||
class CitizenOpinions(citizen: UUID, id: List<String>) {
|
||||
val citizen = CitizenRef(citizen)
|
||||
val id: List<UUID> = id.toUUID()
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.type.TypeReference
|
||||
import fr.dcproject.common.entity.TargetI
|
||||
import fr.dcproject.common.entity.TargetRef
|
||||
import fr.dcproject.component.article.ArticleForView
|
||||
import fr.dcproject.component.citizen.CitizenI
|
||||
import fr.dcproject.component.citizen.CitizenRef
|
||||
import fr.dcproject.component.comment.generic.CommentForView
|
||||
import fr.dcproject.component.constitution.Constitution
|
||||
@@ -52,7 +53,7 @@ abstract class VoteRepositoryAbs<T : TargetI>(override var requester: Requester)
|
||||
}
|
||||
|
||||
fun findCitizenVotesByTargets(
|
||||
citizen: CitizenEntity,
|
||||
citizen: CitizenI,
|
||||
targets: List<UUID>
|
||||
): List<VoteEntity<*>> {
|
||||
val typeReference = object : TypeReference<List<VoteEntity<TargetRef>>>() {}
|
||||
@@ -73,7 +74,7 @@ class VoteRepository(requester: Requester) : VoteRepositoryAbs<TargetRef>(reques
|
||||
|
||||
class VoteArticleRepository(requester: Requester) : VoteRepositoryAbs<ArticleForView>(requester) {
|
||||
fun findByCitizen(
|
||||
citizen: CitizenEntity,
|
||||
citizen: CitizenI,
|
||||
page: Int = 1,
|
||||
limit: Int = 50
|
||||
): Paginated<VoteEntity<ArticleForView>> =
|
||||
|
||||
@@ -2,6 +2,7 @@ package fr.dcproject.component.vote.routes
|
||||
|
||||
import fr.dcproject.component.auth.citizenOrNull
|
||||
import fr.dcproject.component.citizen.Citizen
|
||||
import fr.dcproject.component.citizen.CitizenRef
|
||||
import fr.dcproject.component.vote.VoteAccessControl
|
||||
import fr.dcproject.component.vote.VoteRepository
|
||||
import fr.dcproject.security.assert
|
||||
@@ -17,7 +18,8 @@ import java.util.UUID
|
||||
@KtorExperimentalLocationsAPI
|
||||
object GetCitizenVotes {
|
||||
@Location("/citizens/{citizen}/votes")
|
||||
class CitizenVotesRequest(val citizen: Citizen, id: List<String>) {
|
||||
class CitizenVotesRequest(citizen: UUID, id: List<String>) {
|
||||
val citizen = CitizenRef(citizen)
|
||||
val id: List<UUID> = id.toUUID()
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package fr.dcproject.component.vote.routes
|
||||
|
||||
import fr.dcproject.component.auth.citizenOrNull
|
||||
import fr.dcproject.component.citizen.Citizen
|
||||
import fr.dcproject.component.citizen.CitizenRef
|
||||
import fr.dcproject.component.vote.VoteAccessControl
|
||||
import fr.dcproject.component.vote.VoteArticleRepository
|
||||
import fr.dcproject.routes.PaginatedRequest
|
||||
@@ -13,16 +14,19 @@ import io.ktor.locations.Location
|
||||
import io.ktor.locations.get
|
||||
import io.ktor.response.respond
|
||||
import io.ktor.routing.Route
|
||||
import java.util.UUID
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object GetCitizenVotesOnArticle {
|
||||
@Location("/citizens/{citizen}/votes/articles")
|
||||
class CitizenVoteArticleRequest(
|
||||
val citizen: Citizen,
|
||||
citizen: UUID,
|
||||
page: Int = 1,
|
||||
limit: Int = 50,
|
||||
val search: String? = null
|
||||
) : PaginatedRequestI by PaginatedRequest(page, limit)
|
||||
) : PaginatedRequestI by PaginatedRequest(page, limit) {
|
||||
val citizen = CitizenRef(citizen)
|
||||
}
|
||||
|
||||
fun Route.getCitizenVotesOnArticle(repo: VoteArticleRepository, ac: VoteAccessControl) {
|
||||
get<CitizenVoteArticleRequest> {
|
||||
|
||||
25
src/main/kotlin/utils/Request.kt
Normal file
25
src/main/kotlin/utils/Request.kt
Normal file
@@ -0,0 +1,25 @@
|
||||
package fr.dcproject.utils
|
||||
|
||||
import com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.application.log
|
||||
import io.ktor.features.BadRequestException
|
||||
import io.ktor.request.receive
|
||||
import kotlin.reflect.KType
|
||||
import kotlin.reflect.typeOf
|
||||
|
||||
|
||||
/**
|
||||
* Receives content for this request.
|
||||
* @param type instance of `KClass` specifying type to be received.
|
||||
* @return instance of [T] received from this call, or `null` if content cannot be transformed to the requested type..
|
||||
*/
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
public suspend inline fun <reified T : Any> ApplicationCall.receiveOrBadRequest(message: String = "Bad Request, wrong body request"): T {
|
||||
return try {
|
||||
receive<T>(typeOf<T>())
|
||||
} catch (cause: MissingKotlinParameterException) {
|
||||
application.log.debug("Conversion failed, throw bad exeption", cause)
|
||||
throw BadRequestException(message, cause)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user