Search in sources :

Example 36 with DatawavePrincipal

use of datawave.security.authorization.DatawavePrincipal in project datawave by NationalSecurityAgency.

the class QueryExecutorBeanTest method testCreateWithNoSelectedAuths.

@SuppressWarnings("unchecked")
@Test(expected = DatawaveWebApplicationException.class)
public void testCreateWithNoSelectedAuths() throws Exception {
    String queryLogicName = "EventQueryLogic";
    String queryName = "Something";
    String query = "FOO == BAR";
    Date beginDate = new Date();
    Date expirationDate = DateUtils.addDays(new Date(), 1);
    int pagesize = 10;
    QueryPersistence persist = QueryPersistence.TRANSIENT;
    Set<QueryImpl.Parameter> parameters = new HashSet<>();
    // need to call the getQueryByName() method. Maybe a partial mock of QueryExecutorBean would be better
    // setup principal mock
    String userDN = "CN=Guy Some Other soguy, OU=MY_SUBDIVISION, OU=MY_DIVISION, O=ORG, C=US";
    String[] auths = new String[2];
    auths[0] = "PRIVATE";
    auths[1] = "PUBLIC";
    QueryImpl q = new QueryImpl();
    q.setBeginDate(beginDate);
    q.setEndDate(beginDate);
    q.setExpirationDate(expirationDate);
    q.setPagesize(pagesize);
    q.setParameters(parameters);
    q.setQuery(query);
    q.setQueryAuthorizations(StringUtils.join(auths, ","));
    q.setQueryLogicName(queryLogicName);
    q.setUserDN(userDN);
    q.setId(UUID.randomUUID());
    @SuppressWarnings("rawtypes") QueryLogic logic = createMock(BaseQueryLogic.class);
    MultivaluedMap<String, String> p = new MultivaluedMapImpl<>();
    p.putSingle(QueryParameters.QUERY_AUTHORIZATIONS, "");
    p.putSingle(QueryParameters.QUERY_BEGIN, QueryParametersImpl.formatDate(beginDate));
    p.putSingle(QueryParameters.QUERY_END, QueryParametersImpl.formatDate(beginDate));
    p.putSingle(QueryParameters.QUERY_EXPIRATION, QueryParametersImpl.formatDate(expirationDate));
    p.putSingle(QueryParameters.QUERY_NAME, queryName);
    p.putSingle(QueryParameters.QUERY_PAGESIZE, Integer.toString(pagesize));
    p.putSingle(QueryParameters.QUERY_STRING, query);
    p.putSingle(QueryParameters.QUERY_PERSISTENCE, persist.name());
    p.putSingle(ColumnVisibilitySecurityMarking.VISIBILITY_MARKING, "PRIVATE|PUBLIC");
    InMemoryInstance instance = new InMemoryInstance();
    Connector c = instance.getConnector("root", new PasswordToken(""));
    QueryParameters qp = new QueryParametersImpl();
    MultivaluedMap<String, String> optionalParameters = new MultivaluedMapImpl<>();
    optionalParameters.putAll(qp.getUnknownParameters(p));
    DatawaveUser user = new DatawaveUser(SubjectIssuerDNPair.of(userDN, "<CN=MY_CA, OU=MY_SUBDIVISION, OU=MY_DIVISION, O=ORG, C=US>"), UserType.USER, Arrays.asList(auths), null, null, 0L);
    DatawavePrincipal principal = new DatawavePrincipal(Collections.singletonList(user));
    String[] dns = principal.getDNs();
    Arrays.sort(dns);
    List<String> dnList = Arrays.asList(dns);
    PowerMock.resetAll();
    EasyMock.expect(ctx.getCallerPrincipal()).andReturn(principal).anyTimes();
    suppress(constructor(QueryParametersImpl.class));
    EasyMock.expect(persister.create(userDN, dnList, (SecurityMarking) Whitebox.getField(bean.getClass(), "marking").get(bean), queryLogicName, (QueryParameters) Whitebox.getField(bean.getClass(), "qp").get(bean), optionalParameters)).andReturn(q);
    EasyMock.expect(queryLogicFactory.getQueryLogic(queryLogicName, principal)).andReturn(logic);
    EasyMock.expect(logic.getRequiredQueryParameters()).andReturn(Collections.EMPTY_SET);
    EasyMock.expect(logic.containsDNWithAccess(dnList)).andReturn(true);
    EasyMock.expect(logic.getMaxPageSize()).andReturn(0);
    EasyMock.expect(logic.getAuditType(EasyMock.<Query>anyObject())).andReturn(AuditType.ACTIVE).anyTimes();
    EasyMock.expect(logic.getSelectors(anyObject())).andReturn(null);
    Map<String, String> auditParams = new HashMap<>();
    auditParams.put(QueryParameters.QUERY_STRING, p.getFirst(QueryParameters.QUERY_STRING));
    auditParams.put(AuditParameters.USER_DN, userDN);
    auditParams.put(AuditParameters.QUERY_SECURITY_MARKING_COLVIZ, "PRIVATE|PUBLIC");
    auditParams.put(AuditParameters.QUERY_AUDIT_TYPE, AuditType.ACTIVE.name());
    auditParams.put(AuditParameters.QUERY_LOGIC_CLASS, "EventQueryLogic");
    EasyMock.expect(auditService.audit(eq(auditParams))).andReturn(null);
    logic.close();
    EasyMock.expectLastCall();
    persister.remove(anyObject(Query.class));
    PowerMock.replayAll();
    bean.createQuery(queryLogicName, p);
    PowerMock.verifyAll();
}
Also used : Connector(org.apache.accumulo.core.client.Connector) Query(datawave.webservice.query.Query) HashMap(java.util.HashMap) DatawaveUser(datawave.security.authorization.DatawaveUser) MultivaluedMapImpl(org.jboss.resteasy.specimpl.MultivaluedMapImpl) InMemoryInstance(datawave.accumulo.inmemory.InMemoryInstance) BaseQueryLogic(datawave.webservice.query.logic.BaseQueryLogic) QueryLogic(datawave.webservice.query.logic.QueryLogic) QueryParameters(datawave.webservice.query.QueryParameters) QueryParametersImpl(datawave.webservice.query.QueryParametersImpl) Date(java.util.Date) DatawavePrincipal(datawave.security.authorization.DatawavePrincipal) QueryImpl(datawave.webservice.query.QueryImpl) PasswordToken(org.apache.accumulo.core.client.security.tokens.PasswordToken) QueryPersistence(datawave.webservice.query.QueryPersistence) HashSet(java.util.HashSet) Test(org.junit.Test) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest)

