You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openaz.apache.org by pd...@apache.org on 2016/03/17 02:07:00 UTC
[21/23] incubator-openaz git commit: Ported original att source to
openaz
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/META-INF/drop.sql
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/META-INF/drop.sql b/openaz-xacml-pap-admin/src/META-INF/drop.sql
new file mode 100644
index 0000000..8aee7ee
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/META-INF/drop.sql
@@ -0,0 +1,21 @@
+DROP TABLE IF EXISTS AttributeAssignment;
+DROP TABLE IF EXISTS ConstraintValues;
+DROP TABLE IF EXISTS ObadviceExpressions;
+DROP TABLE IF EXISTS Attribute;
+DROP TABLE IF EXISTS Category;
+DROP TABLE IF EXISTS ConstraintType;
+DROP VIEW IF EXISTS match_functions;
+DROP VIEW IF EXISTS higherorder_bag_functions;
+DROP VIEW IF EXISTS function_flattener;
+DROP TABLE IF EXISTS FunctionArguments;
+DROP TABLE IF EXISTS FunctionDefinition;
+DROP TABLE IF EXISTS Datatype;
+DROP TABLE IF EXISTS Obadvice;
+DROP TABLE IF EXISTS PIPConfigParams;
+DROP TABLE IF EXISTS PIPResolverParams;
+DROP TABLE IF EXISTS PIPResolver;
+DROP TABLE IF EXISTS PIPConfiguration;
+DROP TABLE IF EXISTS PIPType;
+DROP TABLE IF EXISTS PolicyAlgorithms;
+DROP TABLE IF EXISTS RuleAlgorithms;
+DROP TABLE IF EXISTS SEQUENCE;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/META-INF/empty.sql
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/META-INF/empty.sql b/openaz-xacml-pap-admin/src/META-INF/empty.sql
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/META-INF/persistence.xml
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/META-INF/persistence.xml b/openaz-xacml-pap-admin/src/META-INF/persistence.xml
new file mode 100644
index 0000000..79594a9
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/META-INF/persistence.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
+ <persistence-unit name="XACML-PAP-ADMIN">
+ <class>org.apache.openaz.xacml.admin.jpa.Attribute</class>
+ <class>org.apache.openaz.xacml.admin.jpa.AttributeAssignment</class>
+ <class>org.apache.openaz.xacml.admin.jpa.Category</class>
+ <class>org.apache.openaz.xacml.admin.jpa.ConstraintType</class>
+ <class>org.apache.openaz.xacml.admin.jpa.ConstraintValue</class>
+ <class>org.apache.openaz.xacml.admin.jpa.Datatype</class>
+ <class>org.apache.openaz.xacml.admin.jpa.Obadvice</class>
+ <class>org.apache.openaz.xacml.admin.jpa.ObadviceExpression</class>
+ <class>org.apache.openaz.xacml.admin.jpa.PolicyAlgorithms</class>
+ <class>org.apache.openaz.xacml.admin.jpa.RuleAlgorithms</class>
+ <class>org.apache.openaz.xacml.admin.jpa.FunctionArgument</class>
+ <class>org.apache.openaz.xacml.admin.jpa.FunctionDefinition</class>
+ <class>org.apache.openaz.xacml.admin.jpa.PIPConfigParam</class>
+ <class>org.apache.openaz.xacml.admin.jpa.PIPConfiguration</class>
+ <class>org.apache.openaz.xacml.admin.jpa.PIPResolver</class>
+ <class>org.apache.openaz.xacml.admin.jpa.PIPResolverParam</class>
+ <class>org.apache.openaz.xacml.admin.jpa.PIPType</class>
+ <properties>
+ <!--
+ The properties defined below are the default settings to be used when someone initially
+ wants to start working with the XACML-PAP-ADMIN web gui. They are not intended for production
+ use.
+
+ They are setup to drop and create the tables and then load an initial set of data into the database
+ every time the application is deployed. So if you add anything to the dictionaries or PIP
+ configuration, they will get lost upon each deployment. It uses an H2 database engine configured
+ for a local file so you don't have to setup you're own SQL database environment to start.
+
+ Instead of modifying this file directly, please refer to the xacml.admin.properties file for
+ customizing the application settings.
+
+ -->
+ <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
+ <property name="javax.persistence.schema-generation.create-source" value="metadata-then-script"/>
+ <property name="javax.persistence.schema-generation.create-script-source" value="META-INF/views.sql" />
+ <property name="javax.persistence.schema-generation.drop-source" value="script"/>
+ <property name="javax.persistence.schema-generation.drop-script-source" value="META-INF/drop.sql" />
+ <property name="javax.persistence.sql-load-script-source" value="META-INF/data.sql" />
+
+ <!--
+
+ These properties should be set in the xacml.admin.properties file, so they can be re-used by non-JPA
+ database functionality.
+
+ <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
+ <property name="javax.persistence.jdbc.url" value="jdbc:h2:file:sql/xacml"/>
+ <property name="javax.persistence.jdbc.user" value="sa"/>
+ <property name="javax.persistence.jdbc.password" value=""/>
+ -->
+ </properties>
+ </persistence-unit>
+</persistence>
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/META-INF/views.sql
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/META-INF/views.sql b/openaz-xacml-pap-admin/src/META-INF/views.sql
new file mode 100644
index 0000000..7c4a820
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/META-INF/views.sql
@@ -0,0 +1,6 @@
+
+CREATE VIEW match_functions AS SELECT D.ID AS id, D.SHORT_NAME AS shortname, D.XACML_ID AS xacmlid, D.RETURN_DATATYPE AS return_datatype, D.IS_BAG_RETURN AS is_bag_return, D.ARG_LB AS arg_lb, D.ARG_UB AS arg_ub, A1.IS_BAG AS arg1_isbag, A1.DATATYPE_ID AS arg1_datatype, A2.IS_BAG AS arg2_isbag, A2.DATATYPE_ID AS arg2_datatype FROM (FunctionDefinition D left join FunctionArguments A1 on (A1.FUNCTION_ID = D.ID and A1.ARG_INDEX = 1) left join FunctionArguments A2 on (A2.FUNCTION_ID = D.ID and A2.ARG_INDEX = 2)) where (D.ARG_LB = 2 and D.ARG_UB = 2 and D.RETURN_DATATYPE = 18 and A1.IS_BAG = 0) order by D.SHORT_NAME;
+
+CREATE VIEW function_flattener AS SELECT D.ID AS id, D.SHORT_NAME AS shortname, D.RETURN_DATATYPE AS return_datatype, D.IS_BAG_RETURN AS is_bag_return, D.IS_HIGHER_ORDER AS is_higher_order, D.ARG_LB AS arg_lb, D.ARG_UB AS arg_ub, A1.IS_BAG AS arg1_isbag, A1.DATATYPE_ID AS arg1_datatype, A2.IS_BAG AS arg2_isbag, A2.DATATYPE_ID AS arg2_datatype, A3.IS_BAG AS arg3_isbag, A3.DATATYPE_ID AS arg3_datatype FROM (FunctionDefinition D left join FunctionArguments A1 ON (A1.FUNCTION_ID = D.ID and A1.ARG_INDEX = 1) left join FunctionArguments A2 ON (A2.FUNCTION_ID = D.ID and A2.ARG_INDEX = 2) LEFT JOIN FunctionArguments A3 ON (A3.FUNCTION_ID = D.ID and A3.ARG_INDEX = 3)) ORDER BY D.ID;
+
+CREATE VIEW higherorder_bag_functions AS SELECT * FROM function_flattener WHERE is_higher_order = 1 AND is_bag_return = 1 AND return_datatype=18 AND arg_lb=2 AND arg_ub=2 AND arg1_isbag = 1 AND (arg2_isbag = 1 OR arg2_isbag IS NULL);
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/PAPNotificationBroadcaster.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/PAPNotificationBroadcaster.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/PAPNotificationBroadcaster.java
new file mode 100644
index 0000000..b2deda7
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/PAPNotificationBroadcaster.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.openaz.xacml.admin;
+
+import java.io.Serializable;
+import java.util.LinkedList;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Handle Notifications from the PAP that the PDP Groups have been changed.
+ * We need a Server Push Broadcaster because there may be multiple Vaadin instances (i.e. Users) that need to be told when a change occurs.
+ *
+ * Initially we only update the entire set of PDPGroups in one shot.
+ *
+ * (Code copied from Book of Vaadin chapter on Server Push
+ * @author glenngriffin
+ *
+ */
+public class PAPNotificationBroadcaster implements Serializable {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2539940306348821754L;
+
+
+ private static Log logger = LogFactory.getLog(PAPNotificationBroadcaster.class);
+
+
+ static ExecutorService executorService = Executors.newSingleThreadExecutor();
+
+ /**
+ * Interface used by all classes that need to be notified when PAP sends an update message.
+ *
+ * @author glenngriffin
+ *
+ */
+ public interface PAPNotificationBroadcastListener {
+ void updateAllGroups();
+ }
+
+
+
+ /*
+ * list of registered listeners
+ */
+ private static LinkedList<PAPNotificationBroadcastListener> listeners =
+ new LinkedList<PAPNotificationBroadcastListener>();
+
+ /**
+ * Listener registers to hear about updates.
+ * @param listener
+ */
+ public static synchronized void register(
+ PAPNotificationBroadcastListener listener) {
+ listeners.add(listener);
+ }
+
+
+ /**
+ * Listener is going away.
+ *
+ * @param listener
+ */
+ public static synchronized void unregister(
+ PAPNotificationBroadcastListener listener) {
+ listeners.remove(listener);
+ }
+
+
+
+ /**
+ * Tell all listeners about an update.
+ *
+ * @param message
+ */
+ public static synchronized void updateAllGroups() {
+ for (final PAPNotificationBroadcastListener listener: listeners) {
+ // Original code copied from example:
+ // executorService.execute(new Runnable() {
+ // @Override
+ // public void run() {
+ // The problem with this is that the execute starts a new Thread, but the thing we are calling (the listener.updateAllGroups)
+ // happens in this case to ALSO create a new thread, and it locks up because the shared threadpool queue is already locked by this method.
+ // On application shutdown that left us with a blocked thread, so the process never goes away.
+ // Since the listener.updateAllGroups does ALL of its work inside a new Runnable thread, there should be no need for this method to also create a thread.
+
+ /*
+ * IMPORTANT:
+ * All listeners MUST either execute with no possibility of blocking
+ * OR must start their own threads to handle blocking and concurrent operations.
+ */
+ if (logger.isDebugEnabled()) {
+ logger.debug("updateAllGroups");
+ }
+ listener.updateAllGroups();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminAuthorization.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminAuthorization.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminAuthorization.java
new file mode 100644
index 0000000..2a065d5
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminAuthorization.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.openaz.xacml.admin;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.openaz.xacml.std.annotations.XACMLRequest;
+import org.apache.openaz.xacml.std.annotations.RequestParser;
+import org.apache.openaz.xacml.std.annotations.XACMLSubject;
+import org.apache.openaz.xacml.std.annotations.XACMLAction;
+import org.apache.openaz.xacml.std.annotations.XACMLResource;
+import org.apache.openaz.xacml.api.DataTypeException;
+import org.apache.openaz.xacml.api.Decision;
+import org.apache.openaz.xacml.api.Request;
+import org.apache.openaz.xacml.api.Response;
+import org.apache.openaz.xacml.api.Result;
+import org.apache.openaz.xacml.api.pdp.PDPEngine;
+import org.apache.openaz.xacml.api.pdp.PDPEngineFactory;
+import org.apache.openaz.xacml.api.pdp.PDPException;
+import org.apache.openaz.xacml.util.FactoryException;
+
+public class XacmlAdminAuthorization {
+ private static Log logger = LogFactory.getLog(XacmlAdminAuthorization.class);
+
+ public enum AdminAction {
+ ACTION_ACCESS("access"),
+ ACTION_READ("read"),
+ ACTION_WRITE("write"),
+ ACTION_ADMIN("admin");
+
+ String action;
+ AdminAction(String a) {
+ this.action = a;
+ }
+ public String toString() {
+ return this.action;
+ }
+ }
+
+ public enum AdminResource {
+ RESOURCE_APPLICATION("application"),
+ RESOURCE_POLICY_WORKSPACE("workspace"),
+ RESOURCE_POLICY_EDITOR("editor"),
+ RESOURCE_DICTIONARIES("dictionaries"),
+ RESOURCE_PDP_ADMIN("pdp_admin"),
+ RESOURCE_PIP_ADMIN("pip_admin");
+
+ String resource;
+ AdminResource(String r) {
+ this.resource = r;
+ }
+ public String toString() {
+ return this.resource;
+ }
+ }
+
+ @XACMLRequest(ReturnPolicyIdList=true)
+ public class AuthorizationRequest {
+
+ @XACMLSubject(includeInResults=true)
+ String userID;
+
+ @XACMLAction()
+ String action;
+
+ @XACMLResource()
+ String resource;
+
+ public AuthorizationRequest(String userId, String action, String resource) {
+ this.userID = userId;
+ this.action = action;
+ this.resource = resource;
+ }
+
+ public String getUserID() {
+ return userID;
+ }
+
+ public void setUserID(String userID) {
+ this.userID = userID;
+ }
+
+ public String getAction() {
+ return action;
+ }
+
+ public void setAction(String action) {
+ this.action = action;
+ }
+
+ public String getResource() {
+ return resource;
+ }
+
+ public void setResource(String resource) {
+ this.resource = resource;
+ }
+ }
+
+ //
+ // The PDP Engine
+ //
+ protected PDPEngine pdpEngine;
+
+ public XacmlAdminAuthorization() {
+ PDPEngineFactory pdpEngineFactory = null;
+ try {
+ pdpEngineFactory = PDPEngineFactory.newInstance();
+ if (pdpEngineFactory == null) {
+ logger.error("Failed to create PDP Engine Factory");
+ }
+ this.pdpEngine = pdpEngineFactory.newEngine();
+ } catch (FactoryException e) {
+ logger.error("Exception create PDP Engine: " + e.getLocalizedMessage());
+ }
+ }
+
+ public boolean isAuthorized(String userid, AdminAction action, AdminResource resource) {
+ logger.info("authorize: " + userid + " to " + action + " with " + resource);
+ if (this.pdpEngine == null) {
+ logger.warn("no pdp engine available to authorize");
+ return false;
+ }
+ Request request;
+ try {
+ request = RequestParser.parseRequest(new AuthorizationRequest(userid, action.toString(), resource.toString()));
+ } catch (IllegalArgumentException | IllegalAccessException | DataTypeException e) {
+ logger.error("Failed to create request: " + e.getLocalizedMessage());
+ return false;
+ }
+ if (request == null) {
+ logger.error("Failed to parse request.");
+ return false;
+ }
+ logger.info("Request: " + request);
+ //
+ // Ask the engine
+ //
+ try {
+ Response response = this.pdpEngine.decide(request);
+ if (response == null) {
+ logger.error("Null response from PDP decide");
+ }
+ //
+ // Should only be one result
+ //
+ for (Result result : response.getResults()) {
+ Decision decision = result.getDecision();
+ logger.info("Decision: " + decision);
+ if (decision.equals(Decision.PERMIT)) {
+ return true;
+ }
+ }
+ } catch (PDPException e) {
+ logger.error("PDP Decide failed: " + e.getLocalizedMessage());
+ }
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminConsole.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminConsole.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminConsole.java
new file mode 100644
index 0000000..91e831b
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminConsole.java
@@ -0,0 +1,253 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.openaz.xacml.admin;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.openaz.xacml.admin.components.AttributeDictionary;
+import org.apache.openaz.xacml.admin.components.ObadviceDictionary;
+import org.apache.openaz.xacml.admin.components.PDPManagement;
+import org.apache.openaz.xacml.admin.components.PIPManagement;
+import org.apache.openaz.xacml.admin.components.PolicyWorkspace;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.navigator.View;
+import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
+import com.vaadin.server.ThemeResource;
+import com.vaadin.shared.ui.label.ContentMode;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.Embedded;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.TabSheet;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+
+public class XacmlAdminConsole extends CustomComponent implements View {
+ private static final long serialVersionUID = 1L;
+ @AutoGenerated
+ private VerticalLayout mainLayout;
+ @AutoGenerated
+ private Label labelCopyright;
+ @AutoGenerated
+ private TabSheet tabSheet;
+ @AutoGenerated
+ private HorizontalLayout horizontalLayout_1;
+ @AutoGenerated
+ private Label labelWelcome;
+ @AutoGenerated
+ private Label caption;
+ @AutoGenerated
+ private Embedded embedded_1;
+
+ private static Log logger = LogFactory.getLog(XacmlAdminConsole.class);
+
+ private final PolicyWorkspace policyWorkspace;
+ private final AttributeDictionary attributeDictionary;
+ private final ObadviceDictionary obadvice;
+ private final PDPManagement pdp;
+ private final PIPManagement pip;
+// private final UserManagement user;
+
+ /**
+ * The constructor should first build the main layout, set the
+ * composition root and then do any custom initialization.
+ *
+ * The constructor will not be automatically regenerated by the
+ * visual editor.
+ */
+ public XacmlAdminConsole() {
+ buildMainLayout();
+ setCompositionRoot(mainLayout);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Creating tabs...");
+ }
+
+ this.labelWelcome.setValue("Welcome " + ((XacmlAdminUI)UI.getCurrent()).getUserName());
+ this.labelCopyright.setContentMode(ContentMode.HTML);
+
+ if (((XacmlAdminUI)UI.getCurrent()).isAuthorized(
+ XacmlAdminAuthorization.AdminAction.ACTION_READ,
+ XacmlAdminAuthorization.AdminResource.RESOURCE_POLICY_WORKSPACE)) {
+ this.policyWorkspace = new PolicyWorkspace();
+ this.tabSheet.addComponent(this.policyWorkspace);
+ this.tabSheet.getTab(this.policyWorkspace).setCaption("Policy Workspace");
+ } else {
+ this.policyWorkspace = null;
+ }
+
+ if (((XacmlAdminUI)UI.getCurrent()).isAuthorized(
+ XacmlAdminAuthorization.AdminAction.ACTION_READ,
+ XacmlAdminAuthorization.AdminResource.RESOURCE_DICTIONARIES)) {
+ this.attributeDictionary = new AttributeDictionary();
+ this.tabSheet.addComponent(this.attributeDictionary);
+ this.tabSheet.getTab(this.attributeDictionary).setCaption("Attribute Dictionary");
+
+ this.obadvice = new ObadviceDictionary();
+ this.tabSheet.addComponent(this.obadvice);
+ this.tabSheet.getTab(this.obadvice).setCaption("Obligation/Advice Dictionary");
+ } else {
+ this.attributeDictionary = null;
+ this.obadvice = null;
+ }
+ if (((XacmlAdminUI)UI.getCurrent()).isAuthorized(
+ XacmlAdminAuthorization.AdminAction.ACTION_READ,
+ XacmlAdminAuthorization.AdminResource.RESOURCE_PDP_ADMIN)) {
+ this.pdp = new PDPManagement(((XacmlAdminUI)UI.getCurrent()).getPAPEngine());
+ this.tabSheet.addComponent(this.pdp);
+ this.tabSheet.getTab(this.pdp).setCaption("PDP Management");
+ } else {
+ this.pdp = null;
+ }
+
+ if (((XacmlAdminUI)UI.getCurrent()).isAuthorized(
+ XacmlAdminAuthorization.AdminAction.ACTION_READ,
+ XacmlAdminAuthorization.AdminResource.RESOURCE_PIP_ADMIN)) {
+ this.pip = new PIPManagement();
+ this.tabSheet.addComponent(this.pip);
+ this.tabSheet.getTab(this.pip).setCaption("PIP Management");
+ } else {
+ this.pip = null;
+ }
+ /*
+ * TODO - figure out how to add this in
+ *
+ if (((XacmlAdminUI)UI.getCurrent()).isAuthorized(
+ XacmlAdminAuthorization.AdminAction.ACTION_READ,
+ XacmlAdminAuthorization.AdminResource.RESOURCE_POLICY_WORKSPACE)) {
+ this.user = new UserManagement();
+ this.tabSheet.addComponent(this.user);
+ this.tabSheet.getTab(this.user).setCaption("User Management");
+ }
+ */
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Done creating tabs.");
+ }
+ }
+
+ public void refreshAttributes() {
+ this.attributeDictionary.refreshContainer();
+ }
+ public void refreshObadvice() {
+ this.obadvice.refreshContainer();
+ }
+
+ public void refreshPIPConfiguration() {
+ this.pip.refreshContainer();
+ }
+
+ public void refreshPDPGroups() {
+ this.pdp.refreshContainer();
+ }
+
+ public TabSheet getTabSheet() { return tabSheet;}
+
+ @AutoGenerated
+ private VerticalLayout buildMainLayout() {
+ // common part: create layout
+ mainLayout = new VerticalLayout();
+ mainLayout.setImmediate(false);
+ mainLayout.setWidth("100%");
+ mainLayout.setHeight("100%");
+ mainLayout.setMargin(true);
+
+ // top-level component properties
+ setWidth("100.0%");
+ setHeight("100.0%");
+
+ // horizontalLayout_1
+ horizontalLayout_1 = buildHorizontalLayout_1();
+ mainLayout.addComponent(horizontalLayout_1);
+
+ // tabSheet
+ tabSheet = new TabSheet();
+ tabSheet.setImmediate(false);
+ tabSheet.setWidth("100.0%");
+ tabSheet.setHeight("100.0%");
+ mainLayout.addComponent(tabSheet);
+ mainLayout.setExpandRatio(tabSheet, 1.0f);
+
+ // labelCopyright
+ labelCopyright = new Label();
+ labelCopyright.setImmediate(false);
+ labelCopyright.setWidth("-1px");
+ labelCopyright.setHeight("40px");
+ labelCopyright
+ .setValue("<center>Copyright © 2015 The Apache Software Foundation, Licensed under the Apache License, Version 2.0.</center>");
+ mainLayout.addComponent(labelCopyright);
+ mainLayout.setComponentAlignment(labelCopyright, new Alignment(48));
+
+ return mainLayout;
+ }
+
+ @AutoGenerated
+ private HorizontalLayout buildHorizontalLayout_1() {
+ // common part: create layout
+ horizontalLayout_1 = new HorizontalLayout();
+ horizontalLayout_1.setImmediate(false);
+ horizontalLayout_1.setWidth("100.0%");
+ horizontalLayout_1.setHeight("40px");
+ horizontalLayout_1.setMargin(false);
+
+ // embedded_1
+ embedded_1 = new Embedded();
+ embedded_1.setImmediate(false);
+ embedded_1.setWidth("30px");
+ embedded_1.setHeight("30px");
+ embedded_1.setSource(new ThemeResource("img/att.png"));
+ embedded_1.setType(1);
+ embedded_1.setMimeType("image/png");
+ horizontalLayout_1.addComponent(embedded_1);
+ horizontalLayout_1.setComponentAlignment(embedded_1, new Alignment(33));
+
+ // caption
+ caption = new Label();
+ caption.setImmediate(false);
+ caption.setWidth("-1px");
+ caption.setHeight("-1px");
+ caption.setValue("Apache OpenAZ Admin Console");
+ horizontalLayout_1.addComponent(caption);
+ horizontalLayout_1.setExpandRatio(caption, 1.0f);
+ horizontalLayout_1.setComponentAlignment(caption, new Alignment(33));
+
+ // labelWelcome
+ labelWelcome = new Label();
+ labelWelcome.setImmediate(false);
+ labelWelcome.setWidth("-1px");
+ labelWelcome.setHeight("40px");
+ labelWelcome.setValue("Label");
+ horizontalLayout_1.addComponent(labelWelcome);
+ horizontalLayout_1.setComponentAlignment(labelWelcome,
+ new Alignment(34));
+
+ return horizontalLayout_1;
+ }
+
+ @Override
+ public void enter(ViewChangeEvent event) {
+ //
+ // This needs to be implemented
+ //
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminServlet.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminServlet.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminServlet.java
new file mode 100644
index 0000000..fa48543
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminServlet.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.openaz.xacml.admin;
+
+import java.io.IOException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebInitParam;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.vaadin.annotations.Push;
+import com.vaadin.annotations.VaadinServletConfiguration;
+import com.vaadin.server.VaadinServlet;
+
+import org.apache.openaz.xacml.rest.XACMLRest;
+
+
+//
+// The Servlet underlying the Vaadin Servlet
+//
+@Push
+@WebServlet(
+ value = "/*",
+ description = "XACML Admin Console",
+ asyncSupported = true,
+ loadOnStartup=1,
+ initParams = {
+ @WebInitParam(name = "XACML_PROPERTIES_NAME", value = "xacml.admin.properties", description = "The location of the properties file holding configuration information.")
+})
+@VaadinServletConfiguration(productionMode = false, ui = XacmlAdminUI.class)
+public class XacmlAdminServlet extends VaadinServlet {
+ //
+ // All static declarations
+ //
+ private static Log logger = LogFactory.getLog(XacmlAdminServlet.class); //NOPMD
+
+ @Override
+ public void init(ServletConfig servletConfig) throws ServletException {
+ super.init(servletConfig);
+ //
+ // Common initialization
+ //
+ XACMLRest.xacmlInit(servletConfig);
+
+ // Initialization
+ XacmlAdminUI.servletInit();
+ }
+
+ @Override
+ public void destroy() {
+ XacmlAdminUI.servletDestroy();
+ super.destroy();
+ }
+
+ /**
+ *
+ * Called by:
+ * - PAP to notify Vaadin GUIs that something has changed
+ *
+ * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
+ */
+ @Override
+ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ // watch for notifications from the PAP
+ if (request.getMethod().equals("PUT") && request.getParameter("PAPNotification") != null) {
+ XacmlAdminUI.doPAPNotification(request, response);
+ return;
+ }
+
+ // not a PAP notification, so let Vaadin handle normally
+ super.service(request,response);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminUI.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminUI.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminUI.java
new file mode 100644
index 0000000..e553749
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlAdminUI.java
@@ -0,0 +1,801 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.openaz.xacml.admin;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.sql.SQLException;
+import java.util.Properties;
+import java.util.UUID;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.api.errors.InvalidRemoteException;
+import org.eclipse.jgit.api.errors.TransportException;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.StoredConfig;
+import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
+import org.eclipse.persistence.config.PersistenceUnitProperties;
+
+import org.apache.openaz.xacml.admin.XacmlAdminAuthorization.AdminAction;
+import org.apache.openaz.xacml.admin.XacmlAdminAuthorization.AdminResource;
+import org.apache.openaz.xacml.admin.converters.XacmlConverterFactory;
+import org.apache.openaz.xacml.admin.jpa.Attribute;
+import org.apache.openaz.xacml.admin.jpa.Category;
+import org.apache.openaz.xacml.admin.jpa.ConstraintType;
+import org.apache.openaz.xacml.admin.jpa.Datatype;
+import org.apache.openaz.xacml.admin.jpa.FunctionArgument;
+import org.apache.openaz.xacml.admin.jpa.FunctionDefinition;
+import org.apache.openaz.xacml.admin.jpa.Obadvice;
+import org.apache.openaz.xacml.admin.jpa.ObadviceExpression;
+import org.apache.openaz.xacml.admin.jpa.PIPConfiguration;
+import org.apache.openaz.xacml.admin.jpa.PIPResolver;
+import org.apache.openaz.xacml.admin.jpa.PIPType;
+import org.apache.openaz.xacml.admin.jpa.PolicyAlgorithms;
+import org.apache.openaz.xacml.admin.jpa.RuleAlgorithms;
+import org.apache.openaz.xacml.admin.model.MatchFunctionQueryDelegate;
+import org.apache.openaz.xacml.admin.util.RESTfulPAPEngine;
+import org.apache.openaz.xacml.api.XACML3;
+import org.apache.openaz.xacml.api.pap.PAPEngine;
+import org.apache.openaz.xacml.api.pap.PAPException;
+import org.apache.openaz.xacml.rest.XACMLRestProperties;
+import org.apache.openaz.xacml.util.XACMLProperties;
+import com.google.gwt.thirdparty.guava.common.base.Joiner;
+import com.google.gwt.thirdparty.guava.common.base.Splitter;
+import com.vaadin.addon.jpacontainer.JPAContainer;
+import com.vaadin.addon.jpacontainer.provider.CachingLocalEntityProvider;
+import com.vaadin.addon.jpacontainer.provider.CachingMutableLocalEntityProvider;
+import com.vaadin.annotations.Push;
+import com.vaadin.annotations.Theme;
+import com.vaadin.data.util.sqlcontainer.SQLContainer;
+import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
+import com.vaadin.data.util.sqlcontainer.query.FreeformQuery;
+import com.vaadin.navigator.Navigator;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinServletService;
+import com.vaadin.ui.UI;
+
+@Push
+@SuppressWarnings("serial")
+@Theme("xacml_pap_admin")
+public class XacmlAdminUI extends UI implements PAPNotificationBroadcaster.PAPNotificationBroadcastListener {
+ //
+ // All static declarations
+ //
+ public static final String PERSISTENCE_UNIT = "XACML-PAP-ADMIN";
+ private static Log logger = LogFactory.getLog(XacmlAdminUI.class); //NOPMD
+
+ /*
+ * These objects are shared amongst sessions.
+ */
+ private static Path repositoryPath;
+ private static Repository repository;
+ private static EntityManagerFactory emf;
+ private static JDBCConnectionPool pool;
+
+ /*
+ * These objects are created each session.
+ */
+ private Path workspacePath;
+ private Path gitPath;
+ //
+ // Our Persistence Fields. For general use. NOTE: Be careful applying
+ // filters to these container objects. If one window applies a filter, then
+ // when another window uses the object, that filter will show up and cause confusion.
+ // If filters are needed within a window, then create another instance instead of
+ // using one of these pointers.
+ //
+ private EntityManager em;
+ private JPAContainer<Attribute> attributes;
+ private JPAContainer<ConstraintType> constraintTypes;
+ private JPAContainer<Obadvice> obadvice;
+ private JPAContainer<ObadviceExpression> obadviceExpressions;
+ private JPAContainer<Category> categories;
+ private JPAContainer<Datatype> datatypes;
+ private JPAContainer<PolicyAlgorithms> policyAlgorithms;
+ private JPAContainer<RuleAlgorithms> ruleAlgorithms;
+ private JPAContainer<PIPConfiguration> pipConfigurations;
+ private JPAContainer<PIPResolver> pipResolvers;
+ private JPAContainer<PIPType> pipTypes;
+ private JPAContainer<FunctionDefinition> functionDefinitions;
+ private JPAContainer<FunctionArgument> functionArguments;
+ private SQLContainer matchFunctionContainer;
+ private SQLContainer higherorderBagContainer;
+ //
+ // Our authorization object
+ //
+ XacmlAdminAuthorization authorizer = new XacmlAdminAuthorization();
+ //
+ // The PAP Engine
+ //
+ private PAPEngine papEngine;
+ //
+ // GUI navigation
+ //
+ private Navigator navigator = null;
+ private XacmlAdminConsole console = null;
+ //
+ // Vaadin Init
+ //
+ @Override
+ protected void init(VaadinRequest request) {
+ //
+ // Set our title
+ //
+ this.getPage().setTitle("Apache OpenAZ Admin Console");
+ //
+ // Create our authorization object
+ //
+ this.authorizer = new XacmlAdminAuthorization();
+ //
+ // Is the user authorized to use the application?
+ //
+ if (this.authorizer.isAuthorized(this.getUserid(),
+ XacmlAdminAuthorization.AdminAction.ACTION_ACCESS,
+ XacmlAdminAuthorization.AdminResource.RESOURCE_APPLICATION) == false) {
+ logger.error("user " + this.getUserid() + " is not authorized.");
+ //
+ // Create a navigator to manage all our views
+ //
+ this.navigator = new Navigator(this, this);
+ //
+ // Redirect to an error page
+ //
+ this.navigator.addView(XacmlErrorHandler.VIEWNAME, new XacmlErrorHandler("User " + this.getUserid() + " is not authorized to access application", null));
+ this.navigator.navigateTo(XacmlErrorHandler.VIEWNAME);
+ return;
+ }
+ try {
+ //
+ // Initialize user's Git repository
+ //
+ this.workspacePath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_ADMIN_WORKSPACE), this.getUserid());
+ this.gitPath = XacmlAdminUI.initializeUserRepository(this.workspacePath, this.getUserid(), this.getUserEmail());
+ } catch (Exception e) {
+ logger.error("Git Setup failure", e);
+ //
+ // Create a navigator to manage all our views
+ //
+ this.navigator = new Navigator(this, this);
+ //
+ // Redirect to an error page
+ //
+ this.navigator.addView(XacmlErrorHandler.VIEWNAME, new XacmlErrorHandler(e.getMessage(), null));
+ this.navigator.navigateTo(XacmlErrorHandler.VIEWNAME);
+ return;
+ }
+ //
+ // Create a navigator to manage all our views
+ //
+ this.navigator = new Navigator(this, this);
+ //
+ // Set our converter factory
+ //
+ this.getSession().setConverterFactory(new XacmlConverterFactory());
+ //
+ // Initialize our data objects
+ //
+ try {
+ //
+ // Initialize JPA and SQL. Create our custom entity manager.
+ //
+ logger.info("Creating Persistence Entity Manager");
+ //
+ // Now create the entity manager. This is used throughout the application to create JPA
+ // containers of the entities located in the database.
+ //
+ this.em = XacmlAdminUI.emf.createEntityManager();
+ //
+ // Our Read-Only containers
+ //
+ logger.info("Creating JPA read-only containers");
+ this.constraintTypes = new JPAContainer<ConstraintType>(ConstraintType.class);
+ this.constraintTypes.setEntityProvider(new CachingLocalEntityProvider<ConstraintType>(ConstraintType.class, this.em));
+
+ this.categories = new JPAContainer<Category>(Category.class);
+ this.categories.setEntityProvider(new CachingLocalEntityProvider<Category>(Category.class, this.em));
+
+ this.datatypes = new JPAContainer<Datatype>(Datatype.class);
+ this.datatypes.setEntityProvider(new CachingLocalEntityProvider<Datatype>(Datatype.class, this.em));
+
+ this.policyAlgorithms = new JPAContainer<PolicyAlgorithms>(PolicyAlgorithms.class);
+ this.policyAlgorithms.setEntityProvider(new CachingLocalEntityProvider<PolicyAlgorithms>(PolicyAlgorithms.class, this.em));
+
+ this.ruleAlgorithms = new JPAContainer<RuleAlgorithms>(RuleAlgorithms.class);
+ this.ruleAlgorithms.setEntityProvider(new CachingLocalEntityProvider<RuleAlgorithms>(RuleAlgorithms.class, this.em));
+
+ this.pipTypes = new JPAContainer<PIPType>(PIPType.class);
+ this.pipTypes.setEntityProvider(new CachingLocalEntityProvider<PIPType>(PIPType.class, this.em));
+
+ this.functionDefinitions = new JPAContainer<FunctionDefinition>(FunctionDefinition.class);
+ this.functionDefinitions.setEntityProvider(new CachingLocalEntityProvider<FunctionDefinition>(FunctionDefinition.class, this.em));
+
+ this.functionArguments = new JPAContainer<FunctionArgument>(FunctionArgument.class);
+ this.functionArguments.setEntityProvider(new CachingLocalEntityProvider<FunctionArgument>(FunctionArgument.class, this.em));
+ //
+ // Our writable containers. NOTE: The dictionaries have their own JPA instance since they can
+ // apply filters to their table views. If you update these, then refresh the dictionary containers
+ // by calling the appropriate refresh method defined in XacmlAdminUI.
+ //
+ logger.info("Creating JPA writable containers");
+ this.attributes = new JPAContainer<Attribute>(Attribute.class);
+ this.attributes.setEntityProvider(new CachingMutableLocalEntityProvider<Attribute>(Attribute.class, this.em));
+
+ this.obadvice = new JPAContainer<Obadvice>(Obadvice.class);
+ this.obadvice.setEntityProvider(new CachingMutableLocalEntityProvider<Obadvice>(Obadvice.class, this.em));
+
+ this.obadviceExpressions = new JPAContainer<ObadviceExpression>(ObadviceExpression.class);
+ this.obadviceExpressions.setEntityProvider(new CachingMutableLocalEntityProvider<ObadviceExpression>(ObadviceExpression.class, this.em));
+
+ this.pipConfigurations = new JPAContainer<PIPConfiguration>(PIPConfiguration.class);
+ this.pipConfigurations.setEntityProvider(new CachingMutableLocalEntityProvider<PIPConfiguration>(PIPConfiguration.class, this.em));
+
+ this.pipResolvers = new JPAContainer<PIPResolver>(PIPResolver.class);
+ this.pipResolvers.setEntityProvider(new CachingMutableLocalEntityProvider<PIPResolver>(PIPResolver.class, this.em));
+ //
+ // Sort our persistence data
+ //
+ logger.info("Sorting containers");
+ this.categories.sort(new String[]{"xacmlId"}, new boolean[]{true});
+ this.datatypes.sort(new String[]{"xacmlId"}, new boolean[]{true});
+ this.policyAlgorithms.sort(new String[]{"xacmlId"}, new boolean[]{true});
+ this.ruleAlgorithms.sort(new String[]{"xacmlId"}, new boolean[]{true});
+ this.functionDefinitions.sort(new String[]{"xacmlid"}, new boolean[]{true});
+ //this.functionArguments.sort(new String[]{"datatypeBean"}, new boolean[]{true});
+ //
+ // Create our special query for MatchType functions. We need a custom
+ // QueryDelegate because these functions are accessible via a View (vs a Table).
+ // The basic FreeformQuery does not work with filters on a View (via Vaadin).
+ //
+ // TODO: Consider putting this into a couple of Map's. Doing so would speed up
+ // access. However, if we want to support custom functions, then there needs to
+ // be a way for those custom functions to get into the Map. This is why a database
+ // is being used to store ALL the functions, both standard and custom.
+ //
+ logger.info("Creating SQL Queries");
+ MatchFunctionQueryDelegate delegate = new MatchFunctionQueryDelegate();
+ FreeformQuery query = new FreeformQuery("SELECT * FROM match_functions", XacmlAdminUI.pool, new String[] {});
+ query.setDelegate(delegate);
+ this.matchFunctionContainer = new SQLContainer(query);
+ //
+ // Same for this one
+ //
+ delegate = new MatchFunctionQueryDelegate();
+ query = new FreeformQuery("SELECT * FROM higherorder_bag_functions", XacmlAdminUI.pool, new String[] {});
+ query.setDelegate(delegate);
+ this.higherorderBagContainer = new SQLContainer(query);
+ //
+ // Load our PAP engine
+ //
+ logger.info("Creating PAP engine");
+ String myRequestURL = VaadinServletService.getCurrentServletRequest().getRequestURL().toString();
+ try {
+ //
+ // Set the URL for the RESTful PAP Engine
+ //
+ papEngine = new RESTfulPAPEngine(myRequestURL);
+ } catch (PAPException e ) {
+ logger.error("Failed to create PAP engine", e);
+ } catch (Exception e) {
+ logger.error("Failed to create PAP engine", e);
+ }
+ logger.info("done creating connections");
+ } catch(Exception e) {
+ //
+ // Redirect to an error page
+ //
+ logger.error(e);
+ e.printStackTrace();
+ this.navigator.addView("", new XacmlErrorHandler(e.getMessage(), null));
+ this.navigator.navigateTo("");
+ return;
+ }
+ logger.info("Creating main layout");
+ //
+ // Create our main component layout
+ //
+ this.console = new XacmlAdminConsole();
+ this.navigator.addView("", console);
+ this.navigator.setErrorView(new XacmlErrorHandler(null, null));
+ //
+ // Navigate to our view
+ //
+ this.navigator.navigateTo("");
+ //
+ // Register to receive PAP change notifications broadcasts
+ //
+ PAPNotificationBroadcaster.register(this);
+ }
+
+ public static void servletInit() throws ServletException {
+ //
+ // Initialize GIT repository.
+ //
+ XacmlAdminUI.initializeGitRepository();
+ //
+ // Initialize Entity Factory
+ //
+ XacmlAdminUI.initializeEntityFactory();
+ //
+ // If we get here, then the configuration information
+ // seems ok.
+ //
+ }
+
+ public static void servletDestroy() {
+ if (XacmlAdminUI.repository != null) {
+ XacmlAdminUI.repository.close();
+ }
+ }
+
+ /**
+ * An Update Notification has arrived from the PAP.
+ * Tell the Vaadin users to change their data.
+ *
+ * @param request
+ * @param response
+ * @throws ServletException
+ * @throws IOException
+ */
+ public static void doPAPNotification(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ try {
+ //
+ // Notify all user instances to update groups
+ //
+ PAPNotificationBroadcaster.updateAllGroups();
+ } catch (Exception e) {
+ logger.error("Unable to process PAP request: "+e, e);
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
+ }
+ response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+ }
+
+ // Must unregister when the UI expires
+ @Override
+ public void detach() {
+ PAPNotificationBroadcaster.unregister(this);
+ super.detach();
+ }
+
+ /**
+ * This will initialize the JPA Entity Manager Factory. This will determine if
+ * the database connection settings are correct.
+ *
+ * @throws ServletException
+ */
+ private static void initializeEntityFactory() throws ServletException {
+ logger.info("intializing Persistence Entity Factory");
+ //
+ // Pull custom persistence settings
+ //
+ Properties properties;
+ try {
+ properties = XACMLProperties.getProperties();
+ } catch (IOException e) {
+ throw new ServletException(e.getMessage(), e.getCause());
+ }
+ //
+ // Create the factory
+ //
+ emf = Persistence.createEntityManagerFactory(XacmlAdminUI.PERSISTENCE_UNIT, properties);
+ //
+ // Did it get created?
+ //
+ if (emf == null) {
+ throw new ServletException("Unable to create Entity Manager Factory");
+ }
+ //
+ // Create our JDBC connection pool
+ //
+ try {
+ logger.info("intializing JDBC Connection Pool");
+ XacmlAdminUI.pool = new XacmlJDBCConnectionPool(
+ properties.getProperty(PersistenceUnitProperties.JDBC_DRIVER),
+ properties.getProperty(PersistenceUnitProperties.JDBC_URL),
+ properties.getProperty(PersistenceUnitProperties.JDBC_USER),
+ properties.getProperty(PersistenceUnitProperties.JDBC_PASSWORD));
+ } catch (SQLException e) {
+ throw new ServletException(e.getMessage(), e.getCause());
+ }
+ }
+
+ private static void initializeGitRepository() throws ServletException {
+ XacmlAdminUI.repositoryPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_ADMIN_REPOSITORY));
+ FileRepositoryBuilder builder = new FileRepositoryBuilder();
+ try {
+ XacmlAdminUI.repository = builder.setGitDir(XacmlAdminUI.repositoryPath.toFile()).readEnvironment().findGitDir().setBare().build();
+ if (Files.notExists(XacmlAdminUI.repositoryPath) || Files.notExists(Paths.get(XacmlAdminUI.repositoryPath.toString(), "HEAD"))) {
+ //
+ // Create it if it doesn't exist. As a bare repository
+ //
+ logger.info("Creating bare git repository: " + XacmlAdminUI.repositoryPath.toString());
+ XacmlAdminUI.repository.create();
+ //
+ // Add the magic file so remote works.
+ //
+ Path daemon = Paths.get(XacmlAdminUI.repositoryPath.toString(), "git-daemon-export-ok");
+ Files.createFile(daemon);
+ }
+ } catch (IOException e) {
+ logger.error("Failed to build repository: " + repository, e);
+ throw new ServletException(e.getMessage(), e.getCause());
+ }
+ //
+ // Make sure the workspace directory is created
+ //
+ Path workspace = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_ADMIN_WORKSPACE));
+ workspace = workspace.toAbsolutePath();
+ if (Files.notExists(workspace)) {
+ try {
+ Files.createDirectory(workspace);
+ } catch (IOException e) {
+ logger.error("Failed to build workspace: " + workspace, e);
+ throw new ServletException(e.getMessage(), e.getCause());
+ }
+ }
+ //
+ // Create the user workspace directory
+ //
+ workspace = Paths.get(workspace.toString(), "pe");
+ if (Files.notExists(workspace)) {
+ try {
+ Files.createDirectory(workspace);
+ } catch (IOException e) {
+ logger.error("Failed to create directory: " + workspace, e);
+ throw new ServletException(e.getMessage(), e.getCause());
+ }
+ }
+ //
+ // Get the path to where the repository is going to be
+ //
+ Path gitPath = Paths.get(workspace.toString(), XacmlAdminUI.repositoryPath.getFileName().toString());
+ if (Files.notExists(gitPath)) {
+ try {
+ Files.createDirectory(gitPath);
+ } catch (IOException e) {
+ logger.error("Failed to create directory: " + gitPath, e);
+ throw new ServletException(e.getMessage(), e.getCause());
+ }
+ }
+ //
+ // Initialize the domain structure
+ //
+ String base = null;
+ String domain = XacmlAdminUI.getDomain();
+ if (domain != null) {
+ for (String part : Splitter.on(':').trimResults().split(domain)) {
+ if (base == null) {
+ base = part;
+ }
+ Path subdir = Paths.get(gitPath.toString(), part);
+ if (Files.notExists(subdir)) {
+ try {
+ Files.createDirectory(subdir);
+ Files.createFile(Paths.get(subdir.toString(), ".svnignore"));
+ } catch (IOException e) {
+ logger.error("Failed to create: " + subdir, e);
+ throw new ServletException(e.getMessage(), e.getCause());
+ }
+ }
+ }
+ } else {
+ try {
+ Files.createFile(Paths.get(workspace.toString(), ".svnignore"));
+ base = ".svnignore";
+ } catch (IOException e) {
+ logger.error("Failed to create file", e);
+ throw new ServletException(e.getMessage(), e.getCause());
+ }
+ }
+ try {
+ //
+ // These are the sequence of commands that must be done initially to
+ // finish setting up the remote bare repository.
+ //
+ Git git = Git.init().setDirectory(gitPath.toFile()).setBare(false).call();
+ git.add().addFilepattern(base).call();
+ git.commit().setMessage("Initialize Bare Repository").call();
+ StoredConfig config = git.getRepository().getConfig();
+ config.setString("remote", "origin", "url", XacmlAdminUI.repositoryPath.toAbsolutePath().toString());
+ config.setString("remote", "origin", "fetch", "+refs/heads/*:refs/remotes/origin/*");
+ config.save();
+ git.push().setRemote("origin").add("master").call();
+ /*
+ * This will not work unless git.push().setRemote("origin").add("master").call();
+ * is called first. Otherwise it throws an exception. However, if the push() is
+ * called then calling this function seems to add nothing.
+ *
+ git.branchCreate().setName("master")
+ .setUpstreamMode(SetupUpstreamMode.SET_UPSTREAM)
+ .setStartPoint("origin/master").setForce(true).call();
+ */
+ } catch (GitAPIException | IOException e) {
+ logger.error(e);
+ throw new ServletException(e.getMessage(), e.getCause());
+ }
+ }
+
+ /**
+ * Initializes a user's git repository.
+ *
+ *
+ * @param workspacePath
+ * @param userId
+ * @param email
+ * @return
+ * @throws IOException
+ * @throws InvalidRemoteException
+ * @throws TransportException
+ * @throws GitAPIException
+ */
+ private static Path initializeUserRepository(Path workspacePath, String userId, URI email) throws IOException, InvalidRemoteException, TransportException, GitAPIException {
+ Path gitPath = null;
+ //
+ // Initialize the User's Git repository
+ //
+ if (Files.notExists(workspacePath)) {
+ logger.info("Creating user workspace: " + workspacePath.toAbsolutePath().toString());
+ //
+ // Create our user's directory
+ //
+ Files.createDirectory(workspacePath);
+ }
+ gitPath = Paths.get(workspacePath.toString(), XacmlAdminUI.repositoryPath.getFileName().toString());
+ if (Files.notExists(gitPath)) {
+ //
+ // It doesn't exist yet, so Clone it and check it out
+ //
+ logger.info("Cloning user git directory: " + gitPath.toAbsolutePath().toString());
+ Git.cloneRepository().setURI(XacmlAdminUI.repositoryPath.toUri().toString())
+ .setDirectory(gitPath.toFile())
+ .setNoCheckout(false)
+ .call();
+ //
+ // Set userid
+ //
+ Git git = Git.open(gitPath.toFile());
+ StoredConfig config = git.getRepository().getConfig();
+ config.setString("user", null, "name", userId);
+ if (email != null && email.getPath() != null) {
+ config.setString("user", null, "email", email.toString());
+ }
+ config.save();
+ }
+ return gitPath;
+ }
+
+
+ public static String getDomain() {
+ return XACMLProperties.getProperty(XACMLRestProperties.PROP_ADMIN_DOMAIN, "urn");
+ }
+
+ public static JDBCConnectionPool getConnectionPool() {
+ return pool;
+ }
+
+ public SQLContainer getMatchFunctionContainer() {
+ return this.matchFunctionContainer;
+ }
+
+ public SQLContainer getHigherOrderBagContainer() {
+ return this.higherorderBagContainer;
+ }
+
+ public EntityManager getEntityManager() {
+ return this.em;
+ }
+
+ public JPAContainer<Attribute> getAttributes() {
+ return this.attributes;
+ }
+
+ public void refreshAttributes() {
+ this.attributes.refresh();
+ this.console.refreshAttributes();
+ }
+
+ public JPAContainer<ConstraintType> getConstraintTypes() {
+ return this.constraintTypes;
+ }
+
+ public JPAContainer<Category> getCategories() {
+ return this.categories;
+ }
+
+ public JPAContainer<Datatype> getDatatypes() {
+ return this.datatypes;
+ }
+
+ public JPAContainer<PolicyAlgorithms> getPolicyAlgorithms() {
+ return this.policyAlgorithms;
+ }
+
+ public JPAContainer<RuleAlgorithms> getRuleAlgorithms() {
+ return this.ruleAlgorithms;
+ }
+
+ public JPAContainer<Obadvice> getObadvice() {
+ return this.obadvice;
+ }
+
+ public JPAContainer<ObadviceExpression> getObadviceExpressions() {
+ return this.obadviceExpressions;
+ }
+
+ public void refreshObadvice() {
+ this.obadvice.refresh();
+ this.obadviceExpressions.refresh();
+ this.console.refreshObadvice();
+ }
+
+ public JPAContainer<FunctionDefinition> getFunctionDefinitions() {
+ return this.functionDefinitions;
+ }
+
+ public JPAContainer<FunctionArgument> getFunctionArguments() {
+ return this.functionArguments;
+ }
+
+ public JPAContainer<PIPConfiguration> getPIPConfigurations() {
+ return this.pipConfigurations;
+ }
+
+ public JPAContainer<PIPResolver> getPIPResolvers() {
+ return this.pipResolvers;
+ }
+
+ public JPAContainer<PIPType> getPIPTypes() {
+ return this.pipTypes;
+ }
+
+ public void refreshPIPConfiguration() {
+ this.pipConfigurations.refresh();
+ this.console.refreshPIPConfiguration();
+ }
+
+ public Category getDefaultCategory() throws Exception {
+ for (Object id : categories.getItemIds()) {
+ Category cat = categories.getItem(id).getEntity();
+ if (cat.getIdentifer().equals(XACML3.ID_SUBJECT_CATEGORY_ACCESS_SUBJECT)) {
+ return cat;
+ }
+ }
+ throw new Exception("There is no default category.");
+ }
+
+ public Datatype getDefaultDatatype() throws Exception {
+ for (Object id: this.datatypes.getItemIds()) {
+ Datatype dt = this.datatypes.getItem(id).getEntity();
+ if (dt.getIdentifer().equals(XACML3.ID_DATATYPE_STRING)) {
+ return dt;
+ }
+ }
+ throw new Exception("There is no default datatype.");
+ }
+
+ public XacmlAdminAuthorization getAuthorizer() {
+ return this.authorizer;
+ }
+
+ public boolean isAuthorized(AdminAction action, AdminResource resource) {
+ return this.authorizer.isAuthorized(this.getUserid(), action, resource);
+ }
+
+ public String getUserid() {
+ Object id = this.getSession().getSession().getAttribute("xacml.rest.admin.user.id");
+ if (id == null) {
+ return XACMLProperties.getProperty("xacml.rest.admin.user.id", "guest");
+ }
+ String str = id.toString();
+ if (str == null || str.isEmpty()) {
+ return "guest";
+ }
+ return str;
+ }
+
+ public String getUserName() {
+ Object id = this.getSession().getSession().getAttribute("xacml.rest.admin.user.name");
+ if (id == null) {
+ return XACMLProperties.getProperty("xacml.rest.admin.user.name", "guest");
+ }
+ String str = id.toString();
+ if (str == null || str.isEmpty()) {
+ return "guest";
+ }
+ return str;
+ }
+
+ public URI getUserEmail() {
+ Object id = this.getSession().getSession().getAttribute("xacml.rest.admin.user.email");
+ if (id == null) {
+ return URI.create(XACMLProperties.getProperty("xacml.rest.admin.user.email", "guest"));
+ }
+ String str = id.toString();
+ if (str == null || str.isEmpty()) {
+ return null;
+ }
+ return URI.create(str);
+ }
+
+ public Path getUserWorkspace() {
+ return this.workspacePath;
+ }
+
+ public Path getUserGitPath() {
+ return this.gitPath;
+ }
+
+ public PAPEngine getPAPEngine() {
+ return this.papEngine;
+ }
+
+ public String newPolicyID() {
+ return Joiner.on(':').skipNulls().join((XacmlAdminUI.getDomain().startsWith("urn") ? null : "urn"),
+ XacmlAdminUI.getDomain().replaceAll("[/\\\\.]", ":"),
+ "xacml", "policy", "id", UUID.randomUUID());
+ }
+
+ public String newRuleID() {
+ return Joiner.on(':').skipNulls().join((XacmlAdminUI.getDomain().startsWith("urn") ? null : "urn"),
+ XacmlAdminUI.getDomain().replaceAll("[/\\\\.]", ":"),
+ "xacml", "rule", "id", UUID.randomUUID());
+ }
+ //
+ // PAPNotificationBroadcaster Interface implementation
+ //
+ /**
+ * Got a notification that the PAP has changed the PDP data,
+ * so update ALL PDPGroups.
+ * This is called once for each Vaadin instance for each PAP change Notification.
+ */
+ public void updateAllGroups() {
+ access(new Runnable() {
+ @Override
+ public void run() {
+ //
+ // locking is needed to avoid race conditions.
+ // Shows up as Exception: "A connector should not be marked as dirty while a response is being written."
+ //
+ getUI().getSession().lock();
+ try {
+ //
+ // Tell the console to refresh its PDP group information
+ //
+ console.refreshPDPGroups();
+ } finally {
+ getUI().getSession().unlock();
+ }
+ }
+ });
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlErrorHandler.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlErrorHandler.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlErrorHandler.java
new file mode 100644
index 0000000..dd014dd
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlErrorHandler.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.openaz.xacml.admin;
+
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.navigator.View;
+import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.VerticalLayout;
+
+public class XacmlErrorHandler extends CustomComponent implements View {
+
+ @AutoGenerated
+ private VerticalLayout mainLayout;
+
+ @AutoGenerated
+ private Button buttonGo;
+
+ @AutoGenerated
+ private Label labelError;
+
+ public static String VIEWNAME="ErrorHandler.View";
+
+ /*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+ private static final long serialVersionUID = 1L;
+ /**
+ * The constructor should first build the main layout, set the
+ * composition root and then do any custom initialization.
+ *
+ * The constructor will not be automatically regenerated by the
+ * visual editor.
+ */
+ public XacmlErrorHandler(String message, String button) {
+ buildMainLayout();
+ setCompositionRoot(mainLayout);
+ this.labelError.setValue(message);
+ if (button != null) {
+ this.buttonGo.setCaption(button);
+ } else {
+ this.buttonGo.setVisible(false);
+ }
+ }
+
+ @Override
+ public void enter(ViewChangeEvent event) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @AutoGenerated
+ private VerticalLayout buildMainLayout() {
+ // common part: create layout
+ mainLayout = new VerticalLayout();
+ mainLayout.setImmediate(false);
+ mainLayout.setWidth("100%");
+ mainLayout.setHeight("-1px");
+ mainLayout.setMargin(true);
+ mainLayout.setSpacing(true);
+
+ // top-level component properties
+ setWidth("100.0%");
+ setHeight("-1px");
+
+ // labelError
+ labelError = new Label();
+ labelError.setImmediate(false);
+ labelError.setWidth("100.0%");
+ labelError.setHeight("80px");
+ labelError.setValue("This holds error messages.");
+ mainLayout.addComponent(labelError);
+
+ // buttonGo
+ buttonGo = new Button();
+ buttonGo.setCaption("Ok");
+ buttonGo.setImmediate(true);
+ buttonGo.setWidth("-1px");
+ buttonGo.setHeight("-1px");
+ mainLayout.addComponent(buttonGo);
+ mainLayout.setComponentAlignment(buttonGo, new Alignment(48));
+
+ return mainLayout;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlJDBCConnectionPool.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlJDBCConnectionPool.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlJDBCConnectionPool.java
new file mode 100644
index 0000000..a11707d
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/XacmlJDBCConnectionPool.java
@@ -0,0 +1,239 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.openaz.xacml.admin;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
+
+public class XacmlJDBCConnectionPool implements JDBCConnectionPool {
+ private static final long serialVersionUID = 1L;
+ private static Log logger = LogFactory.getLog(XacmlJDBCConnectionPool.class);
+
+ private int initialConnections = 5;
+ private int maxConnections = 300;
+
+ private String driverName;
+ private String connectionUri;
+ private String userName;
+ private String password;
+
+ private transient Set<Connection> availableConnections;
+ private transient Set<Connection> reservedConnections;
+
+ private boolean initialized;
+
+ public XacmlJDBCConnectionPool(String driverName, String connectionUri, String userName, String password) throws SQLException {
+ if (driverName == null) {
+ throw new IllegalArgumentException(
+ "JDBC driver class name must be given.");
+ }
+ if (connectionUri == null) {
+ throw new IllegalArgumentException(
+ "Database connection URI must be given.");
+ }
+ if (userName == null) {
+ throw new IllegalArgumentException(
+ "Database username must be given.");
+ }
+ if (password == null) {
+ throw new IllegalArgumentException(
+ "Database password must be given.");
+ }
+ this.driverName = driverName;
+ this.connectionUri = connectionUri;
+ this.userName = userName;
+ this.password = password;
+
+ /* Initialize JDBC driver */
+ try {
+ Class.forName(driverName).newInstance();
+ } catch (Exception ex) {
+ throw new RuntimeException("Specified JDBC Driver: " + driverName
+ + " - initialization failed.", ex);
+ }
+ }
+
+ public XacmlJDBCConnectionPool(String driverName, String connectionUri,
+ String userName, String password, int initialConnections,
+ int maxConnections) throws SQLException {
+ this(driverName, connectionUri, userName, password);
+ this.initialConnections = initialConnections;
+ this.maxConnections = maxConnections;
+ }
+
+ private void initializeConnections() throws SQLException {
+ availableConnections = new HashSet<Connection>(initialConnections);
+ reservedConnections = new HashSet<Connection>(initialConnections);
+ for (int i = 0; i < initialConnections; i++) {
+ availableConnections.add(createConnection());
+ }
+ initialized = true;
+ }
+
+ @Override
+ public synchronized Connection reserveConnection() throws SQLException {
+ if (!initialized) {
+ initializeConnections();
+ }
+ Connection c = null;
+ do {
+ if (availableConnections.isEmpty()) {
+ if (reservedConnections.size() < maxConnections) {
+ logger.info("creating new connection");
+ availableConnections.add(createConnection());
+ } else {
+ throw new SQLException("Connection limit has been reached.");
+ }
+ }
+ //
+ // Get first available
+ //
+ c = availableConnections.iterator().next();
+ //
+ // It is still valid?
+ //
+ if (!this.isValid(c)) {
+ try {
+ logger.warn("Removing invalid connection.");
+ //
+ // No close it
+ //
+ c.close();
+ //
+ // Remove from our list
+ //
+ this.availableConnections.remove(c);
+ //
+ // Try again
+ //
+ c = null;
+ } catch (SQLException e) { // NOPMD
+ // If removing the connection fails, ignore
+ }
+ } else {
+ //
+ // Yes
+ //
+ availableConnections.remove(c);
+ break;
+ }
+ } while (c == null);
+ //
+ // Add it to our reserved list
+ //
+ reservedConnections.add(c);
+ return c;
+ }
+
+ @Override
+ public synchronized void releaseConnection(Connection conn) {
+ if (conn == null || !initialized) {
+ return;
+ }
+ /* Try to roll back if necessary */
+ try {
+ if (!conn.getAutoCommit()) {
+ conn.rollback();
+ }
+ } catch (SQLException e) {
+ /* Roll back failed, close and discard connection */
+ try {
+ conn.close();
+ } catch (SQLException e1) { // NOPMD
+ /* Nothing needs to be done */
+ }
+ reservedConnections.remove(conn);
+ return;
+ }
+ reservedConnections.remove(conn);
+ availableConnections.add(conn);
+ }
+
+ private Connection createConnection() throws SQLException {
+ Connection c = DriverManager.getConnection(connectionUri, userName,
+ password);
+ c.setAutoCommit(false);
+ if (driverName.toLowerCase().contains("mysql")) {
+ try {
+ Statement s = c.createStatement();
+ s.execute("SET SESSION sql_mode = 'ANSI'");
+ s.close();
+ } catch (Exception e) { // NOPMD
+ // Failed to set ansi mode; continue
+ }
+ }
+ return c;
+ }
+
+ @Override
+ public void destroy() {
+ for (Connection c : availableConnections) {
+ try {
+ c.close();
+ } catch (SQLException e) { // NOPMD
+ // No need to do anything
+ }
+ }
+ for (Connection c : reservedConnections) {
+ try {
+ c.close();
+ } catch (SQLException e) { // NOPMD
+ // No need to do anything
+ }
+ }
+
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out) throws IOException {
+ initialized = false;
+ out.defaultWriteObject();
+ }
+
+ private final boolean isValid(final Connection con) throws SQLException {
+ final String bogusQuery = "SELECT 1";
+
+ try (Statement st = con.createStatement(); ResultSet res = st.executeQuery(bogusQuery)) {
+ return true;
+ } catch (final SQLException sqlx) {
+ return false;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "XacmlJDBCConnectionPool [initialConnections="
+ + initialConnections + ", maxConnections=" + maxConnections
+ + ", driverName=" + driverName + ", connectionUri="
+ + connectionUri + ", userName=" + userName + ", password="
+ + password + ", initialized=" + initialized + "]";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-openaz/blob/a1d93100/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/AttributeDictionary.java
----------------------------------------------------------------------
diff --git a/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/AttributeDictionary.java b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/AttributeDictionary.java
new file mode 100644
index 0000000..f0069a7
--- /dev/null
+++ b/openaz-xacml-pap-admin/src/main/java/org/apache/openaz/xacml/admin/components/AttributeDictionary.java
@@ -0,0 +1,503 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.openaz.xacml.admin.components;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.openaz.xacml.admin.XacmlAdminAuthorization;
+import org.apache.openaz.xacml.admin.XacmlAdminUI;
+import org.apache.openaz.xacml.admin.jpa.Attribute;
+import org.apache.openaz.xacml.admin.jpa.Category;
+import org.apache.openaz.xacml.admin.jpa.Datatype;
+import org.apache.openaz.xacml.admin.view.windows.AttributeEditorWindow;
+import com.vaadin.addon.jpacontainer.EntityItem;
+import com.vaadin.addon.jpacontainer.JPAContainer;
+import com.vaadin.addon.jpacontainer.provider.CachingLocalEntityProvider;
+import com.vaadin.addon.jpacontainer.provider.CachingMutableLocalEntityProvider;
+import com.vaadin.annotations.AutoGenerated;
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.data.util.filter.Compare;
+import com.vaadin.event.ItemClickEvent;
+import com.vaadin.event.ItemClickEvent.ItemClickListener;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.AbstractSelect.ItemCaptionMode;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window.CloseEvent;
+import com.vaadin.ui.Window.CloseListener;
+
+public class AttributeDictionary extends CustomComponent {
+ /*- VaadinEditorProperties={"grid":"RegularGrid,20","showGrid":true,"snapToGrid":true,"snapToObject":true,"movingGuides":false,"snappingDistance":10} */
+
+ @AutoGenerated
+ private VerticalLayout mainLayout;
+ @AutoGenerated
+ private Table table;
+ @AutoGenerated
+ private HorizontalLayout horizontalLayoutToolbar;
+ @AutoGenerated
+ private ComboBox comboBoxFilterDatatype;
+ @AutoGenerated
+ private ComboBox comboBoxFilterCategory;
+ @AutoGenerated
+ private Button buttonClone;
+ @AutoGenerated
+ private Button buttonRemove;
+ @AutoGenerated
+ private Button buttonNew;
+ private static final long serialVersionUID = 4553719412188869190L;
+ private static final Log logger = LogFactory.getLog(AttributeDictionary.class);
+ private static final Object[] visibleColumns = new Object[] { "xacmlId", "description", "categoryBean", "datatypeBean", "constraintType", "modifiedBy", "modifiedDate", "createdBy", "createdDate"};
+ private static final String[] columnHeaders = new String[] { "Attribute ID", "Description", "Category", "DataType", "Constraint", "Modified By", "Modified Date", "Created By", "Created Date"};
+
+ private AttributeDictionary self = this;
+
+ private final JPAContainer<Attribute> attributes = new JPAContainer<Attribute>(Attribute.class);
+ private final JPAContainer<Category> categories = new JPAContainer<Category>(Category.class);
+ private final JPAContainer<Datatype> datatypes = new JPAContainer<Datatype>(Datatype.class);
+
+ /**
+ * The constructor should first build the main layout, set the
+ * composition root and then do any custom initialization.
+ *
+ * The constructor will not be automatically regenerated by the
+ * visual editor.
+ */
+ public AttributeDictionary() {
+ buildMainLayout();
+ setCompositionRoot(mainLayout);
+ //
+ // Finish initializing the container
+ //
+ boolean isReadOnly;
+ if (((XacmlAdminUI)UI.getCurrent()).isAuthorized(
+ XacmlAdminAuthorization.AdminAction.ACTION_WRITE,
+ XacmlAdminAuthorization.AdminResource.RESOURCE_DICTIONARIES)) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("write access");
+ }
+ //
+ // Make it mutable
+ //
+ isReadOnly = false;
+ this.attributes.setEntityProvider(new CachingMutableLocalEntityProvider<Attribute>(Attribute.class, ((XacmlAdminUI)UI.getCurrent()).getEntityManager()));
+ } else {
+ if (logger.isDebugEnabled()) {
+ logger.debug("read access");
+ }
+ //
+ // Make it read-only
+ //
+ isReadOnly = true;
+ this.attributes.setEntityProvider(new CachingLocalEntityProvider<Attribute>(Attribute.class, ((XacmlAdminUI)UI.getCurrent()).getEntityManager()));
+ }
+ this.categories.setEntityProvider(new CachingLocalEntityProvider<Category>(Category.class, ((XacmlAdminUI)UI.getCurrent()).getEntityManager()));
+ this.categories.sort(new String[]{"xacmlId"}, new boolean[]{true});
+ this.datatypes.setEntityProvider(new CachingLocalEntityProvider<Datatype>(Datatype.class, ((XacmlAdminUI)UI.getCurrent()).getEntityManager()));
+ this.datatypes.sort(new String[]{"xacmlId"}, new boolean[]{true});
+ //
+ // Initialize
+ //
+ this.initializeTable(isReadOnly);
+ this.initializeButtons(isReadOnly);
+ this.initializeCategoryComboFilter();
+ this.initializeDatatypeComboFilter();
+ }
+
+ protected void initializeTable(boolean isReadOnly) {
+ //
+ // This is the data source
+ //
+ this.table.setContainerDataSource(this.attributes);
+ //
+ // Setup table
+ //
+ this.table.setVisibleColumns(visibleColumns);
+ this.table.setColumnHeaders(columnHeaders);
+ this.table.setImmediate(true);
+ this.table.setColumnCollapsingAllowed(true);
+ //
+ // Read only?
+ //
+ if (isReadOnly) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("read only table");
+ }
+ return;
+ }
+ this.table.setSelectable(true);
+ //
+ // Respond to clicks
+ //
+ this.table.addItemClickListener(new ItemClickListener() {
+ private static final long serialVersionUID = 1L;
+ @Override
+ public void itemClick(ItemClickEvent event) {
+ if (event.isDoubleClick()) {
+ //
+ // Create our editor window
+ //
+ final AttributeEditorWindow attributeEditor = new AttributeEditorWindow(self.attributes.getItem(event.getItemId()));
+ attributeEditor.setCaption("Edit Attribute");
+ attributeEditor.setModal(true);
+ attributeEditor.center();
+ UI.getCurrent().addWindow(attributeEditor);
+ }
+ }
+ });
+ //
+ // Respond to selections
+ //
+ this.table.addValueChangeListener(new ValueChangeListener() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void valueChange(ValueChangeEvent event) {
+ Object value = self.table.getValue();
+ if (value == null) {
+ self.buttonRemove.setEnabled(false);
+ self.buttonClone.setEnabled(false);
+ } else {
+ self.buttonRemove.setEnabled(true);
+ self.buttonClone.setEnabled(true);
+ }
+ }
+ });
+ }
+
+ protected void initializeButtons(boolean isReadOnly) {
+ if (isReadOnly) {
+ this.buttonNew.setVisible(false);
+ this.buttonRemove.setVisible(false);
+ this.buttonClone.setVisible(false);
+ return;
+ }
+ this.buttonNew.addClickListener(new ClickListener() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ AttributeDictionary.createNewAttributeWindow();
+ }
+
+ });
+
+ this.buttonRemove.setEnabled(false);
+ this.buttonRemove.addClickListener(new ClickListener() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ //
+ // Get the selected item
+ //
+ Object id = self.table.getValue();
+ //
+ // Sanity check
+ //
+ if (id == null) {
+ return;
+ }
+ //
+ // Remove the attribute
+ //
+ self.attributes.removeItem(id);
+ //
+ // Unfortunately, removing the item does NOT result
+ // in a ValueChange event being generated. So we must
+ // trigger it ourselves.
+ //
+ self.table.select(self.table.getNullSelectionItemId());
+ }
+ });
+
+ this.buttonClone.setEnabled(false);
+ this.buttonClone.addClickListener(new ClickListener() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ Object id = self.table.getValue();
+ if (id == null) {
+ return;
+ }
+ Item item = self.table.getItem(id);
+ if (item instanceof EntityItem) {
+ @SuppressWarnings("unchecked")
+ //
+ // Get the entity
+ //
+ EntityItem<Attribute> entityItem = (EntityItem<Attribute>) item;
+ //
+ // Clone it
+ //
+ Attribute newAttribute = new Attribute(entityItem.getEntity(), ((XacmlAdminUI)UI.getCurrent()).getUserid());
+ //
+ // Add it to the database
+ //
+ id = self.attributes.addEntity(newAttribute);
+ //
+ // Now select it
+ //
+ self.table.select(id);
+ //
+ // Refresh it to get the latest modified date
+ //
+ self.attributes.refreshItem(id);
+ }
+ }
+ });
+ }
+
+ protected void initializeCategoryComboFilter() {
+ //
+ // Set data source
+ //
+ this.comboBoxFilterCategory.setContainerDataSource(self.categories);
+ this.comboBoxFilterCategory.setItemCaptionMode(ItemCaptionMode.PROPERTY);
+ this.comboBoxFilterCategory.setItemCaptionPropertyId("xacmlId");
+ //
+ // Initialize GUI properties
+ //
+ this.comboBoxFilterCategory.setNullSelectionAllowed(true);
+ this.comboBoxFilterCategory.setImmediate(true);
+ //
+ // Respond to value changes
+ //
+ this.comboBoxFilterCategory.addValueChangeListener(new ValueChangeListener() {
+ private static final long serialVersionUID = 1L;
+ Filter currentFilter = null;
+
+ @Override
+ public void valueChange(ValueChangeEvent event) {
+ //
+ // Remove filter
+ //
+ if (currentFilter != null) {
+ self.attributes.removeContainerFilter(this.currentFilter);
+ this.currentFilter = null;
+ }
+ //
+ // Set the new one
+ //
+ Object id = self.comboBoxFilterCategory.getValue();
+ if (id == null) {
+ return;
+ }
+ Category cat = self.categories.getItem(id).getEntity();
+ this.currentFilter = new Compare.Equal("categoryBean", cat);
+ self.attributes.addContainerFilter(this.currentFilter);
+ }
+ });
+ }
+
+ protected void initializeDatatypeComboFilter() {
+ //
+ // Set data source
+ //
+ this.comboBoxFilterDatatype.setContainerDataSource(self.datatypes);
+ this.comboBoxFilterDatatype.setItemCaptionMode(ItemCaptionMode.PROPERTY);
+ this.comboBoxFilterDatatype.setItemCaptionPropertyId("xacmlId");
+ //
+ // Initialize GUI properties
+ //
+ this.comboBoxFilterDatatype.setNullSelectionAllowed(true);
+ this.comboBoxFilterDatatype.setImmediate(true);
+ //
+ // Respond to value changes
+ //
+ this.comboBoxFilterDatatype.addValueChangeListener(new ValueChangeListener() {
+ private static final long serialVersionUID = 1L;
+ Filter currentFilter = null;
+
+ @Override
+ public void valueChange(ValueChangeEvent event) {
+ //
+ // Remove filter
+ //
+ if (currentFilter != null) {
+ self.attributes.removeContainerFilter(this.currentFilter);
+ this.currentFilter = null;
+ }
+ //
+ // Set the new one
+ //
+ Object id = self.comboBoxFilterDatatype.getValue();
+ if (id == null) {
+ return;
+ }
+ Datatype cat = self.datatypes.getItem(id).getEntity();
+ this.currentFilter = new Compare.Equal("datatypeBean", cat);
+ self.attributes.addContainerFilter(this.currentFilter);
+ }
+ });
+ }
+
+ public void refreshContainer() {
+ this.attributes.refresh();
+ this.categories.refresh();
+ this.datatypes.refresh();
+ }
+
+ public static void createNewAttributeWindow() {
+ //
+ // Create our new attribute
+ //
+ String domain = XacmlAdminUI.getDomain();
+ String userid = ((XacmlAdminUI)UI.getCurrent()).getUserid();
+ final Attribute newAttribute = new Attribute(domain, userid);
+ try {
+ newAttribute.setCategoryBean(((XacmlAdminUI)UI.getCurrent()).getDefaultCategory());
+ newAttribute.setDatatypeBean(((XacmlAdminUI)UI.getCurrent()).getDefaultDatatype());
+ } catch (Exception e) {
+ logger.error(e);
+ return;
+ }
+ //
+ // Create our editor window
+ //
+ final AttributeEditorWindow attributeEditor = new AttributeEditorWindow(((XacmlAdminUI)UI.getCurrent()).getAttributes().createEntityItem(newAttribute));
+ attributeEditor.setCaption("Add New Attribute");
+ attributeEditor.setModal(true);
+ attributeEditor.addCloseListener(new CloseListener() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void windowClose(CloseEvent e) {
+ //
+ // Did the user hit save?
+ //
+ if (attributeEditor.isSaved()) {
+ //
+ // Add the new attribute
+ //
+ ((XacmlAdminUI)UI.getCurrent()).getAttributes().addEntity(newAttribute);
+ ((XacmlAdminUI)UI.getCurrent()).refreshAttributes();
+ }
+ }
+
+ });
+ attributeEditor.center();
+ UI.getCurrent().addWindow(attributeEditor);
+ }
+
+ @AutoGenerated
+ private VerticalLayout buildMainLayout() {
+ // common part: create layout
+ mainLayout = new VerticalLayout();
+ mainLayout.setImmediate(false);
+ mainLayout.setWidth("-1px");
+ mainLayout.setHeight("-1px");
+ mainLayout.setMargin(true);
+ mainLayout.setSpacing(true);
+
+ // top-level component properties
+ setWidth("-1px");
+ setHeight("-1px");
+
+ // horizontalLayoutToolbar
+ horizontalLayoutToolbar = buildHorizontalLayoutToolbar();
+ mainLayout.addComponent(horizontalLayoutToolbar);
+
+ // table
+ table = new Table();
+ table.setImmediate(false);
+ table.setWidth("100.0%");
+ table.setHeight("-1px");
+ mainLayout.addComponent(table);
+
+ return mainLayout;
+ }
+
+ @AutoGenerated
+ private HorizontalLayout buildHorizontalLayoutToolbar() {
+ // common part: create layout
+ horizontalLayoutToolbar = new HorizontalLayout();
+ horizontalLayoutToolbar.setImmediate(false);
+ horizontalLayoutToolbar.setWidth("-1px");
+ horizontalLayoutToolbar.setHeight("-1px");
+ horizontalLayoutToolbar.setMargin(false);
+ horizontalLayoutToolbar.setSpacing(true);
+
+ // buttonNew
+ buttonNew = new Button();
+ buttonNew.setCaption("New");
+ buttonNew.setImmediate(true);
+ buttonNew.setDescription("Create a new attribute");
+ buttonNew.setWidth("70px");
+ buttonNew.setHeight("-1px");
+ horizontalLayoutToolbar.addComponent(buttonNew);
+ horizontalLayoutToolbar.setComponentAlignment(buttonNew, new Alignment(
+ 9));
+
+ // buttonRemove
+ buttonRemove = new Button();
+ buttonRemove.setCaption("Remove");
+ buttonRemove.setImmediate(true);
+ buttonRemove.setDescription("Remove the selected attribute(s)");
+ buttonRemove.setWidth("-1px");
+ buttonRemove.setHeight("-1px");
+ horizontalLayoutToolbar.addComponent(buttonRemove);
+ horizontalLayoutToolbar.setComponentAlignment(buttonRemove,
+ new Alignment(9));
+
+ // buttonClone
+ buttonClone = new Button();
+ buttonClone.setCaption("Clone");
+ buttonClone.setImmediate(true);
+ buttonClone.setDescription("Clone an attribute.");
+ buttonClone.setWidth("-1px");
+ buttonClone.setHeight("-1px");
+ horizontalLayoutToolbar.addComponent(buttonClone);
+ horizontalLayoutToolbar.setComponentAlignment(buttonClone,
+ new Alignment(9));
+
+ // comboBoxFilterCategory
+ comboBoxFilterCategory = new ComboBox();
+ comboBoxFilterCategory.setCaption("Filter By Category");
+ comboBoxFilterCategory.setImmediate(false);
+ comboBoxFilterCategory.setWidth("-1px");
+ comboBoxFilterCategory.setHeight("-1px");
+ horizontalLayoutToolbar.addComponent(comboBoxFilterCategory);
+
+ // comboBoxFilterDatatype
+ comboBoxFilterDatatype = new ComboBox();
+ comboBoxFilterDatatype.setCaption("Filter By Data Type");
+ comboBoxFilterDatatype.setImmediate(false);
+ comboBoxFilterDatatype.setWidth("-1px");
+ comboBoxFilterDatatype.setHeight("-1px");
+ horizontalLayoutToolbar.addComponent(comboBoxFilterDatatype);
+
+ return horizontalLayoutToolbar;
+ }
+
+}