Search in sources :

Example 1 with OperationRequest

use of won.auth.model.OperationRequest in project webofneeds by researchstudio-sat.

the class AclChecker method process.

@Override
public void process(Exchange exchange) throws Exception {
    URI recipientAtomUri = WonCamelHelper.getRecipientAtomURIRequired(exchange);
    WonMessage message = WonCamelHelper.getMessageRequired(exchange);
    if (message.getMessageType().isCreateAtom()) {
        // no checks required for a create message
        return;
    }
    if (message.getMessageType().isHintMessage()) {
        // no checks required for a hint message
        return;
    }
    URI signer = message.getSignerURIRequired();
    URI sender = message.getSenderAtomURIRequired();
    URI senderNode = message.getSenderNodeURIRequired();
    WonMessageDirection direction = WonCamelHelper.getDirectionRequired(exchange);
    if (direction.isFromExternal() || direction.isFromSystem()) {
        if (signer.equals(senderNode)) {
            // nodes are allowed to messages on behalf of an atom (for now)
            return;
        }
    }
    Atom atom = atomService.getAtomForMessageRequired(message, direction);
    Optional<Graph> aclGraph = atom.getAclGraph();
    if (aclGraph.isEmpty()) {
        // no checks if no acl present
        if (!sender.equals(signer)) {
            throw new IllegalMessageSignerException(String.format("%s must not be signer of %s message %s", signer, message.getMessageTypeRequired(), message.getMessageURIRequired()));
        }
        return;
    }
    boolean isMessageOnBehalf = false;
    URI requestor = sender;
    if (direction.isFromOwner()) {
        if (signer.equals(sender)) {
            // no checks if the owner is the signer
            return;
        } else {
            isMessageOnBehalf = true;
            requestor = signer;
        }
    }
    OperationRequest operationRequest = OperationRequest.builder().setReqAtom(atom.getAtomURI()).setReqAtomState(AuthUtils.toAuthAtomState(atom.getState())).setRequestor(requestor).build();
    if (message.getMessageType().isConnectionSpecificMessage()) {
        if (direction.isFromOwner() || direction.isFromSystem()) {
            Optional<Socket> s = socketService.getSocket(message.getSenderSocketURIRequired());
            operationRequest.setReqSocketType(s.get().getTypeURI());
            operationRequest.setReqSocket(s.get().getSocketURI());
        } else if (direction.isFromExternal()) {
            Optional<Socket> s = socketService.getSocket(message.getRecipientSocketURIRequired());
            operationRequest.setReqSocketType(s.get().getTypeURI());
            operationRequest.setReqSocket(s.get().getSocketURI());
        }
    } else {
        operationRequest.setReqPosition(POSITION_ROOT);
    }
    Optional<Connection> con = WonCamelHelper.getConnection(exchange, connectionService);
    if (con.isPresent()) {
        operationRequest.setReqPosition(POSITION_CONNECTION);
        Connection c = con.get();
        operationRequest.setReqConnection(c.getConnectionURI());
        operationRequest.setReqConnectionTargetAtom(c.getTargetAtomURI());
        operationRequest.setReqConnectionState(AuthUtils.toAuthConnectionState(c.getState()));
        // we already set these values, but now that we know we have a connection, make
        // sure these values match the connection's
        operationRequest.setReqSocketType(c.getTypeURI());
        operationRequest.setReqSocket(c.getSocketURI());
    } else {
        operationRequest.setReqPosition(POSITION_SOCKET);
    }
    if (isMessageOnBehalf) {
        operationRequest.setOperationMessageOperationExpression(MessageOperationExpression.builder().addMessageOnBehalfsMessageType(AuthUtils.toAuthMessageType(message.getMessageType())).build());
    } else {
        operationRequest.setOperationMessageOperationExpression(MessageOperationExpression.builder().addMessageTosMessageType(AuthUtils.toAuthMessageType(message.getMessageType())).build());
    }
    WonAclEvaluator evaluator = wonAclEvaluatorFactory.create(aclGraph.get());
    if (message.getMessageType().isReplace()) {
    // decision for replace messages is deferred to where replacement actually
    // happens
    } else {
        AclEvalResult result = evaluator.decide(operationRequest);
        if (DecisionValue.ACCESS_DENIED.equals(result.getDecision())) {
            throw new ForbiddenMessageException(String.format("Message not allowed"));
        }
    }
    WonCamelHelper.putWonAclEvaluator(exchange, evaluator);
    WonCamelHelper.putWonAclOperationRequest(exchange, operationRequest);
}
Also used : Optional(java.util.Optional) OperationRequest(won.auth.model.OperationRequest) Connection(won.protocol.model.Connection) WonAclEvaluator(won.auth.WonAclEvaluator) AclEvalResult(won.auth.model.AclEvalResult) URI(java.net.URI) Atom(won.protocol.model.Atom) Graph(org.apache.jena.graph.Graph) ForbiddenMessageException(won.protocol.exception.ForbiddenMessageException) WonMessage(won.protocol.message.WonMessage) IllegalMessageSignerException(won.protocol.exception.IllegalMessageSignerException) WonMessageDirection(won.protocol.message.WonMessageDirection) Socket(won.protocol.model.Socket)

