@Test
  public void shouldReadResourceSetToken() throws Exception {

    // Given
    ResourceSetDescription resourceSetDescription =
        new ResourceSetDescription(
            "RESOURCE_SET_ID",
            "CLIENT_ID",
            "RESOURCE_OWNER_ID",
            Collections.<String, Object>emptyMap());

    given(
            dataStore.query(
                QueryFilter.and(
                    QueryFilter.equalTo(ResourceSetTokenField.RESOURCE_SET_ID, "RESOURCE_SET_ID"),
                    QueryFilter.equalTo(ResourceSetTokenField.REALM, "REALM"))))
        .willReturn(Collections.singleton(resourceSetDescription));

    // When
    ResourceSetDescription readResourceSetDescription =
        store.read("RESOURCE_SET_ID", "RESOURCE_OWNER_ID");

    // Then
    assertThat(readResourceSetDescription).isEqualTo(readResourceSetDescription);
  }
  @Test
  public void shouldDeleteResourceSetToken() throws Exception {

    // Given
    ResourceSetDescription resourceSetDescription =
        new ResourceSetDescription(
            "RESOURCE_SET_ID",
            "CLIENT_ID",
            "RESOURCE_OWNER_ID",
            Collections.<String, Object>emptyMap());

    resourceSetDescription.setRealm("REALM");

    given(
            dataStore.query(
                QueryFilter.and(
                    QueryFilter.equalTo(ResourceSetTokenField.RESOURCE_SET_ID, "RESOURCE_SET_ID"),
                    QueryFilter.equalTo(ResourceSetTokenField.REALM, "REALM"))))
        .willReturn(Collections.singleton(resourceSetDescription));

    // When
    store.delete("RESOURCE_SET_ID", "RESOURCE_OWNER_ID");

    // Then
    verify(dataStore).delete("RESOURCE_SET_ID");
  }
  /**
   * Queries relationships, returning the relationship associated with this providers resource path
   * and the specified relationship field.
   *
   * @param context The current context
   * @param managedObjectId The id of the managed object to find relationships associated with
   * @return
   */
  private Promise<ResourceResponse, ResourceException> queryRelationship(
      final Context context, final String managedObjectId) {
    try {
      final QueryRequest queryRequest = Requests.newQueryRequest(REPO_RESOURCE_PATH);
      final List<ResourceResponse> relationships = new ArrayList<>();

      queryRequest.setQueryFilter(
          QueryFilter.and(
              QueryFilter.equalTo(
                  new JsonPointer(isReverse ? REPO_FIELD_SECOND_ID : REPO_FIELD_FIRST_ID),
                  resourcePath.child(managedObjectId)),
              QueryFilter.equalTo(new JsonPointer(REPO_FIELD_FIRST_PROPERTY_NAME), propertyName)));

      connectionFactory.getConnection().query(context, queryRequest, relationships);

      if (relationships.isEmpty()) {
        return new NotFoundException().asPromise();
      } else {
        // TODO OPENIDM-4094 - check size and throw illegal state if more than one?
        return newResultPromise(FORMAT_RESPONSE.apply(relationships.get(0)));
      }
    } catch (ResourceException e) {
      return e.asPromise();
    }
  }
  @Test
  public void nameQueryShouldBeSupported() throws Exception {

    // Given
    ServerContext context = mock(ServerContext.class);
    QueryRequest request = mock(QueryRequest.class);
    given(request.getFields()).willReturn(Arrays.asList(new JsonPointer("/fred")));
    QueryResultHandler handler = mock(QueryResultHandler.class);
    ResourceSetDescription resourceSet = mock(ResourceSetDescription.class);
    QueryFilter queryFilter =
        QueryFilter.and(
            QueryFilter.equalTo("/name", "NAME"),
            QueryFilter.equalTo("/resourceServer", "myclient"),
            QueryFilter.equalTo("/policy/permissions/subject", "SUBJECT"));
    Promise<Collection<ResourceSetDescription>, ResourceException> resourceSetsPromise =
        Promises.newSuccessfulPromise((Collection<ResourceSetDescription>) asSet(resourceSet));

    given(contextHelper.getRealm(context)).willReturn("REALM");
    given(contextHelper.getUserId(context)).willReturn("RESOURCE_OWNER_ID");
    given(request.getQueryFilter()).willReturn(queryFilter);
    given(
            resourceSetService.getResourceSets(
                eq(context),
                eq("REALM"),
                Matchers.<ResourceSetWithPolicyQuery>anyObject(),
                eq("RESOURCE_OWNER_ID"),
                eq(false)))
        .willReturn(resourceSetsPromise);

    // When
    resource.queryCollection(context, request, handler);

    // Then
    ArgumentCaptor<ResourceSetWithPolicyQuery> queryCaptor =
        ArgumentCaptor.forClass(ResourceSetWithPolicyQuery.class);
    verify(resourceSetService)
        .getResourceSets(
            eq(context), eq("REALM"), queryCaptor.capture(), eq("RESOURCE_OWNER_ID"), eq(false));
    assertThat(queryCaptor.getValue().getOperator()).isEqualTo(AggregateQuery.Operator.AND);
    assertThat(queryCaptor.getValue().getPolicyQuery())
        .isEqualTo(QueryFilter.equalTo("/permissions/subject", "SUBJECT"));
    assertThat(queryCaptor.getValue().getResourceSetQuery())
        .isEqualTo(
            org.forgerock.util.query.QueryFilter.and(
                org.forgerock.util.query.QueryFilter.equalTo("name", "NAME"),
                org.forgerock.util.query.QueryFilter.equalTo("clientId", "myclient")));
    verify(handler).handleResult(any(QueryResult.class));
  }
  @Test
  public void shouldQueryResourceSetToken() throws Exception {

    // Given
    Map<String, Object> queryParameters = new HashMap<String, Object>();
    queryParameters.put(ResourceSetTokenField.CLIENT_ID, "CLIENT_ID");
    ResourceSetDescription resourceSet1 =
        new ResourceSetDescription(
            "123", "CLIENT_ID", "RESOURCE_OWNER_ID", Collections.<String, Object>emptyMap());
    ResourceSetDescription resourceSet2 =
        new ResourceSetDescription(
            "456", "CLIENT_ID", "RESOURCE_OWNER_ID", Collections.<String, Object>emptyMap());

    given(dataStore.query(Matchers.<QueryFilter<String>>anyObject()))
        .willReturn(asSet(resourceSet1, resourceSet2));
    resourceSet1.setRealm("REALM");
    resourceSet2.setRealm("REALM");

    // When
    QueryFilter<String> query = QueryFilter.alwaysTrue();
    Set<ResourceSetDescription> resourceSetDescriptions = store.query(query);

    // Then
    assertThat(resourceSetDescriptions).contains(resourceSet1, resourceSet2);
    ArgumentCaptor<QueryFilter> tokenFilterCaptor = ArgumentCaptor.forClass(QueryFilter.class);
    verify(dataStore).query(tokenFilterCaptor.capture());
    assertThat(tokenFilterCaptor.getValue())
        .isEqualTo(
            QueryFilter.and(query, QueryFilter.equalTo(ResourceSetTokenField.REALM, "REALM")));
  }
 @Override
 public QueryFilter<CoreTokenField> visitEqualsFilter(
     Void aVoid, JsonPointer field, Object valueAssertion) {
   final String fieldString = field.toString().substring(1);
   if (STSIssuedTokenState.STS_ID_QUERY_ATTRIBUTE.equals(fieldString)) {
     return QueryFilter.equalTo(
         CTSTokenPersistence.CTS_TOKEN_FIELD_STS_ID, valueAssertion);
   } else if (STSIssuedTokenState.STS_TOKEN_PRINCIPAL_QUERY_ATTRIBUTE.equals(
       fieldString)) {
     return QueryFilter.equalTo(CoreTokenField.USER_ID, valueAssertion);
   } else {
     throw new IllegalArgumentException(
         "Querying TokenService on field "
             + fieldString
             + " not supported. Query format: "
             + getUsageString());
   }
 }
  private boolean isEntitled(
      UmaProviderSettings umaProviderSettings,
      PermissionTicket permissionTicket,
      AccessToken authorisationApiToken)
      throws EntitlementException, ServerException {
    String realm = permissionTicket.getRealm();
    String resourceSetId = permissionTicket.getResourceSetId();
    String resourceName = UmaConstants.UMA_POLICY_SCHEME;
    Subject resourceOwnerSubject;
    try {
      ResourceSetStore store =
          oauth2ProviderSettingsFactory
              .get(requestFactory.create(getRequest()))
              .getResourceSetStore();
      Set<ResourceSetDescription> results =
          store.query(
              org.forgerock.util.query.QueryFilter.equalTo(
                  ResourceSetTokenField.RESOURCE_SET_ID, resourceSetId));
      if (results.size() != 1) {
        throw new NotFoundException("Could not find Resource Set, " + resourceSetId);
      }
      resourceName += results.iterator().next().getId();
      resourceOwnerSubject =
          UmaUtils.createSubject(
              createIdentity(results.iterator().next().getResourceOwnerId(), realm));
    } catch (NotFoundException e) {
      debug.message("Couldn't find resource that permission ticket is registered for", e);
      throw new ServerException("Couldn't find resource that permission ticket is registered for");
    }
    Subject requestingPartySubject =
        UmaUtils.createSubject(createIdentity(authorisationApiToken.getResourceOwnerId(), realm));

    // Implicitly grant access to the resource owner
    if (isRequestingPartyResourceOwner(requestingPartySubject, resourceOwnerSubject)) {
      return true;
    }

    List<Entitlement> entitlements =
        umaProviderSettings
            .getPolicyEvaluator(
                requestingPartySubject, permissionTicket.getClientId().toLowerCase())
            .evaluate(realm, requestingPartySubject, resourceName, null, false);

    Set<String> requestedScopes = permissionTicket.getScopes();
    Set<String> requiredScopes = new HashSet<String>(requestedScopes);
    for (Entitlement entitlement : entitlements) {
      for (String requestedScope : requestedScopes) {
        final Boolean actionValue = entitlement.getActionValue(requestedScope);
        if (actionValue != null && actionValue) {
          requiredScopes.remove(requestedScope);
        }
      }
    }

    return requiredScopes.isEmpty();
  }
 private ResourceSetDescription getResourceSet(
     String resourceSetId, OAuth2ProviderSettings providerSettings) throws UmaException {
   try {
     ResourceSetStore store = providerSettings.getResourceSetStore();
     Set<ResourceSetDescription> results =
         store.query(
             org.forgerock.util.query.QueryFilter.equalTo(
                 ResourceSetTokenField.RESOURCE_SET_ID, resourceSetId));
     if (results.size() != 1) {
       throw new UmaException(
           400, "invalid_resource_set_id", "Could not fing Resource Set, " + resourceSetId);
     }
     return results.iterator().next();
   } catch (ServerException e) {
     throw new UmaException(400, "invalid_resource_set_id", e.getMessage());
   }
 }