Clean code
This commit is contained in:
@@ -78,7 +78,8 @@ fun Application.module(env: Env = PROD) {
|
||||
convert<Article> {
|
||||
decode { values, _ ->
|
||||
values.singleOrNull()?.let {
|
||||
get<RepositoryArticle>().findById(UUID.fromString(it)) ?: throw InternalError("Article $values not found")
|
||||
get<RepositoryArticle>().findById(UUID.fromString(it))
|
||||
?: throw InternalError("Article $values not found")
|
||||
} ?: throw NotFoundException("Article $values not found")
|
||||
}
|
||||
}
|
||||
@@ -157,7 +158,7 @@ fun Application.module(env: Env = PROD) {
|
||||
}
|
||||
|
||||
install(Routing) {
|
||||
// trace { application.log.trace(it.buildText()) }
|
||||
// trace { application.log.trace(it.buildText()) }
|
||||
authenticate(optional = true) {
|
||||
article(get())
|
||||
auth(get(), get(), get())
|
||||
|
||||
@@ -17,7 +17,8 @@ val ApplicationCall.citizen: CitizenEntity
|
||||
get() = attributes.computeIfAbsent(citizenAttributeKey) {
|
||||
runBlocking {
|
||||
val user = authentication.principal<UserI>() ?: throw ForbiddenException()
|
||||
GlobalContext.get().koin.get<CitizenRepository>().findByUser(user) ?: throw ForbiddenException("Citizen not found for this user id \"${user.id}\"")
|
||||
GlobalContext.get().koin.get<CitizenRepository>().findByUser(user)
|
||||
?: throw ForbiddenException("Citizen not found for this user id \"${user.id}\"")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,12 +27,22 @@ val Module = module {
|
||||
|
||||
single { config }
|
||||
|
||||
single { Connection(host = config.host, port = config.port, database = config.database, username = config.username, password = config.password) }
|
||||
single {
|
||||
Connection(
|
||||
host = config.host,
|
||||
port = config.port,
|
||||
database = config.database,
|
||||
username = config.username,
|
||||
password = config.password
|
||||
)
|
||||
}
|
||||
|
||||
single { Requester.RequesterFactory(
|
||||
connection = get(),
|
||||
functionsDirectory = config.sqlFiles.resolve("functions")
|
||||
).createRequester() }
|
||||
single {
|
||||
Requester.RequesterFactory(
|
||||
connection = get(),
|
||||
functionsDirectory = config.sqlFiles.resolve("functions")
|
||||
).createRequester()
|
||||
}
|
||||
|
||||
// TODO: create generic declaration
|
||||
single { UserRepository(get()) }
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
package fr.dcproject.entity
|
||||
|
||||
import fr.postgresjson.entity.immutable.*
|
||||
import fr.postgresjson.entity.mutable.EntityDeletedAt
|
||||
import fr.postgresjson.entity.mutable.EntityDeletedAtImp
|
||||
@@ -62,6 +63,7 @@ interface ArticleSimpleI :
|
||||
Votable {
|
||||
var title: String
|
||||
}
|
||||
|
||||
interface ArticleBasicI :
|
||||
ArticleSimpleI {
|
||||
var anonymous: Boolean
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package fr.dcproject.entity
|
||||
|
||||
import java.util.*
|
||||
|
||||
class Follow <T : TargetI> (
|
||||
class Follow<T : TargetI>(
|
||||
id: UUID = UUID.randomUUID(),
|
||||
override val createdBy: CitizenBasic,
|
||||
target: T
|
||||
|
||||
@@ -4,7 +4,7 @@ import fr.postgresjson.entity.immutable.EntityUpdatedAt
|
||||
import fr.postgresjson.entity.immutable.EntityUpdatedAtImp
|
||||
import java.util.*
|
||||
|
||||
open class Vote <T : TargetI> (
|
||||
open class Vote<T : TargetI>(
|
||||
id: UUID = UUID.randomUUID(),
|
||||
override val createdBy: CitizenBasic,
|
||||
target: T,
|
||||
|
||||
@@ -46,5 +46,6 @@ class SsoManager(
|
||||
class EmailNotFound(val email: String) : Exception() {
|
||||
override val message: String = "No Citizen with this email : $email"
|
||||
}
|
||||
|
||||
private fun noEmail(email: String): Nothing = throw EmailNotFound(email)
|
||||
}
|
||||
@@ -12,7 +12,7 @@ import fr.dcproject.entity.Citizen as CitizenEntity
|
||||
import fr.dcproject.entity.Comment as CommentEntity
|
||||
import fr.dcproject.entity.Constitution as ConstitutionEntity
|
||||
|
||||
abstract class Comment <T : TargetI>(override var requester: Requester) : RepositoryI {
|
||||
abstract class Comment<T : TargetI>(override var requester: Requester) : RepositoryI {
|
||||
abstract fun findById(id: UUID): CommentEntity<T>?
|
||||
|
||||
abstract fun findByCitizen(
|
||||
@@ -36,9 +36,10 @@ abstract class Comment <T : TargetI>(override var requester: Requester) : Reposi
|
||||
): Paginated<CommentEntity<T>> {
|
||||
return requester.run {
|
||||
getFunction("find_comments_by_parent")
|
||||
.select(page, limit,
|
||||
"parent_id" to parentId
|
||||
)
|
||||
.select(
|
||||
page, limit,
|
||||
"parent_id" to parentId
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,9 +58,10 @@ abstract class Comment <T : TargetI>(override var requester: Requester) : Reposi
|
||||
): Paginated<CommentEntity<T>> {
|
||||
return requester.run {
|
||||
getFunction("find_comments_by_target")
|
||||
.select(page, limit,
|
||||
"target_id" to targetId
|
||||
)
|
||||
.select(
|
||||
page, limit,
|
||||
"target_id" to targetId
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +98,8 @@ class CommentGeneric(requester: Requester) : Comment<TargetRef>(requester) {
|
||||
): Paginated<CommentEntity<TargetRef>> {
|
||||
return requester.run {
|
||||
getFunction("find_comments_by_citizen")
|
||||
.select(page, limit,
|
||||
.select(
|
||||
page, limit,
|
||||
"created_by_id" to citizen.id
|
||||
)
|
||||
}
|
||||
@@ -117,7 +120,8 @@ class CommentArticle(requester: Requester) : Comment<ArticleRef>(requester) {
|
||||
): Paginated<CommentEntity<ArticleRef>> {
|
||||
return requester.run {
|
||||
getFunction("find_comments_by_citizen")
|
||||
.select(page, limit,
|
||||
.select(
|
||||
page, limit,
|
||||
"created_by_id" to citizen.id,
|
||||
"reference" to TargetI.getReference(ArticleRef::class)
|
||||
)
|
||||
@@ -139,7 +143,8 @@ class CommentConstitution(requester: Requester) : Comment<ConstitutionEntity>(re
|
||||
): Paginated<CommentEntity<ConstitutionEntity>> {
|
||||
return requester.run {
|
||||
getFunction("find_comments_by_citizen")
|
||||
.select(page, limit,
|
||||
.select(
|
||||
page, limit,
|
||||
"created_by_id" to citizen.id,
|
||||
"reference" to TargetI.getReference(ConstitutionEntity::class)
|
||||
)
|
||||
|
||||
@@ -10,7 +10,7 @@ import fr.dcproject.entity.Article as ArticleEntity
|
||||
import fr.dcproject.entity.Constitution as ConstitutionEntity
|
||||
import fr.dcproject.entity.Follow as FollowEntity
|
||||
|
||||
open class Follow <T : TargetI>(override var requester: Requester) : RepositoryI {
|
||||
open class Follow<T : TargetI>(override var requester: Requester) : RepositoryI {
|
||||
open fun findByCitizen(
|
||||
citizen: CitizenI,
|
||||
page: Int = 1,
|
||||
@@ -25,9 +25,10 @@ open class Follow <T : TargetI>(override var requester: Requester) : RepositoryI
|
||||
): Paginated<FollowEntity<T>> {
|
||||
return requester.run {
|
||||
getFunction("find_follows_by_citizen")
|
||||
.select(page, limit,
|
||||
"created_by_id" to citizenId
|
||||
)
|
||||
.select(
|
||||
page, limit,
|
||||
"created_by_id" to citizenId
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +61,8 @@ class FollowArticle(requester: Requester) : Follow<ArticleEntity>(requester) {
|
||||
): Paginated<FollowEntity<ArticleEntity>> {
|
||||
return requester.run {
|
||||
getFunction("find_follows_article_by_citizen")
|
||||
.select(page, limit,
|
||||
.select(
|
||||
page, limit,
|
||||
"created_by_id" to citizenId
|
||||
)
|
||||
}
|
||||
@@ -75,7 +77,8 @@ class FollowConstitution(requester: Requester) : Follow<ConstitutionEntity>(requ
|
||||
): Paginated<FollowEntity<ConstitutionEntity>> {
|
||||
return requester.run {
|
||||
getFunction("find_follows_constitution_by_citizen")
|
||||
.select(page, limit,
|
||||
.select(
|
||||
page, limit,
|
||||
"created_by_id" to citizenId
|
||||
)
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.*
|
||||
import fr.dcproject.entity.Citizen as CitizenEntity
|
||||
import fr.dcproject.entity.Vote as VoteEntity
|
||||
|
||||
open class Vote <T : TargetI>(override var requester: Requester) : RepositoryI {
|
||||
open class Vote<T : TargetI>(override var requester: Requester) : RepositoryI {
|
||||
fun vote(vote: VoteEntity<T>): VoteAggregation {
|
||||
val author = vote.createdBy
|
||||
val anonymous = author.voteAnonymous
|
||||
@@ -36,10 +36,12 @@ open class Vote <T : TargetI>(override var requester: Requester) : RepositoryI {
|
||||
): Paginated<VoteEntity<T>> {
|
||||
return requester.run {
|
||||
getFunction("find_votes_by_citizen")
|
||||
.select(page, limit, typeReference, mapOf(
|
||||
"created_by_id" to citizenId,
|
||||
"reference" to target
|
||||
))
|
||||
.select(
|
||||
page, limit, typeReference, mapOf(
|
||||
"created_by_id" to citizenId,
|
||||
"reference" to target
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,10 +52,12 @@ open class Vote <T : TargetI>(override var requester: Requester) : RepositoryI {
|
||||
val typeReference = object : TypeReference<List<VoteEntity<TargetRef>>>() {}
|
||||
return requester.run {
|
||||
getFunction("find_citizen_votes_by_target_ids")
|
||||
.select(typeReference, mapOf(
|
||||
"citizen_id" to citizen.id,
|
||||
"ids" to targets
|
||||
))
|
||||
.select(
|
||||
typeReference, mapOf(
|
||||
"citizen_id" to citizen.id,
|
||||
"ids" to targets
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,22 +20,44 @@ 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 createdBy: String? = null) {
|
||||
@Location("/articles")
|
||||
class ArticlesRequest(
|
||||
page: Int = 1,
|
||||
limit: Int = 50,
|
||||
val sort: String? = null,
|
||||
val direction: RepositoryI.Direction? = null,
|
||||
val search: String? = null,
|
||||
val createdBy: 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: ArticleEntity)
|
||||
@Location("/articles/{article}/versions") class ArticleVersionsRequest(val article: ArticleEntity, page: Int = 1, limit: Int = 50, val sort: String? = null, val direction: RepositoryI.Direction? = null, val search: String? = null) {
|
||||
|
||||
@Location("/articles/{article}")
|
||||
class ArticleRequest(val article: ArticleEntity)
|
||||
|
||||
@Location("/articles/{article}/versions")
|
||||
class ArticleVersionsRequest(
|
||||
val article: ArticleEntity,
|
||||
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") class PostArticleRequest
|
||||
|
||||
@Location("/articles")
|
||||
class PostArticleRequest
|
||||
}
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
fun Route.article(repo: ArticleRepository) {
|
||||
get<ArticlesPaths.ArticlesRequest> {
|
||||
val articles = repo.find(it.page, it.limit, it.sort, it.direction, it.search, Filter(createdById = it.createdBy))
|
||||
val articles =
|
||||
repo.find(it.page, it.limit, it.sort, it.direction, it.search, Filter(createdById = it.createdBy))
|
||||
assertCan(VIEW, articles.result)
|
||||
call.respond(articles)
|
||||
}
|
||||
|
||||
@@ -26,9 +26,14 @@ import fr.dcproject.repository.User as UserRepository
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object AuthPaths {
|
||||
@Location("/login") class LoginRequest
|
||||
@Location("/register") class RegisterRequest
|
||||
@Location("/sso") class SsoRequest {
|
||||
@Location("/login")
|
||||
class LoginRequest
|
||||
|
||||
@Location("/register")
|
||||
class RegisterRequest
|
||||
|
||||
@Location("/sso")
|
||||
class SsoRequest {
|
||||
data class Content(val email: String, val url: String)
|
||||
}
|
||||
}
|
||||
@@ -40,7 +45,7 @@ fun Route.auth(
|
||||
citizenRepo: CitizenRepository,
|
||||
ssoManager: SsoManager
|
||||
) {
|
||||
post <LoginRequest> {
|
||||
post<LoginRequest> {
|
||||
try {
|
||||
val credentials = call.receive<UserPasswordCredential>()
|
||||
val user = userRepo.findByCredentials(credentials) ?: throw WrongLoginOrPassword()
|
||||
@@ -52,7 +57,7 @@ fun Route.auth(
|
||||
}
|
||||
}
|
||||
|
||||
post <RegisterRequest> {
|
||||
post<RegisterRequest> {
|
||||
try {
|
||||
val citizen = call.receive<CitizenEntity>()
|
||||
citizen.user.roles = listOf(ROLE_USER)
|
||||
|
||||
@@ -24,13 +24,26 @@ import fr.dcproject.repository.User as UserRepository
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object CitizenPaths {
|
||||
@Location("/citizens") class CitizensRequest(page: Int = 1, limit: Int = 50, val sort: String? = null, val direction: Direction? = null, val search: String? = null) {
|
||||
@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/current") class CurrentCitizenRequest
|
||||
@Location("/citizens/{citizen}/password/change") class ChangePasswordCitizenRequest(val citizen: Citizen) {
|
||||
|
||||
@Location("/citizens/{citizen}")
|
||||
class CitizenRequest(val citizen: Citizen)
|
||||
|
||||
@Location("/citizens/current")
|
||||
class CurrentCitizenRequest
|
||||
|
||||
@Location("/citizens/{citizen}/password/change")
|
||||
class ChangePasswordCitizenRequest(val citizen: Citizen) {
|
||||
data class Content(val password: String)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@ import fr.dcproject.repository.CommentGeneric as CommentRepository
|
||||
@KtorExperimentalLocationsAPI
|
||||
object CommentPaths {
|
||||
// TODO: change UUID by entity converter
|
||||
@Location("/comments/{comment}") class CommentRequest(val comment: UUID)
|
||||
@Location("/comments/{comment}")
|
||||
class CommentRequest(val comment: UUID)
|
||||
|
||||
@Location("/comments/{comment}/children")
|
||||
class CommentChildrenRequest(
|
||||
|
||||
@@ -31,7 +31,9 @@ object CommentArticlePaths {
|
||||
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}/comments/articles") class CitizenCommentArticleRequest(val citizen: Citizen)
|
||||
|
||||
@Location("/citizens/{citizen}/comments/articles")
|
||||
class CitizenCommentArticleRequest(val citizen: Citizen)
|
||||
}
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
|
||||
@@ -20,8 +20,11 @@ import fr.dcproject.repository.CommentConstitution as CommentConstitutionReposit
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object CommentConstitutionPaths {
|
||||
@Location("/constitutions/{constitution}/comments") class ConstitutionCommentRequest(val constitution: ConstitutionEntity)
|
||||
@Location("/citizens/{citizen}/comments/constitutions") class CitizenCommentConstitutionRequest(val citizen: Citizen)
|
||||
@Location("/constitutions/{constitution}/comments")
|
||||
class ConstitutionCommentRequest(val constitution: ConstitutionEntity)
|
||||
|
||||
@Location("/citizens/{citizen}/comments/constitutions")
|
||||
class CitizenCommentConstitutionRequest(val citizen: Citizen)
|
||||
}
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
|
||||
@@ -19,13 +19,26 @@ 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) {
|
||||
@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: ConstitutionEntity)
|
||||
@Location("/constitutions/{constitution}/follow") class ConstitutionFollowRequest(val constitution: ConstitutionEntity)
|
||||
@Location("/constitutions") class PostConstitutionRequest
|
||||
|
||||
@Location("/constitutions/{constitution}")
|
||||
class ConstitutionRequest(val constitution: ConstitutionEntity)
|
||||
|
||||
@Location("/constitutions/{constitution}/follow")
|
||||
class ConstitutionFollowRequest(val constitution: ConstitutionEntity)
|
||||
|
||||
@Location("/constitutions")
|
||||
class PostConstitutionRequest
|
||||
}
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
|
||||
@@ -15,8 +15,11 @@ import fr.dcproject.repository.FollowArticle as FollowArticleRepository
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object FollowArticlePaths {
|
||||
@Location("/articles/{article}/follows") class ArticleFollowRequest(val article: ArticleEntity)
|
||||
@Location("/citizens/{citizen}/follows/articles") class CitizenFollowArticleRequest(val citizen: Citizen)
|
||||
@Location("/articles/{article}/follows")
|
||||
class ArticleFollowRequest(val article: ArticleEntity)
|
||||
|
||||
@Location("/citizens/{citizen}/follows/articles")
|
||||
class CitizenFollowArticleRequest(val citizen: Citizen)
|
||||
}
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
|
||||
@@ -15,8 +15,11 @@ import fr.dcproject.repository.FollowConstitution as FollowConstitutionRepositor
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object FollowConstitutionPaths {
|
||||
@Location("/constitutions/{constitution}/follow") class ConstitutionFollowRequest(val constitution: ConstitutionEntity)
|
||||
@Location("/citizens/{citizen}/follows/constitutions") class CitizenFollowConstitutionRequest(val citizen: Citizen)
|
||||
@Location("/constitutions/{constitution}/follow")
|
||||
class ConstitutionFollowRequest(val constitution: ConstitutionEntity)
|
||||
|
||||
@Location("/citizens/{citizen}/follows/constitutions")
|
||||
class CitizenFollowConstitutionRequest(val citizen: Citizen)
|
||||
}
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
|
||||
@@ -19,10 +19,13 @@ import fr.dcproject.repository.VoteConstitution as VoteConstitutionRepository
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object VoteConstitutionPaths {
|
||||
@Location("/constitutions/{constitution}/vote") class ConstitutionVoteRequest(val constitution: ConstitutionEntity) {
|
||||
@Location("/constitutions/{constitution}/vote")
|
||||
class ConstitutionVoteRequest(val constitution: ConstitutionEntity) {
|
||||
data class Content(var note: Int)
|
||||
}
|
||||
@Location("/citizens/{citizen}/votes/constitutions") class CitizenVoteConstitutionRequest(val citizen: Citizen)
|
||||
|
||||
@Location("/citizens/{citizen}/votes/constitutions")
|
||||
class CitizenVoteConstitutionRequest(val citizen: Citizen)
|
||||
}
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
|
||||
@@ -50,7 +50,8 @@ class CitizenVoter : Voter {
|
||||
if (action == Action.UPDATE &&
|
||||
user is UserI &&
|
||||
subject is CitizenBasicI &&
|
||||
subject.user.id == user.id) {
|
||||
subject.user.id == user.id
|
||||
) {
|
||||
return Vote.GRANTED
|
||||
}
|
||||
|
||||
|
||||
@@ -11,9 +11,9 @@ class VoteVoter : Voter {
|
||||
|
||||
override fun supports(action: ActionI, call: ApplicationCall, subject: Any?): Boolean {
|
||||
return action is Action && (
|
||||
subject is VoteEntity<*>? ||
|
||||
subject is List<*>
|
||||
)
|
||||
subject is VoteEntity<*>? ||
|
||||
subject is List<*>
|
||||
)
|
||||
}
|
||||
|
||||
override fun vote(action: ActionI, call: ApplicationCall, subject: Any?): Vote {
|
||||
|
||||
@@ -78,7 +78,10 @@ class AuthorizationVoter {
|
||||
override val key = AttributeKey<AuthorizationVoter>("Voter")
|
||||
|
||||
@KtorExperimentalAPI
|
||||
override fun install(pipeline: ApplicationCallPipeline, configure: Configuration.() -> Unit): AuthorizationVoter {
|
||||
override fun install(
|
||||
pipeline: ApplicationCallPipeline,
|
||||
configure: Configuration.() -> Unit
|
||||
): AuthorizationVoter {
|
||||
val configuration = Configuration().apply(configure)
|
||||
|
||||
pipeline.intercept(ApplicationCallPipeline.Features) {
|
||||
|
||||
Reference in New Issue
Block a user