Example 2 with OperationRequest

use of won.auth.model.OperationRequest in project webofneeds by researchstudio-sat.

the class GrantedOperationsTest method testSet1.

@Test
public void testSet1() throws IOException {
    Shacl2JavaInstanceFactory factory = AuthUtils.instanceFactory();
    Shapes atomDataShapes = loadShapes(atomDataShapesDef);
    ModelBasedConnectionTargetCheckEvaluator targetAtomChecker = new ModelBasedConnectionTargetCheckEvaluator(atomDataShapes, "won.auth.test.model");
    ModelBasedAtomNodeChecker atomNodeChecker = new ModelBasedAtomNodeChecker(atomDataShapes, "won.auth.test.model");
    String folder = "set1";
    for (Resource socketGraphResource : getInputs(folder)) {
        String baseName = getTestBaseName(socketGraphResource.getFilename());
        Graph inputGraph = loadGraph(socketGraphResource);
        String testIdentifier = folder + "/" + baseName;
        logger.debug("running test {}", testIdentifier);
        validateTestData(atomDataShapes, inputGraph, true, testIdentifier);
        validateTestData(AuthUtils.shapes(), inputGraph, true, testIdentifier);
        Shacl2JavaInstanceFactory.Accessor ac = factory.accessor(inputGraph);
        targetAtomChecker.loadData(inputGraph);
        atomNodeChecker.loadData(inputGraph);
        Set<OperationRequest> operationRequestSet = ac.getInstancesOfType(OperationRequest.class);
        if (operationRequestSet.size() > 1) {
            Assert.fail("only one operationRequest allowed per file");
        }
        OperationRequest operationRequest = operationRequestSet.stream().findFirst().get();
        setValidTokenExpiryDate(operationRequest);
        WonAclEvaluatorTestFactory evaluatorFactory = new WonAclEvaluatorTestFactory(targetAtomChecker, atomNodeChecker, null);
        evaluatorFactory.load(inputGraph);
        WonAclEvaluator evaluator = evaluatorFactory.create(false);
        Optional<AseRoot> grantedOperations = evaluator.getGrants(operationRequest);
        Graph actualResult = RdfOutput.toGraph(grantedOperations.get(), false);
        actualResult = new Difference(actualResult, AuthUtils.shapes().getGraph());
        Graph expectedResult = loadGraph(new ClassPathResource("/won/grantedOps/" + folder + "/" + baseName + "-expected.ttl"));
        assertIsomorphicGraphs(expectedResult, actualResult, testIdentifier);
    }
}
Also used : ClassPathResource(org.springframework.core.io.ClassPathResource) Resource(org.springframework.core.io.Resource) OperationRequest(won.auth.model.OperationRequest) Difference(org.apache.jena.graph.compose.Difference) ClassPathResource(org.springframework.core.io.ClassPathResource) Graph(org.apache.jena.graph.Graph) Shapes(org.apache.jena.shacl.Shapes) AseRoot(won.auth.model.AseRoot) Shacl2JavaInstanceFactory(won.shacl2java.Shacl2JavaInstanceFactory) Test(org.junit.Test)

Example 3 with OperationRequest

use of won.auth.model.OperationRequest in project webofneeds by researchstudio-sat.

