Permalink
Browse files

OZP-502: Data Guard merge

  • Loading branch information...
1 parent 7ba99f0 commit 60ce5fa4d35ded09a943b643b987845d4f98741a @tdehart tdehart committed Mar 7, 2013
Showing with 1,241 additions and 194 deletions.
  1. +53 −0 README.md
  2. BIN build-libs/jsdoctoolkit-ant-task-1.0.jar
  3. +8 −0 build.xml
  4. +1 −0 grails-app/conf/BuildConfig.groovy
  5. +20 −0 grails-app/conf/Config.groovy
  6. +8 −0 grails-app/conf/UrlMappings.groovy
  7. +4 −1 grails-app/conf/spring/resources.xml
  8. +13 −0 grails-app/controllers/ozone/owf/grails/controllers/AccessController.groovy
  9. +13 −0 grails-app/controllers/ozone/owf/grails/controllers/AuditController.groovy
  10. +43 −0 grails-app/services/ozone/owf/grails/services/AccessService.groovy
  11. +22 −0 grails-app/services/ozone/owf/grails/services/AuditService.groovy
  12. +8 −0 grails-app/utils/AccessServiceTestHelper.groovy
  13. +9 −4 plugins/code-coverage-1.2.5/scripts/_Events.groovy
  14. +23 −0 src/java/custom/access/AccessLevel.java
  15. +47 −0 src/java/custom/access/CustomAccessChecker.java
  16. +18 −0 src/resources/OwfConfig.groovy
  17. +58 −0 test/integration/ozone/owf/grails/test/integration/AccessServiceTests.groovy
  18. +15 −15 test/unit/ozone/owf/grails/controllers/ThemeControllerTests.groovy
  19. +41 −0 web-app/examples/walkthrough/descriptors/ChannelShouterRPC_descriptor.html
  20. +41 −0 web-app/examples/walkthrough/descriptors/WidgetAccess_descriptor.html
  21. +1 −0 web-app/examples/walkthrough/widgets/ChannelListener.gsp
  22. +9 −1 web-app/examples/walkthrough/widgets/ChannelListenerPanel.js
  23. +10 −3 web-app/examples/walkthrough/widgets/ChannelShouter.gsp
  24. +153 −0 web-app/examples/walkthrough/widgets/ChannelShouterRPC.gsp
  25. +2 −1 web-app/examples/walkthrough/widgets/NYSE.gsp
  26. +62 −0 web-app/examples/walkthrough/widgets/WidgetAccess.gsp
  27. +2 −2 web-app/js-lib/shindig/pubsub.js
  28. +29 −10 web-app/js-lib/shindig/pubsub_router.js
  29. +34 −0 web-app/js/audit/Audit.js
  30. +1 −1 web-app/js/components/admin/DashboardsTabPanel.js
  31. +1 −1 web-app/js/components/admin/GroupsTabPanel.js
  32. +1 −1 web-app/js/components/admin/ManagementPanel.js
  33. +1 −1 web-app/js/components/admin/StacksTabPanel.js
  34. +1 −1 web-app/js/components/admin/UsersTabPanel.js
  35. +1 −1 web-app/js/components/admin/WidgetsTabPanel.js
  36. +1 −1 web-app/js/components/admin/dashboard/GroupDashboardManagementPanel.js
  37. +1 −1 web-app/js/components/admin/group/GroupManagementPanel.js
  38. +1 −1 web-app/js/components/admin/stack/StackManagementPanel.js
  39. +1 −1 web-app/js/components/admin/widget/WidgetDetailPanel.js
  40. +128 −95 web-app/js/dd/WidgetDragAndDrop.js
  41. +1 −1 web-app/js/dd/WidgetDragAndDropContainer.js
  42. +8 −2 web-app/js/eventing/Container.js
  43. +3 −2 web-app/js/eventing/Widget.js
  44. +2 −1 web-app/js/intents/WidgetIntents.js
  45. +39 −12 web-app/js/intents/WidgetIntentsContainer.js
  46. +11 −2 web-app/js/kernel/kernel-client.js
  47. +13 −2 web-app/js/launcher/WidgetLauncherContainer.js
  48. +255 −29 web-app/js/util/util.js
  49. +24 −1 web-app/js/widget/Widget.js
