#29 Implement Workgroup members routes (Add, remove, update)
This commit is contained in:
@@ -151,10 +151,10 @@ fun Application.module(env: Env = PROD) {
|
||||
}
|
||||
}
|
||||
|
||||
convert<CitizenRef> {
|
||||
convert<WorkgroupRef> {
|
||||
decode { values, _ ->
|
||||
values.singleOrNull()?.let {
|
||||
CitizenRef(UUID.fromString(it))
|
||||
WorkgroupRef(UUID.fromString(it))
|
||||
} ?: throw NotFoundException("""UUID "$values" is not valid for Workgroup""")
|
||||
}
|
||||
}
|
||||
@@ -288,7 +288,6 @@ fun Application.module(env: Env = PROD) {
|
||||
install(AutoHeadResponse)
|
||||
|
||||
install(ContentNegotiation) {
|
||||
// TODO move to postgresJson lib
|
||||
jackson {
|
||||
propertyNamingStrategy = PropertyNamingStrategy.SNAKE_CASE
|
||||
|
||||
|
||||
@@ -43,10 +43,9 @@ open class WorkgroupRef(
|
||||
id: UUID?
|
||||
) : UuidEntity(id ?: UUID.randomUUID()), WorkgroupI
|
||||
|
||||
interface WorkgroupWithAuthI<Z : CitizenWithUserI> : WorkgroupI, EntityCreatedBy<Z>, EntityDeletedAt {
|
||||
interface WorkgroupWithAuthI<Z : CitizenWithUserI> : WorkgroupWithMembersI<Z>, EntityCreatedBy<Z>, EntityDeletedAt {
|
||||
val anonymous: Boolean
|
||||
val owner: Z
|
||||
var members: List<Z>
|
||||
|
||||
fun isMember(user: UserI): Boolean =
|
||||
members.map { it.user.id }.contains(user.id) || owner.user.id == user.id
|
||||
@@ -55,4 +54,8 @@ interface WorkgroupWithAuthI<Z : CitizenWithUserI> : WorkgroupI, EntityCreatedBy
|
||||
isMember(citizen.user)
|
||||
}
|
||||
|
||||
interface WorkgroupWithMembersI<Z : CitizenI> : WorkgroupI {
|
||||
var members: List<Z>
|
||||
}
|
||||
|
||||
interface WorkgroupI : UuidEntityI
|
||||
@@ -1,12 +1,12 @@
|
||||
package fr.dcproject.repository
|
||||
|
||||
import fr.dcproject.entity.CitizenRef
|
||||
import fr.dcproject.entity.WorkgroupSimple
|
||||
import fr.dcproject.entity.*
|
||||
import fr.postgresjson.connexion.Paginated
|
||||
import fr.postgresjson.connexion.Requester
|
||||
import fr.postgresjson.entity.Parameter
|
||||
import fr.postgresjson.repository.RepositoryI
|
||||
import fr.postgresjson.repository.RepositoryI.Direction
|
||||
import fr.postgresjson.serializer.serialize
|
||||
import net.pearx.kasechange.toSnakeCase
|
||||
import java.util.*
|
||||
import fr.dcproject.entity.Workgroup as WorkgroupEntity
|
||||
@@ -40,6 +40,41 @@ class Workgroup(override var requester: Requester) : RepositoryI {
|
||||
.getFunction("upsert_workgroup")
|
||||
.selectOne("resource" to workgroup) ?: error("query 'upsert_workgroup' return null")
|
||||
|
||||
fun addMember(workgroup: WorkgroupI, member: CitizenI): List<CitizenBasic> =
|
||||
addMembers(workgroup, listOf(member))
|
||||
|
||||
fun addMembers(workgroup: WorkgroupI, members: List<CitizenI>): List<CitizenBasic> = requester
|
||||
.getFunction("add_workgroup_members")
|
||||
.select(
|
||||
"id" to workgroup.id,
|
||||
"resource" to members.serialize()
|
||||
)
|
||||
|
||||
fun removeMember(workgroup: WorkgroupI, memberToDelete: CitizenI): List<CitizenBasic> =
|
||||
removeMembers(workgroup, listOf(memberToDelete))
|
||||
|
||||
fun removeMembers(workgroup: WorkgroupI, membersToDelete: List<CitizenI>): List<CitizenBasic> = requester
|
||||
.getFunction("remove_workgroup_members")
|
||||
.select(
|
||||
"id" to workgroup.id,
|
||||
"resource" to membersToDelete
|
||||
)
|
||||
|
||||
fun updateMembers(workgroup: WorkgroupI, members: List<CitizenI>): List<CitizenBasic> = requester
|
||||
.getFunction("update_workgroup_members")
|
||||
.select(
|
||||
"id" to workgroup.id,
|
||||
"resource" to members
|
||||
)
|
||||
|
||||
fun <W : WorkgroupWithMembersI<CitizenI>> updateMembers(workgroup: W): W {
|
||||
updateMembers(workgroup, workgroup.members).let {
|
||||
workgroup.members = it
|
||||
}
|
||||
|
||||
return workgroup
|
||||
}
|
||||
|
||||
class Filter(
|
||||
val createdById: String? = null
|
||||
) : Parameter
|
||||
|
||||
@@ -8,7 +8,9 @@ import fr.dcproject.entity.request.getContent
|
||||
import fr.dcproject.repository.Workgroup.Filter
|
||||
import fr.dcproject.security.voter.WorkgroupVoter.Action.VIEW
|
||||
import fr.dcproject.security.voter.WorkgroupVoter.Action.CREATE
|
||||
import fr.dcproject.security.voter.WorkgroupVoter.Action.UPDATE
|
||||
import fr.dcproject.security.voter.assertCan
|
||||
import fr.dcproject.utils.toUUID
|
||||
import fr.postgresjson.repository.RepositoryI
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.application.call
|
||||
@@ -17,6 +19,8 @@ import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.locations.Location
|
||||
import io.ktor.locations.get
|
||||
import io.ktor.locations.post
|
||||
import io.ktor.locations.put
|
||||
import io.ktor.locations.delete
|
||||
import io.ktor.request.receive
|
||||
import io.ktor.response.respond
|
||||
import io.ktor.routing.Route
|
||||
@@ -72,6 +76,22 @@ object WorkgroupsPaths {
|
||||
}
|
||||
}
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
object WorkgroupsMembersPaths {
|
||||
@Location("/workgroups/members/{workgroup}")
|
||||
class WorkgroupsMembersRequest(val workgroup: WorkgroupEntity) : RequestBuilder<List<CitizenRef>> {
|
||||
class Content : MutableList<Content.Item> by mutableListOf() {
|
||||
class Item(val id: String)
|
||||
}
|
||||
|
||||
override suspend fun getContent(call: ApplicationCall): List<CitizenRef> {
|
||||
return call.receive<Content>().map {
|
||||
CitizenRef(it.id.toUUID())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@KtorExperimentalLocationsAPI
|
||||
fun Route.workgroup(repo: WorkgroupRepository) {
|
||||
get<WorkgroupsPaths.WorkgroupsRequest> {
|
||||
@@ -96,4 +116,37 @@ fun Route.workgroup(repo: WorkgroupRepository) {
|
||||
call.respond(HttpStatusCode.Created, it)
|
||||
}
|
||||
}
|
||||
|
||||
/* Add members to workgroup */
|
||||
post<WorkgroupsMembersPaths.WorkgroupsMembersRequest> {
|
||||
call.getContent(it)
|
||||
.let { members ->
|
||||
assertCan(UPDATE, it.workgroup)
|
||||
repo.addMembers(it.workgroup, members)
|
||||
}.let {
|
||||
call.respond(HttpStatusCode.OK, it)
|
||||
}
|
||||
}
|
||||
|
||||
/* Delete members of workgroup */
|
||||
delete<WorkgroupsMembersPaths.WorkgroupsMembersRequest> {
|
||||
call.getContent(it)
|
||||
.let { members ->
|
||||
assertCan(UPDATE, it.workgroup)
|
||||
repo.removeMembers(it.workgroup, members)
|
||||
}.let {
|
||||
call.respond(HttpStatusCode.OK, it)
|
||||
}
|
||||
}
|
||||
|
||||
/* Update members of workgroup */
|
||||
put<WorkgroupsMembersPaths.WorkgroupsMembersRequest> {
|
||||
call.getContent(it)
|
||||
.let { members ->
|
||||
assertCan(UPDATE, it.workgroup)
|
||||
repo.updateMembers(it.workgroup, members)
|
||||
}.let {
|
||||
call.respond(HttpStatusCode.OK, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user