Example 37 with DatawavePrincipal

use of datawave.security.authorization.DatawavePrincipal in project datawave by NationalSecurityAgency.

the class QueryExecutorBeanTest method defineTestRunner.

private void defineTestRunner(QueryImpl q, MultivaluedMap p) throws Exception {
    MultivaluedMap<String, String> optionalParameters = createNewQueryParameters(q, p);
    @SuppressWarnings("rawtypes") QueryLogic logic = createMock(BaseQueryLogic.class);
    DatawaveUser user = new DatawaveUser(SubjectIssuerDNPair.of(userDN, "<CN=MY_CA, OU=MY_SUBDIVISION, OU=MY_DIVISION, O=ORG, C=US>"), UserType.USER, Arrays.asList(auths), null, null, 0L);
    DatawavePrincipal principal = new DatawavePrincipal(Collections.singletonList(user));
    String[] dns = principal.getDNs();
    Arrays.sort(dns);
    List<String> dnList = Arrays.asList(dns);
    PowerMock.resetAll();
    EasyMock.expect(ctx.getCallerPrincipal()).andReturn(principal).anyTimes();
    suppress(constructor(QueryParametersImpl.class));
    EasyMock.expect(persister.create(principal.getUserDN().subjectDN(), dnList, (SecurityMarking) Whitebox.getField(bean.getClass(), "marking").get(bean), queryLogicName, (QueryParameters) Whitebox.getField(bean.getClass(), "qp").get(bean), optionalParameters)).andReturn(q);
    EasyMock.expect(queryLogicFactory.getQueryLogic(queryLogicName, principal)).andReturn(logic);
    EasyMock.expect(logic.getRequiredQueryParameters()).andReturn(Collections.EMPTY_SET);
    EasyMock.expect(logic.getConnectionPriority()).andReturn(AccumuloConnectionFactory.Priority.NORMAL);
    EasyMock.expect(logic.containsDNWithAccess(dnList)).andReturn(true);
    EasyMock.expect(logic.getMaxPageSize()).andReturn(0);
    EasyMock.expect(logic.getCollectQueryMetrics()).andReturn(Boolean.FALSE);
    EasyMock.expect(logic.getResultLimit(q.getDnList())).andReturn(-1L);
    EasyMock.expect(logic.getMaxResults()).andReturn(-1L);
    PowerMock.replayAll();
    bean.defineQuery(queryLogicName, p);
    PowerMock.verifyAll();
    Object cachedRunningQuery = cache.get(q.getId().toString());
    Assert.assertNotNull(cachedRunningQuery);
    RunningQuery rq2 = (RunningQuery) cachedRunningQuery;
    Assert.assertEquals(q, rq2.getSettings());
}
Also used : DatawaveUser(datawave.security.authorization.DatawaveUser) EasyMock.anyObject(org.easymock.EasyMock.anyObject) BaseQueryLogic(datawave.webservice.query.logic.BaseQueryLogic) QueryLogic(datawave.webservice.query.logic.QueryLogic) QueryParametersImpl(datawave.webservice.query.QueryParametersImpl) DatawavePrincipal(datawave.security.authorization.DatawavePrincipal)