View
@@ -15,6 +15,58 @@ The Ozone Widget Framework (OWF) is a web application for composing other lightw
## Technology components
For Version 7 of OWF, the front-end user interface uses ExtJS, and the back-end uses Grails. User preferences are stored in a relational database - anything supported by Hibernate. Authentication of users is a modular function provided by Spring Security. There is a re-factoring effort planned for 2013 to improve performance modularity and maintainability, which is expected to eliminate the dependency on Grails and ExtJS.
+### Secured Messaging
+The eventing, drag-and-drop, launching, rpc, and intents APIs have been modified to enforce secured messaging. This is achieved by requiring the sending widgets to pass along an accessLevel parameter as part of the payload when using any of these APIs.
+
+#### Eventing Example
+OWF.Eventing.publish(channel, message, null, accessLevel);
+
+#### RPC Example
+OWF.RPC.getWidgetProxy(widgetId, function(widget) {
+ var sender = Ozone.util.toString({
+ "id": OWF.getInstanceId()
+ });
+ widget.addToGrid(sender, message, channel);
+}, accessLevel);
+
+#### Drag and Drop Example
+OWF.DragAndDrop.startDrag({
+ dragDropLabel: Ext.String.htmlEncode(data),
+ dragDropData: data,
+ accessLevel: accessLevel
+});
+
+#### Launching Example
+OWF.Launcher.launch({
+ guid: scope.guid,
+ launchOnlyIfClosed: true,
+ data: dataString,
+ accessLevel: accessLevel
+}, function(response) {
+ //check if the widgetLaunch call failed
+ if (response.error) {
+ //display error message
+ }
+});
+
+#### Intents Example
+OWF.Intents.startActivity(
+ {
+ action:'View',
+ dataType: 'text/html'
+ },
+ {
+ data: data,
+ accessLevel: accessLevel
+ },
+ function (dest) {
+ //dest is an array of destination widget proxies
+ if (dest.length <= 0) {
+ // alert('Intent was canceled');
+ }
+ }
+);
+
## Browser Support
Numbered releases are tested on IE7, IE8, IE9, Firefox 3.6 and the latest public version of Firefox. Some of the developers use Safari or Chrome, so generally it works well with those browsers also.
@@ -43,6 +95,7 @@ Released under the [Apache License, Version 2.](http://www.apache.org/licenses/L
OWF started as a project at a single US Government agency, but developed into a collaborative project spanning multiple federal agencies. Overall project direction is managed by "The OWF Government Open Source Software Board"; i.e. what features should the core team work on next, what patches should get accepted, etc. Gov't agencies wishing to be represented on the board should check http://owfgoss.org for more details. Membership on the board is currently limited to Government agencies that are using OWF and have demonstrated willingness to invest their own energy and resources into developing it as a shared resource of the community. At this time, the board is not considering membership for entities that are not US Government Agencies, but we would be willing to discuss proposals.
### Contributions
+
#### Non-Government
Contributions to the baseline project from outside the US Federal Government should be submitted as a pull request to the core project on GitHub. Before patches will be accepted by the core project, contributors have a signed Contributor License Agreement on file with the core team. If you or your company wish your copyright in your contribution to be annotated in the project documentation (such as this README), then your pull request should include that annotation.
Binary file not shown.
View
@@ -359,6 +359,14 @@
<grails script="Compile" preargs="${offline.arg}"/>
</target>
+ <target name="compileAccess" description="--->Compile data guard access capability">
+ <delete dir="${temp.dir}"/>
+ <mkdir dir="${temp.dir}"/>
+ <javac srcdir="${basedir}/src/java/custom/access" destdir="${temp.dir}"/>
+ <jar jarfile="${lib.dir}/access-1.0.jar" basedir="${temp.dir}"/>
+ <delete dir="${temp.dir}"/>
+ </target>
+
<!-- =================================
target: war
================================= -->
@@ -218,6 +218,7 @@ grails.project.dependency.resolution = {
//need ant for createWebBundles.jar
runtime 'org.apache.ant:ant:1.7.0'
+ compile('access:access:1.0')
}
}
@@ -136,6 +136,7 @@ uiperformance.bundles = [
files: [
'../js-lib/dojo-1.5.0-windowname-only/dojo/owfdojo.js.uncompressed',
+ 'audit/Audit',
'util/pageload',
'util/version',
'util/util',
@@ -188,6 +189,7 @@ uiperformance.bundles = [
'../js-lib/shindig/rpc',
'../js-lib/shindig/pubsub',
'ux/menu/Item',
+ 'audit/Audit',
'util/version',
'util/log',
'util/pageload',
@@ -527,6 +529,7 @@ uiperformance.bundles = [
'ux/MessageBoxPlus',
'ux/OWFVtypes',
'../js-lib/log4javascript/log4javascript',
+ 'audit/Audit',
'util/version',
'util/util',
'util/widget_utils',
@@ -981,6 +984,23 @@ owf {
cssImports = []
}
+ dataguard {
+ // Option to restrict messages between widgets based on access levels.
+ // If this option is set to false, all other dataguard options are ignored.
+ restrictMessages = true
+
+ // Option to audit all messages between widgets, not just failed messages.
+ // restrictMessages must be set to true
+ auditAllMessages = false
+
+ // Option to allow widgets to send messages without specifying their access level.
+ // restrictMessages must be set to true
+ allowMessagesWithoutAccessLevel = true
+
+ // The amount of time (in milliseconds) to cache a widget's access level.
+ // restrictMessages must be set to true
+ accessLevelCacheTimeout = 3600000
+ }
}
// log4j configuration : see log4j.xml
@@ -453,6 +453,14 @@ class UrlMappings {
controller = 'marketplace'
action = 'retrieveFromMarketplace'
}
+ "/audit" {
+ controller='audit'
+ action='logMessage'
+ }
+ "/access" {
+ controller='access'
+ action='checkAccess'
+ }
"500"(controller: 'error')
}
}
@@ -6,5 +6,8 @@
<import resource="classpath*:*OWFsecurityContext*.xml" />
<import resource="classpath*:OwfConfig.xml" />
-
+
+ <bean id="customAccessChecker" class="custom.access.CustomAccessChecker">
+
+ </bean>
</beans>
@@ -0,0 +1,13 @@
+package ozone.owf.grails.controllers
+
+import grails.converters.JSON
+
+
+class AccessController extends BaseOwfRestController {
+
+ def accessService
+
+ def checkAccess = {
+ renderResult((accessService.checkAccess(params)) as JSON, 200)
+ }
+}
@@ -0,0 +1,13 @@
+package ozone.owf.grails.controllers
+
+import grails.converters.JSON
+
+
+class AuditController extends BaseOwfRestController {
+
+ def auditService
+
+ def logMessage = {
+ renderResult((auditService.logMessage(params)) as JSON, 200)
+ }
+}
@@ -0,0 +1,43 @@
+package ozone.owf.grails.services
+
+import grails.converters.JSON
+import custom.access.AccessLevel
+import custom.access.CustomAccessChecker
+import ozone.owf.grails.domain.WidgetDefinition
+
+class AccessService {
+
+ def accountService
+ def customAccessChecker
+
+
+ def checkAccess(def params) {
+ def username = accountService.getLoggedInUsername()
+ println "Within Access Service"
+ println "Listing info passed in via params: " + params.widgetId
+ def widgetId = params.widgetId
+ def receivingWidget = WidgetDefinition.findByWidgetGuid(widgetId)
+
+ def formalAccesses = []
+
+ // Define formal access levels to check
+ if (params.accessLevel == null) {
+ // Check all access levels sending widget is permitted to accept.
+ // Receiving widget must be permitted to accept all these access levels.
+ def sendingWidget = WidgetDefinition.findByWidgetGuid(params.senderId)
+ formalAccesses = customAccessChecker.getFormalAccesses(sendingWidget.widgetUrl)
+ } else {
+ // Only check specified access level
+ def accessLevel = new AccessLevel(params.accessLevel)
+ formalAccesses.push(accessLevel)
+ }
+
+ def userHasAccess = customAccessChecker.checkAccess(username, formalAccesses)
+ def widgetHasAccess = customAccessChecker.checkAccess(receivingWidget.widgetUrl, formalAccesses)
+ def hasAccess = (userHasAccess && widgetHasAccess)
+
+ return [success:true, data:[widgetId: params.widgetId, accessLevel: params.accessLevel?.toUpperCase(), hasAccess: hasAccess]]
+ }
+
+}
+
@@ -0,0 +1,22 @@
+package ozone.owf.grails.services
+
+import grails.converters.JSON
+import ozone.owf.grails.AuditOWFWebRequestsLogger
+import ozone.owf.grails.util.OWFDate
+
+class AuditService {
+
+ def grailsApplication
+ def accountService
+ def loggingService = new AuditOWFWebRequestsLogger()
+
+ def logMessage(def params) {
+ def username = accountService.getLoggedInUsername()
+ def requestTime = OWFDate.format(new Date())
+ def logMessage = requestTime + " - " + params.message + " [username:" + username + "]"
+ loggingService.log(logMessage)
+ return [success:true, data:[message: logMessage]]
+ }
+
+}
+
@@ -0,0 +1,8 @@
+
+
+// data to configure test run for AccessServiceTests
+class AccessServiceTestHelper {
+
+ def testDataFile
+
+}
@@ -132,10 +132,15 @@ def replaceClosureNames(artefacts) {
def replaceClosureNamesInXmlReports(artefacts) {
def xml = new File("${coverageReportDir}/coverage.xml")
if (xml.exists()) {
- def p = new XmlParser()
- p.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
- def parser = p.parse(xml)
-
+ def entityResolver = { publicId,systemId ->
+ if(systemId.endsWith(".dtd"))
+ return new org.xml.sax.InputSource(new StringReader(" "))
+ else
+ return null
+ } as org.xml.sax.EntityResolver
+
+ def parser = new XmlParser(entityResolver: entityResolver).parse(xml)
+
artefacts?.each {artefact ->
def closures = [:]
artefact.reference.propertyDescriptors.each {propertyDescriptor ->
@@ -0,0 +1,23 @@
+package custom.access;
+
+public class AccessLevel {
+ private int accessLevel;
+
+ public AccessLevel() {
+ this.accessLevel = 0;
+ }
+
+ public AccessLevel(String accessLevel) {
+ this.accessLevel = Integer.parseInt(accessLevel);
+ }
+
+ public int setAccessLevel(String accessLevel) {
+ this.accessLevel = Integer.parseInt(accessLevel);
+ return this.accessLevel;
+ }
+
+ public int getAccessLevel() {
+ return this.accessLevel;
+ }
+
+}
@@ -0,0 +1,47 @@
+/**
+ * Package for custom access classes
+ */
+package custom.access;
+
+import java.util.ArrayList;
+
+import custom.access.AccessLevel;
+
+/**
+ * This is a very simple example class that checks widget access levels.
+ * It is intended to be overridden. Implementation below expects the access level
+ * to be an integer between 1 and 6.
+ *
+ * @author
+ *
+ */
+public class CustomAccessChecker {
+ /**
+ * Default constructor
+ */
+ public CustomAccessChecker() {}
+
+ /**
+ * Check whether the specified username (which can be a user or a url)
+ * has access to the specified access level.
+ */
+ public boolean checkAccess(String username, ArrayList<AccessLevel> formalAccesses) {
+ ArrayList<AccessLevel> receivingWidgetFormalAccesses = getFormalAccesses(username);
+
+ for (int i = 0; i < formalAccesses.size(); i++) {
+ AccessLevel accessLevel = formalAccesses.get(i);
+ if (accessLevel.getAccessLevel() > receivingWidgetFormalAccesses.get(0).getAccessLevel()) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public ArrayList<AccessLevel> getFormalAccesses(String username) {
+ ArrayList<AccessLevel> formalAccesses = new ArrayList<AccessLevel>();
+ AccessLevel accessLevel = new AccessLevel("4");
+ formalAccesses.add(accessLevel);
+ return formalAccesses;
+ }
+}
@@ -99,6 +99,24 @@ owf {
//truststorePath = System.properties['javax.net.ssl.trustStore']
//timeout = 1800000
}
+
+ dataguard {
+ // Option to restrict messages between widgets based on access levels.
+ // If this option is set to false, all other dataguard options are ignored.
+ restrictMessages = true
+
+ // Option to audit all messages between widgets, not just failed messages.
+ // restrictMessages must be set to true
+ auditAllMessages = false
+
+ // Option to allow widgets to send messages without specifying their access level.
+ // restrictMessages must be set to true
+ allowMessagesWithoutAccessLevel = true
+
+ // The amount of time (in milliseconds) to cache a widget's access level.
+ // restrictMessages must be set to true
+ accessLevelCacheTimeout = 3600000
+ }
}
Oops, something went wrong.

0 comments on commit 60ce5fa

Please sign in to comment.