Search in sources :

Example 1 with AclEvalResult

use of won.auth.model.AclEvalResult 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 AclEvalResult

use of won.auth.model.AclEvalResult 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 3 with AclEvalResult

use of won.auth.model.AclEvalResult 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 4 with AclEvalResult

use of won.auth.model.AclEvalResult 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)

Example 5 with AclEvalResult

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

the class AclEnforcer method isAccessGranted.

private static boolean isAccessGranted(WonAclEvalContext wonAclEvalContext, Connection con) {
    OperationRequest or = populateOperationRequest(wonAclEvalContext, con);
    AclEvalResult result = wonAclEvalContext.decideAndRemember(or);
    return DecisionValue.ACCESS_GRANTED.equals(result.getDecision());
}
Also used : OperationRequest(won.auth.model.OperationRequest) AclEvalResult(won.auth.model.AclEvalResult)

Aggregations

AclEvalResult (won.auth.model.AclEvalResult)10 URI (java.net.URI)7 OperationRequest (won.auth.model.OperationRequest)7 Dataset (org.apache.jena.query.Dataset)5 RequestMapping (org.springframework.web.bind.annotation.RequestMapping)3 WonAclEvalContext (won.node.springsecurity.acl.WonAclEvalContext)3 NoSuchAtomException (won.protocol.exception.NoSuchAtomException)3 HttpStatus (org.springframework.http.HttpStatus)2 ResponseEntity (org.springframework.http.ResponseEntity)2 NoSuchConnectionException (won.protocol.exception.NoSuchConnectionException)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 Graph (org.apache.jena.graph.Graph)1 NoSuchMessageException (org.springframework.context.NoSuchMessageException)1 HttpHeaders (org.springframework.http.HttpHeaders)1 PreAuthorize (org.springframework.security.access.prepost.PreAuthorize)1 Transactional (org.springframework.transaction.annotation.Transactional)1