diff --git a/src/main/java/fr/inra/oresing/domain/data/deposit/DataImporter.java b/src/main/java/fr/inra/oresing/domain/data/deposit/DataImporter.java index 7c91477cfdf8cb09f62e9aa887cb93adafe88f95..21a7d8563694907c8e2d0d735d779a9d47b43cb0 100644 --- a/src/main/java/fr/inra/oresing/domain/data/deposit/DataImporter.java +++ b/src/main/java/fr/inra/oresing/domain/data/deposit/DataImporter.java @@ -473,6 +473,9 @@ public class DataImporter { private fr.inra.oresing.domain.Authorization getLineAuthorization(DataDatum referenceDatum, long lineNumber, ReportErrors errors) { final Authorization authorization = dataImporterContext.getAuthorization(); + if(authorization==null){ + return new fr.inra.oresing.domain.Authorization(); + } BinaryFileDataset binaryFileDataset = Optional.ofNullable(dataImporterContext.getPublishContextBuilder()) .map(PublishContext.PublishContextBuilder::build) diff --git a/src/main/java/fr/inra/oresing/rest/AuthorizationService.java b/src/main/java/fr/inra/oresing/rest/AuthorizationService.java index 9a737e9c144a620088931c20aa7b8aae3e0922e9..f6782a8ba54fd2b9e71e8281f577fc46ce871a16 100644 --- a/src/main/java/fr/inra/oresing/rest/AuthorizationService.java +++ b/src/main/java/fr/inra/oresing/rest/AuthorizationService.java @@ -556,7 +556,7 @@ public class AuthorizationService implements fr.inra.oresing.domain.services.aut .toList(); } - private Map<String, List<GetGrantableResult.ReferenceScope>> getAuthorizationScopes(final Application application, final MenuType menuType) { + public Map<String, List<GetGrantableResult.ReferenceScope>> getAuthorizationScopes(final Application application, final MenuType menuType) { Map<ReferenceScope.Context, List<ReferenceScope.TreeNode>> nodesByContext = repository.getRepository(application).data() .getNodesForMenu(menuType) diff --git a/src/main/java/fr/inra/oresing/rest/OreSiResources.java b/src/main/java/fr/inra/oresing/rest/OreSiResources.java index 2d72658168fba0f72b6780a941e99371f349ac99..0c9d473f7dba88455c31bd7d0ef1ce30274c527b 100644 --- a/src/main/java/fr/inra/oresing/rest/OreSiResources.java +++ b/src/main/java/fr/inra/oresing/rest/OreSiResources.java @@ -18,6 +18,7 @@ import fr.inra.oresing.domain.checker.type.ReferenceType; import fr.inra.oresing.domain.data.DataValue; import fr.inra.oresing.domain.data.RefsLinkedToValue; import fr.inra.oresing.domain.data.deposit.validation.CsvRowValidationCheckResult; +import fr.inra.oresing.domain.data.menu.MenuType; import fr.inra.oresing.domain.data.read.ouput.KeepAliveZipOutputStream; import fr.inra.oresing.domain.data.read.query.DownloadDatasetQueryOnlyMetadata; import fr.inra.oresing.domain.exceptions.SiOreIllegalArgumentException; @@ -41,6 +42,7 @@ import fr.inra.oresing.rest.filesenderclient.BuildBundleReport; import fr.inra.oresing.rest.model.additionalfiles.CreateAdditionalFileRequest; import fr.inra.oresing.rest.model.additionalfiles.exceptions.BadAdditionalFileParamsSearchException; import fr.inra.oresing.rest.model.application.ApplicationResult; +import fr.inra.oresing.rest.model.authorization.GetGrantableResult; import fr.inra.oresing.rest.model.data.*; import fr.inra.oresing.rest.model.data.query.DownloadDatasetQuery; import fr.inra.oresing.rest.model.reference.GetReferenceResult; @@ -918,14 +920,15 @@ public class OreSiResources { ) ) .orElseGet(LinkedHashMap::new); - + Map<String, List<GetGrantableResult.ReferenceScope>> referenceScopes = service.getAuthorizationScopes(application, MenuType.submission); return ResponseEntity.ok(new GetDataResult( variables, dataRowResults, totalRows, checkedFormatcomponents, - referenceTypeForReferencingColumns)); + referenceTypeForReferencingColumns, + referenceScopes)); } /** diff --git a/src/main/java/fr/inra/oresing/rest/OreSiService.java b/src/main/java/fr/inra/oresing/rest/OreSiService.java index 7b1a97130d82b80ef314e06ca9f49be674bacc18..2ddc3c3f649a5be18f1c58bad281b9b2050d10ee 100644 --- a/src/main/java/fr/inra/oresing/rest/OreSiService.java +++ b/src/main/java/fr/inra/oresing/rest/OreSiService.java @@ -21,6 +21,7 @@ import fr.inra.oresing.domain.checker.LineChecker; import fr.inra.oresing.domain.checker.type.*; import fr.inra.oresing.domain.data.*; import fr.inra.oresing.domain.data.deposit.PublishContext; +import fr.inra.oresing.domain.data.menu.MenuType; import fr.inra.oresing.domain.data.read.query.*; import fr.inra.oresing.domain.exceptions.OreSiTechnicalException; import fr.inra.oresing.domain.exceptions.SiOreIllegalArgumentException; @@ -1312,4 +1313,8 @@ public class OreSiService { public DataRepositoryWithBuffer getNewDataRepositoryWithBuffer(Application application) { return new DataRepositoryWithBuffer(application, repository.getRepository(application).data()); } + + public Map<String, List<GetGrantableResult.ReferenceScope>> getAuthorizationScopes(Application application, MenuType menuType) { + return authorizationService.getAuthorizationScopes(application, menuType); + } } diff --git a/src/main/java/fr/inra/oresing/rest/model/authorization/AuthorizationsResult.java b/src/main/java/fr/inra/oresing/rest/model/authorization/AuthorizationsResult.java index 2900b81ab19ae200d51cceb9caecbd3a3d875c49..29615d18460b630892408441fda9210a7b6c22c9 100644 --- a/src/main/java/fr/inra/oresing/rest/model/authorization/AuthorizationsResult.java +++ b/src/main/java/fr/inra/oresing/rest/model/authorization/AuthorizationsResult.java @@ -12,7 +12,8 @@ public record AuthorizationsResult( Boolean applicationManager, Boolean isAdministrator, Boolean userManager, - Boolean applicationUser, Boolean activeApplicationUser + Boolean applicationUser, + Boolean activeApplicationUser ) { public AuthorizationsResult(Map<String, List<AuthorizationParsed>> userAuthorization, Map<String, AuthorizationParsed> publicAuthorization, String applicationName, Boolean applicationCreator, Boolean applicationManager, Boolean userManager, Boolean applicationUser, Boolean activeApplicationUser) { this(userAuthorization, publicAuthorization, applicationName, applicationCreator, applicationManager, applicationCreator||applicationManager, userManager, applicationUser, activeApplicationUser); diff --git a/src/main/java/fr/inra/oresing/rest/model/data/GetDataResult.java b/src/main/java/fr/inra/oresing/rest/model/data/GetDataResult.java index 4ea09aa3c42ae1dd52c3f242d68a9c82e4d36e4f..aadb455d894d3b14757f1a78ac55c3541fcf7ea3 100644 --- a/src/main/java/fr/inra/oresing/rest/model/data/GetDataResult.java +++ b/src/main/java/fr/inra/oresing/rest/model/data/GetDataResult.java @@ -5,6 +5,7 @@ import fr.inra.oresing.domain.checker.LineChecker; import fr.inra.oresing.domain.checker.type.FieldType; import fr.inra.oresing.domain.checker.type.ListType; import fr.inra.oresing.domain.data.DataColumn; +import fr.inra.oresing.rest.model.authorization.GetGrantableResult; import java.util.List; import java.util.Map; @@ -14,5 +15,6 @@ import java.util.Set; public record GetDataResult(Set<String> variables, List<DataRowResult> rows, Long totalRows, Map<String, Map<String, fr.inra.oresing.rest.model.data.LineCheckerResult>> checkedFormatComponents, - Map<String, String> referenceTypeForReferencingColumns) { + Map<String, String> referenceTypeForReferencingColumns, + Map<String, List<GetGrantableResult.ReferenceScope>> referenceScopes) { } \ No newline at end of file diff --git a/src/main/resources/migration/application/V1__init_schema.sql b/src/main/resources/migration/application/V1__init_schema.sql index 38739ca564bec003a9391a2033605febcd466233..4a6441c1987da7e371151a589664f59f6f64565c 100644 --- a/src/main/resources/migration/application/V1__init_schema.sql +++ b/src/main/resources/migration/application/V1__init_schema.sql @@ -157,18 +157,21 @@ with recursive d(key, "data") as ( treetype, key, authorizationscope.component, - Coalesce(("configuration" #> array['i18n', 'data', key, 'components'] #>> array[authorizationscope.component,'exportheader', 'fr'] ),authorizationscope.component) exportheader_fr, - Coalesce(("configuration" #> array['i18n', 'data', key, 'components'] #>> array[authorizationscope.component,'exportheader', 'en'] ),authorizationscope.component) exportheader_en, - authorizationscope.data reference, + Coalesce(("configuration" #> array['i18n', 'data', key, 'components'] #>> array[authorizationscope.component,'exportheader', 'title', 'fr'] ),authorizationscope.component) exportheader_fr, + Coalesce(("configuration" #> array['i18n', 'data', key, 'components'] #>> array[authorizationscope.component,'exportheader', 'title', 'en'] ),authorizationscope.component) exportheader_en, + CASE + WHEN treetype = 'authorization' then authorizationscope.data + WHEN treetype = 'submission' then authorizationscope.reference + end reference, "configuration" from d, jsonb_to_recordset( CASE WHEN treetype = 'authorization' then "configuration"#> array['datadescription', key, 'authorization', 'authorizationscope'] - WHEN treetype = 'submission' then "configuration"#> array['datadescription', key, 'authorization', 'authorizationscope'] + WHEN treetype = 'submission' then "configuration"#> array['datadescription', key, 'submission', 'submissionscope', 'referencescopes'] end - ) as authorizationscope(component text, "data" text) + ) as authorizationscope(component text, reference text, "data" text) ), nodes as ( select @@ -196,8 +199,8 @@ with recursive d(key, "data") as ( 'value', node[2], 'node_key', rv2.hierarchicalkey, 'node_NK', rv2.naturalkey, - 'fr', coalesce(rv2.refvalues ->> '__display___display_fr',rv2.refvalues ->> '__display___display_default') , - 'en', coalesce(rv2.refvalues ->> '__display___display_en',rv2.refvalues ->> '__display___display_default') + 'fr', coalesce(rv2.refvalues ->> '__display_fr',rv2.refvalues ->> '__display_default') , + 'en', coalesce(rv2.refvalues ->> '__display_en',rv2.refvalues ->> '__display_default') ) )::node node from diff --git a/src/main/resources/migration/first_roles.sql b/src/main/resources/migration/first_roles.sql index bcaa0b3c09f889a3ce696c9ab441eb108c99253c..cc06c99b9e16e1f0f75b76468f1cf4963064aaf4 100644 --- a/src/main/resources/migration/first_roles.sql +++ b/src/main/resources/migration/first_roles.sql @@ -1,17 +1,42 @@ INSERT INTO public.oresiuser (id, login, password, authorizations, accountstate, email) -VALUES ('35157557-616a-46b8-aee3-487d7450ec23'::uuid,'philippe', '$2a$12$2RXZnc/w9K2rlevPIXUfNeXfTzQGD3GWCWh7Noe8aoFyF2935PRA2', '{.*}', 'active', 'philippe.tcherniatinsky@inrae.fr'), +VALUES + ('5a4dbd41-3fc9-4b3e-b593-a46bc888a7f9'::uuid,'openadom', '$2a$12$eF88cLz.KdQDUvWR7ztaiOeN3fstIAqqrDFHLdem0Kq/we1bmxUM2', '{}', 'active', 'openadom@inrae.fr'), + ('35157557-616a-46b8-aee3-487d7450ec23'::uuid,'philippe', '$2a$12$2RXZnc/w9K2rlevPIXUfNeXfTzQGD3GWCWh7Noe8aoFyF2935PRA2', '{.*}', 'active', 'philippe.tcherniatinsky@inrae.fr'), ('31bd5755-3433-49f1-856e-7e99f3aef5f4'::uuid,'dmaurice', '$2a$12$VLGZZglGbZfpAHK41.TRyOO7DwhGsXU7Ts2rJGPuxb7SDf.aCcGH6', '{.*}', 'active', 'damien.maurice@inrae.fr'), ('3477ed15-15b1-4fee-ad45-6f2a94a3d66f'::uuid,'gmonet', '$2a$12$zyuSWKjmf2ZViwyv7o7P.Ohsdhb73p9.QC067KFXlAkOF0IOsspFq', '{.*}', 'active', 'ghislaine.monet@inrae.fr'), ('73de78e0-c16c-4a55-a176-1a1feb0dd290'::uuid,'lvarloteaux', '$2a$12$hFi9JFLQ24BxT0Ht/NokmuaMTHp5oc7YOrg9TgpwSLjeAQBR2/qMy', '{.*}', 'active', 'lucile.varloteaux@inrae.fr'), ('45b08ce0-f83b-44b5-8d6a-ec55ebf62548'::uuid,'ryahiaoui', '$2a$12$C/CpmXGxN22OJXUqvXY/DuCzA7PUaS6YbVMPYIFOe7iLKs7Go6XoC', '{.*}', 'active', 'rachid.yahiaoui@inra.fr'), ('893dd0f7-a369-4ca2-af3b-21c11719d350'::uuid,'vkoyao', '$2a$12$.nC/NJlNI.eZnyLNN49CXerwwprIk/UHN9mYpQ0172zixwmZGiExS', '{.*}', 'active', 'vivianne.koyao-yayende@inrae.fr'), ('7f7dec88-9c0a-44ed-82fa-3ec0362b9889'::uuid, 'hboukir', '$2a$12$YVqXsLZ5FkD0MnIjskvJduUWO91BnLU7X188TVgOfiEZcFpXSyEXS', '{.*}', 'active', 'hakima.boukir@inrae.fr'), - ('af63dfbd-54eb-4c11-8e3e-b5a00bb27a4f'::uuid,'afioca', '$2a$12$47CBQ4yxhxfvnwJ5gyh9o.4caLTbPTuy.zQUA7Mx/MFgK1aJwArvC', '{.*}', 'active', 'amelie.fiocca@inrae.fr'); -CREATE ROLE "35157557-616a-46b8-aee3-487d7450ec23";COMMENT ON ROLE "35157557-616a-46b8-aee3-487d7450ec23" IS 'Philippe'; GRANT "openAdomAdmin" TO "35157557-616a-46b8-aee3-487d7450ec23" WITH INHERIT TRUE; GRANT "35157557-616a-46b8-aee3-487d7450ec23" TO "openAdomTechUser" WITH INHERIT TRUE; -CREATE ROLE "31bd5755-3433-49f1-856e-7e99f3aef5f4";COMMENT ON ROLE "31bd5755-3433-49f1-856e-7e99f3aef5f4" IS 'Damien'; GRANT "openAdomAdmin" TO "31bd5755-3433-49f1-856e-7e99f3aef5f4" WITH INHERIT TRUE; GRANT "31bd5755-3433-49f1-856e-7e99f3aef5f4" TO "openAdomTechUser" WITH INHERIT TRUE; -CREATE ROLE "3477ed15-15b1-4fee-ad45-6f2a94a3d66f";COMMENT ON ROLE "3477ed15-15b1-4fee-ad45-6f2a94a3d66f" IS 'Ghislaine'; GRANT "openAdomAdmin" TO "3477ed15-15b1-4fee-ad45-6f2a94a3d66f" WITH INHERIT TRUE; GRANT "3477ed15-15b1-4fee-ad45-6f2a94a3d66f" TO "openAdomTechUser" WITH INHERIT TRUE; -CREATE ROLE "73de78e0-c16c-4a55-a176-1a1feb0dd290";COMMENT ON ROLE "73de78e0-c16c-4a55-a176-1a1feb0dd290" IS 'Lucile'; GRANT "openAdomAdmin" TO "73de78e0-c16c-4a55-a176-1a1feb0dd290" WITH INHERIT TRUE; GRANT "73de78e0-c16c-4a55-a176-1a1feb0dd290" TO "openAdomTechUser" WITH INHERIT TRUE; -CREATE ROLE "45b08ce0-f83b-44b5-8d6a-ec55ebf62548";COMMENT ON ROLE "45b08ce0-f83b-44b5-8d6a-ec55ebf62548" IS 'Rachid'; GRANT "openAdomAdmin" TO "45b08ce0-f83b-44b5-8d6a-ec55ebf62548" WITH INHERIT TRUE; GRANT "45b08ce0-f83b-44b5-8d6a-ec55ebf62548" TO "openAdomTechUser" WITH INHERIT TRUE; -CREATE ROLE "893dd0f7-a369-4ca2-af3b-21c11719d350";COMMENT ON ROLE "893dd0f7-a369-4ca2-af3b-21c11719d350" IS 'Viviane'; GRANT "openAdomAdmin" TO "893dd0f7-a369-4ca2-af3b-21c11719d350" WITH INHERIT TRUE; GRANT "893dd0f7-a369-4ca2-af3b-21c11719d350" TO "openAdomTechUser" WITH INHERIT TRUE; -CREATE ROLE "7f7dec88-9c0a-44ed-82fa-3ec0362b9889";COMMENT ON ROLE "7f7dec88-9c0a-44ed-82fa-3ec0362b9889" IS 'Hackima'; GRANT "openAdomAdmin" TO "7f7dec88-9c0a-44ed-82fa-3ec0362b9889" WITH INHERIT TRUE; GRANT "7f7dec88-9c0a-44ed-82fa-3ec0362b9889" TO "openAdomTechUser" WITH INHERIT TRUE; -CREATE ROLE "af63dfbd-54eb-4c11-8e3e-b5a00bb27a4f";COMMENT ON ROLE "af63dfbd-54eb-4c11-8e3e-b5a00bb27a4f" IS 'Amélie'; GRANT "openAdomAdmin" TO "af63dfbd-54eb-4c11-8e3e-b5a00bb27a4f" WITH INHERIT TRUE; GRANT "af63dfbd-54eb-4c11-8e3e-b5a00bb27a4f" TO "openAdomTechUser" WITH INHERIT TRUE; \ No newline at end of file + ('af63dfbd-54eb-4c11-8e3e-b5a00bb27a4f'::uuid,'afioca', '$2a$12$47CBQ4yxhxfvnwJ5gyh9o.4caLTbPTuy.zQUA7Mx/MFgK1aJwArvC', '{.*}', 'active', 'amelie.fiocca@inrae.fr') +ON CONFLICT DO NOTHING; + + + +-- Fonction pour créer un rôle et accorder des privilèges +CREATE OR REPLACE FUNCTION create_role_and_grant(role_id UUID, role_name TEXT) +RETURNS VOID AS $$ +BEGIN + IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = role_id::text) THEN + EXECUTE format('CREATE ROLE "%s"', role_id); +EXECUTE format('COMMENT ON ROLE "%s" IS %L', role_id, role_name); +EXECUTE format('GRANT "openAdomAdmin" TO "%s" WITH INHERIT TRUE', role_id); +EXECUTE format('GRANT "%s" TO "openAdomTechUser" WITH INHERIT TRUE', role_id); +END IF; +END; +$$ +LANGUAGE plpgsql; + +-- Création des rôles et octroi des privilèges +SELECT create_role_and_grant('5a4dbd41-3fc9-4b3e-b593-a46bc888a7f9'::uuid, 'openadom'); +SELECT create_role_and_grant('35157557-616a-46b8-aee3-487d7450ec23'::uuid, 'Philippe'); +SELECT create_role_and_grant('31bd5755-3433-49f1-856e-7e99f3aef5f4'::uuid, 'Damien'); +SELECT create_role_and_grant('3477ed15-15b1-4fee-ad45-6f2a94a3d66f'::uuid, 'Ghislaine'); +SELECT create_role_and_grant('73de78e0-c16c-4a55-a176-1a1feb0dd290'::uuid, 'Lucile'); +SELECT create_role_and_grant('45b08ce0-f83b-44b5-8d6a-ec55ebf62548'::uuid, 'Rachid'); +SELECT create_role_and_grant('893dd0f7-a369-4ca2-af3b-21c11719d350'::uuid, 'Viviane'); +SELECT create_role_and_grant('7f7dec88-9c0a-44ed-82fa-3ec0362b9889'::uuid, 'Hackima'); +SELECT create_role_and_grant('af63dfbd-54eb-4c11-8e3e-b5a00bb27a4f'::uuid, 'Amélie'); + +-- Suppression de la fonction temporaire +DROP FUNCTION create_role_and_grant(UUID, TEXT); \ No newline at end of file diff --git a/src/test/resources/data/acbb/acbb_openAdom_V2.yaml b/src/test/resources/data/acbb/acbb_openAdom_V2.yaml index 9c0f38d67848b55854bbb4ed6d9651bc261c9cfd..c65ada511b0a2da36fe7709fde689f2d403644b6 100644 --- a/src/test/resources/data/acbb/acbb_openAdom_V2.yaml +++ b/src/test/resources/data/acbb/acbb_openAdom_V2.yaml @@ -10,7 +10,7 @@ OA_application: en: "Agroecosystems, Biogeochemical Cycles and Biodiversity" OA_comment: "L'application ACBB V2" OA_name: acbb_openadom_v2 - OA_version: 1.0.2 + OA_version: 1.0.4 OA_data: tr_agroecosystemes_agr: OA_i18n: @@ -20,6 +20,10 @@ OA_data: OA_description: fr: Les agroécosystèmes représentent des regroupements par type de traitement en: Agroecosystems represent groupings by type of treatment + OA_i18nDisplayPattern: #mandatory + OA_title: #optional + fr: "{agr_agroecosystem_fr}" + en: "{agr_agroecosystem_en}" OA_naturalKey: [agr_agroecosystem_key] OA_basicComponents: agr_agroecosystem_key: @@ -62,6 +66,10 @@ OA_data: OA_description: fr: sites d'etudes en: study sites + OA_i18nDisplayPattern: #mandatory + OA_title: #optional + fr: "{sit_site_fr}" + en: "{sit_site_en}" OA_naturalKey: [sit_site_key] OA_validations: sit_checkDateMiseEnService: @@ -384,6 +392,13 @@ OA_data: OA_description: fr: les sites sont divisés en parcelles sur lesquelles on applique un traitement. Il peut y avoir des blocs de répétitions de parcelles en: Sites are divided into plots on which a treatment is applied. There may be blocks of plot repetitions + OA_i18nDisplayPattern: #mandatory + OA_title: #optional + fr: "{par_parcelle_fr}" + en: "{par_parcelle_en}" + OA_description: #optional + fr: "{par_commentaire_fr}" + en: "{par_commentaire_en}" OA_basicComponents: sit_site: OA_exportHeader: @@ -695,7 +710,35 @@ OA_data: } OA_components: #optional - flx_fc_gf_value #optional - + OA_submission: #optional + OA_strategy: OA_VERSIONING #optional + OA_submissionScope: #mandatory + OA_referenceScopes: #optional + - #optional + OA_component: sit_key #mandatory + OA_reference: tr_sites_sit #optional + OA_i18n: #mandatory + OA_title: #optional + fr: Site + en: Site + OA_description: #optional + fr: Référentiel des Sites + en: Site repository + OA_exportHeader: #mandatory + OA_title: #optional + fr: Site + en: Site + OA_description: #optional + fr: Référentiel des Sites + en: Site repository + OA_timeScope: #optional + OA_component: flx_date #mandatory + OA_fileName: #optional + OA_filePattern: (.*)_(.*)_(.*).csv #mandatory + OA_matchPatternScopes: #optional + - sit_key #optional + - __START_DATE__ #optional + - __END_DATE__ #optional OA_computedComponents: flx_date: OA_exportHeader: