Skip to content
Snippets Groups Projects
Commit 3e7623d8 authored by OZGCloud's avatar OZGCloud
Browse files

Merge branch 'master' of git.ozg-sh.de:mgm/pluto

parents 2d21c501 53b0da88
No related branches found
No related tags found
No related merge requests found
...@@ -54,7 +54,7 @@ public class VorgangAttachedItem { ...@@ -54,7 +54,7 @@ public class VorgangAttachedItem {
static final String FIELDNAME_VORGANG_ID = "vorgangId"; static final String FIELDNAME_VORGANG_ID = "vorgangId";
static final String FIELDNAME_ITEM_NAME = "itemName"; static final String FIELDNAME_ITEM_NAME = "itemName";
static final String FIELDNAME_ITEM = "item"; static final String FIELDNAME_ITEM = "item";
static final String FIELDNAME_IS_DELETED = "deleted"; public static final String FIELDNAME_IS_DELETED = "deleted";
@Id @Id
private String id; private String id;
......
...@@ -25,6 +25,8 @@ package de.itvsh.ozg.pluto.common.security; ...@@ -25,6 +25,8 @@ package de.itvsh.ozg.pluto.common.security;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.Optional;
import org.bson.Document; import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -36,6 +38,8 @@ import org.springframework.stereotype.Repository; ...@@ -36,6 +38,8 @@ import org.springframework.stereotype.Repository;
import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItem; import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItem;
import de.itvsh.ozg.pluto.command.Command; import de.itvsh.ozg.pluto.command.Command;
import de.itvsh.ozg.pluto.common.db.CriteriaUtil;
import de.itvsh.ozg.pluto.common.errorhandling.NotFoundException;
import de.itvsh.ozg.pluto.vorgang.Vorgang; import de.itvsh.ozg.pluto.vorgang.Vorgang;
@Repository @Repository
...@@ -51,51 +55,75 @@ class PolicyRepository { ...@@ -51,51 +55,75 @@ class PolicyRepository {
private static final AggregationOperation ADD_VORGANG_FROM_FILE = context -> org.bson.Document.parse(VORANG_ID_FROM_FILE_AS_OBJECT_ID_FIELD); private static final AggregationOperation ADD_VORGANG_FROM_FILE = context -> org.bson.Document.parse(VORANG_ID_FROM_FILE_AS_OBJECT_ID_FIELD);
public static final String FIELD_ORGANISATIONSEINHEIT_ID = "organisationseinheitenId";
public static final String FIELD_VORGANG = "vorgang";
public static final String FIELD_VORGANG_ORGANISATIONSEINHEIT = FIELD_VORGANG + "." + Vorgang.FIELD_ORGANISATIONSEINHEIT;
@Autowired @Autowired
private MongoTemplate template; private MongoTemplate template;
public boolean existsByCommandId(String commandId, Collection<String> organisationEinheitenIds) { public boolean existsByCommandId(String commandId, Collection<String> organisationEinheitenIds) {
return evaluateAggregation(buildAggregation(commandId, organisationEinheitenIds, ADD_VORGANG_OBJECT_ID_FIELD), Command.class); var document = executeAggregation(buildAggregation(matchId(commandId), ADD_VORGANG_OBJECT_ID_FIELD), Command.class).orElseThrow(
() -> new NotFoundException(Command.class, commandId));
return evaluateOrganisationseinheitId(document, organisationEinheitenIds);
}
public boolean existsByFileId(String fileId, Collection<String> organisationEinheitenIds) {
var resultDocument = executeAggregation(buildAggregation(matchId(fileId), ADD_VORGANG_FROM_FILE), "fs.files");
return resultDocument.map(document -> evaluateOrganisationseinheitId(document, organisationEinheitenIds)).orElse(false);
}
private AggregationOperation matchId(String id) {
return Aggregation.match(new Criteria(Vorgang.MONGODB_FIELDNAME_ID).is(id));
} }
public boolean existsByVorgangAttachedItem(String vorgangAttachedItemId, Collection<String> organisationEinheitenIds) { public boolean existsByVorgangAttachedItem(String vorgangAttachedItemId, Collection<String> organisationEinheitenIds) {
return evaluateAggregation(buildAggregation(vorgangAttachedItemId, organisationEinheitenIds, ADD_VORGANG_OBJECT_ID_FIELD), var result = executeAggregation(buildAggregation(matchVorgangAttachedItemId(vorgangAttachedItemId), ADD_VORGANG_OBJECT_ID_FIELD),
VorgangAttachedItem.class); VorgangAttachedItem.class).orElseThrow(() -> new NotFoundException(VorgangAttachedItem.class, vorgangAttachedItemId));
return evaluateOrganisationseinheitId(result, organisationEinheitenIds);
} }
public boolean existsByFileId(String fileId, Collection<String> organisationEinheitenIds) { private AggregationOperation matchVorgangAttachedItemId(String id) {
return evaluateAggregation(buildAggregation(fileId, organisationEinheitenIds, ADD_VORGANG_FROM_FILE), Document.class, "fs.files"); return Aggregation.match(CriteriaUtil.isId(id).and(VorgangAttachedItem.FIELDNAME_IS_DELETED).is(false));
} }
private Aggregation buildAggregation(String objectId, Collection<String> organisationEinheitenIds, AggregationOperation operation) { private Aggregation buildAggregation(AggregationOperation idAggregation, AggregationOperation operation) {
return Aggregation.newAggregation(Arrays.asList( return Aggregation.newAggregation(Arrays.asList(
matchId(objectId), idAggregation,
operation, operation,
lookupVorgang(), lookupVorgang(),
matchOrganisationEinheitenId(organisationEinheitenIds))); Aggregation.project().and(FIELD_VORGANG_ORGANISATIONSEINHEIT).as(FIELD_ORGANISATIONSEINHEIT_ID)
));
} }
private boolean evaluateAggregation(Aggregation aggregation, Class<?> givenCollectionClass) { private AggregationOperation lookupVorgang() {
var foundResult = template.aggregate(aggregation, givenCollectionClass, givenCollectionClass).getMappedResults(); return Aggregation.lookup(Vorgang.COLLECTION_NAME, "vorgangObjecId", "_id", FIELD_VORGANG);
return !foundResult.isEmpty();
} }
private boolean evaluateAggregation(Aggregation aggregation, Class<?> givenCollectionClass, String collectionName) { private Optional<Document> executeAggregation(Aggregation aggregation, Class<?> inputType) {
var foundResult = template.aggregate(aggregation, collectionName, givenCollectionClass).getMappedResults(); var results = template.aggregate(aggregation, inputType, Document.class).getRawResults();
return getResult(results);
return !foundResult.isEmpty();
} }
private AggregationOperation matchId(String id) { private Optional<Document> executeAggregation(Aggregation aggregation, String collectionName) {
return Aggregation.match(new Criteria(Vorgang.MONGODB_FIELDNAME_ID).is(id)); var results = template.aggregate(aggregation, collectionName, Document.class).getRawResults();
return getResult(results);
} }
private AggregationOperation lookupVorgang() { Optional<Document> getResult(Document aggregationResult) {
return Aggregation.lookup(Vorgang.COLLECTION_NAME, "vorgangObjecId", "_id", "vorgang"); return aggregationResult.getList("results", Document.class).stream().findFirst();
} }
private AggregationOperation matchOrganisationEinheitenId(Collection<String> organisationEinheitenIds) { boolean evaluateOrganisationseinheitId(Document result, Collection<String> organisationEinheitenIds) {
return Aggregation.match(Criteria.where("vorgang." + Vorgang.FIELD_ORGANISATIONSEINHEIT).in(organisationEinheitenIds)); var nestedList = result.getList(FIELD_ORGANISATIONSEINHEIT_ID, Object.class);
if (nestedList.isEmpty()) {
return false;
}
var organisationseinheitenId = nestedList.get(0);
if (organisationseinheitenId instanceof List<?> orgaIdList) {
return orgaIdList.stream().map(String::valueOf).anyMatch(organisationEinheitenIds::contains);
} }
return organisationEinheitenIds.contains(String.valueOf(organisationseinheitenId));
}
} }
\ No newline at end of file
...@@ -81,7 +81,7 @@ public class PolicyService { ...@@ -81,7 +81,7 @@ public class PolicyService {
} }
public void checkPermissionByVorgangAttachedItem(String vorgangAttachedItemId) { public void checkPermissionByVorgangAttachedItem(String vorgangAttachedItemId) {
evaluatePermissions(List.of(hasOrganisationEinheitenIdByVorgangAttachedItem(vorgangAttachedItemId)).stream(), VorgangAttachedItem.class, evaluatePermissions(Stream.of(hasOrganisationEinheitenIdByVorgangAttachedItem(vorgangAttachedItemId)), VorgangAttachedItem.class,
vorgangAttachedItemId); vorgangAttachedItemId);
} }
......
...@@ -27,6 +27,7 @@ import static org.assertj.core.api.Assertions.*; ...@@ -27,6 +27,7 @@ import static org.assertj.core.api.Assertions.*;
import java.util.List; import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
...@@ -39,6 +40,7 @@ import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItem; ...@@ -39,6 +40,7 @@ import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItem;
import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItemTestFactory; import de.itvsh.ozg.pluto.attached_item.VorgangAttachedItemTestFactory;
import de.itvsh.ozg.pluto.command.Command; import de.itvsh.ozg.pluto.command.Command;
import de.itvsh.ozg.pluto.command.CommandTestFactory; import de.itvsh.ozg.pluto.command.CommandTestFactory;
import de.itvsh.ozg.pluto.common.errorhandling.NotFoundException;
import de.itvsh.ozg.pluto.files.GridFsTestFactory; import de.itvsh.ozg.pluto.files.GridFsTestFactory;
import de.itvsh.ozg.pluto.vorgang.Vorgang; import de.itvsh.ozg.pluto.vorgang.Vorgang;
import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory; import de.itvsh.ozg.pluto.vorgang.VorgangTestFactory;
...@@ -124,6 +126,19 @@ class PolicyRepositoryITCase { ...@@ -124,6 +126,19 @@ class PolicyRepositoryITCase {
assertThat(result).isFalse(); assertThat(result).isFalse();
} }
@Test
void shouldThrowNotFoundIfDeleted() {
var vorgangAttachedItem = mongoOperations.save(
VorgangAttachedItemTestFactory.createBuilder().id(null).deleted(true).version(0).build());
var id = vorgangAttachedItem.getId();
Assertions.assertThrows(NotFoundException.class, () -> existsByVorgangAttachedItem(id));
}
private void existsByVorgangAttachedItem(String vorgangAttachedItemId) {
repository.existsByVorgangAttachedItem(vorgangAttachedItemId, List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID));
}
} }
@DisplayName("by file id") @DisplayName("by file id")
......
/*
* Copyright (C) 2023 Das Land Schleswig-Holstein vertreten durch den
* Ministerpräsidenten des Landes Schleswig-Holstein
* Staatskanzlei
* Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
*
* Lizenziert unter der EUPL, Version 1.2 oder - sobald
* diese von der Europäischen Kommission genehmigt wurden -
* Folgeversionen der EUPL ("Lizenz");
* Sie dürfen dieses Werk ausschließlich gemäß
* dieser Lizenz nutzen.
* Eine Kopie der Lizenz finden Sie hier:
*
* https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
*
* Sofern nicht durch anwendbare Rechtsvorschriften
* gefordert oder in schriftlicher Form vereinbart, wird
* die unter der Lizenz verbreitete Software "so wie sie
* ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
* ausdrücklich oder stillschweigend - verbreitet.
* Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen.
*/
package de.itvsh.ozg.pluto.common.security;
import static org.assertj.core.api.Assertions.*;
import java.util.List;
import org.bson.Document;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.data.mongodb.core.MongoTemplate;
import de.itvsh.ozg.pluto.vorgang.ZustaendigeStelleTestFactory;
class PolicyRepositoryTest {
@InjectMocks
private PolicyRepository repository;
@Mock
private MongoTemplate mongoTemplate;
@Nested
class TestEvaluateOrganisationseinheitId {
@Nested
class TestMatch {
@Test
void shouldEvaluateVorgang() {
var document = new Document(PolicyRepository.FIELD_ORGANISATIONSEINHEIT_ID,
List.of(List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID)));
var result = repository.evaluateOrganisationseinheitId(document, List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID));
assertThat(result).isTrue();
}
@Test
void shouldEvaluateVorgangStub() {
var document = new Document(PolicyRepository.FIELD_ORGANISATIONSEINHEIT_ID,
List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID));
var result = repository.evaluateOrganisationseinheitId(document, List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID));
assertThat(result).isTrue();
}
}
@Test
void shouldReturnFalseIfNoMatch() {
var document = new Document(PolicyRepository.FIELD_ORGANISATIONSEINHEIT_ID,
List.of(List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID)));
var result = repository.evaluateOrganisationseinheitId(document, List.of("otherId"));
assertThat(result).isFalse();
}
@Test
void shouldReturnFalseIfEmpty() {
var document = new Document(PolicyRepository.FIELD_ORGANISATIONSEINHEIT_ID, List.of());
var result = repository.evaluateOrganisationseinheitId(document, List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID));
assertThat(result).isFalse();
}
@Test
void shouldReturnFalseIfNestedEmpty() {
var document = new Document(PolicyRepository.FIELD_ORGANISATIONSEINHEIT_ID, List.of(List.of()));
var result = repository.evaluateOrganisationseinheitId(document, List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID));
assertThat(result).isFalse();
}
}
}
\ No newline at end of file
...@@ -160,7 +160,7 @@ class PolicyServiceTest { ...@@ -160,7 +160,7 @@ class PolicyServiceTest {
} }
@Test @Test
void shouldThrowAccessDeniedExceptionOnAllNonMatch() { void shouldThrowNotFoundException() {
when(repository.existsByVorgangAttachedItem(any(), any())).thenReturn(false); when(repository.existsByVorgangAttachedItem(any(), any())).thenReturn(false);
assertThrows(AccessDeniedException.class, () -> service.checkPermissionByVorgangAttachedItem(VorgangAttachedItemTestFactory.ID)); assertThrows(AccessDeniedException.class, () -> service.checkPermissionByVorgangAttachedItem(VorgangAttachedItemTestFactory.ID));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment