Fix upsert_workgroup

This commit is contained in:
2020-06-02 01:01:08 +02:00
parent a6c36c542e
commit 32510652d1
3 changed files with 28 additions and 23 deletions

View File

@@ -6,30 +6,24 @@ import fr.dcproject.entity.WorkgroupSimple
import fr.dcproject.entity.WorkgroupWithMembersI.Member import fr.dcproject.entity.WorkgroupWithMembersI.Member
import fr.dcproject.entity.WorkgroupWithMembersI.Member.Role import fr.dcproject.entity.WorkgroupWithMembersI.Member.Role
import fr.dcproject.repository.Workgroup.Filter 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.CREATE
import fr.dcproject.security.voter.WorkgroupVoter.Action.UPDATE import fr.dcproject.security.voter.WorkgroupVoter.Action.UPDATE
import fr.dcproject.security.voter.WorkgroupVoter.ActionMembers.ADD as ADD_MEMBERS import fr.dcproject.security.voter.WorkgroupVoter.Action.VIEW
import fr.dcproject.security.voter.WorkgroupVoter.ActionMembers.UPDATE as UPDATE_MEMBERS
import fr.dcproject.security.voter.WorkgroupVoter.ActionMembers.REMOVE as REMOVE_MEMBERS
import fr.ktorVoter.assertCan import fr.ktorVoter.assertCan
import fr.dcproject.utils.toUUID
import fr.postgresjson.repository.RepositoryI import fr.postgresjson.repository.RepositoryI
import io.ktor.application.ApplicationCall import io.ktor.application.ApplicationCall
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.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.request.receive
import io.ktor.response.respond import io.ktor.response.respond
import io.ktor.routing.Route import io.ktor.routing.Route
import java.util.* import java.util.*
import fr.dcproject.entity.Workgroup as WorkgroupEntity import fr.dcproject.entity.Workgroup as WorkgroupEntity
import fr.dcproject.repository.Workgroup as WorkgroupRepository import fr.dcproject.repository.Workgroup as WorkgroupRepository
import fr.dcproject.security.voter.WorkgroupVoter.ActionMembers.ADD as ADD_MEMBERS
import fr.dcproject.security.voter.WorkgroupVoter.ActionMembers.REMOVE as REMOVE_MEMBERS
import fr.dcproject.security.voter.WorkgroupVoter.ActionMembers.UPDATE as UPDATE_MEMBERS
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
object WorkgroupsPaths { object WorkgroupsPaths {
@@ -97,8 +91,7 @@ object WorkgroupsMembersPaths {
@Location("/workgroups/{workgroup}/members") @Location("/workgroups/{workgroup}/members")
class WorkgroupsMembersRequest(val workgroup: WorkgroupEntity) { class WorkgroupsMembersRequest(val workgroup: WorkgroupEntity) {
class Body : MutableList<Body.Item> by mutableListOf() { class Body : MutableList<Body.Item> by mutableListOf() {
class Item(id: String, roles: List<String>) { class Item(val citizen: CitizenRef, roles: List<String> = emptyList()) {
val citizen = CitizenRef(id.toUUID())
val roles: List<Role> = roles.map { val roles: List<Role> = roles.map {
Role.valueOf(it) Role.valueOf(it)
} }
@@ -160,8 +153,8 @@ fun Route.workgroup(repo: WorkgroupRepository) {
.let { members -> .let { members ->
assertCan(ADD_MEMBERS, it.workgroup) assertCan(ADD_MEMBERS, it.workgroup)
repo.addMembers(it.workgroup, members) repo.addMembers(it.workgroup, members)
}.let { }.let { members ->
call.respond(HttpStatusCode.Created, it) call.respond(HttpStatusCode.Created, members)
} }
} }
@@ -171,8 +164,8 @@ fun Route.workgroup(repo: WorkgroupRepository) {
.let { members -> .let { members ->
assertCan(REMOVE_MEMBERS, it.workgroup) assertCan(REMOVE_MEMBERS, it.workgroup)
repo.removeMembers(it.workgroup, members) repo.removeMembers(it.workgroup, members)
}.let { }.let { members ->
call.respond(HttpStatusCode.OK, it) call.respond(HttpStatusCode.OK, members)
} }
} }
@@ -182,8 +175,8 @@ fun Route.workgroup(repo: WorkgroupRepository) {
.let { members -> .let { members ->
assertCan(UPDATE_MEMBERS, it.workgroup) assertCan(UPDATE_MEMBERS, it.workgroup)
repo.updateMembers(it.workgroup, members) repo.updateMembers(it.workgroup, members)
}.let { }.let { members ->
call.respond(HttpStatusCode.OK, it) call.respond(HttpStatusCode.OK, members)
} }
} }
} }

View File

@@ -3,6 +3,7 @@ create or replace function upsert_workgroup(inout resource json)
$$ $$
declare declare
new_id uuid = coalesce((resource->>'id')::uuid, uuid_generate_v4()); new_id uuid = coalesce((resource->>'id')::uuid, uuid_generate_v4());
exists boolean = case when (select true from workgroup where id = new_id) is null then true else false end;
begin begin
insert into workgroup (id, created_by_id, name, description, anonymous, logo) insert into workgroup (id, created_by_id, name, description, anonymous, logo)
select select
@@ -22,9 +23,19 @@ begin
insert into citizen_in_workgroup (workgroup_id, citizen_id, roles) insert into citizen_in_workgroup (workgroup_id, citizen_id, roles)
select select
new_id::uuid, new_id::uuid,
(resource#>>'{created_by, id}')::uuid, citizen_id,
'{MASTER}' roles
from json_populate_recordset(null::workgroup, resource->'members'); from json_populate_recordset(null::citizen_in_workgroup, resource->'members') m;
-- insert master if no members
if (exists) then
insert into citizen_in_workgroup (workgroup_id, citizen_id, roles)
select
new_id::uuid,
(resource#>>'{created_by, id}')::uuid,
'{MASTER}'
on conflict do nothing;
end if;
select find_workgroup_by_id(new_id) into resource; select find_workgroup_by_id(new_id) into resource;
end; end;

View File

@@ -25,6 +25,7 @@ begin
select upsert_workgroup(created_workgroup) into created_workgroup; select upsert_workgroup(created_workgroup) into created_workgroup;
assert created_workgroup->>'description' is not null, 'description should not be null'; assert created_workgroup->>'description' is not null, 'description should not be null';
assert (created_workgroup->>'name') = 'Le groupe des vert', format('name must be equal to "Le groupe des vert", %s instead', created_workgroup->>'name'); assert (created_workgroup->>'name') = 'Le groupe des vert', format('name must be equal to "Le groupe des vert", %s instead', created_workgroup->>'name');
assert (created_workgroup#>>'{members, 0, citizen, id}') = _citizen_id::text, 'workgroup must have creator in members on creation';
-- insert another workgroup -- insert another workgroup
created_workgroup_2 := jsonb_set(created_workgroup_2::jsonb, '{created_by}'::text[], jsonb_build_object('id', _citizen_id::text), true)::json; created_workgroup_2 := jsonb_set(created_workgroup_2::jsonb, '{created_by}'::text[], jsonb_build_object('id', _citizen_id::text), true)::json;
@@ -50,7 +51,7 @@ begin
json_build_object('citizen', json_build_object('id', _citizen_id3), 'roles', '{MASTER}'::text[]) json_build_object('citizen', json_build_object('id', _citizen_id3), 'roles', '{MASTER}'::text[])
)) m; )) m;
assert json_array_length(members) = 2, 'The members count must be equal to 2'; assert json_array_length(members) = 3, 'The members count must be equal to 3';
assert (members::jsonb) @> jsonb_build_array(jsonb_build_object( assert (members::jsonb) @> jsonb_build_array(jsonb_build_object(
'id', (created_workgroup->>'id'), 'id', (created_workgroup->>'id'),
'citizen', jsonb_build_object('id', _citizen_id3), 'citizen', jsonb_build_object('id', _citizen_id3),