From 82bf122cdb723f926b81795a5b8651cfd77d7f29 Mon Sep 17 00:00:00 2001 From: alainbodiguel Date: Thu, 14 Dec 2023 21:44:14 +0100 Subject: [PATCH] Allow access to no org resources to logged-in users --- ...GoogleFirestorePersistenceServiceImpl.java | 40 ++++++++++++++++++- .../impl/HibernatePersistenceServiceImpl.java | 25 +++++++++++- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/arlas-persistence-core/src/main/java/io/arlas/persistence/server/impl/GoogleFirestorePersistenceServiceImpl.java b/arlas-persistence-core/src/main/java/io/arlas/persistence/server/impl/GoogleFirestorePersistenceServiceImpl.java index 00b34b1..267dc94 100644 --- a/arlas-persistence-core/src/main/java/io/arlas/persistence/server/impl/GoogleFirestorePersistenceServiceImpl.java +++ b/arlas-persistence-core/src/main/java/io/arlas/persistence/server/impl/GoogleFirestorePersistenceServiceImpl.java @@ -234,7 +234,7 @@ public Pair> list(String zone, IdentityParam identityParam, Int @Override public Data get(String zone, String key, IdentityParam identityParam) throws ArlasException { - Optional data = getByZoneKeyOrga(zone, key, identityParam.organisation); + Optional data = getByZoneKeyOrga(zone, key, identityParam); if (data.isPresent()) { if (PersistenceService.isReaderOnData(identityParam, data.get()) || PersistenceService.isWriterOnData(identityParam, data.get())) { @@ -298,7 +298,7 @@ public Data update(String id, String key, IdentityParam identityParam, Set alreadyExisting = getByZoneKeyOrga(zone, key, List.of(data.getDocOrganization())); if (alreadyExisting.isPresent()) { throw new ArlasException("A resource with zone " + zone + " and key " + key + " already exists."); @@ -373,6 +373,42 @@ private Optional getByZoneKeyOrga(String zone, String key, List or } } + private Optional getByZoneKeyOrga(String zone, String key, IdentityParam idp) throws ArlasException { + + try { + // get the data matching zone+key whatever the organisation + List res = db.collection(this.collection) + .whereEqualTo(Data.zoneColumn, zone) + .whereEqualTo(Data.keyColumn, key) + .get().get() + .getDocuments() + .stream() + .map(d -> { + try { + return toData(d.getId(), d); + } catch (NotFoundException e) { //can't happen in this case + return null; + } + }) + .filter(Objects::nonNull) + // if the data's organisation is the org of the user + .filter(d -> idp.organisation.contains(d.getDocOrganization()) + // or the user is anonymous (we don't have an organisation to match with) + || idp.isAnonymous) + .toList(); + + if (res.isEmpty()) { + return Optional.empty(); + } else if (res.size() == 1) { + return Optional.of(res.get(0)); + } else { + throw new ArlasException("More than one doc for key/zone: need one org to filter properly"); + } + } catch (InterruptedException | ExecutionException e) { + throw new ArlasException("Error listing document: " + e.getMessage()); + } + } + private Data getById(String id) throws ArlasException { try { return toData(id, db.collection(collection).document(id).get().get()); diff --git a/arlas-persistence-core/src/main/java/io/arlas/persistence/server/impl/HibernatePersistenceServiceImpl.java b/arlas-persistence-core/src/main/java/io/arlas/persistence/server/impl/HibernatePersistenceServiceImpl.java index 07dd5db..c33a86e 100644 --- a/arlas-persistence-core/src/main/java/io/arlas/persistence/server/impl/HibernatePersistenceServiceImpl.java +++ b/arlas-persistence-core/src/main/java/io/arlas/persistence/server/impl/HibernatePersistenceServiceImpl.java @@ -79,7 +79,7 @@ public Pair list(String zone, IdentityParam identityParam, Integer size, Integer @Override public Data get(String zone, String key, IdentityParam identityParam) throws ArlasException { - Optional data = getByZoneKeyOrga(zone, key, identityParam.organisation); + Optional data = getByZoneKeyOrga(zone, key, identityParam); if (data.isPresent()) { if (PersistenceService.isReaderOnData(identityParam, data.get()) || PersistenceService.isWriterOnData(identityParam, data.get())) { @@ -192,6 +192,29 @@ private Optional getByZoneKeyOrga(String zone, String key, List or return Optional.ofNullable(data); } + private Optional getByZoneKeyOrga(String zone, String key, IdentityParam idp) throws ArlasException { + List res = currentSession().createQuery("from Data ud" + + " where ud." + Data.zoneColumn + "=:zone" + + " and ud." + Data.keyColumn + "=:key", Data.class) + .setParameter("zone", zone) + .setParameter("key", key) + .list() + .stream() + // if the data's organisation is the org of the user + .filter(d -> idp.organisation.contains(d.getDocOrganization()) + // or the user is anonymous (we don't have an organisation to match with) + || idp.isAnonymous) + .toList(); + + if (res.isEmpty()) { + return Optional.empty(); + } else if (res.size() == 1) { + return Optional.of(res.get(0)); + } else { + throw new ArlasException("More than one doc for key/zone: need one org to filter properly"); + } + } + private Data deleteData(Data data, IdentityParam identityParam) throws ForbiddenException { if (PersistenceService.isWriterOnData(identityParam, data)) { currentSession().delete(data);