summaryrefslogtreecommitdiffstats
path: root/idrop-web
diff options
context:
space:
mode:
authorMike Conway <mikeconway@Mike-Conways-MacBook-Pro.local>2011-04-14 15:54:53 (GMT)
committer Mike Conway <mikeconway@Mike-Conways-MacBook-Pro.local>2011-04-14 15:54:53 (GMT)
commit6c9126780adc4b28ac2d0e6b5f84e333454882e6 (patch)
tree2ca975819ac7bbf2d34ae9d184f910bbed2bc9f3 /idrop-web
parent6ebe8300c5f9f1ac361881706dd105a096b765a0 (diff)
downloadQCG-Data-6c9126780adc4b28ac2d0e6b5f84e333454882e6.zip
QCG-Data-6c9126780adc4b28ac2d0e6b5f84e333454882e6.tar.gz
QCG-Data-6c9126780adc4b28ac2d0e6b5f84e333454882e6.tar.bz2
acl listing in web
Diffstat (limited to 'idrop-web')
-rw-r--r--idrop-web/grails-app/conf/Config.groovy4
-rw-r--r--idrop-web/grails-app/conf/UrlMappings.groovy3
-rw-r--r--idrop-web/grails-app/conf/spring/resources.groovy4
-rw-r--r--idrop-web/grails-app/controllers/org/irods/mydrop/controller/FileController.groovy11
-rw-r--r--idrop-web/grails-app/controllers/org/irods/mydrop/controller/SharingController.groovy78
-rw-r--r--idrop-web/grails-app/views/common/_panelmessages.gsp3
-rw-r--r--idrop-web/grails-app/views/common/_secondarymain.gsp4
-rw-r--r--idrop-web/grails-app/views/file/uploadDialog.gsp20
-rw-r--r--idrop-web/grails-app/views/home/index.gsp4
-rw-r--r--idrop-web/grails-app/views/login/login.gsp3
-rw-r--r--idrop-web/grails-app/views/metadata/metadataDetails.gsp14
-rw-r--r--idrop-web/grails-app/views/sharing/aclDetails.gsp55
-rw-r--r--idrop-web/src/templates/scaffolding/create.gsp61
-rw-r--r--idrop-web/src/templates/scaffolding/edit.gsp64
-rw-r--r--idrop-web/src/templates/scaffolding/list.gsp61
-rw-r--r--idrop-web/src/templates/scaffolding/show.gsp64
-rw-r--r--idrop-web/test/unit/org/irods/mydrop/controller/SharingControllerTests.groovy102
-rw-r--r--idrop-web/web-app/css/main.css49
-rw-r--r--idrop-web/web-app/js/mydrop/home.js60
19 files changed, 353 insertions, 311 deletions
diff --git a/idrop-web/grails-app/conf/Config.groovy b/idrop-web/grails-app/conf/Config.groovy
index 48aa191..bc351c2 100644
--- a/idrop-web/grails-app/conf/Config.groovy
+++ b/idrop-web/grails-app/conf/Config.groovy
@@ -60,7 +60,7 @@ grails.validateable.packages = ['org.irods']
// set per-environment serverURL stem for creating absolute links
environments {
- production { grails.serverURL = "http://irendb.renci.org:8080/${appName}" }
+ production { grails.serverURL = "http://iren-web.renci.org:8080/${appName}" }
development { grails.serverURL = "http://localhost:8080/${appName}" }
test { grails.serverURL = "http://localhost:8080/${appName}" }
}
@@ -94,7 +94,7 @@ log4j = {
warn 'org.mortbay.log'
debug 'org.irods.mydrop'
- info 'org.irods.jargon'
+ debug 'org.irods.jargon'
warn 'grails.app.controller'
warn 'org.springframework.security'
}
diff --git a/idrop-web/grails-app/conf/UrlMappings.groovy b/idrop-web/grails-app/conf/UrlMappings.groovy
index 20520eb..834929b 100644
--- a/idrop-web/grails-app/conf/UrlMappings.groovy
+++ b/idrop-web/grails-app/conf/UrlMappings.groovy
@@ -4,8 +4,7 @@ class UrlMappings {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
- }
-
+ }
}
//"/file/**" (controller:"file", action:"index")
diff --git a/idrop-web/grails-app/conf/spring/resources.groovy b/idrop-web/grails-app/conf/spring/resources.groovy
index ba48eef..18a2d2c 100644
--- a/idrop-web/grails-app/conf/spring/resources.groovy
+++ b/idrop-web/grails-app/conf/spring/resources.groovy
@@ -20,4 +20,8 @@ beans = {
irodsAccessObjectFactory = ref("irodsAccessObjectFactory")
}
+ sharingController(org.irods.mydrop.controller.MetadataController) {
+ irodsAccessObjectFactory = ref("irodsAccessObjectFactory")
+ }
+
}
diff --git a/idrop-web/grails-app/controllers/org/irods/mydrop/controller/FileController.groovy b/idrop-web/grails-app/controllers/org/irods/mydrop/controller/FileController.groovy
index 19923bf..1706ed0 100644
--- a/idrop-web/grails-app/controllers/org/irods/mydrop/controller/FileController.groovy
+++ b/idrop-web/grails-app/controllers/org/irods/mydrop/controller/FileController.groovy
@@ -117,7 +117,9 @@ class FileController {
render(view:"uploadDialog", model:[irodsTargetCollection:irodsTargetCollection])
}
- //FIXME: move to flash for these errors?
+ /**
+ * Process an actual call to upload data to iRODS as a multi-part file
+ */
def upload = {
log.info("upload action in file controller")
def f = request.getFile('file')
@@ -149,13 +151,6 @@ class FileController {
irodsFileOutputStream.flush()
irodsFileOutputStream.close()
- def jsonBuff = []
-
- jsonBuff.add(
- ["name": name, "type":"blah", "size":100]
- )
-
- //render jsonBuff as JSON
render "{\"name\":\"${name}\",\"type\":\"image/jpeg\",\"size\":\"1000\"}"
}
diff --git a/idrop-web/grails-app/controllers/org/irods/mydrop/controller/SharingController.groovy b/idrop-web/grails-app/controllers/org/irods/mydrop/controller/SharingController.groovy
new file mode 100644
index 0000000..ec5fe34
--- /dev/null
+++ b/idrop-web/grails-app/controllers/org/irods/mydrop/controller/SharingController.groovy
@@ -0,0 +1,78 @@
+package org.irods.mydrop.controller
+
+
+import org.irods.jargon.core.connection.IRODSAccount
+import org.irods.jargon.core.exception.JargonException
+import org.irods.jargon.core.exception.JargonRuntimeException
+import org.irods.jargon.core.pub.CollectionAO
+import org.irods.jargon.core.pub.CollectionAndDataObjectListAndSearchAO
+import org.irods.jargon.core.pub.DataObjectAO
+import org.irods.jargon.core.pub.IRODSAccessObjectFactory
+import org.irods.jargon.core.pub.domain.DataObject
+import org.springframework.security.core.context.SecurityContextHolder
+
+
+class SharingController {
+
+ IRODSAccessObjectFactory irodsAccessObjectFactory
+ IRODSAccount irodsAccount
+
+ /**
+ * Interceptor grabs IRODSAccount from the SecurityContextHolder
+ */
+ def beforeInterceptor = {
+ def irodsAuthentication = SecurityContextHolder.getContext().authentication
+
+ if (irodsAuthentication == null) {
+ throw new JargonRuntimeException("no irodsAuthentication in security context!")
+ }
+
+ irodsAccount = irodsAuthentication.irodsAccount
+ log.debug("retrieved account for request: ${irodsAccount}")
+ }
+
+ def afterInterceptor = {
+ log.debug("closing the session")
+ irodsAccessObjectFactory.closeSession()
+ }
+
+
+ def listAcl = {
+
+ def absPath = params['absPath']
+ if (absPath == null) {
+ throw new JargonException("no absolute path passed to the method")
+ }
+
+ log.info("listAcl for absPath: ${absPath}")
+ def acls;
+
+ try {
+
+ CollectionAndDataObjectListAndSearchAO collectionAndDataObjectListAndSearchAO = irodsAccessObjectFactory.getCollectionAndDataObjectListAndSearchAO(irodsAccount)
+
+ def retObj = collectionAndDataObjectListAndSearchAO.getFullObjectForType(absPath)
+
+ def isDataObject = retObj instanceof DataObject
+
+
+ if (isDataObject) {
+ log.debug("retrieving ACLs for a data object");
+ DataObjectAO dataObjectAO = irodsAccessObjectFactory.getDataObjectAO(irodsAccount)
+ acls = dataObjectAO.listPermissionsForDataObject(retObj.collectionName + "/" + retObj.dataName)
+ } else {
+ log.debug("retrieveing ACLs for collection")
+ CollectionAO collectionAO = irodsAccessObjectFactory.getCollectionAO(irodsAccount)
+ acls = collectionAO.listPermissionsForCollection(retObj.collectionName)
+ }
+ } catch (Exception je){
+ log.error("exception getting acl data ${je}", je)
+ flash.message = "Unable to find ACL data"
+ }
+
+ //flash.message = "there ya go"
+
+ render(view:"aclDetails", model:[acls:acls])
+
+ }
+}
diff --git a/idrop-web/grails-app/views/common/_panelmessages.gsp b/idrop-web/grails-app/views/common/_panelmessages.gsp
new file mode 100644
index 0000000..8a53243
--- /dev/null
+++ b/idrop-web/grails-app/views/common/_panelmessages.gsp
@@ -0,0 +1,3 @@
+<g:if test="${flash.message}">
+<div class="message">${flash.message}<!-- panel messages --></div>
+</g:if>
diff --git a/idrop-web/grails-app/views/common/_secondarymain.gsp b/idrop-web/grails-app/views/common/_secondarymain.gsp
index febe418..ddde587 100644
--- a/idrop-web/grails-app/views/common/_secondarymain.gsp
+++ b/idrop-web/grails-app/views/common/_secondarymain.gsp
@@ -33,9 +33,9 @@
<script src="http://www.java.com/js/deployJava.js"></script>
<script>
// using JavaScript to get location of JNLP file relative to HTML page
- var url = "http://irendb.renci.org:8080/idrop/launchIDrop.html";
+ //var url = "http://irendb.renci.org:8080/idrop/launchIDrop.html";
//deployJava.createWebStartLaunchButton(url, '1.6.0');
- </script><a onmouseover="window.status=''; return true;" href="javascript:if (!deployJava.isWebStartInstalled(&quot;1.6.0&quot;)) {if (deployJava.installLatestJRE()) {if (deployJava.launch(&quot;http://irendb.renci.org:8080/idrop/idrop.jnlp&quot;)) {}}} else {if (deployJava.launch(&quot;http://irendb.renci.org:8080/idrop/idrop.jnlp&quot;)) {}}"><img border="0" src="http://java.sun.com/products/jfc/tsc/articles/swing2d/webstart.png"></a>
+ </script><a onmouseover="window.status=''; return true;" href="javascript:if (!deployJava.isWebStartInstalled(&quot;1.6.0&quot;)) {if (deployJava.installLatestJRE()) {if (deployJava.launch(&quot;http://ruby.ils.unc.edu/ll/idrop/idrop.jnlp&quot;)) {}}} else {if (deployJava.launch(&quot;http://ruby.ils.unc.edu/ll/idrop/idrop.jnlp&quot;)) {}}"><img border="0" src="http://java.sun.com/products/jfc/tsc/articles/swing2d/webstart.png"></a>
</div>
diff --git a/idrop-web/grails-app/views/file/uploadDialog.gsp b/idrop-web/grails-app/views/file/uploadDialog.gsp
index ab68d8b..5c49c49 100644
--- a/idrop-web/grails-app/views/file/uploadDialog.gsp
+++ b/idrop-web/grails-app/views/file/uploadDialog.gsp
@@ -1,5 +1,4 @@
<div id="uploadDialogDiv">
-
<div class="box">
<g:form controller="file" action="upload" method="post"
name="uploadForm" enctype="multipart/form-data"
@@ -8,20 +7,23 @@
<label for="">Parent Collection:</label>
<g:textField name="collectionParentName"
value="${irodsTargetCollection}" readonly="true" />
- <br />
+ <br /> <label for="infoTags">Tags:</label>
+ <g:textField id="infoTags" name="tags"
+ value="tags.spaceDelimitedTagsForDomain" />
+ <br /> <label for="description">Description:</label>
+ <g:textArea name="description" rows="5" cols="80" />
+ <br/><label>File: (selecting a file will upload with provided metadata)</label>
+ <br/>
<div id="file_upload_container">
- <input type="file" name="file" multiple>
+ <input type="file" name="file">
<button>Upload</button>
- <div>Upload files</div>
+ <div></div>
+ </div>
+ <div id="upload_message_area">
</div>
- <g:textField id="infoTags" name="tags"
- value="tags.spaceDelimitedTagsForDomain" />
- <br />
<table id="files"></table>
</fieldset>
</g:form>
-
-
</div>
</div>
diff --git a/idrop-web/grails-app/views/home/index.gsp b/idrop-web/grails-app/views/home/index.gsp
index 7cdf013..3c6ec5a 100644
--- a/idrop-web/grails-app/views/home/index.gsp
+++ b/idrop-web/grails-app/views/home/index.gsp
@@ -81,7 +81,6 @@
<div id="browseMenu" class="fg-buttonset fg-buttonset-multi"
style="float: left">
-
Display Option:
<g:select name="browseDisplayOption" id="browseDisplayOption"
from="${['info', 'sharing', 'metadata']}"
@@ -96,7 +95,8 @@
</div>
-
+ <g:render template="/common/panelmessages"/>
+
<div id="infoDiv" class="ui-layout-center">
<h2>Select a directory or file to see info and tags based on
the view option</h2>
diff --git a/idrop-web/grails-app/views/login/login.gsp b/idrop-web/grails-app/views/login/login.gsp
index 7168a42..968d087 100644
--- a/idrop-web/grails-app/views/login/login.gsp
+++ b/idrop-web/grails-app/views/login/login.gsp
@@ -1,8 +1,7 @@
<head>
<meta name="layout" content="main" />
</head>
-<g:renderErrors as="list"></g:renderErrors>
-
+
<div class="box" style="width:300px; margin:0px auto;"><g:form controller="j_spring_security_check"
absolute="true" method="post">
diff --git a/idrop-web/grails-app/views/metadata/metadataDetails.gsp b/idrop-web/grails-app/views/metadata/metadataDetails.gsp
index 12cd527..c67a2c8 100644
--- a/idrop-web/grails-app/views/metadata/metadataDetails.gsp
+++ b/idrop-web/grails-app/views/metadata/metadataDetails.gsp
@@ -1,12 +1,14 @@
<div id="detailsTopSection" class="box">
-
-<div id="detailsToolbar" class="nav">
-<button type="button" id="addMetadataButton" class="menuButton" value="addMetadata" onclick="addMetadata()")>Add Metadata</button>
-<button type="button" id="updateMetadataButton" class="menuButton" value="updateMetadata" onclick="updateMetadata()")>Update Metadata</button>
-<button type="button" id="deleteMetadataButton" class="menuButton" value="deleteMetadata" onclick="deleteMetadata()")>Delete Metadata</button>
+<div id="detailsToolbar" class="fg-toolbar ui-widget-header">
+<div id="detailsMenu" class="fg-buttonset fg-buttonset-multi"
+ style="float: left">
+<button type="button" id="addMetadataButton" class="ui-state-default ui-corner-all" value="addMetadata" onclick="addMetadata()")>Add Metadata</button>
+<button type="button" id="updateMetadataButton" class="ui-state-default ui-corner-all" value="updateMetadata" onclick="updateMetadata()")>Update Metadata</button>
+<button type="button" id="deleteMetadataButton" class="ui-state-default ui-corner-all" value="deleteMetadata" onclick="deleteMetadata()")>Delete Metadata</button>
</div>
</div>
-<div>
+<g:render template="/common/panelmessages"/>
+
<table cellspacing="0" cellpadding="0" border="0"
id="metaDataDetailsTable" style="width: 100%;">
<thead>
diff --git a/idrop-web/grails-app/views/sharing/aclDetails.gsp b/idrop-web/grails-app/views/sharing/aclDetails.gsp
new file mode 100644
index 0000000..7995cd7
--- /dev/null
+++ b/idrop-web/grails-app/views/sharing/aclDetails.gsp
@@ -0,0 +1,55 @@
+
+<div id="detailsToolbar" class="fg-toolbar ui-widget-header">
+<div id="detailsMenu" class="fg-buttonset fg-buttonset-multi"
+ style="float: left">
+<button type="button" id="addAclButton" class="ui-state-default ui-corner-all" value="addAcl" onclick="addAcl()")>Add Share</button>
+<button type="button" id="updateAclButton" class="ui-state-default ui-corner-all" value="updateAcl" onclick="updateAcl()")>Update Share</button>
+<button type="button" id="deleteAclButton" class="ui-state-default ui-corner-all" value="deleteAcl" onclick="deleteAcl()")>Delete Share</button>
+</div>
+</div>
+<g:render template="/common/panelmessages"/>
+
+<div>
+ <table cellspacing="0" cellpadding="0" border="0"
+ id="aclDetailsTable" style="width: 100%;">
+ <thead>
+ <tr>
+ <th></th>
+ <th>Person</th>
+ <th>Access</th>
+ </tr>
+ </thead>
+ <tbody>
+ <g:each in="${acls}" var="acl">
+ <tr id="${acl.userId}">
+ <td><g:checkBox name="selectedAcl" />
+ </td>
+ <td>
+ ${acl.userName}
+ </td>
+ <td>
+ ${acl.filePermissionEnum}
+ </td>
+
+ </tr>
+ </g:each>
+
+ </tbody>
+
+ <tfoot>
+ <tr>
+ <th></th>
+ <th></th>
+ <th></th>
+ <th></th>
+ </tr>
+ </tfoot>
+ </table>
+</div>
+<script type="text/javascript">
+
+ $(function() {
+ dataTable = lcBuildTableInPlace("#aclDetailsTable", null, null);
+ });
+
+ </script> \ No newline at end of file
diff --git a/idrop-web/src/templates/scaffolding/create.gsp b/idrop-web/src/templates/scaffolding/create.gsp
deleted file mode 100644
index 1adfd6b..0000000
--- a/idrop-web/src/templates/scaffolding/create.gsp
+++ /dev/null
@@ -1,61 +0,0 @@
-<% import grails.persistence.Event %>
-<% import org.codehaus.groovy.grails.plugins.PluginManagerHolder %>
-<%=packageName%>
-<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <meta name="layout" content="main" />
- <g:set var="entityName" value="\${message(code: '${domainClass.propertyName}.label', default: '${className}')}" />
- <title><g:message code="default.create.label" args="[entityName]" /></title>
- </head>
- <body>
- <div class="nav">
- <span class="menuButton"><a class="home" href="\${createLink(uri: '/')}"><g:message code="default.home.label"/></a></span>
- <span class="menuButton"><g:link class="list" action="list"><g:message code="default.list.label" args="[entityName]" /></g:link></span>
- </div>
- <div class="body">
- <h1><g:message code="default.create.label" args="[entityName]" /></h1>
- <g:if test="\${flash.message}">
- <div class="message">\${flash.message}</div>
- </g:if>
- <g:hasErrors bean="\${${propertyName}}">
- <div class="errors">
- <g:renderErrors bean="\${${propertyName}}" as="list" />
- </div>
- </g:hasErrors>
- <g:form action="save" <%= multiPart ? ' enctype="multipart/form-data"' : '' %>>
- <div class="dialog">
- <table>
- <tbody>
- <% excludedProps = Event.allEvents.toList() << 'version' << 'id' << 'dateCreated' << 'lastUpdated'
- persistentPropNames = domainClass.persistentProperties*.name
- props = domainClass.properties.findAll { persistentPropNames.contains(it.name) && !excludedProps.contains(it.name) }
- Collections.sort(props, comparator.constructors[0].newInstance([domainClass] as Object[]))
- display = true
- boolean hasHibernate = PluginManagerHolder.pluginManager.hasGrailsPlugin('hibernate')
- props.each { p ->
- if (!Collection.class.isAssignableFrom(p.type)) {
- if (hasHibernate) {
- cp = domainClass.constrainedProperties[p.name]
- display = (cp ? cp.display : true)
- }
- if (display) { %>
- <tr class="prop">
- <td valign="top" class="name">
- <label for="${p.name}"><g:message code="${domainClass.propertyName}.${p.name}.label" default="${p.naturalName}" /></label>
- </td>
- <td valign="top" class="value \${hasErrors(bean: ${propertyName}, field: '${p.name}', 'errors')}">
- ${renderEditor(p)}
- </td>
- </tr>
- <% } } } %>
- </tbody>
- </table>
- </div>
- <div class="buttons">
- <span class="button"><g:submitButton name="create" class="save" value="\${message(code: 'default.button.create.label', default: 'Create')}" /></span>
- </div>
- </g:form>
- </div>
- </body>
-</html>
diff --git a/idrop-web/src/templates/scaffolding/edit.gsp b/idrop-web/src/templates/scaffolding/edit.gsp
deleted file mode 100644
index ce1f293..0000000
--- a/idrop-web/src/templates/scaffolding/edit.gsp
+++ /dev/null
@@ -1,64 +0,0 @@
-<% import grails.persistence.Event %>
-<% import org.codehaus.groovy.grails.plugins.PluginManagerHolder %>
-<%=packageName%>
-<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <meta name="layout" content="main" />
- <g:set var="entityName" value="\${message(code: '${domainClass.propertyName}.label', default: '${className}')}" />
- <title><g:message code="default.edit.label" args="[entityName]" /></title>
- </head>
- <body>
- <div class="nav">
- <span class="menuButton"><a class="home" href="\${createLink(uri: '/')}"><g:message code="default.home.label"/></a></span>
- <span class="menuButton"><g:link class="list" action="list"><g:message code="default.list.label" args="[entityName]" /></g:link></span>
- <span class="menuButton"><g:link class="create" action="create"><g:message code="default.new.label" args="[entityName]" /></g:link></span>
- </div>
- <div class="body">
- <h1><g:message code="default.edit.label" args="[entityName]" /></h1>
- <g:if test="\${flash.message}">
- <div class="message">\${flash.message}</div>
- </g:if>
- <g:hasErrors bean="\${${propertyName}}">
- <div class="errors">
- <g:renderErrors bean="\${${propertyName}}" as="list" />
- </div>
- </g:hasErrors>
- <g:form method="post" <%= multiPart ? ' enctype="multipart/form-data"' : '' %>>
- <g:hiddenField name="id" value="\${${propertyName}?.id}" />
- <g:hiddenField name="version" value="\${${propertyName}?.version}" />
- <div class="dialog">
- <table>
- <tbody>
- <% excludedProps = Event.allEvents.toList() << 'version' << 'id' << 'dateCreated' << 'lastUpdated'
- persistentPropNames = domainClass.persistentProperties*.name
- props = domainClass.properties.findAll { persistentPropNames.contains(it.name) && !excludedProps.contains(it.name) }
- Collections.sort(props, comparator.constructors[0].newInstance([domainClass] as Object[]))
- display = true
- boolean hasHibernate = PluginManagerHolder.pluginManager.hasGrailsPlugin('hibernate')
- props.each { p ->
- if (hasHibernate) {
- cp = domainClass.constrainedProperties[p.name]
- display = (cp?.display ?: true)
- }
- if (display) { %>
- <tr class="prop">
- <td valign="top" class="name">
- <label for="${p.name}"><g:message code="${domainClass.propertyName}.${p.name}.label" default="${p.naturalName}" /></label>
- </td>
- <td valign="top" class="value \${hasErrors(bean: ${propertyName}, field: '${p.name}', 'errors')}">
- ${renderEditor(p)}
- </td>
- </tr>
- <% } } %>
- </tbody>
- </table>
- </div>
- <div class="buttons">
- <span class="button"><g:actionSubmit class="save" action="update" value="\${message(code: 'default.button.update.label', default: 'Update')}" /></span>
- <span class="button"><g:actionSubmit class="delete" action="delete" value="\${message(code: 'default.button.delete.label', default: 'Delete')}" onclick="return confirm('\${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}');" /></span>
- </div>
- </g:form>
- </div>
- </body>
-</html>
diff --git a/idrop-web/src/templates/scaffolding/list.gsp b/idrop-web/src/templates/scaffolding/list.gsp
deleted file mode 100644
index 05533f9..0000000
--- a/idrop-web/src/templates/scaffolding/list.gsp
+++ /dev/null
@@ -1,61 +0,0 @@
-<% import grails.persistence.Event %>
-<%=packageName%>
-<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <meta name="layout" content="main" />
- <g:set var="entityName" value="\${message(code: '${domainClass.propertyName}.label', default: '${className}')}" />
- <title><g:message code="default.list.label" args="[entityName]" /></title>
- </head>
- <body>
- <div class="nav">
- <span class="menuButton"><a class="home" href="\${createLink(uri: '/')}"><g:message code="default.home.label"/></a></span>
- <span class="menuButton"><g:link class="create" action="create"><g:message code="default.new.label" args="[entityName]" /></g:link></span>
- </div>
- <div class="body">
- <h1><g:message code="default.list.label" args="[entityName]" /></h1>
- <g:if test="\${flash.message}">
- <div class="message">\${flash.message}</div>
- </g:if>
- <div class="list">
- <table>
- <thead>
- <tr>
- <% excludedProps = Event.allEvents.toList() << 'version'
- allowedNames = domainClass.persistentProperties*.name << 'id' << 'dateCreated' << 'lastUpdated'
- props = domainClass.properties.findAll { allowedNames.contains(it.name) && !excludedProps.contains(it.name) && !Collection.isAssignableFrom(it.type) }
- Collections.sort(props, comparator.constructors[0].newInstance([domainClass] as Object[]))
- props.eachWithIndex { p, i ->
- if (i < 6) {
- if (p.isAssociation()) { %>
- <th><g:message code="${domainClass.propertyName}.${p.name}.label" default="${p.naturalName}" /></th>
- <% } else { %>
- <g:sortableColumn property="${p.name}" title="\${message(code: '${domainClass.propertyName}.${p.name}.label', default: '${p.naturalName}')}" />
- <% } } } %>
- </tr>
- </thead>
- <tbody>
- <g:each in="\${${propertyName}List}" status="i" var="${propertyName}">
- <tr class="\${(i % 2) == 0 ? 'odd' : 'even'}">
- <% props.eachWithIndex { p, i ->
- if (i == 0) { %>
- <td><g:link action="show" id="\${${propertyName}.id}">\${fieldValue(bean: ${propertyName}, field: "${p.name}")}</g:link></td>
- <% } else if (i < 6) {
- if (p.type == Boolean.class || p.type == boolean.class) { %>
- <td><g:formatBoolean boolean="\${${propertyName}.${p.name}}" /></td>
- <% } else if (p.type == Date.class || p.type == java.sql.Date.class || p.type == java.sql.Time.class || p.type == Calendar.class) { %>
- <td><g:formatDate date="\${${propertyName}.${p.name}}" /></td>
- <% } else { %>
- <td>\${fieldValue(bean: ${propertyName}, field: "${p.name}")}</td>
- <% } } } %>
- </tr>
- </g:each>
- </tbody>
- </table>
- </div>
- <div class="paginateButtons">
- <g:paginate total="\${${propertyName}Total}" />
- </div>
- </div>
- </body>
-</html>
diff --git a/idrop-web/src/templates/scaffolding/show.gsp b/idrop-web/src/templates/scaffolding/show.gsp
deleted file mode 100644
index 5172148..0000000
--- a/idrop-web/src/templates/scaffolding/show.gsp
+++ /dev/null
@@ -1,64 +0,0 @@
-<% import grails.persistence.Event %>
-<%=packageName%>
-<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <meta name="layout" content="main" />
- <g:set var="entityName" value="\${message(code: '${domainClass.propertyName}.label', default: '${className}')}" />
- <title><g:message code="default.show.label" args="[entityName]" /></title>
- </head>
- <body>
- <div class="nav">
- <span class="menuButton"><a class="home" href="\${createLink(uri: '/')}"><g:message code="default.home.label"/></a></span>
- <span class="menuButton"><g:link class="list" action="list"><g:message code="default.list.label" args="[entityName]" /></g:link></span>
- <span class="menuButton"><g:link class="create" action="create"><g:message code="default.new.label" args="[entityName]" /></g:link></span>
- </div>
- <div class="body">
- <h1><g:message code="default.show.label" args="[entityName]" /></h1>
- <g:if test="\${flash.message}">
- <div class="message">\${flash.message}</div>
- </g:if>
- <div class="dialog">
- <table>
- <tbody>
- <% excludedProps = Event.allEvents.toList() << 'version'
- allowedNames = domainClass.persistentProperties*.name << 'id' << 'dateCreated' << 'lastUpdated'
- props = domainClass.properties.findAll { allowedNames.contains(it.name) && !excludedProps.contains(it.name) }
- Collections.sort(props, comparator.constructors[0].newInstance([domainClass] as Object[]))
- props.each { p -> %>
- <tr class="prop">
- <td valign="top" class="name"><g:message code="${domainClass.propertyName}.${p.name}.label" default="${p.naturalName}" /></td>
- <% if (p.isEnum()) { %>
- <td valign="top" class="value">\${${propertyName}?.${p.name}?.encodeAsHTML()}</td>
- <% } else if (p.oneToMany || p.manyToMany) { %>
- <td valign="top" style="text-align: left;" class="value">
- <ul>
- <g:each in="\${${propertyName}.${p.name}}" var="${p.name[0]}">
- <li><g:link controller="${p.referencedDomainClass?.propertyName}" action="show" id="\${${p.name[0]}.id}">\${${p.name[0]}?.encodeAsHTML()}</g:link></li>
- </g:each>
- </ul>
- </td>
- <% } else if (p.manyToOne || p.oneToOne) { %>
- <td valign="top" class="value"><g:link controller="${p.referencedDomainClass?.propertyName}" action="show" id="\${${propertyName}?.${p.name}?.id}">\${${propertyName}?.${p.name}?.encodeAsHTML()}</g:link></td>
- <% } else if (p.type == Boolean.class || p.type == boolean.class) { %>
- <td valign="top" class="value"><g:formatBoolean boolean="\${${propertyName}?.${p.name}}" /></td>
- <% } else if (p.type == Date.class || p.type == java.sql.Date.class || p.type == java.sql.Time.class || p.type == Calendar.class) { %>
- <td valign="top" class="value"><g:formatDate date="\${${propertyName}?.${p.name}}" /></td>
- <% } else if(!p.type.isArray()) { %>
- <td valign="top" class="value">\${fieldValue(bean: ${propertyName}, field: "${p.name}")}</td>
- <% } %>
- </tr>
- <% } %>
- </tbody>
- </table>
- </div>
- <div class="buttons">
- <g:form>
- <g:hiddenField name="id" value="\${${propertyName}?.id}" />
- <span class="button"><g:actionSubmit class="edit" action="edit" value="\${message(code: 'default.button.edit.label', default: 'Edit')}" /></span>
- <span class="button"><g:actionSubmit class="delete" action="delete" value="\${message(code: 'default.button.delete.label', default: 'Delete')}" onclick="return confirm('\${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}');" /></span>
- </g:form>
- </div>
- </div>
- </body>
-</html>
diff --git a/idrop-web/test/unit/org/irods/mydrop/controller/SharingControllerTests.groovy b/idrop-web/test/unit/org/irods/mydrop/controller/SharingControllerTests.groovy
new file mode 100644
index 0000000..4cc2180
--- /dev/null
+++ b/idrop-web/test/unit/org/irods/mydrop/controller/SharingControllerTests.groovy
@@ -0,0 +1,102 @@
+package org.irods.mydrop.controller
+
+import grails.test.ControllerUnitTestCase
+
+import java.util.Properties
+
+import org.irods.jargon.core.connection.IRODSAccount
+import org.irods.jargon.core.pub.CollectionAO
+import org.irods.jargon.core.pub.CollectionAndDataObjectListAndSearchAO
+import org.irods.jargon.core.pub.DataObjectAO
+import org.irods.jargon.core.pub.IRODSAccessObjectFactory
+import org.irods.jargon.core.pub.IRODSFileSystem
+import org.irods.jargon.core.pub.domain.Collection
+import org.irods.jargon.core.pub.domain.DataObject
+import org.irods.jargon.core.query.UserFilePermission
+import org.irods.jargon.spring.security.IRODSAuthenticationToken
+import org.irods.jargon.testutils.TestingPropertiesHelper
+import org.mockito.Mockito
+import org.springframework.security.core.context.SecurityContextHolder
+
+
+class SharingControllerTests extends ControllerUnitTestCase {
+ IRODSAccessObjectFactory irodsAccessObjectFactory
+ IRODSAccount irodsAccount
+ Properties testingProperties
+ TestingPropertiesHelper testingPropertiesHelper
+ IRODSFileSystem irodsFileSystem
+
+
+ protected void setUp() {
+ super.setUp()
+ testingPropertiesHelper = new TestingPropertiesHelper()
+ testingProperties = testingPropertiesHelper.getTestProperties()
+ irodsAccount = testingPropertiesHelper.buildIRODSAccountFromTestProperties(testingProperties)
+ irodsFileSystem = IRODSFileSystem.instance()
+ irodsAccessObjectFactory = irodsFileSystem.getIRODSAccessObjectFactory()
+ def irodsAuthentication = new IRODSAuthenticationToken(irodsAccount)
+ SecurityContextHolder.getContext().authentication = irodsAuthentication
+ }
+
+ protected void tearDown() {
+ super.tearDown()
+ }
+
+ void testListAclCollection() {
+ def testPath = "/testpath"
+ def irodsAccessObjectFactory = Mockito.mock(IRODSAccessObjectFactory.class)
+ CollectionAndDataObjectListAndSearchAO collectionListAndSearchAO = Mockito.mock(CollectionAndDataObjectListAndSearchAO.class)
+ Collection retObject = new Collection()
+ retObject.setCollectionName(testPath)
+ Mockito.when(collectionListAndSearchAO.getFullObjectForType(testPath)).thenReturn(retObject)
+ Mockito.when(irodsAccessObjectFactory.getCollectionAndDataObjectListAndSearchAO(irodsAccount)).thenReturn(collectionListAndSearchAO)
+
+ CollectionAO collectionAO = Mockito.mock(CollectionAO.class)
+ List<UserFilePermission> mockMetadata = new ArrayList<UserFilePermission>();
+ Mockito.when(collectionAO.listPermissionsForCollection(testPath)).thenReturn(mockMetadata);
+ Mockito.when(irodsAccessObjectFactory.getCollectionAO(irodsAccount)).thenReturn(collectionAO)
+
+ controller.irodsAccessObjectFactory = irodsAccessObjectFactory
+ controller.irodsAccount = irodsAccount
+ controller.params.absPath = testPath
+ controller.listAcl()
+ def mav = controller.modelAndView
+ def name = mav.viewName
+
+ assertNotNull("null mav", mav)
+ assertEquals("view name should be aclDetails", "aclDetails", name)
+ def metadata = mav.model.acls
+ assertNotNull("null acls object", metadata)
+ }
+
+
+ void testListAclDataObject() {
+ def testPath = "/testpath"
+ def testFileName = "filename.txt"
+ def irodsAccessObjectFactory = Mockito.mock(IRODSAccessObjectFactory.class)
+ CollectionAndDataObjectListAndSearchAO collectionListAndSearchAO = Mockito.mock(CollectionAndDataObjectListAndSearchAO.class)
+ DataObject retObject = new DataObject()
+ retObject.setCollectionName(testPath)
+ retObject.setDataName(testFileName)
+ Mockito.when(collectionListAndSearchAO.getFullObjectForType(testPath)).thenReturn(retObject)
+ Mockito.when(irodsAccessObjectFactory.getCollectionAndDataObjectListAndSearchAO(irodsAccount)).thenReturn(collectionListAndSearchAO)
+
+ DataObjectAO dataObjectAO = Mockito.mock(DataObjectAO.class)
+ List<UserFilePermission> mockMetadata = new ArrayList<UserFilePermission>();
+ Mockito.when(dataObjectAO.listPermissionsForDataObject(testPath + "/" + testFileName)).thenReturn(mockMetadata);
+ Mockito.when(irodsAccessObjectFactory.getDataObjectAO(irodsAccount)).thenReturn(dataObjectAO)
+
+ controller.irodsAccessObjectFactory = irodsAccessObjectFactory
+ controller.irodsAccount = irodsAccount
+ controller.params.absPath = testPath
+ controller.listAcl()
+ def mav = controller.modelAndView
+ def name = mav.viewName
+
+ assertNotNull("null mav", mav)
+ assertEquals("view name should be aclDetails", "aclDetails", name)
+ def metadata = mav.model.acls
+ assertNotNull("null acls object", metadata)
+ }
+
+}
diff --git a/idrop-web/web-app/css/main.css b/idrop-web/web-app/css/main.css
index 682730f..9eea20c 100644
--- a/idrop-web/web-app/css/main.css
+++ b/idrop-web/web-app/css/main.css
@@ -194,7 +194,9 @@ div#tabs {
border: 1px solid #b2d1ff;
color: #fff;
margin: 10px 0 5px 0;
- padding: 5px 5px 5px 30px
+ padding: 5px 5px 5px 30px;
+ display:block;
+ overflow:auto;
}
div.errors {
@@ -413,6 +415,12 @@ th.desc a {
width: 15em;
}
+
+#columnarForm textarea {
+ display: block;
+ width: 15em;
+}
+
#columnarForm label {
display: block;
margin-bottom: 1em;
@@ -452,6 +460,12 @@ th.desc a {
width: 15em;
}
+
+#horizontalForm textarea {
+ display: block;
+ width: 15em;
+}
+
#horizontalForm input.submit {
clear: both;
}
@@ -508,6 +522,14 @@ th.desc a {
display: block;
}
+
+#marginForm textarea {
+ position: relative;
+ top: -1.4em;
+ left: 8em;
+ display: block;
+}
+
#marginForm input.submit {
clear: both;
top: 0;
@@ -560,6 +582,12 @@ th.desc a {
width: 20em;
}
+
+#verticalForm textarea {
+ display: block;
+ width: 20em;
+}
+
#verticalForm label {
display: block;
margin-bottom: 1em;
@@ -626,4 +654,21 @@ th.desc a {
float: right;
height: 100%;
background: #f4f4f4;
-} \ No newline at end of file
+}
+
+#detailsToolbar {
+ text-align: left;
+ height:25px;
+ margin: 0px auto;
+ padding: 0px;
+ border: 0;
+ display: inline-block;
+ overflow: auto;
+ width:100%;
+}
+
+
+/* file upload dialog */
+#file_upload_container {
+ margin: 5px;
+}
diff --git a/idrop-web/web-app/js/mydrop/home.js b/idrop-web/web-app/js/mydrop/home.js
index 69b8723..928a84c 100644
--- a/idrop-web/web-app/js/mydrop/home.js
+++ b/idrop-web/web-app/js/mydrop/home.js
@@ -154,6 +154,10 @@ function updateBrowseDetailsForPathBasedOnCurrentModel(absPath) {
lcSendValueAndCallbackHtmlAfterErrorCheck(
"/metadata/listMetadata?absPath=" + absPath, "#infoDiv",
"#infoDiv", null);
+ } else if (browseOptionVal == "sharing") {
+ lcSendValueAndCallbackHtmlAfterErrorCheck(
+ "/sharing/listAcl?absPath=" + absPath, "#infoDiv",
+ "#infoDiv", null);
}
}
@@ -191,7 +195,7 @@ function fillInUploadDialog(data) {
}
$('#uploadDialog').remove();
-
+
var $dialog = $('<div id="uploadDialog"></div>').html(data).dialog({
autoOpen : false,
modal : true,
@@ -201,35 +205,39 @@ function fillInUploadDialog(data) {
initializeUploadDialogAjaxLoader();
}
});
-
-
+
$dialog.dialog('open');
}
function initializeUploadDialogAjaxLoader() {
if (fileUploadUI != null) {
- $("#fileUploadForm").remove;
+ $("#fileUploadForm").remove;
}
- //} else {
- fileUploadUI = $('#uploadForm')
- .fileUploadUI(
- {
- uploadTable : $('#files'),
- downloadTable : $('#files'),
- buildUploadRow : function(files, index) {
- return $('<tr><td>'
- + files[index].name
- + '<\/td>'
- + '<td class="file_upload_progress"><div><\/div><\/td>'
- + '<td class="file_upload_cancel">'
- + '<button class="ui-state-default ui-corner-all" title="Cancel">'
- + '<span class="ui-icon ui-icon-cancel">Cancel<\/span>'
- + '<\/button><\/td><\/tr>');
- },
- buildDownloadRow : function(file) {
- return $('<tr><td>' + file.name
- + '<\/td><\/tr>');
- }
- });
- //}
+
+ fileUploadUI = $('#uploadForm')
+ .fileUploadUI(
+ {
+ uploadTable : $('#files'),
+ downloadTable : $('#files'),
+ buildUploadRow : function(files, index) {
+ $("#upload_message_area").html("");
+ $("#upload_message_area").removeClass();
+ return $('<tr><td>'
+ + files[index].name
+ + '<\/td>'
+ + '<td class="file_upload_progress"><div><\/div><\/td>'
+ + '<td class="file_upload_cancel">'
+ + '<button class="ui-state-default ui-corner-all" title="Cancel">'
+ + '<span class="ui-icon ui-icon-cancel">Cancel<\/span>'
+ + '<\/button><\/td><\/tr>');
+ },
+ buildDownloadRow : function(file) {
+ return $('<tr><td>' + file.name + '<\/td><\/tr>');
+ },
+ onError : function(event, files, index, xhr, handler) {
+ $("#upload_message_area").html("an error occurred in the upload");
+ $("#upload_message_area").addClass("message");
+ }
+ });
+
}