the class LinkedDataServiceImpl method getAtomDataset.

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, readOnly = true)
public DataWithEtag<Dataset> getAtomDataset(final URI atomUri, String etag, WonAclEvalContext wonAclEvalContext) {
    if (wonAclEvalContext == null) {
        wonAclEvalContext = WonAclEvalContext.allowAll();
    }
    Instant start = logger.isDebugEnabled() ? Instant.now() : null;
    DataWithEtag<Atom> atomDataWithEtag;
    try {
        atomDataWithEtag = atomInformationService.readAtom(atomUri, etag);
    } catch (NoSuchAtomException e) {
        if (logger.isDebugEnabled() && start != null) {
            Instant finish = Instant.now();
            logger.debug("getAtomDataset({}) took {}ms", atomUri, Duration.between(start, finish).toMillis());
        }
        return DataWithEtag.dataNotFound();
    }
    if (atomDataWithEtag.isNotFound()) {
        if (logger.isDebugEnabled() && start != null) {
            Instant finish = Instant.now();
            logger.debug("getAtomDataset({}) took {}ms", atomUri, Duration.between(start, finish).toMillis());
        }
        return DataWithEtag.dataNotFound();
    }
    if (!atomDataWithEtag.isChanged()) {
        if (logger.isDebugEnabled() && start != null) {
            Instant finish = Instant.now();
            logger.debug("getAtomDataset({}) took {}ms", atomUri, Duration.between(start, finish).toMillis());
        }
        return DataWithEtag.dataNotChanged(atomDataWithEtag);
    }
    Atom atom = atomDataWithEtag.getData();
    String newEtag = atomDataWithEtag.getEtag();
    // load the dataset from storage or use empty one
    boolean isDeleted = (atom.getState() == AtomState.DELETED);
    Dataset dataset = isDeleted ? DatasetFactory.createGeneral() : atom.getDatatsetHolder().getDataset();
    // filter by acl
    if (!isDeleted && wonAclEvalContext.isModeFilter()) {
        dataset = filterByAcl(atom.getAtomURI(), dataset, wonAclEvalContext);
    }
    // check acl: should we add sysinfo graph?
    AclEvalResult result = null;
    if (wonAclEvalContext.isModeFilter()) {
        URI sysInfoGraphUri = uriService.createSysInfoGraphURIForAtomURI(atomUri);
        OperationRequest operationRequest = AuthUtils.cloneShallow(wonAclEvalContext.getOperationRequest());
        operationRequest.setReqPosition(POSITION_ATOM_GRAPH);
        operationRequest.setReqGraphs(Collections.singleton(sysInfoGraphUri));
        result = wonAclEvalContext.decideAndRemember(operationRequest);
    }
    if (wonAclEvalContext.isModeAllowAll() || DecisionValue.ACCESS_GRANTED.equals(result.getDecision())) {
        addSysInfoGraph(atom, dataset);
    }
    // add prefixes
    addBaseUriAndDefaultPrefixes(dataset);
    if (logger.isDebugEnabled() && start != null) {
        Instant finish = Instant.now();
        logger.debug("getAtomDataset({}) took {} ms", atomUri, Duration.between(start, finish).toMillis());
    }
    if (dataset.isEmpty()) {
        return DataWithEtag.accessDenied();
    }
    return new DataWithEtag<>(dataset, newEtag, etag, isDeleted);
}
Also used : NoSuchAtomException(won.protocol.exception.NoSuchAtomException) Dataset(org.apache.jena.query.Dataset) Instant(java.time.Instant) OperationRequest(won.auth.model.OperationRequest) AclEvalResult(won.auth.model.AclEvalResult) URI(java.net.URI) UnreadMessageInfoForAtom(won.protocol.model.unread.UnreadMessageInfoForAtom) Transactional(org.springframework.transaction.annotation.Transactional)

Example 4 with OperationRequest

use of won.auth.model.OperationRequest in project webofneeds by researchstudio-sat.

the class LinkedDataServiceImpl method filterByAcl.

