diff --git a/search-commons/src/main/java/no/unit/nva/search/common/QueryFilter.java b/search-commons/src/main/java/no/unit/nva/search/common/QueryFilter.java index 2a04c9a53..7797d4441 100644 --- a/search-commons/src/main/java/no/unit/nva/search/common/QueryFilter.java +++ b/search-commons/src/main/java/no/unit/nva/search/common/QueryFilter.java @@ -17,6 +17,9 @@ * @author Stig Norland */ public class QueryFilter { + private static final String SUFFIX = "]"; + private static final String PREFIX = "["; + private final transient Map filters = new HashMap<>(); public QueryFilter() {} @@ -27,6 +30,11 @@ public BoolQueryBuilder get() { return boolQueryBuilder; } + /** + * Clears filter and sets new filters. + * + * @param filters QueryBuilder + */ public void set(QueryBuilder... filters) { this.filters.clear(); Arrays.stream(filters).forEach(this::add); @@ -44,6 +52,6 @@ public void add(QueryBuilder builder) { public String toString() { return filters.values().stream() .map(QueryBuilder::toString) - .collect(Collectors.joining(COMMA)); + .collect(Collectors.joining(COMMA, PREFIX, SUFFIX)); } } diff --git a/search-commons/src/main/java/no/unit/nva/search/resource/ResourceAccessFilter.java b/search-commons/src/main/java/no/unit/nva/search/resource/ResourceAccessFilter.java index 7101d9501..ae7da7cdf 100644 --- a/search-commons/src/main/java/no/unit/nva/search/resource/ResourceAccessFilter.java +++ b/search-commons/src/main/java/no/unit/nva/search/resource/ResourceAccessFilter.java @@ -28,10 +28,11 @@ import java.util.Arrays; /** - * FilterBuilder for ResourceSearchQuery. + * ResourceAccessFilter is a class that filters tickets based on access rights. * * @author Stig Norland * @author Sondre Vestad + * @author Lars-Olav Vågene * @see DefaultRoleSource * Definitions of roles diff --git a/search-commons/src/main/java/no/unit/nva/search/ticket/Constants.java b/search-commons/src/main/java/no/unit/nva/search/ticket/Constants.java index f46ceed3a..066d96d7b 100644 --- a/search-commons/src/main/java/no/unit/nva/search/ticket/Constants.java +++ b/search-commons/src/main/java/no/unit/nva/search/ticket/Constants.java @@ -1,5 +1,6 @@ package no.unit.nva.search.ticket; +import static no.unit.nva.constants.Words.ASTERISK; import static no.unit.nva.constants.Words.CUSTOMER_ID; import static no.unit.nva.constants.Words.DOT; import static no.unit.nva.constants.Words.FIRST_NAME; @@ -12,7 +13,6 @@ import static no.unit.nva.constants.Words.MODIFIED_DATE; import static no.unit.nva.constants.Words.ORGANIZATION; import static no.unit.nva.constants.Words.OWNER; -import static no.unit.nva.constants.Words.PART_OF; import static no.unit.nva.constants.Words.PIPE; import static no.unit.nva.constants.Words.PUBLICATION; import static no.unit.nva.constants.Words.PUBLICATION_INSTANCE; @@ -47,24 +47,8 @@ public final class Constants { public static final String ORGANIZATION_ID_KEYWORD = ORGANIZATION + DOT + ID_KEYWORD; public static final String ORGANIZATION_IDENTIFIER_KEYWORD = ORGANIZATION + DOT + IDENTIFIER + DOT + KEYWORD; - public static final String ORGANIZATION_PART_OF = - ORGANIZATION - + DOT - + PART_OF - + DOT - + ID - + PIPE - + ORGANIZATION - + DOT - + PART_OF - + DOT - + IDENTIFIER; - public static final String ORGANIZATION_PATHS = - ORGANIZATION_ID_KEYWORD - + PIPE - + ORGANIZATION_IDENTIFIER_KEYWORD - + PIPE - + ORGANIZATION_PART_OF; + + public static final String ORGANIZATION_PATHS = ORGANIZATION + DOT + ASTERISK; public static final String OWNER_KEYWORD = OWNER + DOT + KEYWORD; public static final String PUBLICATION_ID_OR_IDENTIFIER_KEYWORD = PUBLICATION diff --git a/search-commons/src/main/java/no/unit/nva/search/ticket/TicketAccessFilter.java b/search-commons/src/main/java/no/unit/nva/search/ticket/TicketAccessFilter.java new file mode 100644 index 000000000..9e98785ac --- /dev/null +++ b/search-commons/src/main/java/no/unit/nva/search/ticket/TicketAccessFilter.java @@ -0,0 +1,276 @@ +package no.unit.nva.search.ticket; + +import static no.unit.nva.search.ticket.Constants.OWNER_USERNAME; +import static no.unit.nva.search.ticket.Constants.TYPE_KEYWORD; +import static no.unit.nva.search.ticket.TicketParameter.ORGANIZATION_ID; +import static no.unit.nva.search.ticket.TicketParameter.OWNER; +import static no.unit.nva.search.ticket.TicketParameter.STATISTICS; +import static no.unit.nva.search.ticket.TicketType.UNPUBLISH_REQUEST; + +import static nva.commons.apigateway.AccessRight.MANAGE_CUSTOMERS; +import static nva.commons.apigateway.AccessRight.MANAGE_DOI; +import static nva.commons.apigateway.AccessRight.MANAGE_PUBLISHING_REQUESTS; + +import static org.opensearch.index.query.QueryBuilders.boolQuery; +import static org.opensearch.index.query.QueryBuilders.termsQuery; + +import static java.util.Objects.nonNull; + +import no.unit.nva.search.common.builder.AcrossFieldsQuery; +import no.unit.nva.search.common.records.FilterBuilder; + +import nva.commons.apigateway.AccessRight; +import nva.commons.apigateway.RequestInfo; +import nva.commons.apigateway.exceptions.UnauthorizedException; + +import org.opensearch.index.query.BoolQueryBuilder; +import org.opensearch.index.query.DisMaxQueryBuilder; +import org.opensearch.index.query.QueryBuilder; +import org.opensearch.index.query.QueryBuilders; +import org.opensearch.index.query.TermQueryBuilder; +import org.opensearch.index.query.TermsQueryBuilder; + +import java.net.URI; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * TicketAccessFilter is a class that filters tickets based on access rights. + * + * + * + * @author Stig Norland + * @author Sondre Vestad + * @author Lars-Olav Vågene + * @author Kir Truhacev + */ +public class TicketAccessFilter implements FilterBuilder { + + private static final String NOT_ANY_OF_TICKET_TYPE = "notAnyOfTicketType"; + private static final String ANY_OF_TICKET_TYPE_OR_USER_NAME = "anyOfTicketTypeOrUserName"; + private static final String USER_HAS_NO_ACCESS_TO_SEARCH_FOR_ANY_TICKET_TYPES = + "User has no access to search for any ticket types!"; + private static final String USER_IS_NOT_ALLOWED_TO_SEARCH_FOR_TICKETS_NOT_OWNED_BY_THEMSELVES = + "User is not allowed to search for tickets not owned by themselves"; + + private final TicketSearchQuery ticketSearchQuery; + private String currentUser; + private Set allowedTicketTypes; + private Set excludeTicketTypes; + private URI organizationId; + + public TicketAccessFilter(TicketSearchQuery ticketSearchQuery) { + this.ticketSearchQuery = ticketSearchQuery; + this.ticketSearchQuery.filters().set(); + } + + /** + * Authorize and set 'ViewScope'. + * + *

Authorize and set filters -> ticketTypes, organization and owner + * + *

This is to avoid the Query to return documents that are not available for the user. + * + * @param requestInfo all required is here + * @return TicketQuery (builder pattern) + */ + @Override + public TicketSearchQuery fromRequestInfo(RequestInfo requestInfo) throws UnauthorizedException { + currentUser = requestInfo.getUserName(); + + final var organization = + requestInfo.getTopLevelOrgCristinId().orElse(requestInfo.getPersonAffiliation()); + + final var ticketTypes = applyBusinessRules(requestInfo.getAccessRights()); + + return organization(organization) + .includedTypes(ticketTypes) + .excludeTypes(UNPUBLISH_REQUEST) + .apply(); + } + + @Override + public TicketSearchQuery apply() { + if (nonNull(organizationId)) { + this.ticketSearchQuery.filters().add(getOrgFilter()); + } + + if (nonNull(currentUser) && nonNull(allowedTicketTypes)) { + this.ticketSearchQuery.filters().add(getTicketTypeUserNameFilter()); + } + + if (nonNull(excludeTicketTypes) || nonNull(allowedTicketTypes)) { + this.ticketSearchQuery.filters().add(getExcludedFilter()); + } + + return ticketSearchQuery; + } + + /** + * Filter on owner (user). + * + * @param userName current user + * @return TicketQuery (builder pattern) + * @apiNote ONLY SET THIS MANUALLY IN TESTS + */ + public TicketAccessFilter user(String userName) { + this.currentUser = userName; + return this; + } + + /** + * Filter on ticket types. + * + * @param ticketTypes ticket types available for the user + * @return TicketQuery (builder pattern) + * @apiNote ONLY SET THIS MANUALLY IN TESTS + */ + public TicketAccessFilter includedTypes(TicketType... ticketTypes) { + return includedTypes(listToEnumSet(ticketTypes)); + } + + /** + * Exclude these ticket types. + * + * @param ticketTypes ticket types to exclude + * @return TicketQuery (builder pattern) + * @apiNote ONLY SET THIS MANUALLY IN TESTS + */ + public TicketAccessFilter excludeTypes(TicketType... ticketTypes) { + return excludeTypes(listToEnumSet(ticketTypes)); + } + + /** + * Filter on organization. + * + * @param organization organization id + * @return TicketQuery (builder pattern) + * @apiNote ONLY SET THIS MANUALLY IN TESTS + */ + public TicketAccessFilter organization(URI organization) { + this.organizationId = organization; + return this; + } + + public String getCurrentUser() { + return currentUser; + } + + protected DisMaxQueryBuilder getTicketTypeUserNameFilter() { + return QueryBuilders.disMaxQuery() + .add(new TermQueryBuilder(OWNER_USERNAME, currentUser)) + .add(new TermsQueryBuilder(TYPE_KEYWORD, allowedTicketTypes)) + .queryName(ANY_OF_TICKET_TYPE_OR_USER_NAME); + } + + protected QueryBuilder getOrgFilter() { + return new AcrossFieldsQuery() + .buildQuery(ORGANIZATION_ID, organizationId.toString()) + .findFirst() + .orElseThrow() + .getValue() + .queryName(ORGANIZATION_ID.asCamelCase()); + } + + protected BoolQueryBuilder getExcludedFilter() { + var excludedSet = + nonNull(excludeTicketTypes) + ? excludeTicketTypes + : Arrays.stream(TicketType.values()) + .filter(f -> !allowedTicketTypes.contains(f)) + .collect( + Collectors.toCollection( + () -> EnumSet.noneOf(TicketType.class))); + return boolQuery() + .mustNot(termsQuery(TYPE_KEYWORD, excludedSet)) + .queryName(NOT_ANY_OF_TICKET_TYPE); + } + + private TicketAccessFilter includedTypes(Set ticketTypes) { + this.allowedTicketTypes = ticketTypes; + return this; + } + + private TicketAccessFilter excludeTypes(Set ticketTypes) { + this.excludeTicketTypes = ticketTypes; + return this; + } + + /** + * Apply business rules to determine which ticket types are allowed. + * + *

    + * Business Rules. + *
  • manage_doi -> DOI_REQUEST + *
  • support -> GENERAL_SUPPORT_CASE + *
  • manage_publishing_requests -> PUBLISHING_REQUEST + *
  • manage_customers -> DOI_REQUEST, GENERAL_SUPPORT_CASE, PUBLISHING_REQUEST + *
  • is_owner -> DOI_REQUEST, GENERAL_SUPPORT_CASE, PUBLISHING_REQUEST + *
+ */ + private Set applyBusinessRules(List accessRights) + throws UnauthorizedException { + + var isOwner = searchAsTicketOwner() && validateOwner(currentUser); + var isCustomManager = searchAsCustomManager() && validateCustomManager(accessRights); + + var allowed = EnumSet.noneOf(TicketType.class); + if (accessRights.contains(MANAGE_DOI) || isOwner || isCustomManager) { + allowed.add(TicketType.DOI_REQUEST); + } + if (accessRights.contains(AccessRight.SUPPORT) || isOwner || isCustomManager) { + allowed.add(TicketType.GENERAL_SUPPORT_CASE); + } + if (accessRights.contains(MANAGE_PUBLISHING_REQUESTS) || isOwner || isCustomManager) { + allowed.add(TicketType.PUBLISHING_REQUEST); + } + if (allowed.isEmpty()) { + throw new UnauthorizedException(USER_HAS_NO_ACCESS_TO_SEARCH_FOR_ANY_TICKET_TYPES); + } + return allowed; + } + + private Set listToEnumSet(TicketType... ticketTypes) { + return Arrays.stream(ticketTypes) + .collect(Collectors.toCollection(() -> EnumSet.noneOf(TicketType.class))); + } + + private boolean validateCustomManager(List accessRights) + throws UnauthorizedException { + if (!accessRights.contains(MANAGE_CUSTOMERS)) { + throw new UnauthorizedException( + USER_IS_NOT_ALLOWED_TO_SEARCH_FOR_TICKETS_NOT_OWNED_BY_THEMSELVES); + } + return true; + } + + private boolean validateOwner(String userName) throws UnauthorizedException { + if (currentUserIsNotOwner(userName)) { + throw new UnauthorizedException( + USER_IS_NOT_ALLOWED_TO_SEARCH_FOR_TICKETS_NOT_OWNED_BY_THEMSELVES); + } + return true; + } + + private boolean currentUserIsNotOwner(String userName) { + return !userName.equalsIgnoreCase(ticketSearchQuery.parameters().get(OWNER).as()); + } + + private boolean searchAsTicketOwner() { + return ticketSearchQuery.parameters().isPresent(OWNER); + } + + private boolean searchAsCustomManager() { + return ticketSearchQuery.parameters().isPresent(STATISTICS); + } +} diff --git a/search-commons/src/main/java/no/unit/nva/search/ticket/TicketFilter.java b/search-commons/src/main/java/no/unit/nva/search/ticket/TicketFilter.java deleted file mode 100644 index c47fd422d..000000000 --- a/search-commons/src/main/java/no/unit/nva/search/ticket/TicketFilter.java +++ /dev/null @@ -1,192 +0,0 @@ -package no.unit.nva.search.ticket; - -import static no.unit.nva.constants.Words.POST_FILTER; -import static no.unit.nva.search.ticket.Constants.OWNER_USERNAME; -import static no.unit.nva.search.ticket.Constants.TYPE_KEYWORD; -import static no.unit.nva.search.ticket.TicketParameter.ORGANIZATION_ID; -import static no.unit.nva.search.ticket.TicketParameter.OWNER; -import static no.unit.nva.search.ticket.TicketParameter.STATISTICS; - -import static nva.commons.apigateway.AccessRight.MANAGE_DOI; -import static nva.commons.apigateway.AccessRight.MANAGE_PUBLISHING_REQUESTS; - -import no.unit.nva.search.common.builder.KeywordQuery; -import no.unit.nva.search.common.records.FilterBuilder; - -import nva.commons.apigateway.AccessRight; -import nva.commons.apigateway.RequestInfo; -import nva.commons.apigateway.exceptions.UnauthorizedException; - -import org.opensearch.index.query.QueryBuilders; -import org.opensearch.index.query.TermQueryBuilder; -import org.opensearch.index.query.TermsQueryBuilder; - -import java.net.URI; -import java.util.Arrays; -import java.util.EnumSet; -import java.util.List; -import java.util.Objects; -import java.util.Set; - -/** - * TicketFilter is a class that filters tickets. - * - * @author Stig Norland - */ -public class TicketFilter implements FilterBuilder { - - private final TicketSearchQuery ticketSearchQuery; - private String currentUser; - - public TicketFilter(TicketSearchQuery ticketSearchQuery) { - this.ticketSearchQuery = ticketSearchQuery; - this.ticketSearchQuery.filters().set(); - } - - @Override - public TicketSearchQuery apply() { - return ticketSearchQuery; - } - - /** - * Authorize and set 'ViewScope'. - * - *

Authorize and set filters -> ticketTypes, organization and owner - * - *

This is to avoid the Query to return documents that are not available for the user. - * - * @param requestInfo all required is here - * @return TicketQuery (builder pattern) - */ - @Override - public TicketSearchQuery fromRequestInfo(RequestInfo requestInfo) throws UnauthorizedException { - if (Objects.isNull(requestInfo.getUserName())) { - throw new UnauthorizedException(); - } - - if (isSearchingForAllTickets(requestInfo)) { - return ticketSearchQuery; - } - - final var organization = - requestInfo.getTopLevelOrgCristinId().orElse(requestInfo.getPersonAffiliation()); - - final var allowedTicketTypes = getTicketTypes(requestInfo); - - return organization(organization) - .userAndTicketTypes(requestInfo.getUserName(), allowedTicketTypes) - .excludeTicketTypes(TicketType.UNPUBLISH_REQUEST) - .apply(); - } - - private TicketType[] getTicketTypes(RequestInfo requestInfo) throws UnauthorizedException { - if (searchingIsTicketOwner()) { - validateOwner(requestInfo); - return TicketType.values(); - } else { - return getAccessRights(requestInfo.getAccessRights()).toArray(TicketType[]::new); - } - } - - private void validateOwner(RequestInfo requestInfo) throws UnauthorizedException { - if (ownerIsNotCurrentUser(requestInfo)) { - throw new UnauthorizedException( - "User is not allowed to search for tickets not owned by themselves"); - } - } - - private boolean ownerIsNotCurrentUser(RequestInfo requestInfo) throws UnauthorizedException { - return !requestInfo - .getUserName() - .equals(ticketSearchQuery.parameters().get(OWNER).toString()); - } - - private boolean searchingIsTicketOwner() { - return ticketSearchQuery.parameters().isPresent(OWNER); - } - - private boolean isSearchingForAllTickets(RequestInfo requestInfo) { - return ticketSearchQuery.parameters().isPresent(STATISTICS) - && requestInfo.userIsAuthorized(AccessRight.MANAGE_CUSTOMERS); - } - - /** - * Filter on owner (user). - * - *

ONLY SET THIS MANUALLY IN TESTS - * - *

Only tickets owned by user will be available for the Query. - * - *

This is to avoid the Query to return documents that are not available for the user. - * - * @param userName current user - * @return TicketQuery (builder pattern) - */ - public TicketFilter userAndTicketTypes(String userName, TicketType... ticketTypes) { - this.currentUser = userName; - var ticketTypeList = Arrays.stream(ticketTypes).map(TicketType::toString).toList(); - var disMax = - QueryBuilders.disMaxQuery() - .queryName("anyOfTicketTypeUserName") - .add(new TermQueryBuilder(OWNER_USERNAME, currentUser)); - if (!ticketTypeList.isEmpty()) { - disMax.add(new TermsQueryBuilder(TYPE_KEYWORD, ticketTypeList)); - } - this.ticketSearchQuery.filters().add(disMax); - return this; - } - - public TicketFilter excludeTicketTypes(TicketType... ticketTypes) { - var ticketTypeList = Arrays.stream(ticketTypes).map(TicketType::toString).toList(); - var filter = - QueryBuilders.boolQuery() - .mustNot(QueryBuilders.termsQuery(TYPE_KEYWORD, ticketTypeList)); - this.ticketSearchQuery.filters().add(filter); - return this; - } - - /** - * Filter on organization. - * - *

ONLY SET THIS MANUALLY IN TESTS - * - *

Only documents belonging to organization specified are searchable (for the user) - * - * @param organization uri of publisher - * @return ResourceQuery (builder pattern) - */ - public TicketFilter organization(URI organization) { - final var organisationId = - new KeywordQuery() - .buildQuery(ORGANIZATION_ID, organization.toString()) - .findFirst() - .orElseThrow() - .getValue() - .queryName(ORGANIZATION_ID.asCamelCase() + POST_FILTER); - this.ticketSearchQuery.filters().add(organisationId); - return this; - } - - public String getCurrentUser() { - return currentUser; - } - - private Set getAccessRights(List accessRights) - throws UnauthorizedException { - - var allowed = EnumSet.noneOf(TicketType.class); - if (accessRights.contains(MANAGE_DOI)) { - allowed.add(TicketType.DOI_REQUEST); - } - if (accessRights.contains(AccessRight.SUPPORT)) { - allowed.add(TicketType.GENERAL_SUPPORT_CASE); - } - if (accessRights.contains(MANAGE_PUBLISHING_REQUESTS)) { - allowed.add(TicketType.PUBLISHING_REQUEST); - } - if (allowed.isEmpty()) { - throw new UnauthorizedException("User has no access to search for any ticket types!"); - } - return allowed; - } -} diff --git a/search-commons/src/main/java/no/unit/nva/search/ticket/TicketSearchQuery.java b/search-commons/src/main/java/no/unit/nva/search/ticket/TicketSearchQuery.java index f0f3d6622..129c086eb 100644 --- a/search-commons/src/main/java/no/unit/nva/search/ticket/TicketSearchQuery.java +++ b/search-commons/src/main/java/no/unit/nva/search/ticket/TicketSearchQuery.java @@ -72,12 +72,12 @@ */ public final class TicketSearchQuery extends SearchQuery { - private final TicketFilter filterBuilder; + private final TicketAccessFilter accessFilter; private TicketSearchQuery() { super(); applyImpossibleWhiteListFilters(); - filterBuilder = new TicketFilter(this); + accessFilter = new TicketAccessFilter(this); } public static TicketParameterValidator builder() { @@ -146,7 +146,7 @@ protected Map facetPaths() { @Override protected List builderAggregations() { - return getTicketsAggregations(filterBuilder.getCurrentUser()); + return getTicketsAggregations(accessFilter.getCurrentUser()); } @JacocoGenerated // default value shouldn't happen, (developer have forgotten to handle a key) @@ -163,22 +163,22 @@ protected Stream> builderCustomQueryStream( private Stream> builderStreamByStatus( TicketParameter key) { + // we cannot query status New here, it is done together with assignee. return hasAssigneeAndOnlyStatusNew() - ? Stream.empty() // we cannot query status New here, it is done together with - // assignee. + ? Stream.empty() : new KeywordQuery() .buildQuery(key, parameters().get(key).toString()); } - public TicketFilter withFilter() { - return filterBuilder; + public TicketAccessFilter withFilter() { + return accessFilter; } private Stream> builderStreamByAssignee() { var searchByUserName = - parameters().isPresent(BY_USER_PENDING) // override assignee if is - // used - ? filterBuilder.getCurrentUser() + // override assignee if is used + parameters().isPresent(BY_USER_PENDING) + ? accessFilter.getCurrentUser() : parameters().get(ASSIGNEE).toString(); var builtQuery = @@ -194,11 +194,14 @@ private Stream> builderStreamByAssignee() { private Stream> builderStreamByOrganization( TicketParameter key) { - var searchKey = parameters().get(EXCLUDE_SUBUNITS).asBoolean() ? EXCLUDE_SUBUNITS : key; - - return new KeywordQuery() - .buildQuery(searchKey, parameters().get(key).toString()) - .map(query -> Map.entry(key, query.getValue())); + if (parameters().get(EXCLUDE_SUBUNITS).asBoolean()) { + return new KeywordQuery() + .buildQuery(EXCLUDE_SUBUNITS, parameters().get(key).toString()) + .map(query -> Map.entry(key, query.getValue())); + } else { + return new AcrossFieldsQuery() + .buildQuery(key, parameters().get(key).toString()); + } } private boolean hasStatusNew() { diff --git a/search-commons/src/test/java/no/unit/nva/search/ticket/TicketClientTest.java b/search-commons/src/test/java/no/unit/nva/search/ticket/TicketClientTest.java index ac289ab1c..2ba476ccd 100644 --- a/search-commons/src/test/java/no/unit/nva/search/ticket/TicketClientTest.java +++ b/search-commons/src/test/java/no/unit/nva/search/ticket/TicketClientTest.java @@ -26,6 +26,7 @@ import static nva.commons.apigateway.AccessRight.MANAGE_CUSTOMERS; import static nva.commons.apigateway.AccessRight.MANAGE_DOI; import static nva.commons.apigateway.AccessRight.MANAGE_PUBLISHING_REQUESTS; +import static nva.commons.apigateway.AccessRight.SUPPORT; import static nva.commons.core.attempt.Try.attempt; import static nva.commons.core.ioutils.IoUtils.stringFromResources; @@ -120,29 +121,28 @@ static Stream uriAccessRights() { createAccessRightArgument("owner=1412322@20754.0.0.0", 16, "1412322@20754.0.0.0"), createAccessRightArgument("owner=1492596@20754.0.0.0", 2, "1492596@20754.0.0.0"), createAccessRightArgument( - "STATISTICS=true", 22, "1492596@20754.0.0.0", MANAGE_CUSTOMERS), + "STATISTICS=true", 20, "1492596@20754.0.0.0", MANAGE_CUSTOMERS), createAccessRightArgument("", 3, "1492596@20754.0.0.0", MANAGE_DOI), - createAccessRightArgument("", 7, "1492596@20754.0.0.0", AccessRight.SUPPORT), + createAccessRightArgument("", 7, "1492596@20754.0.0.0", SUPPORT), createAccessRightArgument( "", 14, "1492596@20754.0.0.0", MANAGE_PUBLISHING_REQUESTS), createAccessRightArgument("", 1, "1485369@5923.0.0.0", MANAGE_DOI), - createAccessRightArgument("", 6, "1485369@5923.0.0.0", AccessRight.SUPPORT), + createAccessRightArgument("", 6, "1485369@5923.0.0.0", SUPPORT), createAccessRightArgument("", 13, "1485369@5923.0.0.0", MANAGE_PUBLISHING_REQUESTS), - createAccessRightArgument( - "", 7, "1485369@5923.0.0.0", MANAGE_DOI, AccessRight.SUPPORT), + createAccessRightArgument("", 7, "1485369@5923.0.0.0", MANAGE_DOI, SUPPORT), createAccessRightArgument( "", 20, "1485369@5923.0.0.0", MANAGE_DOI, - AccessRight.SUPPORT, + SUPPORT, MANAGE_PUBLISHING_REQUESTS), createAccessRightArgument( "", 20, "1412322@20754.0.0.0", MANAGE_DOI, - AccessRight.SUPPORT, + SUPPORT, MANAGE_PUBLISHING_REQUESTS)); } @@ -241,11 +241,8 @@ void shouldCheckFacets() throws BadRequestException { .withRequiredParameters(FROM, SIZE) .build() .withFilter() - .userAndTicketTypes( - CURRENT_USERNAME, - DOI_REQUEST, - PUBLISHING_REQUEST, - GENERAL_SUPPORT_CASE) + .user(CURRENT_USERNAME) + .includedTypes(DOI_REQUEST, PUBLISHING_REQUEST, GENERAL_SUPPORT_CASE) .apply() .doSearch(searchClient); @@ -262,8 +259,8 @@ void shouldCheckFacets() throws BadRequestException { assertThat(aggregations.get(PUBLICATION_STATUS).size(), is(3)); assertNotNull(FROM.asLowerCase()); - assertEquals(TicketStatus.fromString("ewrdfg"), TicketStatus.NONE); - assertEquals(TicketType.fromString("wre"), TicketType.NONE); + assertEquals(TicketStatus.NONE, TicketStatus.fromString("ewrdfg")); + assertEquals(TicketType.NONE, TicketType.fromString("wre")); } @Test @@ -277,11 +274,8 @@ void emptyResultShouldIncludeHits() throws BadRequestException { .withRequiredParameters(FROM, SIZE, SORT) .build() .withFilter() - .userAndTicketTypes( - CURRENT_USERNAME, - DOI_REQUEST, - PUBLISHING_REQUEST, - GENERAL_SUPPORT_CASE) + .user(CURRENT_USERNAME) + .includedTypes(DOI_REQUEST, PUBLISHING_REQUEST, GENERAL_SUPPORT_CASE) .organization(testOrganizationId) .apply() .doSearch(searchClient); @@ -301,11 +295,8 @@ void shouldReturnNewTicketsWhenSearchingForNewTicketsOnlyAndTypes() throws BadRe .withDockerHostUri(URI.create(container.getHttpHostAddress())) .build() .withFilter() - .userAndTicketTypes( - CURRENT_USERNAME, - DOI_REQUEST, - PUBLISHING_REQUEST, - GENERAL_SUPPORT_CASE) + .user(CURRENT_USERNAME) + .includedTypes(DOI_REQUEST, PUBLISHING_REQUEST, GENERAL_SUPPORT_CASE) .organization(testOrganizationId) .apply() .doSearch(searchClient) @@ -324,11 +315,8 @@ void shouldReturnNewTicketsWhenSearchingForNewTicketsOnly() throws BadRequestExc .withDockerHostUri(URI.create(container.getHttpHostAddress())) .build() .withFilter() - .userAndTicketTypes( - CURRENT_USERNAME, - DOI_REQUEST, - PUBLISHING_REQUEST, - GENERAL_SUPPORT_CASE) + .user(CURRENT_USERNAME) + .includedTypes(DOI_REQUEST, PUBLISHING_REQUEST, GENERAL_SUPPORT_CASE) .organization(testOrganizationId) .apply() .doSearch(searchClient) @@ -351,11 +339,8 @@ void shouldReturnNewTicketsWhenSearchingForNewTicketsOnly() throws BadRequestExc .withDockerHostUri(URI.create(container.getHttpHostAddress())) .build() .withFilter() - .userAndTicketTypes( - CURRENT_USERNAME, - DOI_REQUEST, - PUBLISHING_REQUEST, - GENERAL_SUPPORT_CASE) + .user(CURRENT_USERNAME) + .includedTypes(DOI_REQUEST, PUBLISHING_REQUEST, GENERAL_SUPPORT_CASE) .organization(testOrganizationId) .apply() .doSearch(searchClient) @@ -376,11 +361,8 @@ void uriRequestPageableReturnsSuccessfulResponse(URI uri, int expectedCount) .withDockerHostUri(URI.create(container.getHttpHostAddress())) .build() .withFilter() - .userAndTicketTypes( - CURRENT_USERNAME, - DOI_REQUEST, - PUBLISHING_REQUEST, - GENERAL_SUPPORT_CASE) + .user(CURRENT_USERNAME) + .includedTypes(DOI_REQUEST, PUBLISHING_REQUEST, GENERAL_SUPPORT_CASE) .organization(testOrganizationId) .apply() .doSearch(searchClient); @@ -404,11 +386,8 @@ void uriRequestReturnsSuccessfulResponseAsAdmin(URI uri, int expectedCount) .withDockerHostUri(URI.create(container.getHttpHostAddress())) .build() .withFilter() - .userAndTicketTypes( - CURRENT_USERNAME, - DOI_REQUEST, - PUBLISHING_REQUEST, - GENERAL_SUPPORT_CASE) + .user(CURRENT_USERNAME) + .includedTypes(DOI_REQUEST, PUBLISHING_REQUEST, GENERAL_SUPPORT_CASE) .organization(testOrganizationId) .apply() .doSearch(searchClient); @@ -432,15 +411,14 @@ void uriRequestReturnsSuccessfulResponseAsUser( URI uri, Integer expectedCount, String userName, AccessRight... accessRights) throws ApiGatewayException { - final var accessRightList = - nonNull(accessRights) ? Arrays.asList(accessRights) : List.of(); + var accessRightList = + new java.util.ArrayList<>( + nonNull(accessRights) ? Arrays.asList(accessRights) : List.of()); var mockedRequestInfoLocal = mock(RequestInfo.class); when(mockedRequestInfoLocal.getUserName()).thenReturn(userName); when(mockedRequestInfoLocal.getTopLevelOrgCristinId()) .thenReturn(Optional.of(testOrganizationId)); - when(mockedRequestInfoLocal.userIsAuthorized(MANAGE_CUSTOMERS)).thenReturn(true); - when(mockedRequestInfoLocal.getAccessRights()).thenReturn(accessRightList); var response = @@ -519,12 +497,9 @@ void uriRequestWithSortingReturnsSuccessfulResponse(URI uri) throws ApiGatewayEx .withDockerHostUri(URI.create(container.getHttpHostAddress())) .build() .withFilter() - .userAndTicketTypes( - CURRENT_USERNAME, - DOI_REQUEST, - PUBLISHING_REQUEST, - GENERAL_SUPPORT_CASE) .organization(testOrganizationId) + .user(CURRENT_USERNAME) + .includedTypes(DOI_REQUEST, PUBLISHING_REQUEST, GENERAL_SUPPORT_CASE) .apply() .doSearch(searchClient); diff --git a/search-commons/src/test/resources/resource_urls.json b/search-commons/src/test/resources/resource_urls.json index d46988cca..a1818e7b8 100644 --- a/search-commons/src/test/resources/resource_urls.json +++ b/search-commons/src/test/resources/resource_urls.json @@ -1,4 +1,5 @@ { + "query=Metoder+for+måle+vannføring+i+umålte+vassdrag": 0, "title=D4.1+Status%3A+legal%2Fregulatory+barriers+for%0D%0Atransboundary+CO2+ship+transport": 0, "HAS_CHILDREN=true": 1, "HAS_PARENT=true": 2,