Example 38 with DatawavePrincipal

use of datawave.security.authorization.DatawavePrincipal in project datawave by NationalSecurityAgency.

the class QueryExecutorBeanTest method testCloseActuallyCloses.

@SuppressWarnings("unchecked")
@Test(timeout = 5000)
public void testCloseActuallyCloses() throws Exception {
    QueryImpl q = createNewQuery();
    final MultivaluedMap<String, String> queryParameters = createNewQueryParameterMap();
    queryParameters.putSingle(QueryParameters.QUERY_LOGIC_NAME, "EventQueryLogic");
    final Thread createQuery = new Thread(() -> {
        try {
            bean.createQuery("EventQueryLogic", queryParameters);
        } catch (Exception e) {
            // ok if we fail the call
            log.debug("createQuery terminated with " + e);
        }
    });
    final Throwable[] createQueryException = { null };
    createQuery.setUncaughtExceptionHandler((t, e) -> createQueryException[0] = e);
    @SuppressWarnings("rawtypes") QueryLogic logic = createMock(BaseQueryLogic.class);
    DatawaveUser user = new DatawaveUser(SubjectIssuerDNPair.of(userDN, "<CN=MY_CA, OU=MY_SUBDIVISION, OU=MY_DIVISION, O=ORG, C=US>"), UserType.USER, Arrays.asList(auths), null, null, 0L);
    DatawavePrincipal principal = new DatawavePrincipal(Collections.singletonList(user));
    principal.getShortName();
    String[] dns = principal.getDNs();
    Arrays.sort(dns);
    List<String> dnList = Arrays.asList(dns);
    InMemoryInstance instance = new InMemoryInstance();
    Connector c = instance.getConnector("root", new PasswordToken(""));
    MultivaluedMap<String, String> optionalParameters = createNewQueryParameters(q, queryParameters);
    PowerMock.resetAll();
    EasyMock.expect(ctx.getCallerPrincipal()).andReturn(principal).anyTimes();
    EasyMock.expect(logic.getAuditType(null)).andReturn(AuditType.NONE);
    EasyMock.expect(persister.create(principal.getUserDN().subjectDN(), dnList, Whitebox.getInternalState(bean, SecurityMarking.class), queryLogicName, Whitebox.getInternalState(bean, QueryParameters.class), optionalParameters)).andReturn(q);
    EasyMock.expect(persister.findById(EasyMock.anyString())).andReturn(null).anyTimes();
    EasyMock.expect(connectionFactory.getTrackingMap(anyObject())).andReturn(Maps.newHashMap()).anyTimes();
    BaseQueryMetric metric = new QueryMetricFactoryImpl().createMetric();
    metric.populate(q);
    EasyMock.expectLastCall();
    metric.setQueryType(RunningQuery.class.getSimpleName());
    metric.setLifecycle(Lifecycle.DEFINED);
    System.out.println(metric);
    Set<Prediction> predictions = new HashSet<>();
    predictions.add(new Prediction("source", 1));
    EasyMock.expect(predictor.predict(metric)).andReturn(predictions);
    connectionRequestBean.requestBegin(q.getId().toString());
    EasyMock.expectLastCall();
    EasyMock.expect(connectionFactory.getConnection(eq("connPool1"), anyObject(), anyObject())).andReturn(c).anyTimes();
    connectionRequestBean.requestEnd(q.getId().toString());
    EasyMock.expectLastCall();
    connectionFactory.returnConnection(c);
    EasyMock.expectLastCall();
    EasyMock.expect(queryLogicFactory.getQueryLogic(queryLogicName, principal)).andReturn(logic);
    EasyMock.expect(logic.getRequiredQueryParameters()).andReturn(Collections.emptySet());
    EasyMock.expect(logic.getConnectionPriority()).andReturn(AccumuloConnectionFactory.Priority.NORMAL).atLeastOnce();
    EasyMock.expect(logic.containsDNWithAccess(dnList)).andReturn(true);
    EasyMock.expect(logic.getMaxPageSize()).andReturn(0);
    EasyMock.expect(logic.getAuditType(q)).andReturn(AuditType.NONE);
    EasyMock.expect(logic.getConnPoolName()).andReturn("connPool1");
    EasyMock.expect(logic.getResultLimit(eq(q.getDnList()))).andReturn(-1L).anyTimes();
    EasyMock.expect(logic.getMaxResults()).andReturn(-1L).anyTimes();
    EasyMock.expect(connectionRequestBean.cancelConnectionRequest(q.getId().toString(), principal)).andReturn(false).anyTimes();
    connectionFactory.returnConnection(EasyMock.isA(Connector.class));
    final AtomicBoolean initializeLooping = new AtomicBoolean(false);
    // During initialize, mark that we get here, and then sleep
    final IAnswer<GenericQueryConfiguration> initializeAnswer = () -> {
        initializeLooping.set(true);
        try {
            while (true) {
                Thread.sleep(1000);
                log.debug("Initialize: woke up");
            }
        } catch (InterruptedException e) {
            throw new QueryException("EXPECTED EXCEPTION: initialize interrupted");
        }
    };
    EasyMock.expect(logic.initialize(anyObject(Connector.class), anyObject(Query.class), anyObject(Set.class))).andAnswer(initializeAnswer);
    EasyMock.expect(logic.getCollectQueryMetrics()).andReturn(Boolean.FALSE);
    // On close, interrupt the thread to simulate the ScannerFactory cleaning up
    final IAnswer<Object> closeAnswer = () -> {
        if (null != createQuery) {
            log.debug("createQuery thread is not null. interrupting");
            createQuery.interrupt();
        } else {
            log.debug("createQuery thread is null. not interrupting");
        }
        return null;
    };
    logic.close();
    EasyMock.expectLastCall().andAnswer(closeAnswer).anyTimes();
    // Make the QueryLogic mock not threadsafe, otherwise it will be blocked infinitely
    // trying to get the lock on the infinite loop
    EasyMock.makeThreadSafe(logic, false);
    metrics.updateMetric(EasyMock.isA(QueryMetric.class));
    PowerMock.replayAll();
    try {
        createQuery.start();
        // Wait for the create call to get to initialize
        while (!initializeLooping.get()) {
            if (!createQuery.isAlive() && !initializeLooping.get()) {
                Assert.fail("createQuery thread died before reaching initialize: " + createQueryException[0]);
            }
            Thread.sleep(50);
        }
        // initialize has not completed yet so it will not appear in the cache
        Object cachedRunningQuery = cache.get(q.getId().toString());
        Assert.assertNull(cachedRunningQuery);
        Pair<QueryLogic<?>, Connector> pair = qlCache.poll(q.getId().toString());
        Assert.assertNotNull(pair);
        Assert.assertEquals(logic, pair.getFirst());
        Assert.assertEquals(c, pair.getSecond());
        // Have to add these back because poll was destructive
        qlCache.add(q.getId().toString(), principal.getShortName(), pair.getFirst(), pair.getSecond());
        // Call close
        bean.close(q.getId().toString());
        // Make sure that it's gone from the qlCache
        pair = qlCache.poll(q.getId().toString());
        Assert.assertNull("Still found an entry in the qlCache: " + pair, pair);
        // Should have already joined by now, but just to be sure
        createQuery.join();
    } finally {
        if (null != createQuery && createQuery.isAlive()) {
            createQuery.interrupt();
        }
    }
}
Also used : Connector(org.apache.accumulo.core.client.Connector) Set(java.util.Set) HashSet(java.util.HashSet) Query(datawave.webservice.query.Query) InMemoryInstance(datawave.accumulo.inmemory.InMemoryInstance) DatawavePrincipal(datawave.security.authorization.DatawavePrincipal) GenericQueryConfiguration(datawave.webservice.query.configuration.GenericQueryConfiguration) QueryImpl(datawave.webservice.query.QueryImpl) PasswordToken(org.apache.accumulo.core.client.security.tokens.PasswordToken) SecurityMarking(datawave.marking.SecurityMarking) ColumnVisibilitySecurityMarking(datawave.marking.ColumnVisibilitySecurityMarking) BaseQueryMetric(datawave.microservice.querymetric.BaseQueryMetric) QueryMetric(datawave.microservice.querymetric.QueryMetric) BaseQueryMetric(datawave.microservice.querymetric.BaseQueryMetric) QueryMetricFactoryImpl(datawave.microservice.querymetric.QueryMetricFactoryImpl) HashSet(java.util.HashSet) DatawaveUser(datawave.security.authorization.DatawaveUser) Prediction(datawave.microservice.querymetric.BaseQueryMetric.Prediction) BaseQueryLogic(datawave.webservice.query.logic.BaseQueryLogic) QueryLogic(datawave.webservice.query.logic.QueryLogic) QueryParameters(datawave.webservice.query.QueryParameters) DatawaveWebApplicationException(datawave.webservice.common.exception.DatawaveWebApplicationException) IOException(java.io.IOException) QueryException(datawave.webservice.query.exception.QueryException) URISyntaxException(java.net.URISyntaxException) BadRequestException(datawave.webservice.common.exception.BadRequestException) SAXException(org.xml.sax.SAXException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) QueryException(datawave.webservice.query.exception.QueryException) EasyMock.anyObject(org.easymock.EasyMock.anyObject) Test(org.junit.Test) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest)

