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);
}
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);
}
}
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);
}
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;
}
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());
}
Aggregations