use of org.structr.core.entity.Security in project structr by structr.
the class CreateNodeCommand method createNode.
// ----- private methods -----
private Node createNode(final DatabaseService graphDb, final Principal user, final Set<String> labels, final Map<String, Object> properties) throws FrameworkException {
final Map<String, Object> parameters = new HashMap<>();
final Map<String, Object> ownsProperties = new HashMap<>();
final Map<String, Object> securityProperties = new HashMap<>();
final StringBuilder buf = new StringBuilder();
final String newUuid = (String) properties.get("id");
final String tenantId = graphDb.getTenantIdentifier();
if (user != null && user.shouldSkipSecurityRelationships() == false) {
buf.append("MATCH (u:Principal) WHERE id(u) = {userId}");
buf.append(" CREATE (u)-[o:OWNS {ownsProperties}]->(n");
if (tenantId != null) {
buf.append(":");
buf.append(tenantId);
}
for (final String label : labels) {
buf.append(":");
buf.append(label);
}
buf.append(" {nodeProperties})<-[s:SECURITY {securityProperties}]-(u)");
buf.append(" RETURN n");
// configure OWNS relationship
ownsProperties.put(GraphObject.id.dbName(), getNextUuid());
ownsProperties.put(GraphObject.type.dbName(), PrincipalOwnsNode.class.getSimpleName());
ownsProperties.put(AbstractRelationship.sourceId.dbName(), user.getUuid());
ownsProperties.put(AbstractRelationship.targetId.dbName(), newUuid);
// configure SECURITY relationship
securityProperties.put(Security.allowed.dbName(), new String[] { Permission.read.name(), Permission.write.name(), Permission.delete.name(), Permission.accessControl.name() });
securityProperties.put(GraphObject.id.dbName(), getNextUuid());
securityProperties.put(GraphObject.type.dbName(), Security.class.getSimpleName());
securityProperties.put(AbstractRelationship.sourceId.dbName(), user.getUuid());
securityProperties.put(AbstractRelationship.targetId.dbName(), newUuid);
// store properties in statement
parameters.put("userId", user.getId());
parameters.put("ownsProperties", ownsProperties);
parameters.put("securityProperties", securityProperties);
} else {
buf.append("CREATE (n");
if (tenantId != null) {
buf.append(":");
buf.append(tenantId);
}
for (final String label : labels) {
buf.append(":");
buf.append(label);
}
buf.append(" {nodeProperties})");
buf.append(" RETURN n");
}
// make properties available to Cypher statement
parameters.put("nodeProperties", properties);
final NativeResult result = graphDb.execute(buf.toString(), parameters);
try {
if (result.hasNext()) {
final Map<String, Object> data = result.next();
final Node newNode = (Node) data.get("n");
return newNode;
}
} catch (DataFormatException dex) {
throw new FrameworkException(422, dex.getMessage());
} catch (ConstraintViolationException qex) {
throw new FrameworkException(422, qex.getMessage());
}
throw new RuntimeException("Unable to create new node.");
}
use of org.structr.core.entity.Security in project structr by structr.
the class DOMNode method getSecurityInstructions.
static void getSecurityInstructions(final DOMNode thisNode, final Set<String> instructions) {
final Principal _owner = thisNode.getOwnerNode();
if (_owner != null) {
instructions.add("@structr:owner(" + _owner.getProperty(AbstractNode.name) + ")");
}
for (final Security security : thisNode.getSecurityRelationships()) {
if (security != null) {
final Principal grantee = security.getSourceNode();
final Set<String> perms = security.getPermissions();
final StringBuilder shortPerms = new StringBuilder();
// first character only
for (final String perm : perms) {
if (perm.length() > 0) {
shortPerms.append(perm.substring(0, 1));
}
}
if (shortPerms.length() > 0) {
// ignore SECURITY-relationships without permissions
instructions.add("@structr:grant(" + grantee.getProperty(AbstractNode.name) + "," + shortPerms.toString() + ")");
}
}
}
}
use of org.structr.core.entity.Security in project structr by structr.
the class CopyPermissionsFunction method apply.
@Override
public Object apply(final ActionContext ctx, final Object caller, final Object[] sources) throws FrameworkException {
if (arrayHasLengthAndAllElementsNotNull(sources, 2)) {
final Object source = sources[0];
final Object target = sources[1];
if (source instanceof NodeInterface && target instanceof NodeInterface) {
final NodeInterface sourceNode = (NodeInterface) source;
final NodeInterface targetNode = (NodeInterface) target;
for (final Security security : sourceNode.getIncomingRelationships(Security.class)) {
final Principal principal = security.getSourceNode();
for (final String perm : security.getPermissions()) {
targetNode.grant(Permissions.valueOf(perm), principal);
}
}
} else {
logParameterError(caller, sources, ctx.isJavaScriptContext());
}
} else {
return usage(ctx.isJavaScriptContext());
}
return null;
}
use of org.structr.core.entity.Security in project structr by structr.
the class BasicTest method testRelationshipsOnNodeCreation.
@Test
public void testRelationshipsOnNodeCreation() {
Principal user = null;
TestOne test = null;
// create user
try (final Tx tx = app.tx()) {
user = app.create(Principal.class, "tester");
tx.success();
} catch (FrameworkException fex) {
logger.warn("", fex);
fail("Unexpected exception.");
}
final SecurityContext ctx = SecurityContext.getInstance(user, AccessMode.Backend);
final App app = StructrApp.getInstance(ctx);
// create object with user context
try (final Tx tx = app.tx()) {
test = app.create(TestOne.class);
tx.success();
} catch (FrameworkException fex) {
logger.warn("", fex);
fail("Unexpected exception.");
}
// query for relationships
try (final Tx tx = app.tx()) {
final List<? extends RelationshipInterface> rels1 = app.relationshipQuery().and(AbstractRelationship.sourceId, user.getUuid()).getAsList();
final List<Class> classes1 = rels1.stream().map(r -> r.getClass()).collect(Collectors.toList());
assertEquals("Invalid number of relationships after object creation", 2, rels1.size());
assertTrue("Invalid relationship type after object creation", classes1.contains(Security.class));
assertTrue("Invalid relationship type after object creation", classes1.contains(PrincipalOwnsNode.class));
final List<? extends RelationshipInterface> rels2 = app.relationshipQuery().and(AbstractRelationship.targetId, test.getUuid()).getAsList();
final List<Class> classes2 = rels2.stream().map(r -> r.getClass()).collect(Collectors.toList());
assertEquals("Invalid number of relationships after object creation", 2, rels2.size());
assertTrue("Invalid relationship type after object creation", classes2.contains(Security.class));
assertTrue("Invalid relationship type after object creation", classes2.contains(PrincipalOwnsNode.class));
final List<? extends RelationshipInterface> rels3 = Iterables.toList(test.getIncomingRelationships());
final List<Class> classes3 = rels3.stream().map(r -> r.getClass()).collect(Collectors.toList());
assertEquals("Invalid number of relationships after object creation", 2, rels3.size());
assertTrue("Invalid relationship type after object creation", classes3.contains(Security.class));
assertTrue("Invalid relationship type after object creation", classes3.contains(PrincipalOwnsNode.class));
final Security sec = app.relationshipQuery(Security.class).getFirst();
assertNotNull("Relationship caching on node creation is broken", sec);
final PrincipalOwnsNode owns = app.relationshipQuery(PrincipalOwnsNode.class).getFirst();
assertNotNull("Relationship caching on node creation is broken", owns);
tx.success();
} catch (FrameworkException fex) {
logger.warn("", fex);
fail("Unexpected exception.");
}
}
use of org.structr.core.entity.Security in project structr by structr.
the class DeploymentTest method hash.
private void hash(final NodeInterface node, final StringBuilder buf) {
// AbstractNode
buf.append(valueOrEmpty(node, AbstractNode.type));
buf.append(valueOrEmpty(node, AbstractNode.name));
buf.append(valueOrEmpty(node, AbstractNode.visibleToPublicUsers));
buf.append(valueOrEmpty(node, AbstractNode.visibleToAuthenticatedUsers));
// include owner in content hash generation!
final Principal owner = node.getOwnerNode();
if (owner != null) {
buf.append(valueOrEmpty(owner, AbstractNode.name));
}
// include grants in content hash generation!
for (final Security r : node.getSecurityRelationships()) {
if (r != null) {
buf.append(r.getSourceNode().getName());
buf.append(r.getPermissions());
}
}
// DOMNode
buf.append(valueOrEmpty(node, StructrApp.key(DOMNode.class, "showConditions")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMNode.class, "hideConditions")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMNode.class, "showForLocales")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMNode.class, "hideForLocales")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMNode.class, "hideOnIndex")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMNode.class, "hideOnDetail")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMNode.class, "renderDetails")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMNode.class, "sharedComponentConfiguration")));
if (node instanceof DOMNode) {
final Page ownerDocument = ((DOMNode) node).getOwnerDocument();
if (ownerDocument != null) {
buf.append(valueOrEmpty(ownerDocument, AbstractNode.name));
}
}
// DOMElement
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "dataKey")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "restQuery")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "cypherQuery")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "xpathQuery")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "functionQuery")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "data-structr-reload")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "data-structr-confirm")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "data-structr-action")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "data-structr-attributes")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "data-structr-attr")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "data-structr-name")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "data-structr-hide")));
buf.append(valueOrEmpty(node, StructrApp.key(DOMElement.class, "data-structr-raw-value")));
// Content
buf.append(valueOrEmpty(node, StructrApp.key(Content.class, "contentType")));
buf.append(valueOrEmpty(node, StructrApp.key(Content.class, "content")));
// Page
buf.append(valueOrEmpty(node, StructrApp.key(Page.class, "cacheForSeconds")));
buf.append(valueOrEmpty(node, StructrApp.key(Page.class, "dontCache")));
buf.append(valueOrEmpty(node, StructrApp.key(Page.class, "pageCreatesRawData")));
buf.append(valueOrEmpty(node, StructrApp.key(Page.class, "position")));
buf.append(valueOrEmpty(node, StructrApp.key(Page.class, "showOnErrorCodes")));
// HTML attributes
if (node instanceof DOMElement) {
for (final PropertyKey key : ((DOMElement) node).getHtmlAttributes()) {
buf.append(valueOrEmpty(node, key));
}
}
for (final PropertyKey key : node.getPropertyKeys(PropertyView.All)) {
if (!key.isPartOfBuiltInSchema()) {
buf.append(valueOrEmpty(node, key));
}
}
}
Aggregations