diff --git a/src/main/kotlin/routes/Workgroup.kt b/src/main/kotlin/routes/Workgroup.kt index 06614ad..fe37171 100644 --- a/src/main/kotlin/routes/Workgroup.kt +++ b/src/main/kotlin/routes/Workgroup.kt @@ -6,30 +6,24 @@ import fr.dcproject.entity.WorkgroupSimple import fr.dcproject.entity.WorkgroupWithMembersI.Member import fr.dcproject.entity.WorkgroupWithMembersI.Member.Role 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.WorkgroupVoter.ActionMembers.ADD as ADD_MEMBERS -import fr.dcproject.security.voter.WorkgroupVoter.ActionMembers.UPDATE as UPDATE_MEMBERS -import fr.dcproject.security.voter.WorkgroupVoter.ActionMembers.REMOVE as REMOVE_MEMBERS +import fr.dcproject.security.voter.WorkgroupVoter.Action.VIEW import fr.ktorVoter.assertCan -import fr.dcproject.utils.toUUID import fr.postgresjson.repository.RepositoryI import io.ktor.application.ApplicationCall import io.ktor.application.call import io.ktor.http.HttpStatusCode -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.locations.* import io.ktor.request.receive import io.ktor.response.respond import io.ktor.routing.Route import java.util.* import fr.dcproject.entity.Workgroup as WorkgroupEntity 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 object WorkgroupsPaths { @@ -97,8 +91,7 @@ object WorkgroupsMembersPaths { @Location("/workgroups/{workgroup}/members") class WorkgroupsMembersRequest(val workgroup: WorkgroupEntity) { class Body : MutableList by mutableListOf() { - class Item(id: String, roles: List) { - val citizen = CitizenRef(id.toUUID()) + class Item(val citizen: CitizenRef, roles: List = emptyList()) { val roles: List = roles.map { Role.valueOf(it) } @@ -160,8 +153,8 @@ fun Route.workgroup(repo: WorkgroupRepository) { .let { members -> assertCan(ADD_MEMBERS, it.workgroup) repo.addMembers(it.workgroup, members) - }.let { - call.respond(HttpStatusCode.Created, it) + }.let { members -> + call.respond(HttpStatusCode.Created, members) } } @@ -171,8 +164,8 @@ fun Route.workgroup(repo: WorkgroupRepository) { .let { members -> assertCan(REMOVE_MEMBERS, it.workgroup) repo.removeMembers(it.workgroup, members) - }.let { - call.respond(HttpStatusCode.OK, it) + }.let { members -> + call.respond(HttpStatusCode.OK, members) } } @@ -182,8 +175,8 @@ fun Route.workgroup(repo: WorkgroupRepository) { .let { members -> assertCan(UPDATE_MEMBERS, it.workgroup) repo.updateMembers(it.workgroup, members) - }.let { - call.respond(HttpStatusCode.OK, it) + }.let { members -> + call.respond(HttpStatusCode.OK, members) } } } diff --git a/src/main/resources/sql/functions/workgroup/upsert_workgroup.sql b/src/main/resources/sql/functions/workgroup/upsert_workgroup.sql index 7338a3f..797ed71 100644 --- a/src/main/resources/sql/functions/workgroup/upsert_workgroup.sql +++ b/src/main/resources/sql/functions/workgroup/upsert_workgroup.sql @@ -3,6 +3,7 @@ create or replace function upsert_workgroup(inout resource json) $$ declare 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 insert into workgroup (id, created_by_id, name, description, anonymous, logo) select @@ -22,9 +23,19 @@ begin insert into citizen_in_workgroup (workgroup_id, citizen_id, roles) select new_id::uuid, - (resource#>>'{created_by, id}')::uuid, - '{MASTER}' - from json_populate_recordset(null::workgroup, resource->'members'); + citizen_id, + roles + 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; end; diff --git a/src/test/sql/workgroup.sql b/src/test/sql/workgroup.sql index be31877..e2c87ad 100644 --- a/src/test/sql/workgroup.sql +++ b/src/test/sql/workgroup.sql @@ -25,6 +25,7 @@ begin select upsert_workgroup(created_workgroup) into created_workgroup; 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#>>'{members, 0, citizen, id}') = _citizen_id::text, 'workgroup must have creator in members on creation'; -- insert another workgroup 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[]) )) 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( 'id', (created_workgroup->>'id'), 'citizen', jsonb_build_object('id', _citizen_id3),