use of com.manydesigns.portofino.actions.ActionDescriptor in project Portofino by ManyDesigns.
the class CrudActionTest method testBlobs.
public void testBlobs() throws Exception {
MutableHttpServletRequest req = new MutableHttpServletRequest();
ElementsThreadLocals.setMultipart(req);
req.getServletContext().setInitParameter("portofino.api.root", "http://fake");
req.makeMultipart();
Column column = DatabaseLogic.findColumnByName(persistence.getModel(), "jpetstore", "PUBLIC", "PRODUCT", "DESCN");
Annotation ann = new Annotation(column, FileBlob.class.getName());
column.getAnnotations().add(ann);
persistence.initModel();
CrudAction crudAction = new CrudAction() {
public void commitTransaction() {
super.commitTransaction();
session.beginTransaction();
}
@NotNull
@Override
protected ClassAccessor filterAccordingToPermissions(ClassAccessor classAccessor) {
// Let's ignore Shiro
return classAccessor;
}
@Override
protected String getUrlEncoding() {
return PortofinoProperties.URL_ENCODING_DEFAULT;
}
};
CrudConfiguration configuration = new CrudConfiguration();
configuration.setDatabase("jpetstore");
configuration.setQuery("from product");
String metaFilenamePattern = "blob-{0}.properties";
String dataFilenamePattern = "blob-{0}.data";
crudAction.blobManager = new HierarchicalBlobManager(new File(System.getProperty("java.io.tmpdir")), metaFilenamePattern, dataFilenamePattern);
CrudProperty property = new CrudProperty();
property.setName("productid");
property.setEnabled(true);
property.setInsertable(true);
property.setUpdatable(true);
configuration.getProperties().add(property);
property = new CrudProperty();
property.setName("category");
property.setEnabled(true);
property.setInsertable(true);
property.setUpdatable(true);
configuration.getProperties().add(property);
property = new CrudProperty();
property.setName("descn");
property.setEnabled(true);
property.setInsertable(true);
property.setUpdatable(true);
configuration.getProperties().add(property);
property = new CrudProperty();
property.setName("name");
property.setEnabled(true);
property.setInsertable(true);
property.setUpdatable(true);
ann = new Annotation(column, Required.class.getName());
ann.getProperties().add(new Property("value", "true"));
property.getAnnotations().add(ann);
configuration.getProperties().add(property);
configuration.persistence = persistence;
configuration.init();
ActionInstance actionInstance = new ActionInstance(null, null, new ActionDescriptor(), CrudAction.class);
actionInstance.setConfiguration(configuration);
actionInstance.getParameters().add("1");
ActionContext actionContext = new ActionContext();
actionContext.setRequest(req);
actionContext.setActionPath("");
actionContext.setServletContext(req.getServletContext());
req.setParameter("productid", "1");
Map category = (Map) persistence.getSession("jpetstore").createQuery("from category").list().get(0);
req.setParameter("category", (String) category.get("catid"));
crudAction.persistence = persistence;
crudAction.setContext(actionContext);
crudAction.setActionInstance(actionInstance);
crudAction.init();
crudAction.setupForm(Mode.CREATE);
Field descnField = crudAction.getForm().findFieldByPropertyName("descn");
assertNotNull(descnField);
assertTrue(descnField instanceof FileBlobField);
File tmpFile = File.createTempFile("blob", "blob");
DiskFileItem fileItem = new DiskFileItem("descn", "application/octet-stream", false, tmpFile.getName(), 0, tmpFile.getParentFile()) {
@Override
public void delete() {
// Do nothing as we want to reuse this
}
};
OutputStream os = fileItem.getOutputStream();
IOUtils.write("some test data", os, req.getCharacterEncoding());
req.addFileItem("descn", fileItem);
req.setParameter("descn_operation", AbstractBlobField.UPLOAD_MODIFY);
crudAction.httpPostMultipart();
assertFalse(crudAction.form.validate());
AbstractBlobField blobField = (AbstractBlobField) crudAction.form.findFieldByPropertyName("descn");
assertNotNull(blobField.getValue());
assertEquals(tmpFile.getName(), blobField.getValue().getFilename());
assertEquals(fileItem.getSize(), blobField.getValue().getSize());
try {
crudAction.getBlobManager().loadMetadata(new Blob(blobField.getValue().getCode()));
fail("The blob was saved despite validation failing");
} catch (Exception e) {
}
crudAction.object = null;
req.setParameter(blobField.getCodeInputName(), blobField.getValue().getCode());
req.setParameter("name", "name");
req.setParameter("productid", "1");
req.setParameter("category", "BIRDS");
crudAction.httpPostMultipart();
assertTrue(crudAction.form.validate());
blobField = (FileBlobField) crudAction.form.findFieldByPropertyName("descn");
assertNotNull(blobField.getValue());
// This is necessary because the crud might reload the form
crudAction.blobManager.loadMetadata(blobField.getValue());
assertEquals(tmpFile.getName(), blobField.getValue().getFilename());
assertEquals(fileItem.getSize(), blobField.getValue().getSize());
try {
crudAction.blobManager.loadMetadata(new Blob(blobField.getValue().getCode()));
} catch (IOException e) {
e.printStackTrace();
fail("The blob was not saved");
}
crudAction.httpPutMultipart();
assertTrue(crudAction.form.validate());
blobField = (FileBlobField) crudAction.form.findFieldByPropertyName("descn");
assertNotNull(blobField.getValue());
// This is necessary because the crud might reload the form
crudAction.blobManager.loadMetadata(blobField.getValue());
assertEquals(tmpFile.getName(), blobField.getValue().getFilename());
String oldBlobCode = blobField.getValue().getCode();
assertEquals(fileItem.getSize(), blobField.getValue().getSize());
req.setParameter("descn_operation", FileBlobField.UPLOAD_MODIFY);
req.setFileItem("descn", fileItem);
crudAction.httpPutMultipart();
assertTrue(crudAction.form.validate());
blobField = (FileBlobField) crudAction.form.findFieldByPropertyName("descn");
assertNotNull(blobField.getValue());
// This is necessary because the crud might reload the form
crudAction.blobManager.loadMetadata(blobField.getValue());
assertEquals(tmpFile.getName(), blobField.getValue().getFilename());
String newBlobCode = blobField.getValue().getCode();
assertNotEquals(oldBlobCode, newBlobCode);
crudAction.blobManager.loadMetadata(new Blob(newBlobCode));
try {
crudAction.blobManager.loadMetadata(new Blob(oldBlobCode));
fail("The blob " + oldBlobCode + " should have been deleted");
} catch (IOException e) {
// Ok
}
Session session = persistence.getSession("jpetstore");
session.flush();
Object id = ((Map) crudAction.object).get("productid");
int qres = session.createSQLQuery("update product set descn = 'illegal' where productid = :id").setParameter("id", id).executeUpdate();
assertEquals(1, qres);
session.flush();
session.getTransaction().commit();
session.clear();
session.beginTransaction();
// Force loading the object from the DB
crudAction.getParameters().add(id.toString());
crudAction.parametersAcquired();
crudAction.setupForm(Mode.VIEW);
crudAction.form.readFromObject(crudAction.object);
BlobUtils.loadBlobs(crudAction.form, crudAction.getBlobManager(), false);
blobField = (FileBlobField) crudAction.form.findFieldByPropertyName("descn");
assertNotNull(blobField.getValue());
assertNotNull(blobField.getBlobError());
assertNull(blobField.getValue().getFilename());
qres = session.createSQLQuery("update product set descn = :blobCode where productid = :id").setParameter("id", id).setParameter("blobCode", newBlobCode).executeUpdate();
assertEquals(1, qres);
session.flush();
session.getTransaction().commit();
session.clear();
session.beginTransaction();
// Force reload
crudAction.parametersAcquired();
crudAction.httpDelete(Collections.emptyList());
try {
crudAction.blobManager.loadMetadata(new Blob(newBlobCode));
fail("The blob " + newBlobCode + " should have been deleted");
} catch (IOException e) {
// Ok
}
}
use of com.manydesigns.portofino.actions.ActionDescriptor in project Portofino by ManyDesigns.
the class PortofinoRoot method init.
@Override
public PortofinoRoot init() {
super.init();
ActionDescriptor rootActionDescriptor = ActionLogic.getActionDescriptor(location);
ActionInstance actionInstance = new ActionInstance(null, location, rootActionDescriptor, getClass());
setActionInstance(actionInstance);
ActionContext context = new ActionContext();
context.setServletContext(servletContext);
context.setRequest(request);
context.setResponse(response);
context.setActionPath("/");
setContext(context);
applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
autowire(this);
return this;
}
use of com.manydesigns.portofino.actions.ActionDescriptor in project Portofino by ManyDesigns.
the class SecurityLogic method calculateActualPermissions.
public static Permissions calculateActualPermissions(Permissions basePermissions, List<ActionDescriptor> actionDescriptors) {
Permissions result = new Permissions();
Map<String, AccessLevel> resultLevels = result.getActualLevels();
resultLevels.putAll(basePermissions.getActualLevels());
for (ActionDescriptor current : actionDescriptors) {
Permissions currentPerms = current.getPermissions();
Map<String, AccessLevel> currentLevels = currentPerms.getActualLevels();
for (Map.Entry<String, AccessLevel> entry : currentLevels.entrySet()) {
String currentGroup = entry.getKey();
AccessLevel currentLevel = entry.getValue();
AccessLevel resultLevel = resultLevels.get(currentGroup);
if (resultLevel != AccessLevel.DENY && currentLevel != null) {
resultLevels.put(currentGroup, currentLevel);
}
}
}
if (actionDescriptors.size() > 0) {
ActionDescriptor lastAction = actionDescriptors.get(actionDescriptors.size() - 1);
Map<String, Set<String>> lastPermissions = lastAction.getPermissions().getActualPermissions();
result.getActualPermissions().putAll(lastPermissions);
} else {
result.getActualPermissions().putAll(basePermissions.getActualPermissions());
}
return result;
}
use of com.manydesigns.portofino.actions.ActionDescriptor in project Portofino by ManyDesigns.
the class UpstairsAction method createCrudAction.
protected ActionDescriptor createCrudAction(ConnectionProvider connectionProvider, FileObject dir, Table table, String query, Template template, Map<String, String> bindings, Table userTable, Column userPasswordColumn, List<Map> createdPages, int depth) throws Exception {
if (dir.exists()) {
RequestMessages.addWarningMessage(ElementsThreadLocals.getText("directory.exists.page.not.created._", dir.getName().getPath()));
} else {
dir.createFolder();
logger.info("Creating CRUD action {}", dir.getName().getPath());
CrudConfiguration configuration = new CrudConfiguration();
configuration.setDatabase(table.getDatabaseName());
configuration.setupDefaults();
configuration.setQuery(query);
String variable = table.getActualEntityName();
configuration.setVariable(variable);
detectLargeResultSet(connectionProvider, table, configuration);
configuration.setName(table.getActualEntityName());
int summ = 0;
String linkToParentProperty = bindings.get("linkToParentProperty");
for (Column column : table.getColumns()) {
String name = column.getColumnName();
boolean isPassword = column.equals(userPasswordColumn) || (column.getActualJavaType() == String.class && ("password".equalsIgnoreCase(name) || "pwd".equalsIgnoreCase(name)));
summ = setupColumn(connectionProvider, column, configuration, summ, linkToParentProperty, isPassword);
}
ActionLogic.saveConfiguration(dir, configuration);
ActionDescriptor action = new ActionDescriptor();
ActionLogic.saveActionDescriptor(dir, action);
FileObject actionFile = dir.resolveFile("action.groovy");
try (Writer fileWriter = new OutputStreamWriter(actionFile.getContent().getOutputStream())) {
template.make(bindings).writeTo(fileWriter);
}
logger.debug("Creating _detail directory");
FileObject detailDir = dir.resolveFile(ActionInstance.DETAIL);
if (detailDir.exists() && detailDir.getType() != FileType.FOLDER) {
logger.warn("Invalid detail directory {}", detailDir.getName().getPath());
RequestMessages.addWarningMessage(ElementsThreadLocals.getText("invalid.detail.directory", detailDir.getName().getPath()));
} else {
detailDir.createFolder();
}
String path = dir.getName().getBaseName();
// two because of _detail
FileObject parent = dir.getParent().getParent();
for (int i = 1; i < depth; i++) {
path = parent.getName().getBaseName() + "/" + ActionInstance.DETAIL + "/" + path;
parent = parent.getParent().getParent();
}
Map<String, Object> pageInfo = new HashMap<>();
pageInfo.put("path", path);
pageInfo.put("detail", depth > 1);
pageInfo.put("type", "crud");
pageInfo.put("title", Util.guessToWords(dir.getName().getBaseName()));
createdPages.add(pageInfo);
if (depth < maxDepth) {
List<Reference> children = computeChildren(table);
for (Reference ref : children) {
createChildCrudAction(connectionProvider, dir, template, variable, children, ref, userTable, userPasswordColumn, createdPages, depth);
}
}
return action;
}
return null;
}
use of com.manydesigns.portofino.actions.ActionDescriptor in project Portofino by ManyDesigns.
the class UpstairsAction method setupUserPages.
protected void setupUserPages(ConnectionProvider connectionProvider, Template template, Table userTable, List<Map> createdPages) throws Exception {
List<Reference> references = computeChildren(userTable);
if (references != null) {
for (Reference ref : references) {
Column fromColumn = ref.getActualFromColumn();
Column toColumn = ref.getActualToColumn();
Table fromTable = fromColumn.getTable();
Table toTable = toColumn.getTable();
String entityName = fromTable.getActualEntityName();
List<Column> pkColumns = toTable.getPrimaryKey().getColumns();
if (!pkColumns.contains(toColumn)) {
continue;
}
String linkToUserProperty = fromColumn.getActualPropertyName();
String childQuery = "from " + entityName + " where " + linkToUserProperty + " = %{#securityUtils.primaryPrincipal.id}" + " order by id desc";
String dirName = "my-" + entityName;
boolean multipleRoles = isMultipleRoles(fromTable, ref, references);
if (multipleRoles) {
dirName += "-as-" + linkToUserProperty;
}
FileObject dir = actionsDirectory.resolveFile(dirName);
Map<String, String> bindings = new HashMap<>();
bindings.put("generatedClassName", "UserManagementCrudAction");
bindings.put("parentName", "securityUtils");
bindings.put("parentProperty", "primaryPrincipal.id");
bindings.put("linkToParentProperty", linkToUserProperty);
ActionDescriptor action = createCrudAction(connectionProvider, dir, fromTable, childQuery, template, bindings, null, null, createdPages, 1);
if (action != null) {
Group group = new Group();
group.setName(SecurityLogic.getAnonymousGroup(portofinoConfiguration));
group.setAccessLevel(AccessLevel.DENY.name());
Permissions permissions = new Permissions();
permissions.getGroups().add(group);
action.setPermissions(permissions);
ActionLogic.saveActionDescriptor(dir, action);
}
}
}
}
Aggregations