Example 39 with DatawavePrincipal

use of datawave.security.authorization.DatawavePrincipal in project datawave by NationalSecurityAgency.

the class ExtendedRunningQueryTest method testNext_HappyPathUsingDeprecatedConstructor.

@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testNext_HappyPathUsingDeprecatedConstructor() throws Exception {
    // Set local test input
    String userDN = "userDN";
    List<String> dnList = Lists.newArrayList(userDN);
    String userSid = "userSid";
    UUID queryId = UUID.randomUUID();
    String methodAuths = "AUTH_1";
    String columnVisibility = "AUTH_1";
    DatawaveUser user = new DatawaveUser(SubjectIssuerDNPair.of("userDN", "issuerDN"), UserType.USER, Collections.singleton(methodAuths), null, null, 0L);
    DatawavePrincipal principal = new DatawavePrincipal(Collections.singletonList(user));
    String query = "query";
    String queryLogicName = "queryLogicName";
    String queryName = "queryName";
    long currentTime = System.currentTimeMillis();
    Date beginDate = new Date(currentTime - 5000);
    Date endDate = new Date(currentTime - 1000);
    Date expirationDate = new Date(currentTime + 9999);
    int pageSize = 3;
    int maxPageSize = 10;
    long pageByteTrigger = 4 * 1024L;
    long maxWork = Long.MAX_VALUE;
    long maxResults = 100L;
    List<Object> resultObjects = Arrays.asList(new Object(), "resultObject1", null);
    // Set expectations
    expect(this.queryLogic.getCollectQueryMetrics()).andReturn(true);
    expect(this.query.getUncaughtExceptionHandler()).andReturn(exceptionHandler).times(5);
    expect(this.exceptionHandler.getThrowable()).andReturn(null).times(5);
    expect(this.query.getId()).andReturn(queryId).times(4);
    expect(this.query.getOwner()).andReturn(userSid).times(2);
    expect(this.query.getQuery()).andReturn(query).times(2);
    expect(this.query.getQueryLogicName()).andReturn(queryLogicName).times(2);
    expect(this.query.getQueryName()).andReturn(queryName).times(2);
    expect(this.query.getBeginDate()).andReturn(beginDate).times(2);
    expect(this.query.getEndDate()).andReturn(endDate).times(2);
    expect(this.query.isMaxResultsOverridden()).andReturn(false).anyTimes();
    expect(this.query.getExpirationDate()).andReturn(expirationDate);
    expect(this.query.getParameters()).andReturn(new HashSet<>()).times(2);
    expect(this.query.getQueryAuthorizations()).andReturn(methodAuths).times(2);
    expect(this.query.getColumnVisibility()).andReturn(columnVisibility);
    expect(this.query.getUserDN()).andReturn(userDN).times(3);
    expect(this.query.getDnList()).andReturn(dnList);
    expect(this.queryLogic.initialize(eq(this.connector), eq(this.query), isA(Set.class))).andReturn(this.genericConfiguration);
    this.queryLogic.setupQuery(this.genericConfiguration);
    expect(this.queryLogic.getTransformIterator(this.query)).andReturn(this.transformIterator);
    Iterator<Object> iterator = resultObjects.iterator();
    while (iterator.hasNext()) {
        expect(this.transformIterator.hasNext()).andReturn(iterator.hasNext());
        expect(this.transformIterator.next()).andReturn(iterator.next());
        expect(this.transformIterator.getTransformer()).andReturn(transformer);
    }
    expect(this.query.getPagesize()).andReturn(pageSize).anyTimes();
    expect(this.queryLogic.getMaxPageSize()).andReturn(maxPageSize).anyTimes();
    expect(this.queryLogic.getPageByteTrigger()).andReturn(pageByteTrigger).anyTimes();
    expect(this.queryLogic.getMaxWork()).andReturn(maxWork).anyTimes();
    expect(this.queryLogic.getMaxResults()).andReturn(maxResults).anyTimes();
    expect(this.genericConfiguration.getQueryString()).andReturn(query).once();
    expect(this.queryLogic.getResultLimit(eq(dnList))).andReturn(maxResults);
    // Run the test
    PowerMock.replayAll();
    RunningQuery subject = new RunningQuery(this.connector, Priority.NORMAL, this.queryLogic, this.query, methodAuths, principal, new QueryMetricFactoryImpl());
    ResultsPage result1 = subject.next();
    String result2 = subject.toString();
    QueryMetric.Lifecycle status = subject.getMetric().getLifecycle();
    PowerMock.verifyAll();
    // Verify results
    assertNotNull("Expected a non-null page", result1);
    assertNotNull("Expected a non-null list of results", result1.getResults());
    assertEquals("Expected 2 non-null items in the list of results", 2, result1.getResults().size());
    assertSame("Expected status to be closed", status, QueryMetric.Lifecycle.RESULTS);
    assertNotNull("Expected a non-null toString() representation", result2);
    assertSame("Expected lifecycle to be results", QueryMetric.Lifecycle.RESULTS, subject.getMetric().getLifecycle());
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) DatawaveUser(datawave.security.authorization.DatawaveUser) ResultsPage(datawave.webservice.query.cache.ResultsPage) DatawavePrincipal(datawave.security.authorization.DatawavePrincipal) Date(java.util.Date) QueryMetric(datawave.microservice.querymetric.QueryMetric) UUID(java.util.UUID) QueryMetricFactoryImpl(datawave.microservice.querymetric.QueryMetricFactoryImpl) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 40 with DatawavePrincipal