private Dataset filterByAcl(URI atomUri, Dataset dataset, WonAclEvalContext wonAclEvalContext) {
    Dataset filtered = DatasetFactory.createGeneral();
    String aclGraphUri = uriService.createAclGraphURIForAtomURI(atomUri).toString();
    String keyGraphUri = WonRelativeUriHelper.createKeyGraphURIForAtomURI(atomUri).toString();
    Iterator<String> graphUriIt = dataset.listNames();
    while (graphUriIt.hasNext()) {
        String graphUri = graphUriIt.next();
        OperationRequest operationRequest = wonAclEvalContext.getOperationRequest();
        operationRequest.setReqPosition(POSITION_ATOM_GRAPH);
        operationRequest.setReqGraphs(Collections.singleton(URI.create(graphUri)));
        if (graphUri.endsWith(WonMessage.SIGNATURE_URI_GRAPHURI_SUFFIX)) {
            // decide later: signature graphs are added for filtered graphs
            continue;
        }
        if (graphUri.equals(aclGraphUri)) {
            operationRequest.setReqGraphTypes(Collections.singleton(GraphType.ACL_GRAPH));
        } else if (graphUri.equals(keyGraphUri)) {
            operationRequest.setReqGraphTypes(Collections.singleton(GraphType.KEY_GRAPH));
        } else {
            operationRequest.setReqGraphTypes(Collections.singleton(GraphType.CONTENT_GRAPH));
        }
        AclEvalResult result = wonAclEvalContext.decideAndRemember(operationRequest);
        if (DecisionValue.ACCESS_GRANTED.equals(result.getDecision())) {
            filtered.addNamedModel(graphUri, dataset.getNamedModel(graphUri));
            String signatureGraphUri = graphUri + WonMessage.SIGNATURE_URI_GRAPHURI_SUFFIX;
            if (dataset.containsNamedModel(signatureGraphUri)) {
                filtered.addNamedModel(signatureGraphUri, dataset.getNamedModel(signatureGraphUri));
            }
        }
    }
    return filtered;
}
Also used : Dataset(org.apache.jena.query.Dataset) OperationRequest(won.auth.model.OperationRequest) AclEvalResult(won.auth.model.AclEvalResult)

Example 5 with OperationRequest

use of won.auth.model.OperationRequest in project webofneeds by researchstudio-sat.

the class ConnectionService method shouldSendAutoOpenForConnect.

public boolean shouldSendAutoOpenForConnect(WonMessage wonMessage, WonAclEvaluator wonAclEvaluator, OperationRequest operationRequest) {
    URI recipientSocketURI = wonMessage.getRecipientSocketURIRequired();
    Connection con = getConnection(recipientSocketURI, wonMessage.getSenderSocketURI()).get();
    if (con.getState() != ConnectionState.REQUEST_RECEIVED) {
        return false;
    }
    if (socketService.isAutoOpen(recipientSocketURI)) {
        return true;
    }
    if (wonAclEvaluator == null || operationRequest == null) {
        return false;
    }
    OperationRequest or = AuthUtils.cloneShallow(operationRequest);
    or.setOperationSimpleOperationExpression(OP_AUTO_CONNECT);
    or.setReqPosition(POSITION_SOCKET);
    or.setReqSocket(recipientSocketURI);
    or.setReqSocketType(con.getTypeURI());
    or.setReqConnectionState(AuthUtils.toAuthConnectionState(con.getState()));
    or.setReqConnection(con.getConnectionURI());
    AclEvalResult result = wonAclEvaluator.decide(or);
    return DecisionValue.ACCESS_GRANTED.equals(result.getDecision());
}
Also used : OperationRequest(won.auth.model.OperationRequest) AclEvalResult(won.auth.model.AclEvalResult) URI(java.net.URI)

Aggregations

OperationRequest (won.auth.model.OperationRequest)9 AclEvalResult (won.auth.model.AclEvalResult)7 URI (java.net.URI)5 Dataset (org.apache.jena.query.Dataset)3 Graph (org.apache.jena.graph.Graph)2 NoSuchAtomException (won.protocol.exception.NoSuchAtomException)2 Connection (won.protocol.model.Connection)2 URISyntaxException (java.net.URISyntaxException)1 ParseException (java.text.ParseException)1 Instant (java.time.Instant)1 Optional (java.util.Optional)1 Difference (org.apache.jena.graph.compose.Difference)1 Shapes (org.apache.jena.shacl.Shapes)1 Test (org.junit.Test)1 ClassPathResource (org.springframework.core.io.ClassPathResource)1 Resource (org.springframework.core.io.Resource)1 HttpHeaders (org.springframework.http.HttpHeaders)1 HttpStatus (org.springframework.http.HttpStatus)1 ResponseEntity (org.springframework.http.ResponseEntity)1 Transactional (org.springframework.transaction.annotation.Transactional)1