Move paths to separated files

This commit is contained in:
2019-08-26 14:34:18 +02:00
parent b285bad593
commit 0e50921a0a
8 changed files with 87 additions and 75 deletions

View File

@@ -13,14 +13,14 @@ import fr.dcproject.entity.Follow as FollowEntity
open class Follow <T: UuidEntity>(override var requester: Requester): RepositoryI<FollowEntity<T>> { open class Follow <T: UuidEntity>(override var requester: Requester): RepositoryI<FollowEntity<T>> {
override val entityName = FollowEntity::class as KClass<FollowEntity<T>> override val entityName = FollowEntity::class as KClass<FollowEntity<T>>
open fun findByCitizenId( open fun findByCitizen(
citizen: CitizenEntity, citizen: CitizenEntity,
page: Int = 1, page: Int = 1,
limit: Int = 50 limit: Int = 50
): Paginated<FollowEntity<T>> = ): Paginated<FollowEntity<T>> =
findByCitizenId(citizen.id ?: error("The citizen must have an id"), page, limit) findByCitizen(citizen.id ?: error("The citizen must have an id"), page, limit)
open fun findByCitizenId( open fun findByCitizen(
citizenId: UUID, citizenId: UUID,
page: Int = 1, page: Int = 1,
limit: Int = 50 limit: Int = 50
@@ -57,7 +57,7 @@ open class Follow <T: UuidEntity>(override var requester: Requester): Repository
} }
class FollowArticle (requester: Requester): Follow<ArticleEntity>(requester) { class FollowArticle (requester: Requester): Follow<ArticleEntity>(requester) {
override fun findByCitizenId( override fun findByCitizen(
citizenId: UUID, citizenId: UUID,
page: Int, page: Int,
limit: Int limit: Int
@@ -72,7 +72,7 @@ class FollowArticle (requester: Requester): Follow<ArticleEntity>(requester) {
} }
class FollowConstitution (requester: Requester): Follow<ConstitutionEntity>(requester) { class FollowConstitution (requester: Requester): Follow<ConstitutionEntity>(requester) {
override fun findByCitizenId( override fun findByCitizen(
citizenId: UUID, citizenId: UUID,
page: Int, page: Int,
limit: Int limit: Int

View File

@@ -1,11 +1,12 @@
package fr.dcproject.routes package fr.dcproject.routes
import Paths
import fr.dcproject.security.voter.ArticleVoter.Action.CREATE import fr.dcproject.security.voter.ArticleVoter.Action.CREATE
import fr.dcproject.security.voter.ArticleVoter.Action.VIEW import fr.dcproject.security.voter.ArticleVoter.Action.VIEW
import fr.dcproject.security.voter.assertCan import fr.dcproject.security.voter.assertCan
import fr.postgresjson.repository.RepositoryI
import io.ktor.application.call import io.ktor.application.call
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.locations.Location
import io.ktor.locations.get import io.ktor.locations.get
import io.ktor.locations.post import io.ktor.locations.post
import io.ktor.request.receive import io.ktor.request.receive
@@ -14,22 +15,34 @@ import io.ktor.routing.Route
import fr.dcproject.entity.Article as ArticleEntity import fr.dcproject.entity.Article as ArticleEntity
import fr.dcproject.repository.Article as ArticleRepository import fr.dcproject.repository.Article as ArticleRepository
@KtorExperimentalLocationsAPI
object ArticlesPaths {
@Location("/articles") class ArticlesRequest(page: Int = 1, limit: Int = 50, val sort: String? = null, val direction: RepositoryI.Direction? = null, val search: String? = null) {
val page: Int = if (page < 1) 1 else page
val limit: Int = if (limit > 50) 50 else if (limit < 1) 1 else limit
}
@Location("/articles/{article}") class ArticleRequest(val article: fr.dcproject.entity.Article)
@Location("/articles/{article}/follow") class ArticleFollowRequest(val article: fr.dcproject.entity.Article)
@Location("/articles") class PostArticleRequest
}
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
fun Route.article(repo: ArticleRepository) { fun Route.article(repo: ArticleRepository) {
get<Paths.ArticlesRequest> { get<ArticlesPaths.ArticlesRequest> {
assertCan(VIEW) assertCan(VIEW)
val articles = repo.find(it.page, it.limit, it.sort, it.direction, it.search) val articles = repo.find(it.page, it.limit, it.sort, it.direction, it.search)
call.respond(articles) call.respond(articles)
} }
get<Paths.ArticleRequest> { get<ArticlesPaths.ArticleRequest> {
assertCan(VIEW, it.article) assertCan(VIEW, it.article)
call.respond(it.article) call.respond(it.article)
} }
post<Paths.PostArticleRequest> { post<ArticlesPaths.PostArticleRequest> {
assertCan(CREATE) assertCan(CREATE)
val article = call.receive<ArticleEntity>() val article = call.receive<ArticleEntity>()

View File

@@ -1,12 +1,12 @@
package fr.dcproject.routes package fr.dcproject.routes
import Paths
import com.fasterxml.jackson.databind.exc.MismatchedInputException import com.fasterxml.jackson.databind.exc.MismatchedInputException
import fr.dcproject.JwtConfig import fr.dcproject.JwtConfig
import io.ktor.application.call import io.ktor.application.call
import io.ktor.auth.UserPasswordCredential import io.ktor.auth.UserPasswordCredential
import io.ktor.features.BadRequestException import io.ktor.features.BadRequestException
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.locations.Location
import io.ktor.locations.post import io.ktor.locations.post
import io.ktor.request.receive import io.ktor.request.receive
import io.ktor.response.respondText import io.ktor.response.respondText
@@ -16,10 +16,16 @@ import fr.dcproject.entity.Citizen as CitizenEntity
import fr.dcproject.repository.Citizen as CitizenRepository import fr.dcproject.repository.Citizen as CitizenRepository
import fr.dcproject.repository.User as UserRepository import fr.dcproject.repository.User as UserRepository
@KtorExperimentalLocationsAPI
object AuthPaths {
@Location("/login") class LoginRequest
@Location("/register") class RegisterRequest
}
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
@KtorExperimentalAPI @KtorExperimentalAPI
fun Route.auth(userRepo: UserRepository, citizenRepo: CitizenRepository) { fun Route.auth(userRepo: UserRepository, citizenRepo: CitizenRepository) {
post <Paths.LoginRequest> { post <AuthPaths.LoginRequest> {
try { try {
val credentials = call.receive<UserPasswordCredential>() val credentials = call.receive<UserPasswordCredential>()
val user = userRepo.findByCredentials(credentials) ?: throw BadRequestException("Username not exist or password is wrong") val user = userRepo.findByCredentials(credentials) ?: throw BadRequestException("Username not exist or password is wrong")
@@ -29,7 +35,7 @@ fun Route.auth(userRepo: UserRepository, citizenRepo: CitizenRepository) {
} }
} }
post <Paths.RegisterRequest> { post <AuthPaths.RegisterRequest> {
val citizen = call.receive<CitizenEntity>() val citizen = call.receive<CitizenEntity>()
val created = citizenRepo.insertWithUser(citizen)?.user ?: throw BadRequestException("Bad request") val created = citizenRepo.insertWithUser(citizen)?.user ?: throw BadRequestException("Bad request")

View File

@@ -1,25 +1,38 @@
package fr.dcproject.routes package fr.dcproject.routes
import Paths import fr.dcproject.entity.Citizen
import fr.dcproject.security.voter.CitizenVoter.Action.VIEW import fr.dcproject.security.voter.CitizenVoter.Action.VIEW
import fr.dcproject.security.voter.assertCan import fr.dcproject.security.voter.assertCan
import fr.postgresjson.repository.RepositoryI
import io.ktor.application.call import io.ktor.application.call
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.locations.Location
import io.ktor.locations.get import io.ktor.locations.get
import io.ktor.response.respond import io.ktor.response.respond
import io.ktor.routing.Route import io.ktor.routing.Route
import fr.dcproject.repository.Citizen as CitizenRepository import fr.dcproject.repository.Citizen as CitizenRepository
@KtorExperimentalLocationsAPI
object CitizenPaths {
@Location("/citizens") class CitizensRequest(page: Int = 1, limit: Int = 50, val sort: String? = null, val direction: RepositoryI.Direction? = null, val search: String? = null) {
val page: Int = if (page < 1) 1 else page
val limit: Int = if (limit > 50) 50 else if (limit < 1) 1 else limit
}
@Location("/citizens/{citizen}") class CitizenRequest(val citizen: Citizen)
@Location("/citizens/{citizen}/follows/articles") class CitizenFollowArticleRequest(val citizen: Citizen)
@Location("/citizens/{citizen}/follows/constitutions") class CitizenFollowConstitutionRequest(val citizen: Citizen)
}
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
fun Route.citizen(repo: CitizenRepository) { fun Route.citizen(repo: CitizenRepository) {
get<Paths.CitizensRequest> { get<CitizenPaths.CitizensRequest> {
assertCan(VIEW) assertCan(VIEW)
val citizens = repo.find(it.page, it.limit, it.sort, it.direction, it.search) val citizens = repo.find(it.page, it.limit, it.sort, it.direction, it.search)
call.respond(citizens) call.respond(citizens)
} }
get<Paths.CitizenRequest> { get<CitizenPaths.CitizenRequest> {
assertCan(VIEW, it.citizen) assertCan(VIEW, it.citizen)
call.respond(it.citizen) call.respond(it.citizen)

View File

@@ -1,8 +1,9 @@
package fr.dcproject.routes package fr.dcproject.routes
import Paths import fr.postgresjson.repository.RepositoryI
import io.ktor.application.call import io.ktor.application.call
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.locations.Location
import io.ktor.locations.get import io.ktor.locations.get
import io.ktor.locations.post import io.ktor.locations.post
import io.ktor.request.receive import io.ktor.request.receive
@@ -11,18 +12,29 @@ import io.ktor.routing.Route
import fr.dcproject.entity.Constitution as ConstitutionEntity import fr.dcproject.entity.Constitution as ConstitutionEntity
import fr.dcproject.repository.Constitution as ConstitutionRepository import fr.dcproject.repository.Constitution as ConstitutionRepository
@KtorExperimentalLocationsAPI
object ConstitutionPaths {
@Location("/constitutions") class ConstitutionsRequest(page: Int = 1, limit: Int = 50, val sort: String? = null, val direction: RepositoryI.Direction? = null, val search: String? = null) {
val page: Int = if (page < 1) 1 else page
val limit: Int = if (limit > 50) 50 else if (limit < 1) 1 else limit
}
@Location("/constitutions/{constitution}") class ConstitutionRequest(val constitution: fr.dcproject.entity.Constitution)
@Location("/constitutions/{constitution}/follow") class ConstitutionFollowRequest(val constitution: fr.dcproject.entity.Constitution)
@Location("/constitutions") class PostConstitutionRequest
}
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
fun Route.constitution(repo: ConstitutionRepository) { fun Route.constitution(repo: ConstitutionRepository) {
get<Paths.ConstitutionsRequest> { get<ConstitutionPaths.ConstitutionsRequest> {
val constitutions = repo.find(it.page, it.limit, it.sort, it.direction, it.search) val constitutions = repo.find(it.page, it.limit, it.sort, it.direction, it.search)
call.respond(constitutions) call.respond(constitutions)
} }
get<Paths.ConstitutionRequest> { get<ConstitutionPaths.ConstitutionRequest> {
call.respond(it.constitution) call.respond(it.constitution)
} }
post<Paths.PostConstitutionRequest>() { post<ConstitutionPaths.PostConstitutionRequest>() {
val constitution = call.receive<ConstitutionEntity>() val constitution = call.receive<ConstitutionEntity>()
repo.upsert(constitution) repo.upsert(constitution)
call.respond(constitution) call.respond(constitution)

View File

@@ -1,18 +1,15 @@
package fr.dcproject.routes package fr.dcproject.routes
import Paths
import fr.dcproject.entity.Citizen import fr.dcproject.entity.Citizen
import fr.dcproject.entity.User import fr.dcproject.entity.User
import io.ktor.application.call import io.ktor.application.call
import io.ktor.http.HttpStatusCode import io.ktor.http.HttpStatusCode
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.*
import io.ktor.locations.delete
import io.ktor.locations.get
import io.ktor.locations.post
import io.ktor.response.respond import io.ktor.response.respond
import io.ktor.routing.Route import io.ktor.routing.Route
import org.joda.time.DateTime import org.joda.time.DateTime
import java.util.* import java.util.*
import fr.dcproject.entity.Article as ArticleEntity
import fr.dcproject.entity.Follow as FollowEntity import fr.dcproject.entity.Follow as FollowEntity
import fr.dcproject.repository.FollowArticle as FollowArticleRepository import fr.dcproject.repository.FollowArticle as FollowArticleRepository
@@ -24,20 +21,26 @@ val currentCitizen = Citizen(
user = User(username = "plop", plainPassword = "plip") user = User(username = "plop", plainPassword = "plip")
) )
@KtorExperimentalLocationsAPI
object FollowArticlePaths {
@Location("/articles/{article}/follow") class ArticleFollowRequest(val article: ArticleEntity)
@Location("/citizens/{citizen}/follows/articles") class CitizenFollowArticleRequest(val citizen: Citizen)
}
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
fun Route.followArticle(repo: FollowArticleRepository) { fun Route.followArticle(repo: FollowArticleRepository) {
post<Paths.ArticleFollowRequest> { post<FollowArticlePaths.ArticleFollowRequest> {
repo.follow(FollowEntity(target = it.article, citizen = currentCitizen)) repo.follow(FollowEntity(target = it.article, citizen = currentCitizen))
call.respond(HttpStatusCode.Created) call.respond(HttpStatusCode.Created)
} }
delete<Paths.ArticleFollowRequest> { delete<FollowArticlePaths.ArticleFollowRequest> {
repo.unfollow(FollowEntity(target = it.article, citizen = currentCitizen)) repo.unfollow(FollowEntity(target = it.article, citizen = currentCitizen))
call.respond(HttpStatusCode.NoContent) call.respond(HttpStatusCode.NoContent)
} }
get<Paths.CitizenFollowArticleRequest> { get<FollowArticlePaths.CitizenFollowArticleRequest> {
val follows = repo.findByCitizenId(it.citizen) val follows = repo.findByCitizen(it.citizen)
call.respond(follows) call.respond(follows)
} }
} }

View File

@@ -1,18 +1,15 @@
package fr.dcproject.routes package fr.dcproject.routes
import Paths
import fr.dcproject.entity.Citizen import fr.dcproject.entity.Citizen
import fr.dcproject.entity.User import fr.dcproject.entity.User
import io.ktor.application.call import io.ktor.application.call
import io.ktor.http.HttpStatusCode import io.ktor.http.HttpStatusCode
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.*
import io.ktor.locations.delete
import io.ktor.locations.get
import io.ktor.locations.post
import io.ktor.response.respond import io.ktor.response.respond
import io.ktor.routing.Route import io.ktor.routing.Route
import org.joda.time.DateTime import org.joda.time.DateTime
import java.util.* import java.util.*
import fr.dcproject.entity.Constitution as ConstitutionEntity
import fr.dcproject.entity.Follow as FollowEntity import fr.dcproject.entity.Follow as FollowEntity
import fr.dcproject.repository.FollowConstitution as FollowConstitutionRepository import fr.dcproject.repository.FollowConstitution as FollowConstitutionRepository
@@ -24,20 +21,26 @@ val currentCitizen2 = Citizen(
user = User(username = "plop", plainPassword = "plip") user = User(username = "plop", plainPassword = "plip")
) )
@KtorExperimentalLocationsAPI
object FollowConstitutionPaths {
@Location("/constitutions/{constitution}/follow") class ConstitutionFollowRequest(val constitution: ConstitutionEntity)
@Location("/citizens/{citizen}/follows/constitutions") class CitizenFollowConstitutionRequest(val citizen: Citizen)
}
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
fun Route.followConstitution(repo: FollowConstitutionRepository) { fun Route.followConstitution(repo: FollowConstitutionRepository) {
post<Paths.ConstitutionFollowRequest> { post<FollowConstitutionPaths.ConstitutionFollowRequest> {
repo.follow(FollowEntity(target = it.constitution, citizen = currentCitizen2)) repo.follow(FollowEntity(target = it.constitution, citizen = currentCitizen2))
call.respond(HttpStatusCode.Created) call.respond(HttpStatusCode.Created)
} }
delete<Paths.ConstitutionFollowRequest> { delete<FollowConstitutionPaths.ConstitutionFollowRequest> {
repo.unfollow(FollowEntity(target = it.constitution, citizen = currentCitizen2)) repo.unfollow(FollowEntity(target = it.constitution, citizen = currentCitizen2))
call.respond(HttpStatusCode.NoContent) call.respond(HttpStatusCode.NoContent)
} }
get<Paths.CitizenFollowConstitutionRequest> { get<FollowConstitutionPaths.CitizenFollowConstitutionRequest> {
val follows = repo.findByCitizenId(it.citizen) val follows = repo.findByCitizen(it.citizen)
call.respond(follows) call.respond(follows)
} }
} }

View File

@@ -1,38 +0,0 @@
import fr.dcproject.entity.Article
import fr.dcproject.entity.Citizen
import fr.dcproject.entity.Constitution
import fr.postgresjson.repository.RepositoryI.Direction
import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.locations.Location
@KtorExperimentalLocationsAPI
object Paths {
@Location("/login") class LoginRequest
@Location("/register") class RegisterRequest
@Location("/articles") class ArticlesRequest(page: Int = 1, limit: Int = 50, val sort: String? = null, val direction: Direction? = null, val search: String? = null) {
val page: Int = if (page < 1) 1 else page
val limit: Int = if (limit > 50) 50 else if (limit < 1) 1 else limit
}
@Location("/articles/{article}") class ArticleRequest(val article: Article)
@Location("/articles/{article}/follow") class ArticleFollowRequest(val article: Article)
@Location("/articles") class PostArticleRequest
@Location("/constitutions") class ConstitutionsRequest(page: Int = 1, limit: Int = 50, val sort: String? = null, val direction: Direction? = null, val search: String? = null) {
val page: Int = if (page < 1) 1 else page
val limit: Int = if (limit > 50) 50 else if (limit < 1) 1 else limit
}
@Location("/constitutions/{constitution}") class ConstitutionRequest(val constitution: Constitution)
@Location("/constitutions/{constitution}/follow") class ConstitutionFollowRequest(val constitution: Constitution)
@Location("/constitutions") class PostConstitutionRequest
@Location("/citizens") class CitizensRequest(page: Int = 1, limit: Int = 50, val sort: String? = null, val direction: Direction? = null, val search: String? = null) {
val page: Int = if (page < 1) 1 else page
val limit: Int = if (limit > 50) 50 else if (limit < 1) 1 else limit
}
@Location("/citizens/{citizen}") class CitizenRequest(val citizen: Citizen)
@Location("/citizens/{citizen}/follows/articles") class CitizenFollowArticleRequest(val citizen: Citizen)
@Location("/citizens/{citizen}/follows/constitutions") class CitizenFollowConstitutionRequest(val citizen: Citizen)
}