use of datawave.security.authorization.DatawavePrincipal in project datawave by NationalSecurityAgency.

the class UserOperationsBean method listEffectiveAuthorizations.

/**
 * Lists the "effective" Accumulo user authorizations for the calling user. These are authorizations that are returned by the authorization service
 * (possibly mapped to different values, or additional values added for Accumulo compatibility) intersected with the authorizations of the user that is used
 * to connect to Accumulo. The authorizations returned by the call can be passed to query calls in order to return the maximum amount of data the user is
 * authorized to see. Or, authorizations can be removed from this list to downgrade a query.
 * <p>
 * <strong>WARNING:</strong> If this call is made by a server proxying for a user (and/or other servers) then the response will contain multiple
 * authorizations lists--one per entity. It is up to the caller to decide how to combine them if they wish to present a list to the user for downgrading.
 * Note that {@link AuthorizationsListBase#getAllAuths()}, due to recent changes, actually returns only the user's authorizations. That is, these are the
 * authorizations for the calling or proxied entity that represents a human, otherwise, the calling entity's authorizations. This list is sufficient for use
 * in downgrading, but it should be noted the list is not necessarily representative of data that will be returned from a query. When evaluating data for
 * return to a called, the data is tested against every authorization set listed here, and it must pass all of them to be returned. Therefore, if the user
 * has the authorization FOO, but one of the other proxied entities in the chain does not, no data with FOO will be returned even though
 * listEffectiveAuthorizations indicates the user has that authorization.
 * <p>
 * An example scenario where this comes into play is an external person querying through an internal server. The external party will have an authorization
 * for their organization, say EXT1 for example, whereas the server will have the INT authorization. We want to be able to return data with releasabilities
 * such as {@code INT&EXT1}, {@code INT&ALL_EXT}, but not data such as {@code INT&EXT2}. There is no single merged list of authorizations that will allow
 * the correct data to come back. So, instead we test all data against each authorization set. For the {@code INT&EXT2} data example, the server's
 * authorizations will allow the data to be returned since the server has INT. The user's authorizations will not allow the data to be returned however
 * since the user has neither INT nor EXT2. In this scenario, the result for {@link AuthorizationsListBase#getAllAuths()} will contain both INT and EXT1
 * even though the user does not have INT. The INT auth must be passed when queries are created, else no data would be returned (since the INT auth would be
 * removed from the server's auths and then no data would be returned).
 * <p>
 * For most use cases, a GUI can compute the intersection of all authorizations that are not domains and then include the union of organizations. This will
 * not always be the case, however. Consider data marked with something like: {@code FOO&INT|FOO&EXT}. If a system needs to support querying data such as
 * that, then a simple intersection of everything except organization will no longer work.
 * <p>
 * Note that the the return type can be changed by specifying an Accept header, or by adding a suffix to the request URL. The following suffix to return
 * type mppings are:
 * <ul>
 * <li>txt: text/plain
 * <li>xml: application/xml
 * <li>json: application/json
 * </ul>
 * For example, the URL
 *
 * <pre>
 * &lt;baseURL&gt;/User/listEffectiveAuthorizations.json
 * </pre>
 *
 * will return the results in JSON format.
 *
 * @return the user and proxied entities' authorizations
 */
@GET
@Path("/listEffectiveAuthorizations")
@Produces({ "application/xml", "text/xml", "text/plain", "application/json", "text/yaml", "text/x-yaml", "application/x-yaml", "application/x-protobuf", "text/html" })
public AuthorizationsListBase listEffectiveAuthorizations() {
    final AuthorizationsListBase list = responseObjectFactory.getAuthorizationsList();
    // Find out who/what called this method
    Principal p = context.getCallerPrincipal();
    String name = p.getName();
    if (p instanceof DatawavePrincipal) {
        DatawavePrincipal datawavePrincipal = (DatawavePrincipal) p;
        name = datawavePrincipal.getShortName();
        // Add the user DN's auths into the authorization list
        DatawaveUser primaryUser = datawavePrincipal.getPrimaryUser();
        list.setUserAuths(primaryUser.getDn().subjectDN(), primaryUser.getDn().issuerDN(), new HashSet<>(primaryUser.getAuths()));
        // Now add all entity auth sets into the list
        datawavePrincipal.getProxiedUsers().forEach(u -> list.addAuths(u.getDn().subjectDN(), u.getDn().issuerDN(), new HashSet<>(u.getAuths())));
        // Add the role to authorization mapping.
        // NOTE: Currently this is only added for the primary user, which is really all anyone should care about in terms of mucking with
        // authorizations. When used for queries, all non-primary users have all of their auths included -- there is no downgrading.
        list.setAuthMapping(datawavePrincipal.getPrimaryUser().getRoleToAuthMapping().asMap());
    }
    log.trace(name + " has authorizations union " + list.getAllAuths());
    return list;
}
Also used : DatawaveUser(datawave.security.authorization.DatawaveUser) DatawavePrincipal(datawave.security.authorization.DatawavePrincipal) Principal(java.security.Principal) DatawavePrincipal(datawave.security.authorization.DatawavePrincipal) AuthorizationsListBase(datawave.user.AuthorizationsListBase) HashSet(java.util.HashSet) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET)

Aggregations

DatawavePrincipal (datawave.security.authorization.DatawavePrincipal)93 DatawaveUser (datawave.security.authorization.DatawaveUser)41 Principal (java.security.Principal)37 HashSet (java.util.HashSet)33 Test (org.junit.Test)29 QueryException (datawave.webservice.query.exception.QueryException)24 Connector (org.apache.accumulo.core.client.Connector)23 IOException (java.io.IOException)19 DatawaveWebApplicationException (datawave.webservice.common.exception.DatawaveWebApplicationException)18 NotFoundQueryException (datawave.webservice.query.exception.NotFoundQueryException)18 Authorizations (org.apache.accumulo.core.security.Authorizations)17 Query (datawave.webservice.query.Query)16 UnauthorizedQueryException (datawave.webservice.query.exception.UnauthorizedQueryException)15 NoResultsException (datawave.webservice.common.exception.NoResultsException)13 ArrayList (java.util.ArrayList)13 Path (javax.ws.rs.Path)13 Produces (javax.ws.rs.Produces)13 SubjectIssuerDNPair (datawave.security.authorization.SubjectIssuerDNPair)12 WebApplicationException (javax.ws.rs.WebApplicationException)12 BadRequestException (datawave.webservice.common.exception.BadRequestException)11