("Approval Requests", gui.env.newTransNoAvg(),new Model(gui.env()),"class=stdform"))
+ .preamble("The following requires your Approval to proceed in the AAF System.Hover on Identity for Name; click for WebPhone"),
+ new NamedCode(false, "selectAlljs") {
+ @Override
+ public void code(Cache cache, HTMLGen hgen) throws APIException, IOException {
+ Mark jsStart = new Mark();
+ hgen.js(jsStart);
+ hgen.text("function selectAll(radioClass) {");
+ hgen.text("var radios = document.querySelectorAll(\".\"+radioClass);");
+ hgen.text("for (i = 0; i < radios.length; i++) {");
+ hgen.text("radios[i].checked = true;");
+ hgen.text("}");
+ hgen.text("}");
+ hgen.end(jsStart);
+ }
+ });
+
+ }
+
+ /**
+ * Implement the Table Content for Approvals
+ *
+ *
+ */
+ private static class Model implements Table.Data {
+ private static final String[] headers = new String[] {"Identity","Request","Approve","Deny"};
+ private static final Object THE_DOMAIN = null;
+ private Slot sUser;
+
+ public Model(AuthzEnv env) {
+ sUser = env.slot(NAME+".user");
+ }
+
+ @Override
+ public String[] headers() {
+ return headers;
+ }
+
+ @Override
+ public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+ final String userParam = trans.get(sUser, null);
+ ArrayList rv = new ArrayList();
+ String msg = null;
+ TimeTaken tt = trans.start("AAF Get Approvals for Approver",Env.REMOTE);
+ try {
+ final List pendingApprovals = new ArrayList();
+ final List beginIndicesPerApprover = new ArrayList();
+ int numLeft = gui.clientAsUser(trans.getUserPrincipal(), new Retryable() {
+ @Override
+ public Integer code(Rcli> client) throws CadiException, ConnectException, APIException {
+ Future fa = client.read("/authz/approval/approver/"+trans.user(),gui.approvalsDF);
+ int numLeft = 0;
+ if(fa.get(AuthGUI.TIMEOUT)) {
+
+ if(fa.value!=null) {
+ for (Approval appr : fa.value.getApprovals()) {
+ if (appr.getStatus().equals("pending")) {
+ if (userParam!=null) {
+ if (!appr.getUser().equalsIgnoreCase(userParam)) {
+ numLeft++;
+ continue;
+ }
+ }
+ pendingApprovals.add(appr);
+ }
+ }
+ }
+
+ String prevApprover = null;
+ int overallIndex = 0;
+
+ for (Approval appr : pendingApprovals) {
+ String currApprover = appr.getApprover();
+ if (!currApprover.equals(prevApprover)) {
+ prevApprover = currApprover;
+ beginIndicesPerApprover.add(overallIndex);
+ }
+ overallIndex++;
+ }
+ }
+ return numLeft;
+ }
+ });
+
+ if (pendingApprovals.size() > 0) {
+ // Only add select all links if we have approvals
+ AbsCell[] selectAllRow = new AbsCell[] {
+ AbsCell.Null,
+ AbsCell.Null,
+ new ButtonCell("all", "onclick=selectAll('approve')", "class=selectAllButton"),
+ new ButtonCell("all", "onclick=selectAll('deny')", "class=selectAllButton")
+ };
+ rv.add(selectAllRow);
+ }
+
+ int line=-1;
+
+ while (beginIndicesPerApprover.size() > 0) {
+ int beginIndex = beginIndicesPerApprover.remove(0);
+ int endIndex = (beginIndicesPerApprover.isEmpty()?pendingApprovals.size():beginIndicesPerApprover.get(0));
+ List currApproverList = pendingApprovals.subList(beginIndex, endIndex);
+
+ String currApproverFull = currApproverList.get(0).getApprover();
+ String currApproverShort = currApproverFull.substring(0,currApproverFull.indexOf('@'));
+ String currApprover = (trans.user().indexOf('@')<0?currApproverShort:currApproverFull);
+ if (!currApprover.equals(trans.user())) {
+ AbsCell[] approverHeader;
+ if (currApproverFull.substring(currApproverFull.indexOf('@')).equals(THE_DOMAIN)) {
+ approverHeader = new AbsCell[] {
+ new TextAndRefCell("Approvals Delegated to Me by ", currApprover,
+ WEBPHONE + currApproverShort,
+ new String[] {"colspan=4", "class=head"})
+ };
+ } else {
+ approverHeader = new AbsCell[] {
+ new TextCell("Approvals Delegated to Me by " + currApprover,
+ new String[] {"colspan=4", "class=head"})
+ };
+ }
+ rv.add(approverHeader);
+ }
+
+ // Sort by User Requesting
+ Collections.sort(currApproverList, new Comparator() {
+ @Override
+ public int compare(Approval a1, Approval a2) {
+ return a1.getUser().compareTo(a2.getUser());
+ }
+ });
+
+ String prevUser = null;
+ for (Approval appr : currApproverList) {
+ if(++line0) {
+ msg = "After these, there will be " + numLeft + " approvals left to process";
+ }
+ if(rv.size()==0) {
+ if (numLeft>0) {
+ msg = "No Approvals to process at this time for user " + userParam +". You have "
+ + numLeft + " other approvals to process.";
+ } else {
+ msg = "No Approvals to process at this time";
+ }
+ }
+ } catch (Exception e) {
+ trans.error().log(e);
+ } finally {
+ tt.done();
+ }
+ return new Cells(rv,msg);
+ }
+ }
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/Home.java b/authz-gui/src/main/java/com/att/authz/gui/pages/Home.java
new file mode 100644
index 00000000..3c6abd03
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/Home.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import static com.att.xgen.html.HTMLGen.A;
+import static com.att.xgen.html.HTMLGen.H3;
+
+import java.io.IOException;
+
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.inno.env.APIException;
+import com.att.xgen.Cache;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+
+public class Home extends Page {
+ public static final String HREF = "/gui/home";
+ public Home(final AuthGUI gui) throws APIException, IOException {
+ super(gui.env,"Home",HREF, NO_FIELDS, new NamedCode(false,"content") {
+ @Override
+ public void code(final Cache cache, final HTMLGen xgen) throws APIException, IOException {
+// // TEMP
+// JSGen jsg = xgen.js();
+// jsg.function("httpPost","sURL","sParam")
+// .text("var oURL = new java.net.URL(sURL)")
+// .text("var oConn = oURL.openConnection();")
+// .text("oConn.setDoInput(true);")
+// .text("oConn.setDoOutpu(true);")
+// .text("oConn.setUseCaches(false);")
+// .text("oConn.setRequestProperty(\"Content-Type\",\"application/x-www-form-urlencoded\");")
+// .text(text)
+// jsg.done();
+ // TEMP
+ final Mark pages = xgen.divID("Pages");
+ xgen.leaf(H3).text("Choose from the following:").end()
+ .leaf(A,"href=myperms").text("My Permissions").end()
+ .leaf(A,"href=myroles").text("My Roles").end()
+ // TODO: uncomment when on cassandra 2.1.2 for MyNamespace GUI page
+ .leaf(A,"href=mynamespaces").text("My Namespaces").end()
+ .leaf(A,"href=approve").text("My Approvals").end()
+ .leaf(A, "href=myrequests").text("My Pending Requests").end()
+ // Enable later
+// .leaf(A, "href=onboard").text("Onboarding").end()
+ // Password Change. If logged in as CSP/GSO, go to their page
+ .leaf(A,"href=passwd").text("Password Management").end()
+ .leaf(A,"href=cui").text("Command Prompt").end()
+ .leaf(A,"href=api").text("AAF API").end()
+ ;
+
+ xgen.end(pages);
+ }
+ });
+ }
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/LoginLanding.java b/authz-gui/src/main/java/com/att/authz/gui/pages/LoginLanding.java
new file mode 100644
index 00000000..6ca16080
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/LoginLanding.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.URLDecoder;
+
+import javax.servlet.http.HttpServletRequest;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.config.Config;
+import org.onap.aaf.inno.env.APIException;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+public class LoginLanding extends Page {
+ public static final String HREF = "/login";
+ static final String NAME = "Login";
+ static final String fields[] = {"id","password","environment"};
+ static final String envs[] = {"DEV","TEST","PROD"};
+
+ public LoginLanding(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env, NAME,HREF, fields, new NamedCode(true, "content") {
+ @Override
+ public void code(Cache cache, HTMLGen hgen) throws APIException, IOException {
+ hgen.leaf("p").text("No login credentials are found in your current session. " +
+ "Choose your preferred login option to continue.").end();
+
+ Mark loginPaths = hgen.divID("Pages");
+
+ cache.dynamic(hgen, new DynamicCode() {
+ @Override
+ public void code(AuthGUI authGUI, AuthzTrans trans, Cache cache, HTMLGen xgen) throws APIException, IOException {
+ HttpServletRequest req = trans.get(gui.slot_httpServletRequest, null);
+ if(req!=null) {
+ String query = req.getQueryString();
+ if(query!=null) {
+ for(String qs : query.split("&")) {
+ int equals = qs.indexOf('=');
+ xgen.leaf(HTMLGen.A, "href="+URLDecoder.decode(qs.substring(equals+1),Config.UTF_8)).text(qs.substring(0,equals).replace('_', ' ')).end();
+ }
+ }
+ }
+ xgen.leaf(HTMLGen.A, "href=gui/home?Authentication=BasicAuth").text("AAF Basic Auth").end();
+ }
+ });
+// hgen.leaf("a", "href=#","onclick=divVisibility('cso');").text("Global Login").end()
+// .incr("p", "id=cso","style=display:none").text("this will redirect to global login").end()
+// .leaf("a", "href=#","onclick=divVisibility('tguard');").text("tGuard").end()
+// .incr("p", "id=tguard","style=display:none").text("this will redirect to tGuard login").end()
+// hgen.leaf("a", "href=#","onclick=divVisibility('basicauth');").text("AAF Basic Auth").end();
+ hgen.end(loginPaths);
+
+// hgen.incr("form","method=post","style=display:none","id=basicauth","gui/home?Authentication=BasicAuth");
+// Mark table = new Mark(TABLE);
+// hgen.incr(table);
+// cache.dynamic(hgen, new DynamicCode() {
+// @Override
+// public void code(AuthGUI gui, AuthzTrans trans, Cache cache, HTMLGen hgen)
+// throws APIException, IOException {
+// hgen
+// .input(fields[0],"Username",true)
+// .input(fields[1],"Password",true, "type=password");
+// Mark selectRow = new Mark();
+// hgen
+// .incr(selectRow, "tr")
+// .incr("td")
+// .incr("label", "for=envs", "required").text("Environment").end()
+// .end()
+// .incr("td")
+// .incr("select", "name=envs", "id=envs", "required")
+// .incr("option", "value=").text("Select Environment").end();
+// for (String env : envs) {
+// hgen.incr("option", "value="+env).text(env).end();
+// }
+// hgen
+// .end(selectRow)
+
+// hgen.end();
+// }
+// });
+// hgen.end();
+// hgen.tagOnly("input", "type=submit", "value=Submit")
+// .tagOnly("input", "type=reset", "value=Reset")
+// .end();
+
+
+ }
+ });
+ }
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/LoginLandingAction.java b/authz-gui/src/main/java/com/att/authz/gui/pages/LoginLandingAction.java
new file mode 100644
index 00000000..d70aca45
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/LoginLandingAction.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Slot;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+public class LoginLandingAction extends Page {
+ public LoginLandingAction(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env,"Login",LoginLanding.HREF, LoginLanding.fields,
+ new BreadCrumbs(breadcrumbs),
+ new NamedCode(true,"content") {
+ final Slot sID = gui.env.slot(LoginLanding.NAME+'.'+LoginLanding.fields[0]);
+// final Slot sPassword = gui.env.slot(LoginLanding.NAME+'.'+LoginLanding.fields[1]);
+
+ @Override
+ public void code(Cache cache, HTMLGen hgen) throws APIException, IOException {
+ cache.dynamic(hgen, new DynamicCode() {
+ @Override
+ public void code(final AuthGUI gui, final AuthzTrans trans,Cache cache, HTMLGen hgen) throws APIException, IOException {
+ String username = trans.get(sID,null);
+// String password = trans.get(sPassword,null);
+
+ hgen.p("User: "+username);
+ hgen.p("Pass: ********");
+
+ // TODO: clarification from JG
+ // put in request header?
+ // then pass through authn/basicAuth call?
+
+ }
+ });
+ }
+ });
+ }
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/NsDetail.java b/authz-gui/src/main/java/com/att/authz/gui/pages/NsDetail.java
new file mode 100644
index 00000000..75ff137d
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/NsDetail.java
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import com.att.cmd.AAFcli;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.util.Chrono;
+
+import aaf.v2_0.Nss;
+import aaf.v2_0.Nss.Ns;
+import aaf.v2_0.Perm;
+import aaf.v2_0.Perms;
+import aaf.v2_0.Role;
+import aaf.v2_0.Roles;
+import aaf.v2_0.Users;
+import aaf.v2_0.Users.User;
+
+public class NsDetail extends Page {
+
+ public static final String HREF = "/gui/nsdetail";
+ public static final String NAME = "NsDetail";
+ static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
+ public static enum NS_FIELD { OWNERS, ADMINS, ROLES, PERMISSIONS, CREDS};
+ private static final String BLANK = "";
+
+ public NsDetail(final AuthGUI gui, Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env, NAME, HREF, new String[] {"name"},
+ new BreadCrumbs(breadcrumbs),
+ new Table("Namespace Details",gui.env.newTransNoAvg(),new Model(gui.env()),"class=detail")
+ );
+ }
+
+ /**
+ * Implement the table content for Namespace Detail
+ *
+ *
+ */
+ private static class Model implements Table.Data {
+ private static final String[] headers = new String[0];
+ private static final String CSP_ATT_COM = "@csp.att.com";
+ private Slot name;
+ public Model(AuthzEnv env) {
+ name = env.slot(NAME+".name");
+ }
+
+ @Override
+ public String[] headers() {
+ return headers;
+ }
+
+ @Override
+ public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+ final String nsName = trans.get(name, null);
+ if(nsName==null) {
+ return Cells.EMPTY;
+ }
+ ArrayList rv = new ArrayList();
+ rv.add(new AbsCell[]{new TextCell("Name:"),new TextCell(nsName)});
+
+ final TimeTaken tt = trans.start("AAF Namespace Details",Env.REMOTE);
+ try {
+ gui.clientAsUser(trans.getUserPrincipal(),new Retryable() {
+ @Override
+ public Void code(Rcli> client) throws CadiException, ConnectException, APIException {
+ Future fn = client.read("/authz/nss/"+nsName,gui.nssDF);
+
+ if(fn.get(AuthGUI.TIMEOUT)) {
+ tt.done();
+ try {
+// TimeTaken tt = trans.start("Load Data", Env.SUB);
+
+ for(Ns n : fn.value.getNs()) {
+ String desc = (n.getDescription()!=null?n.getDescription():BLANK);
+ rv.add(new AbsCell[]{new TextCell("Description:"),new TextCell(desc)});
+
+ addField(trans, rv, n.getAdmin(), NS_FIELD.ADMINS);
+ addField(trans, rv, n.getResponsible(), NS_FIELD.OWNERS);
+
+ Future fu = client.read(
+ "/authn/creds/ns/"+nsName,
+ gui.usersDF
+ );
+ List creds = new ArrayList();
+ if(fu.get(AAFcli.timeout())) {
+ for (User u : fu.value.getUser()) {
+ StringBuilder sb = new StringBuilder(u.getId());
+ switch(u.getType()) {
+ case 1: sb.append(" (U/Pass) "); break;
+ case 10: sb.append(" (Cert) "); break;
+ case 200: sb.append(" (x509) "); break;
+ default:
+ sb.append(" ");
+ }
+ sb.append(Chrono.niceDateStamp(u.getExpires()));
+ creds.add(sb.toString());
+ }
+ }
+ addField(trans, rv, creds, NS_FIELD.CREDS);
+
+ Future fr = client.read(
+ "/authz/roles/ns/"+nsName,
+ gui.rolesDF
+ );
+ List roles = new ArrayList();
+ if(fr.get(AAFcli.timeout())) {
+ for (Role r : fr.value.getRole()) {
+ roles.add(r.getName());
+ }
+ }
+ addField(trans, rv, roles, NS_FIELD.ROLES);
+
+
+ Future fp = client.read(
+ "/authz/perms/ns/"+nsName,
+ gui.permsDF
+ );
+ List perms = new ArrayList();
+
+ if(fp.get(AAFcli.timeout())) {
+ for (Perm p : fp.value.getPerm()) {
+ perms.add(p.getType() + "|" + p.getInstance() + "|" + p.getAction());
+ }
+ }
+ addField(trans, rv, perms, NS_FIELD.PERMISSIONS);
+ }
+ String historyLink = NsHistory.HREF
+ + "?name=" + nsName;
+ rv.add(new AbsCell[] {new RefCell("See History",historyLink)});
+ } finally {
+ tt.done();
+ }
+ } else {
+ rv.add(new AbsCell[] {new TextCell("*** Data Unavailable ***")});
+ }
+ return null;
+ }
+ });
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ tt.done();
+ }
+ return new Cells(rv,null);
+ }
+
+ private void addField(AuthzTrans trans, ArrayList rv, List values, NS_FIELD field) {
+ if (!values.isEmpty()) {
+ switch(field) {
+ case OWNERS:
+ case ADMINS:
+ case CREDS:
+ for (int i=0; i< values.size(); i++) {
+ AbsCell label = (i==0?new TextCell(sentenceCase(field)+":"):AbsCell.Null);
+ String user = values.get(i);
+ AbsCell userCell = (user.endsWith(CSP_ATT_COM)?
+ new RefCell(user,WEBPHONE + user.substring(0,user.indexOf('@'))):new TextCell(user));
+ rv.add(new AbsCell[] {
+ label,
+ userCell
+ });
+ }
+ break;
+ case ROLES:
+ for (int i=0; i< values.size(); i++) {
+ AbsCell label = (i==0?new TextCell(sentenceCase(field)+":"):AbsCell.Null);
+ rv.add(new AbsCell[] {
+ label,
+ new TextCell(values.get(i))
+ });
+ }
+ break;
+ case PERMISSIONS:
+ for (int i=0; i< values.size(); i++) {
+ AbsCell label = (i==0?new TextCell(sentenceCase(field)+":"):AbsCell.Null);
+ String perm = values.get(i);
+ String[] fields = perm.split("\\|");
+ String grantLink = PermGrantForm.HREF
+ + "?type=" + fields[0].trim()
+ + "&instance=" + fields[1].trim()
+ + "&action=" + fields[2].trim();
+
+ rv.add(new AbsCell[] {
+ label,
+ new TextCell(perm),
+ new RefCell("Grant This Perm", grantLink)
+ });
+ }
+ break;
+ }
+
+ }
+ }
+
+ private String sentenceCase(NS_FIELD field) {
+ String sField = field.toString();
+ return sField.substring(0, 1).toUpperCase() + sField.substring(1).toLowerCase();
+ }
+
+ }
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/NsHistory.java b/authz-gui/src/main/java/com/att/authz/gui/pages/NsHistory.java
new file mode 100644
index 00000000..653b9e7a
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/NsHistory.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Comparator;
+import java.util.List;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.History;
+import aaf.v2_0.History.Item;
+
+public class NsHistory extends Page {
+ static final String NAME="NsHistory";
+ static final String HREF = "/gui/nsHistory";
+ static final String FIELDS[] = {"name","dates"};
+ static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
+ static enum Month { JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY,
+ AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER };
+
+ public NsHistory(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env,NAME,HREF, FIELDS,
+ new BreadCrumbs(breadcrumbs),
+ new Table("History", gui.env.newTransNoAvg(),new Model(gui.env()),"class=std"),
+ new NamedCode(true, "content") {
+ @Override
+ public void code(final Cache cache, final HTMLGen hgen) throws APIException, IOException {
+ final Slot name = gui.env.slot(NAME+".name");
+ cache.dynamic(hgen, new DynamicCode() {
+ @Override
+ public void code(AuthGUI gui, AuthzTrans trans, Cache cache, HTMLGen hgen) throws APIException, IOException {
+ String obName = trans.get(name, null);
+
+ // Use Javascript to make the table title more descriptive
+ hgen.js()
+ .text("var caption = document.querySelector(\".title\");")
+ .text("caption.innerHTML='History for Namespace [ " + obName + " ]';")
+ .done();
+
+ // Use Javascript to change Link Target to our last visited Detail page
+ String lastPage = NsDetail.HREF + "?name=" + obName;
+ hgen.js()
+ .text("alterLink('nsdetail', '"+lastPage + "');")
+ .done();
+
+ hgen.br();
+ hgen.leaf("a","href=#advanced_search","onclick=divVisibility('advanced_search');").text("Advanced Search").end()
+ .divID("advanced_search", "style=display:none");
+ hgen.incr("table");
+
+ addDateRow(hgen,"Start Date");
+ addDateRow(hgen,"End Date");
+ hgen.incr("tr").incr("td");
+ hgen.tagOnly("input", "type=button","value=Get History",
+ "onclick=datesURL('"+HREF+"?name=" + obName+"');");
+ hgen.end().end();
+ hgen.end();
+ hgen.end();
+
+ }
+ });
+ }
+ }
+
+ );
+ }
+
+ private static void addDateRow(HTMLGen hgen, String s) {
+ hgen
+ .incr("tr")
+ .incr("td")
+ .incr("label", "for=month", "required").text(s+"*").end()
+ .end()
+ .incr("td")
+ .incr("select", "name=month"+s.substring(0, s.indexOf(' ')), "id=month"+s.substring(0, s.indexOf(' ')), "required")
+ .incr("option", "value=").text("Month").end();
+ for (Month m : Month.values()) {
+ if (Calendar.getInstance().get(Calendar.MONTH) == m.ordinal()) {
+ hgen.incr("option", "selected", "value="+(m.ordinal()+1)).text(m.name()).end();
+ } else {
+ hgen.incr("option", "value="+(m.ordinal()+1)).text(m.name()).end();
+ }
+ }
+ hgen.end()
+ .end()
+ .incr("td")
+ .tagOnly("input","type=number","id=year"+s.substring(0, s.indexOf(' ')),"required",
+ "value="+Calendar.getInstance().get(Calendar.YEAR), "min=1900",
+ "max="+Calendar.getInstance().get(Calendar.YEAR),
+ "placeholder=Year").end()
+ .end();
+ }
+
+
+
+
+ /**
+ * Implement the Table Content for History
+ *
+ *
+ */
+ private static class Model implements Table.Data {
+ private static final String CSP_ATT_COM = "@csp.att.com";
+ private static final String[] headers = new String[] {"Date","User","Memo"};
+ private Slot name;
+ private Slot dates;
+
+ public Model(AuthzEnv env) {
+ name = env.slot(NAME+".name");
+ dates = env.slot(NAME+".dates");
+ }
+
+ @Override
+ public String[] headers() {
+ return headers;
+ }
+
+ @Override
+ public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+ final String oName = trans.get(name,null);
+ final String oDates = trans.get(dates,null);
+
+ if(oName==null) {
+ return Cells.EMPTY;
+ }
+
+ ArrayList rv = new ArrayList();
+ String msg = null;
+ final TimeTaken tt = trans.start("AAF Get History for Namespace ["+oName+"]",Env.REMOTE);
+ try {
+ gui.clientAsUser(trans.getUserPrincipal(), new Retryable() {
+ @Override
+ public Void code(Rcli> client) throws CadiException, ConnectException, APIException {
+ if (oDates != null) {
+ client.setQueryParams("yyyymm="+oDates);
+ }
+ Future fh = client.read("/authz/hist/ns/"+oName,gui.historyDF);
+ if (fh.get(AuthGUI.TIMEOUT)) {
+ tt.done();
+ TimeTaken tt2 = trans.start("Load History Data", Env.SUB);
+ try {
+ List- histItems = fh.value.getItem();
+
+ java.util.Collections.sort(histItems, new Comparator
- () {
+ @Override
+ public int compare(Item o1, Item o2) {
+ return o2.getTimestamp().compare(o1.getTimestamp());
+ }
+ });
+
+ for (Item i : histItems) {
+ String user = i.getUser();
+ AbsCell userCell = (user.endsWith(CSP_ATT_COM)?
+ new RefCell(user,WEBPHONE + user.substring(0,user.indexOf('@'))):new TextCell(user));
+
+ rv.add(new AbsCell[] {
+ new TextCell(i.getTimestamp().toGregorianCalendar().getTime().toString()),
+ userCell,
+ new TextCell(i.getMemo())
+ });
+ }
+ } finally {
+ tt2.done();
+ }
+ } else {
+ if (fh.code()==403) {
+ rv.add(new AbsCell[] {new TextCell("You may not view History of Namespace [" + oName + "]", "colspan = 3", "class=center")});
+ } else {
+ rv.add(new AbsCell[] {new TextCell("*** Data Unavailable ***", "colspan = 3", "class=center")});
+ }
+ }
+ return null;
+ }
+ });
+ } catch (Exception e) {
+ trans.error().log(e);
+ } finally {
+ tt.done();
+ }
+ return new Cells(rv,msg);
+ }
+ }
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/NsInfoAction.java b/authz-gui/src/main/java/com/att/authz/gui/pages/NsInfoAction.java
new file mode 100644
index 00000000..19a90c3e
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/NsInfoAction.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.text.ParseException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.util.Chrono;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.CredRequest;
+
+public class NsInfoAction extends Page {
+ public NsInfoAction(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env,"Onboard",PassChangeForm.HREF, PassChangeForm.fields,
+ new BreadCrumbs(breadcrumbs),
+ new NamedCode(true,"content") {
+ final Slot sID = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[0]);
+ final Slot sCurrPass = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[1]);
+ final Slot sPassword = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[2]);
+ final Slot sPassword2 = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[3]);
+ final Slot startDate = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[4]);
+
+ @Override
+ public void code(Cache cache, HTMLGen hgen) throws APIException, IOException {
+ cache.dynamic(hgen, new DynamicCode() {
+ @Override
+ public void code(final AuthGUI gui, final AuthzTrans trans,Cache cache, HTMLGen hgen) throws APIException, IOException {
+ String id = trans.get(sID,null);
+ String currPass = trans.get(sCurrPass,null);
+ String password = trans.get(sPassword,null);
+ String password2 = trans.get(sPassword2,null);
+
+ // Run Validations
+ boolean fail = true;
+
+ if (id==null || id.indexOf('@')<=0) {
+ hgen.p("Data Entry Failure: Please enter a valid ID, including domain.");
+ } else if(password == null || password2 == null || currPass == null) {
+ hgen.p("Data Entry Failure: Both Password Fields need entries.");
+ } else if(!password.equals(password2)) {
+ hgen.p("Data Entry Failure: Passwords do not match.");
+ } else { // everything else is checked by Server
+ final CredRequest cred = new CredRequest();
+ cred.setId(id);
+ cred.setPassword(currPass);
+ try {
+ fail = gui.clientAsUser(trans.getUserPrincipal(), new Retryable() {
+ @Override
+ public Boolean code(Rcli> client)throws CadiException, ConnectException, APIException {
+ TimeTaken tt = trans.start("Check Current Password",Env.REMOTE);
+ try {
+ Future fcr = client.create( // Note: Need "Post", because of hiding password in SSL Data
+ "/authn/validate",
+ gui.credReqDF,
+ cred
+ );
+ boolean go;
+ boolean fail = true;
+ fcr.get(5000);
+ if(fcr.code() == 200) {
+ hgen.p("Current Password validated");
+ go = true;
+ } else {
+ hgen.p(String.format("Invalid Current Password: %d %s",fcr.code(),fcr.body()));
+ go = false;
+ }
+ if(go) {
+ tt.done();
+ tt = trans.start("AAF Change Password",Env.REMOTE);
+ try {
+ // Change over Cred to reset mode
+ cred.setPassword(password);
+ String start = trans.get(startDate, null);
+ if(start!=null) {
+ try {
+ cred.setStart(Chrono.timeStamp(Chrono.dateOnlyFmt.parse(start)));
+ } catch (ParseException e) {
+ throw new CadiException(e);
+ }
+ }
+
+ fcr = client.create(
+ "/authn/cred",
+ gui.credReqDF,
+ cred
+ );
+
+ if(fcr.get(5000)) {
+ // Do Remote Call
+ hgen.p("New Password has been added.");
+ fail = false;
+ } else {
+ gui.writeError(trans, fcr, hgen);
+ }
+ } finally {
+ tt.done();
+ }
+ }
+ return fail;
+ } finally {
+ tt.done();
+ }
+ }
+ });
+
+ } catch (Exception e) {
+ hgen.p("Unknown Error");
+ e.printStackTrace();
+ }
+ }
+ hgen.br();
+ if(fail) {
+ hgen.incr("a",true,"href="+PassChangeForm.HREF+"?id="+id).text("Try again").end();
+ } else {
+ hgen.incr("a",true,"href="+Home.HREF).text("Home").end();
+ }
+ }
+ });
+ }
+ });
+ }
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/NsInfoForm.java b/authz-gui/src/main/java/com/att/authz/gui/pages/NsInfoForm.java
new file mode 100644
index 00000000..5cb8ff2c
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/NsInfoForm.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import static com.att.xgen.html.HTMLGen.A;
+import static com.att.xgen.html.HTMLGen.TABLE;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.List;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.Nss;
+import aaf.v2_0.Nss.Ns;
+import aaf.v2_0.Nss.Ns.Attrib;
+
+public class NsInfoForm extends Page {
+ // Package on purpose
+ static final String HREF = "/gui/onboard";
+ static final String NAME = "Onboarding";
+ static final String fields[] = {"ns","description","mots","owners","admins"};
+
+ public NsInfoForm(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env,NAME,HREF, fields,
+ new BreadCrumbs(breadcrumbs),
+ new NamedCode(true,"content") {
+
+ private final Slot sID = gui.env.slot(NsInfoForm.NAME+'.'+NsInfoForm.fields[0]);
+ @Override
+ public void code(final Cache cache, final HTMLGen hgen) throws APIException, IOException {
+ // p tags not closing right using .p() - causes issues in IE8 password form - so using leaf for the moment
+ hgen.leaf(HTMLGen.H2).text("Namespace Info").end()
+ .leaf("p").text("Hover over Fields for Tool Tips, or click ")
+ .leaf(A,"href="+gui.env.getProperty("aaf_url.gui_onboard","")).text("Here").end()
+ .text(" for more information")
+ .end()
+ .incr("form","method=post");
+ Mark table = new Mark(TABLE);
+ hgen.incr(table);
+ cache.dynamic(hgen, new DynamicCode() {
+ @SuppressWarnings("unchecked")
+ @Override
+ public void code(final AuthGUI gui, AuthzTrans trans, Cache cache, HTMLGen hgen) throws APIException, IOException {
+ final String incomingID= trans.get(sID, "");
+ final String[] info = new String[fields.length];
+ final Object own_adm[] = new Object[2];
+ for(int i=0;i0) {
+ TimeTaken tt = trans.start("AAF Namespace Info",Env.REMOTE);
+ try {
+ gui.clientAsUser(trans.getUserPrincipal(), new Retryable() {
+ @Override
+ public Void code(Rcli> client) throws CadiException, ConnectException, APIException {
+ Future fn = client.read("/authz/nss/"+incomingID,gui.nssDF);
+ if(fn.get(AuthGUI.TIMEOUT)) {
+ for(Ns ns : fn.value.getNs()) {
+ info[0]=ns.getName();
+ info[1]=ns.getDescription();
+ for(Attrib attr: ns.getAttrib()) {
+ switch(attr.getKey()) {
+ case "mots":
+ info[2]=attr.getValue();
+ default:
+ }
+ }
+ own_adm[0]=ns.getResponsible();
+ own_adm[1]=ns.getAdmin();
+ }
+ } else {
+ trans.error().log(fn.body());
+ }
+ return null;
+ }
+ });
+ } catch (Exception e) {
+ trans.error().log("Unable to access AAF for NS Info",incomingID);
+ e.printStackTrace();
+ } finally {
+ tt.done();
+ }
+ }
+ hgen.input(fields[0],"Namespace",false,"value="+info[0],"title=AAF Namespace")
+ .input(fields[1],"Description*",true,"value="+info[1],"title=Full Application Name, Tool Name or Group")
+ .input(fields[2],"MOTS ID",false,"value="+info[2],"title=MOTS ID if this is an Application, and has MOTS");
+ Mark endTD = new Mark(),endTR=new Mark();
+ // Owners
+ hgen.incr(endTR,HTMLGen.TR)
+ .incr(endTD,HTMLGen.TD)
+ .leaf("label","for="+fields[3]).text("Responsible Party")
+ .end(endTD)
+ .incr(endTD,HTMLGen.TD)
+ .tagOnly("input","id="+fields[3],"title=Owner of App, must be an Non-Bargained Employee");
+ if(own_adm[0]!=null) {
+ for(String s : (List)own_adm[0]) {
+ hgen.incr("label",true).text(s).end();
+ }
+ }
+ hgen.end(endTR);
+
+ // Admins
+ hgen.incr(endTR,HTMLGen.TR)
+ .incr(endTD,HTMLGen.TD)
+ .leaf("label","for="+fields[4]).text("Administrators")
+ .end(endTD)
+ .incr(endTD,HTMLGen.TD)
+ .tagOnly("input","id="+fields[4],"title=Admins may be employees, contractors or mechIDs");
+ if(own_adm[1]!=null) {
+ for(String s : (List)own_adm[1]) {
+ hgen.incr(HTMLGen.P,true).text(s).end();
+ }
+ }
+ hgen.end(endTR)
+ .end();
+ }
+ });
+ hgen.end();
+ hgen.tagOnly("input", "type=submit", "value=Submit")
+ .end();
+
+ }
+ });
+ }
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/NssShow.java b/authz-gui/src/main/java/com/att/authz/gui/pages/NssShow.java
new file mode 100644
index 00000000..3ca12d9f
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/NssShow.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+
+import aaf.v2_0.Nss;
+import aaf.v2_0.Nss.Ns;
+
+public class NssShow extends Page {
+ public static final String HREF = "/gui/mynamespaces";
+
+ public NssShow(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env, "MyNamespaces",HREF, NO_FIELDS,
+ new BreadCrumbs(breadcrumbs),
+ new Table("Namespaces I administer",gui.env.newTransNoAvg(),new Model("admin",gui.env),
+ "class=std", "style=display: inline-block; width: 45%; margin: 10px;"),
+ new Table("Namespaces I own",gui.env.newTransNoAvg(),new Model("responsible",gui.env),
+ "class=std", "style=display: inline-block; width: 45%; margin: 10px;"));
+ }
+
+ private static class Model implements Table.Data {
+ private String[] headers;
+ private String privilege = null;
+ public final Slot sNssByUser;
+ private boolean isAdmin;
+
+ public Model(String privilege,AuthzEnv env) {
+ super();
+ headers = new String[] {privilege};
+ this.privilege = privilege;
+ isAdmin = "admin".equals(privilege);
+ sNssByUser = env.slot("NSS_SHOW_MODEL_DATA");
+ }
+
+ @Override
+ public String[] headers() {
+ return headers;
+ }
+
+ @Override
+ public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+ ArrayList rv = new ArrayList();
+ List nss = trans.get(sNssByUser, null);
+ if(nss==null) {
+ TimeTaken tt = trans.start("AAF Nss by User for " + privilege,Env.REMOTE);
+ try {
+ nss = gui.clientAsUser(trans.getUserPrincipal(), new Retryable
>() {
+ @Override
+ public List code(Rcli> client) throws CadiException, ConnectException, APIException {
+ List nss = null;
+ Future fp = client.read("/authz/nss/either/" + trans.user(),gui.nssDF);
+ if(fp.get(AuthGUI.TIMEOUT)) {
+ TimeTaken tt = trans.start("Load Data for " + privilege, Env.SUB);
+ try {
+ if(fp.value!=null) {
+ nss = fp.value.getNs();
+ Collections.sort(nss, new Comparator() {
+ public int compare(Ns ns1, Ns ns2) {
+ return ns1.getName().compareToIgnoreCase(ns2.getName());
+ }
+ });
+ trans.put(sNssByUser,nss);
+ }
+ } finally {
+ tt.done();
+ }
+ }else {
+ gui.writeError(trans, fp, null);
+ }
+ return nss;
+ }
+ });
+ } catch (Exception e) {
+ trans.error().log(e);
+ } finally {
+ tt.done();
+ }
+ }
+
+ if(nss!=null) {
+ for(Ns n : nss) {
+ if((isAdmin && !n.getAdmin().isEmpty())
+ || (!isAdmin && !n.getResponsible().isEmpty())) {
+ AbsCell[] sa = new AbsCell[] {
+ new RefCell(n.getName(),NsDetail.HREF
+ +"?name="+n.getName()),
+ };
+ rv.add(sa);
+ }
+ }
+ }
+
+ return new Cells(rv,null);
+ }
+ }
+
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PassChangeAction.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PassChangeAction.java
new file mode 100644
index 00000000..1c575151
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PassChangeAction.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.text.ParseException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.util.Chrono;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.CredRequest;
+
+public class PassChangeAction extends Page {
+ public PassChangeAction(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env,"PassChange",PassChangeForm.HREF, PassChangeForm.fields,
+ new BreadCrumbs(breadcrumbs),
+ new NamedCode(true,"content") {
+ final Slot sID = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[0]);
+ final Slot sCurrPass = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[1]);
+ final Slot sPassword = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[2]);
+ final Slot sPassword2 = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[3]);
+ final Slot startDate = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[4]);
+
+ @Override
+ public void code(Cache cache, HTMLGen hgen) throws APIException, IOException {
+ cache.dynamic(hgen, new DynamicCode() {
+ @Override
+ public void code(final AuthGUI gui, final AuthzTrans trans,Cache cache, HTMLGen hgen) throws APIException, IOException {
+ String id = trans.get(sID,null);
+ String currPass = trans.get(sCurrPass,null);
+ String password = trans.get(sPassword,null);
+ String password2 = trans.get(sPassword2,null);
+
+ // Run Validations
+ boolean fail = true;
+
+ if (id==null || id.indexOf('@')<=0) {
+ hgen.p("Data Entry Failure: Please enter a valid ID, including domain.");
+ } else if(password == null || password2 == null || currPass == null) {
+ hgen.p("Data Entry Failure: Both Password Fields need entries.");
+ } else if(!password.equals(password2)) {
+ hgen.p("Data Entry Failure: Passwords do not match.");
+ } else { // everything else is checked by Server
+ final CredRequest cred = new CredRequest();
+ cred.setId(id);
+ cred.setPassword(currPass);
+ try {
+ fail = gui.clientAsUser(trans.getUserPrincipal(), new Retryable() {
+ @Override
+ public Boolean code(Rcli> client)throws CadiException, ConnectException, APIException {
+ boolean fail = true;
+ boolean go = false;
+ TimeTaken tt = trans.start("Check Current Password",Env.REMOTE);
+ try {
+ Future fcr = client.create( // Note: Need "Post", because of hiding password in SSL Data
+ "/authn/validate",gui.credReqDF,cred);
+
+ fcr.get(5000);
+ if(fcr.code() == 200) {
+ hgen.p("Current Password validated");
+ go = true;
+ } else {
+ hgen.p(String.format("Invalid Current Password: %d %s",fcr.code(),fcr.body()));
+ go = false;
+ }
+ } finally {
+ tt.done();
+ }
+ if(go) {
+ tt = trans.start("AAF Change Password",Env.REMOTE);
+ try {
+ // Change over Cred to reset mode
+ cred.setPassword(password);
+ String start = trans.get(startDate, null);
+ if(start!=null) {
+ try {
+ cred.setStart(Chrono.timeStamp(Chrono.dateOnlyFmt.parse(start)));
+ } catch (ParseException e) {
+ throw new CadiException(e);
+ }
+ }
+
+ Future fcr = client.create(
+ "/authn/cred",
+ gui.credReqDF,
+ cred
+ );
+
+ if(fcr.get(5000)) {
+ // Do Remote Call
+ hgen.p("New Password has been added.");
+ fail = false;
+ } else {
+ gui.writeError(trans, fcr, hgen);
+ }
+ } finally {
+ tt.done();
+ }
+ }
+ return fail;
+ }
+
+ });
+ } catch (Exception e) {
+ hgen.p("Unknown Error");
+ e.printStackTrace();
+ }
+
+ }
+ hgen.br();
+ if(fail) {
+ hgen.incr("a",true,"href="+PassChangeForm.HREF+"?id="+id).text("Try again").end();
+ } else {
+ hgen.incr("a",true,"href="+Home.HREF).text("Home").end();
+ }
+ }
+ });
+ }
+ });
+ }
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PassChangeForm.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PassChangeForm.java
new file mode 100644
index 00000000..440c0db1
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PassChangeForm.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import static com.att.xgen.html.HTMLGen.TABLE;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Slot;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+public class PassChangeForm extends Page {
+ // Package on purpose
+ static final String HREF = "/gui/passwd";
+ static final String NAME = "PassChange";
+ static final String fields[] = {"id","current","password","password2","startDate"};
+
+ public PassChangeForm(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env,NAME,HREF, fields,
+ new BreadCrumbs(breadcrumbs),
+ new NamedCode(true,"content") {
+ private final Slot sID = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[0]);
+ @Override
+ public void code(final Cache cache, final HTMLGen hgen) throws APIException, IOException {
+ // p tags not closing right using .p() - causes issues in IE8 password form - so using leaf for the moment
+ hgen.leaf("p").text("You are requesting a new Mechanical Password in the AAF System. " +
+ "So that you can perform clean migrations, you will be able to use both this " +
+ "new password and the old one until their respective expiration dates.").end()
+ .leaf("p").text("Note: You must be a Namespace Admin where the MechID resides.").end()
+ .incr("form","method=post");
+ Mark table = new Mark(TABLE);
+ hgen.incr(table);
+ cache.dynamic(hgen, new DynamicCode() {
+ @Override
+ public void code(AuthGUI gui, AuthzTrans trans, Cache cache, HTMLGen hgen) throws APIException, IOException {
+// GregorianCalendar gc = new GregorianCalendar();
+// System.out.println(gc.toString());
+ String incomingID= trans.get(sID, "");
+ hgen
+ .input(fields[0],"ID*",true,"value="+incomingID)
+ .input(fields[1],"Current Password*",true,"type=password")
+ .input(fields[2],"New Password*",true, "type=password")
+ .input(fields[3], "Reenter New Password*",true, "type=password")
+// .input(fields[3],"Start Date",false,"type=date", "value="+
+// Chrono.dateOnlyFmt.format(new Date(System.currentTimeMillis()))
+// )
+ .end();
+ }
+ });
+ hgen.end();
+ hgen.tagOnly("input", "type=submit", "value=Submit")
+ .end();
+
+ }
+ });
+ }
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PendingRequestsShow.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PendingRequestsShow.java
new file mode 100644
index 00000000..8bdb3295
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PendingRequestsShow.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.UUID;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.Approval;
+import aaf.v2_0.Approvals;
+
+public class PendingRequestsShow extends Page {
+ public static final String HREF = "/gui/myrequests";
+ public static final String NAME = "MyRequests";
+ static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
+ private static final String DATE_TIME_FORMAT = "yyyy-MM-dd";
+
+ public PendingRequestsShow(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env, NAME,HREF, NO_FIELDS,
+ new BreadCrumbs(breadcrumbs),
+ new NamedCode(true,"expedite") {
+ @Override
+ public void code(final Cache cache, final HTMLGen hgen) throws APIException, IOException {
+ cache.dynamic(hgen, new DynamicCode() {
+ @Override
+ public void code(AuthGUI gui, AuthzTrans trans, Cache cache, HTMLGen hgen) throws APIException, IOException {
+ hgen
+ .leaf("p", "class=expedite_request").text("These are your submitted Requests that are awaiting Approval. ")
+ .br()
+ .text("To Expedite a Request: ")
+ .leaf("a","href=#expedite_directions","onclick=divVisibility('expedite_directions');")
+ .text("Click Here").end()
+ .divID("expedite_directions", "style=display:none");
+ hgen
+ .incr(HTMLGen.OL)
+ .incr(HTMLGen.LI)
+ .leaf("a","href="+ApprovalForm.HREF+"?user="+trans.user(), "id=userApprove")
+ .text("Copy This Link")
+ .end()
+ .end()
+ .incr(HTMLGen.LI)
+ .text("Send it to the Approver Listed")
+ .end()
+ .end()
+ .text("NOTE: Using this link, the Approver will only see your requests. You only need to send this link once!")
+ .end()
+ .end();
+ }
+ });
+ }
+ },
+ new Table("Pending Requests",gui.env.newTransNoAvg(),new Model(), "class=std")
+ );
+
+
+ }
+
+ /**
+ * Implement the Table Content for Requests by User
+ *
+ *
+ */
+ private static class Model implements Table.Data {
+ private static final String CSP_ATT_COM = "@csp.att.com";
+ final long NUM_100NS_INTERVALS_SINCE_UUID_EPOCH = 0x01b21dd213814000L;
+ private static final String[] headers = new String[] {"Request Date","Status","Memo","Approver"};
+
+ @Override
+ public String[] headers() {
+ return headers;
+ }
+
+ @Override
+ public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+ DateFormat createdDF = new SimpleDateFormat(DATE_TIME_FORMAT);
+ ArrayList rv = new ArrayList();
+ try {
+ gui.clientAsUser(trans.getUserPrincipal(), new Retryable() {
+ @Override
+ public Void code(Rcli> client)throws CadiException, ConnectException, APIException {
+ TimeTaken tt = trans.start("AAF Get Approvals by User",Env.REMOTE);
+ try {
+ Future fa = client.read("/authz/approval/user/"+trans.user(),gui.approvalsDF);
+ if(fa.get(5000)) {
+ tt.done();
+ tt = trans.start("Load Data", Env.SUB);
+ if(fa.value!=null) {
+ List approvals = fa.value.getApprovals();
+ Collections.sort(approvals, new Comparator() {
+ @Override
+ public int compare(Approval a1, Approval a2) {
+ UUID id1 = UUID.fromString(a1.getId());
+ UUID id2 = UUID.fromString(a2.getId());
+ return id1.timestamp()<=id2.timestamp()?1:-1;
+ }
+ });
+
+ String prevTicket = null;
+ for(Approval a : approvals) {
+ String approver = a.getApprover();
+ String approverShort = approver.substring(0,approver.indexOf('@'));
+
+ AbsCell tsCell = null;
+ String ticket = a.getTicket();
+ if (ticket.equals(prevTicket)) {
+ tsCell = AbsCell.Null;
+ } else {
+ UUID id = UUID.fromString(a.getId());
+ tsCell = new RefCell(createdDF.format((id.timestamp() - NUM_100NS_INTERVALS_SINCE_UUID_EPOCH)/10000),
+ RequestDetail.HREF + "?ticket=" + a.getTicket());
+ prevTicket = ticket;
+ }
+
+ AbsCell approverCell = null;
+ if (approver.endsWith(CSP_ATT_COM)) {
+ approverCell = new RefCell(approver, WEBPHONE + approverShort);
+ } else {
+ approverCell = new TextCell(approver);
+ }
+ AbsCell[] sa = new AbsCell[] {
+ tsCell,
+ new TextCell(a.getStatus()),
+ new TextCell(a.getMemo()),
+ approverCell
+ };
+ rv.add(sa);
+ }
+ }
+ } else {
+ gui.writeError(trans, fa, null);
+ }
+ } finally {
+ tt.done();
+ }
+
+
+ return null;
+ }
+ });
+ } catch (Exception e) {
+ trans.error().log(e);
+ }
+ return new Cells(rv,null);
+ }
+ }
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PermDetail.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PermDetail.java
new file mode 100644
index 00000000..ad26674f
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PermDetail.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.att.aft.dme2.internal.jetty.http.HttpStatus;
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+
+import aaf.v2_0.Perm;
+import aaf.v2_0.Perms;
+
+/**
+ * Detail Page for Permissions
+ *
+ */
+public class PermDetail extends Page {
+ public static final String HREF = "/gui/permdetail";
+ public static final String NAME = "PermDetail";
+ private static final String BLANK = "";
+
+ public PermDetail(final AuthGUI gui, Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env, NAME, HREF, new String[] {"type","instance","action"},
+ new BreadCrumbs(breadcrumbs),
+ new Table("Permission Details",gui.env.newTransNoAvg(),new Model(gui.env()),"class=detail")
+ );
+ }
+
+ /**
+ * Implement the table content for Permissions Detail
+ *
+ *
+ */
+ private static class Model implements Table.Data {
+ private static final String[] headers = new String[0];
+ private Slot type, instance, action;
+ public Model(AuthzEnv env) {
+ type = env.slot(NAME+".type");
+ instance = env.slot(NAME+".instance");
+ action = env.slot(NAME+".action");
+ }
+
+ @Override
+ public String[] headers() {
+ return headers;
+ }
+
+ @Override
+ public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+ final String pType = trans.get(type, null);
+ final String pInstance = trans.get(instance, null);
+ final String pAction = trans.get(action, null);
+ if(pType==null || pInstance==null || pAction==null) {
+ return Cells.EMPTY;
+ }
+ ArrayList rv = new ArrayList();
+ rv.add(new AbsCell[]{new TextCell("Type:"),new TextCell(pType)});
+ rv.add(new AbsCell[]{new TextCell("Instance:"),new TextCell(pInstance)});
+ rv.add(new AbsCell[]{new TextCell("Action:"),new TextCell(pAction)});
+ try {
+ gui.clientAsUser(trans.getUserPrincipal(), new Retryable() {
+ @Override
+ public Void code(Rcli> client)throws CadiException, ConnectException, APIException {
+ TimeTaken tt = trans.start("AAF Perm Details",Env.REMOTE);
+ try {
+ Future fp= client.read("/authz/perms/"+pType + '/' + pInstance + '/' + pAction,gui.permsDF);
+
+ if(fp.get(AuthGUI.TIMEOUT)) {
+ tt.done();
+ tt = trans.start("Load Data", Env.SUB);
+ List ps = fp.value.getPerm();
+ if(!ps.isEmpty()) {
+ Perm perm = fp.value.getPerm().get(0);
+ String desc = (perm.getDescription()!=null?perm.getDescription():BLANK);
+ rv.add(new AbsCell[]{new TextCell("Description:"),new TextCell(desc)});
+ boolean first=true;
+ for(String r : perm.getRoles()) {
+ if(first){
+ first=false;
+ rv.add(new AbsCell[] {
+ new TextCell("Associated Roles:"),
+ new TextCell(r)
+ });
+ } else {
+ rv.add(new AbsCell[] {
+ AbsCell.Null,
+ new TextCell(r)
+ });
+ }
+ }
+ }
+ String historyLink = PermHistory.HREF
+ + "?type=" + pType + "&instance=" + pInstance + "&action=" + pAction;
+
+ rv.add(new AbsCell[] {new RefCell("See History",historyLink)});
+ } else {
+ rv.add(new AbsCell[] {new TextCell(
+ fp.code()==HttpStatus.NOT_FOUND_404?
+ "*** Implicit Permission ***":
+ "*** Data Unavailable ***"
+ )});
+ }
+ } finally {
+ tt.done();
+ }
+
+ return null;
+ }
+ });
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return new Cells(rv,null);
+ }
+ }
+}
+
\ No newline at end of file
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PermGrantAction.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PermGrantAction.java
new file mode 100644
index 00000000..3fa6508e
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PermGrantAction.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.Pkey;
+import aaf.v2_0.RolePermRequest;
+
+public class PermGrantAction extends Page {
+
+
+ public PermGrantAction(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env,PermGrantForm.NAME, PermGrantForm.HREF, PermGrantForm.fields,
+ new BreadCrumbs(breadcrumbs),
+ new NamedCode(true,"content") {
+ final Slot sType = gui.env.slot(PermGrantForm.NAME+'.'+PermGrantForm.fields[0]);
+ final Slot sInstance = gui.env.slot(PermGrantForm.NAME+'.'+PermGrantForm.fields[1]);
+ final Slot sAction = gui.env.slot(PermGrantForm.NAME+'.'+PermGrantForm.fields[2]);
+ final Slot sRole = gui.env.slot(PermGrantForm.NAME+'.'+PermGrantForm.fields[3]);
+
+ @Override
+ public void code(Cache cache, HTMLGen hgen) throws APIException, IOException {
+ cache.dynamic(hgen, new DynamicCode() {
+ @Override
+ public void code(final AuthGUI gui, final AuthzTrans trans,Cache cache, HTMLGen hgen) throws APIException, IOException {
+
+ String type = trans.get(sType,null);
+ String instance = trans.get(sInstance,null);
+ String action = trans.get(sAction,null);
+ String role = trans.get(sRole,null);
+
+ String lastPage = PermGrantForm.HREF
+ + "?type=" + type + "&instance=" + instance + "&action=" + action;
+
+ // Run Validations
+ boolean fail = true;
+
+ TimeTaken tt = trans.start("AAF Grant Permission to Role",Env.REMOTE);
+ try {
+
+ final RolePermRequest grantReq = new RolePermRequest();
+ Pkey pkey = new Pkey();
+ pkey.setType(type);
+ pkey.setInstance(instance);
+ pkey.setAction(action);
+ grantReq.setPerm(pkey);
+ grantReq.setRole(role);
+
+ fail = gui.clientAsUser(trans.getUserPrincipal(), new Retryable() {
+ @Override
+ public Boolean code(Rcli> client) throws CadiException, ConnectException, APIException {
+ boolean fail = true;
+ Future fgrant = client.create(
+ "/authz/role/perm",
+ gui.rolePermReqDF,
+ grantReq
+ );
+
+ if(fgrant.get(5000)) {
+ hgen.p("Permission has been granted to role.");
+ fail = false;
+ } else {
+ if (202==fgrant.code()) {
+ hgen.p("Permission Grant Request sent, but must be Approved before actualizing");
+ fail = false;
+ } else {
+ gui.writeError(trans, fgrant, hgen);
+ }
+ }
+ return fail;
+ }
+ });
+ } catch (Exception e) {
+ hgen.p("Unknown Error");
+ e.printStackTrace();
+ } finally {
+ tt.done();
+ }
+
+ hgen.br();
+ hgen.incr("a",true,"href="+lastPage);
+ if (fail) {
+ hgen.text("Try again");
+ } else {
+ hgen.text("Grant this Permission to Another Role");
+ }
+ hgen.end();
+ hgen.js()
+ .text("alterLink('permgrant', '"+lastPage + "');")
+ .done();
+
+ }
+ });
+ }
+ });
+ }
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PermGrantForm.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PermGrantForm.java
new file mode 100644
index 00000000..b3b51f63
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PermGrantForm.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import static com.att.xgen.html.HTMLGen.TABLE;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.Role;
+import aaf.v2_0.Roles;
+
+public class PermGrantForm extends Page {
+ static final String HREF = "/gui/permgrant";
+ static final String NAME = "Permission Grant";
+ static final String fields[] = {"type","instance","action","role"};
+
+ public PermGrantForm(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env,NAME,HREF, fields,
+ new BreadCrumbs(breadcrumbs),
+ new NamedCode(true,"content") {
+ @Override
+ public void code(final Cache cache, final HTMLGen hgen) throws APIException, IOException {
+ final Slot type = gui.env.slot(NAME+".type");
+ final Slot instance = gui.env.slot(NAME+".instance");
+ final Slot action = gui.env.slot(NAME+".action");
+ final Slot role = gui.env.slot(NAME+".role");
+ // p tags not closing right using .p() - causes issues in IE8 password form - so using leaf for the moment
+ hgen.leaf("p").text("Choose a role to grant to this permission").end()
+ .incr("form","method=post");
+ Mark table = new Mark(TABLE);
+ hgen.incr(table);
+ cache.dynamic(hgen, new DynamicCode() {
+ @Override
+ public void code(AuthGUI gui, AuthzTrans trans, Cache cache, HTMLGen hgen) throws APIException, IOException {
+
+ Mark copyRoleJS = new Mark();
+ hgen.js(copyRoleJS);
+ hgen.text("function copyRole(role) {");
+ hgen.text("var txtRole = document.querySelector(\"#role\");");
+// hgen.text("if (role==;");
+ hgen.text("txtRole.value=role;");
+ hgen.text("}");
+ hgen.end(copyRoleJS);
+
+ String typeValue = trans.get(type, "");
+ String instanceValue = trans.get(instance, "");
+ String actionValue = trans.get(action, "");
+ String roleValue = trans.get(role,null);
+ List myRoles = getMyRoles(gui, trans);
+ hgen
+ .input(fields[0],"Perm Type",true,"value="+typeValue,"disabled")
+ .input(fields[1],"Perm Instance",true,"value="+instanceValue,"disabled")
+ .input(fields[2],"Perm Action",true,"value="+actionValue,"disabled");
+
+ // select & options are not an input type, so we must create table row & cell tags
+ Mark selectRow = new Mark();
+ hgen
+ .incr(selectRow, "tr")
+ .incr("td")
+ .incr("label", "for=myroles", "required").text("My Roles").end()
+ .end()
+ .incr("td")
+ .incr("select", "name=myroles", "id=myroles", "onchange=copyRole(this.value)")
+ .incr("option", "value=").text("Select one of my roles").end();
+ for (String role : myRoles) {
+ hgen.incr("option", "value="+role).text(role).end();
+ }
+ hgen
+ .incr("option", "value=").text("Other").end()
+ .end(selectRow);
+ if(roleValue==null) {
+ hgen.input(fields[3],"Role", true, "placeholder=or type a role here");
+ } else {
+ hgen.input(fields[3],"Role",true, "value="+roleValue);
+ }
+ hgen.end();
+ }
+ });
+ hgen.end();
+ hgen.tagOnly("input", "type=submit", "value=Submit")
+ .end();
+
+ }
+ });
+ }
+
+ private static List getMyRoles(final AuthGUI gui, final AuthzTrans trans) {
+ List myRoles = new ArrayList();
+ try {
+ gui.clientAsUser(trans.getUserPrincipal(), new Retryable() {
+ @Override
+ public Void code(Rcli> client) throws CadiException, ConnectException, APIException {
+ TimeTaken tt = trans.start("AAF get my roles",Env.REMOTE);
+ try {
+ Future fr = client.read("/authz/roles/user/"+trans.user(),gui.rolesDF);
+ if(fr.get(5000)) {
+ tt.done();
+ tt = trans.start("Load Data", Env.SUB);
+ if (fr.value != null) for (Role r : fr.value.getRole()) {
+ myRoles.add(r.getName());
+ }
+ } else {
+ gui.writeError(trans, fr, null);
+ }
+ } finally {
+ tt.done();
+ }
+ return null;
+ }
+ });
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return myRoles;
+ }
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PermHistory.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PermHistory.java
new file mode 100644
index 00000000..f360b0d5
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PermHistory.java
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Comparator;
+import java.util.List;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.History;
+import aaf.v2_0.History.Item;
+
+
+public class PermHistory extends Page {
+ static final String NAME="PermHistory";
+ static final String HREF = "/gui/permHistory";
+ static final String FIELDS[] = {"type","instance","action","dates"};
+ static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
+ static enum Month { JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY,
+ AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER };
+
+ public PermHistory(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env,NAME,HREF, FIELDS,
+ new BreadCrumbs(breadcrumbs),
+ new Table("History", gui.env.newTransNoAvg(),new Model(gui.env()),"class=std"),
+ new NamedCode(true, "content") {
+ @Override
+ public void code(final Cache cache, final HTMLGen hgen) throws APIException, IOException {
+ final Slot sType = gui.env.slot(NAME+".type");
+ final Slot sInstance = gui.env.slot(NAME+".instance");
+ final Slot sAction = gui.env.slot(NAME+".action");
+ cache.dynamic(hgen, new DynamicCode() {
+ @Override
+ public void code(AuthGUI gui, AuthzTrans trans, Cache cache, HTMLGen hgen) throws APIException, IOException {
+ String type = trans.get(sType, null);
+ String instance = trans.get(sInstance,null);
+ String action = trans.get(sAction,null);
+
+ // Use Javascript to make the table title more descriptive
+ hgen.js()
+ .text("var caption = document.querySelector(\".title\");")
+ .text("caption.innerHTML='History for Permission [ " + type + " ]';")
+ .done();
+
+ // Use Javascript to change Link Target to our last visited Detail page
+ String lastPage = PermDetail.HREF + "?type=" + type
+ + "&instance=" + instance
+ + "&action=" + action;
+ hgen.js()
+ .text("alterLink('permdetail', '"+lastPage + "');")
+ .done();
+
+ hgen.br();
+ hgen.leaf("a", "href=#advanced_search", "onclick=divVisibility('advanced_search');").text("Advanced Search").end()
+ .divID("advanced_search", "style=display:none");
+ hgen.incr("table");
+
+ addDateRow(hgen,"Start Date");
+ addDateRow(hgen,"End Date");
+ hgen.incr("tr").incr("td");
+ hgen.tagOnly("input", "type=button","value=Get History",
+ "onclick=datesURL('"+HREF+"?type=" + type
+ + "&instance=" + instance
+ + "&action=" + action+"');");
+ hgen.end().end();
+ hgen.end();
+ hgen.end();
+ }
+ });
+ }
+ }
+
+ );
+
+ }
+
+ private static void addDateRow(HTMLGen hgen, String s) {
+ hgen
+ .incr("tr")
+ .incr("td")
+ .incr("label", "for=month", "required").text(s+"*").end()
+ .end()
+ .incr("td")
+ .incr("select", "name=month"+s.substring(0, s.indexOf(' ')), "id=month"+s.substring(0, s.indexOf(' ')), "required")
+ .incr("option", "value=").text("Month").end();
+ for (Month m : Month.values()) {
+ if (Calendar.getInstance().get(Calendar.MONTH) == m.ordinal()) {
+ hgen.incr("option", "selected", "value="+(m.ordinal()+1)).text(m.name()).end();
+ } else {
+ hgen.incr("option", "value="+(m.ordinal()+1)).text(m.name()).end();
+ }
+ }
+ hgen.end()
+ .end()
+ .incr("td")
+ .tagOnly("input","type=number","id=year"+s.substring(0, s.indexOf(' ')),"required",
+ "value="+Calendar.getInstance().get(Calendar.YEAR), "min=1900",
+ "max="+Calendar.getInstance().get(Calendar.YEAR),
+ "placeholder=Year").end()
+ .end();
+ }
+
+ /**
+ * Implement the Table Content for History
+ *
+ *
+ */
+ private static class Model implements Table.Data {
+ private static final String CSP_ATT_COM = "@csp.att.com";
+ private static final String[] headers = new String[] {"Date","User","Memo"};
+ private Slot sType;
+ private Slot sDates;
+
+ public Model(AuthzEnv env) {
+ sType = env.slot(NAME+".type");
+ sDates = env.slot(NAME+".dates");
+ }
+
+ @Override
+ public String[] headers() {
+ return headers;
+ }
+
+ @Override
+ public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+ final String oName = trans.get(sType,null);
+ final String oDates = trans.get(sDates,null);
+
+ if(oName==null) {
+ return Cells.EMPTY;
+ }
+
+ ArrayList rv = new ArrayList();
+ String msg = null;
+ try {
+ gui.clientAsUser(trans.getUserPrincipal(), new Retryable() {
+ @Override
+ public Void code(Rcli> client) throws CadiException, ConnectException, APIException {
+ TimeTaken tt = trans.start("AAF Get History for Permission ["+oName+"]",Env.REMOTE);
+ try {
+ if (oDates != null) {
+ client.setQueryParams("yyyymm="+oDates);
+ }
+ Future fh = client.read(
+ "/authz/hist/perm/"+oName,
+ gui.historyDF
+ );
+
+
+ if (fh.get(AuthGUI.TIMEOUT)) {
+ tt.done();
+ tt = trans.start("Load History Data", Env.SUB);
+ List- histItems = fh.value.getItem();
+
+ java.util.Collections.sort(histItems, new Comparator
- () {
+ @Override
+ public int compare(Item o1, Item o2) {
+ return o2.getTimestamp().compare(o1.getTimestamp());
+ }
+ });
+
+ for (Item i : histItems) {
+ String user = i.getUser();
+ AbsCell userCell = (user.endsWith(CSP_ATT_COM)?
+ new RefCell(user,WEBPHONE + user.substring(0,user.indexOf('@'))):new TextCell(user));
+
+ rv.add(new AbsCell[] {
+ new TextCell(i.getTimestamp().toGregorianCalendar().getTime().toString()),
+ userCell,
+ new TextCell(i.getMemo())
+ });
+ }
+
+ } else {
+ if (fh.code()==403) {
+ rv.add(new AbsCell[] {new TextCell("You may not view History of Permission [" + oName + "]", "colspan = 3", "class=center")});
+ } else {
+ rv.add(new AbsCell[] {new TextCell("*** Data Unavailable ***", "colspan = 3", "class=center")});
+ }
+ }
+ } finally {
+ tt.done();
+ }
+
+ return null;
+ }
+ });
+
+ } catch (Exception e) {
+ trans.error().log(e);
+ }
+ return new Cells(rv,msg);
+ }
+ }
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PermsShow.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PermsShow.java
new file mode 100644
index 00000000..1bd3301c
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PermsShow.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+
+import aaf.v2_0.Perm;
+import aaf.v2_0.Perms;
+
+/**
+ * Page content for My Permissions
+ *
+ *
+ */
+public class PermsShow extends Page {
+ public static final String HREF = "/gui/myperms";
+
+ public PermsShow(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env, "MyPerms",HREF, NO_FIELDS,
+ new BreadCrumbs(breadcrumbs),
+ new Table("Permissions",gui.env.newTransNoAvg(),new Model(), "class=std"));
+ }
+
+ /**
+ * Implement the Table Content for Permissions by User
+ *
+ *
+ */
+ private static class Model implements Table.Data {
+ private static final String[] headers = new String[] {"Type","Instance","Action"};
+
+ @Override
+ public String[] headers() {
+ return headers;
+ }
+
+ @Override
+ public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+ ArrayList rv = new ArrayList();
+ TimeTaken tt = trans.start("AAF Perms by User",Env.REMOTE);
+ try {
+ gui.clientAsUser(trans.getUserPrincipal(), new Retryable() {
+ @Override
+ public Void code(Rcli> client) throws CadiException, ConnectException, APIException {
+ Future fp = client.read("/authz/perms/user/"+trans.user(), gui.permsDF);
+ if(fp.get(5000)) {
+ TimeTaken ttld = trans.start("Load Data", Env.SUB);
+ try {
+ if(fp.value!=null) {
+ for(Perm p : fp.value.getPerm()) {
+ AbsCell[] sa = new AbsCell[] {
+ new RefCell(p.getType(),PermDetail.HREF
+ +"?type="+p.getType()
+ +"&instance="+p.getInstance()
+ +"&action="+p.getAction()),
+ new TextCell(p.getInstance()),
+ new TextCell(p.getAction())
+ };
+ rv.add(sa);
+ }
+ } else {
+ gui.writeError(trans, fp, null);
+ }
+ } finally {
+ ttld.done();
+ }
+ }
+ return null;
+ }
+ });
+ } catch (Exception e) {
+ trans.error().log(e);
+ } finally {
+ tt.done();
+ }
+ return new Cells(rv,null);
+ }
+ }
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/RequestDetail.java b/authz-gui/src/main/java/com/att/authz/gui/pages/RequestDetail.java
new file mode 100644
index 00000000..43c21328
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/RequestDetail.java
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.UUID;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+
+import aaf.v2_0.Approval;
+import aaf.v2_0.Approvals;
+
+public class RequestDetail extends Page {
+ public static final String HREF = "/gui/requestdetail";
+ public static final String NAME = "RequestDetail";
+ private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
+ public static final String[] FIELDS = {"ticket"};
+
+ public RequestDetail(final AuthGUI gui, Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env, NAME, HREF, FIELDS,
+ new BreadCrumbs(breadcrumbs),
+ new Table("Request Details",gui.env.newTransNoAvg(),new Model(gui.env()),"class=detail")
+ );
+ }
+
+ /**
+ * Implement the table content for Request Detail
+ *
+ *
+ */
+ private static class Model implements Table.Data {
+ static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
+ private static final String CSP_ATT_COM = "@csp.att.com";
+ final long NUM_100NS_INTERVALS_SINCE_UUID_EPOCH = 0x01b21dd213814000L;
+ private static final String[] headers = new String[0];
+ private Slot sTicket;
+ public Model(AuthzEnv env) {
+ sTicket = env.slot(NAME+".ticket");
+ }
+
+ @Override
+ public String[] headers() {
+ return headers;
+ }
+
+ @Override
+ public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+ Cells rv=Cells.EMPTY;
+ final String ticket = trans.get(sTicket, null);
+ if(ticket!=null) {
+ try {
+ rv = gui.clientAsUser(trans.getUserPrincipal(), new Retryable() {
+ @Override
+ public Cells code(Rcli> client) throws CadiException, ConnectException, APIException {
+ TimeTaken tt = trans.start("AAF Approval Details",Env.REMOTE);
+ ArrayList rv = new ArrayList();
+ try {
+ Future fa = client.read(
+ "/authz/approval/ticket/"+ticket,
+ gui.approvalsDF
+ );
+
+ if(fa.get(AuthGUI.TIMEOUT)) {
+ if (!trans.user().equals(fa.value.getApprovals().get(0).getUser())) {
+ return Cells.EMPTY;
+ }
+ tt.done();
+ tt = trans.start("Load Data", Env.SUB);
+ boolean first = true;
+ for ( Approval approval : fa.value.getApprovals()) {
+ AbsCell[] approverLine = new AbsCell[4];
+ // only print common elements once
+ if (first) {
+ DateFormat createdDF = new SimpleDateFormat(DATE_TIME_FORMAT);
+ UUID id = UUID.fromString(approval.getId());
+
+ rv.add(new AbsCell[]{new TextCell("Ticket ID:"),new TextCell(approval.getTicket(),"colspan=3")});
+ rv.add(new AbsCell[]{new TextCell("Memo:"),new TextCell(approval.getMemo(),"colspan=3")});
+ rv.add(new AbsCell[]{new TextCell("Requested On:"),
+ new TextCell(createdDF.format((id.timestamp() - NUM_100NS_INTERVALS_SINCE_UUID_EPOCH)/10000),"colspan=3")
+ });
+ rv.add(new AbsCell[]{new TextCell("Operation:"),new TextCell(decodeOp(approval.getOperation()),"colspan=3")});
+ String user = approval.getUser();
+ if (user.endsWith(CSP_ATT_COM)) {
+ rv.add(new AbsCell[]{new TextCell("User:"),
+ new RefCell(user,WEBPHONE + user.substring(0, user.indexOf("@")),"colspan=3")});
+ } else {
+ rv.add(new AbsCell[]{new TextCell("User:"),new TextCell(user,"colspan=3")});
+ }
+
+ // headers for listing each approver
+ rv.add(new AbsCell[]{new TextCell(" ","colspan=4","class=blank_line")});
+ rv.add(new AbsCell[]{AbsCell.Null,
+ new TextCell("Approver","class=bold"),
+ new TextCell("Type","class=bold"),
+ new TextCell("Status","class=bold")});
+ approverLine[0] = new TextCell("Approvals:");
+
+ first = false;
+ } else {
+ approverLine[0] = AbsCell.Null;
+ }
+
+ String approver = approval.getApprover();
+ String approverShort = approver.substring(0,approver.indexOf('@'));
+
+ if (approver.endsWith(CSP_ATT_COM)) {
+ approverLine[1] = new RefCell(approver, WEBPHONE + approverShort);
+ } else {
+ approverLine[1] = new TextCell(approval.getApprover());
+ }
+
+ String type = approval.getType();
+ if ("owner".equalsIgnoreCase(type)) {
+ type = "resource owner";
+ }
+
+ approverLine[2] = new TextCell(type);
+ approverLine[3] = new TextCell(approval.getStatus());
+ rv.add(approverLine);
+
+ }
+ } else {
+ rv.add(new AbsCell[] {new TextCell("*** Data Unavailable ***")});
+ }
+ } finally {
+ tt.done();
+ }
+ return new Cells(rv,null);
+ }
+ });
+ } catch (Exception e) {
+ trans.error().log(e);
+ }
+ }
+ return rv;
+ }
+
+ private String decodeOp(String operation) {
+ if ("C".equalsIgnoreCase(operation)) {
+ return "Create";
+ } else if ("D".equalsIgnoreCase(operation)) {
+ return "Delete";
+ } else if ("U".equalsIgnoreCase(operation)) {
+ return "Update";
+ } else if ("G".equalsIgnoreCase(operation)) {
+ return "Grant";
+ } else if ("UG".equalsIgnoreCase(operation)) {
+ return "Un-Grant";
+ }
+ return operation;
+ }
+ }
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/RoleDetail.java b/authz-gui/src/main/java/com/att/authz/gui/pages/RoleDetail.java
new file mode 100644
index 00000000..d45813eb
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/RoleDetail.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+
+import aaf.v2_0.Pkey;
+import aaf.v2_0.Role;
+import aaf.v2_0.Roles;
+
+/**
+ * Detail Page for Permissions
+ *
+ *
+ */
+public class RoleDetail extends Page {
+ public static final String HREF = "/gui/roledetail";
+ public static final String NAME = "RoleDetail";
+ private static final String BLANK = "";
+
+ public RoleDetail(final AuthGUI gui, Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env, NAME, HREF, new String[] {"role"},
+ new BreadCrumbs(breadcrumbs),
+ new Table("Role Details",gui.env.newTransNoAvg(),new Model(gui.env()),"class=detail")
+ );
+ }
+
+ /**
+ * Implement the table content for Permissions Detail
+ *
+ *
+ */
+ private static class Model implements Table.Data {
+ private static final String[] headers = new String[0];
+ private Slot role;
+ public Model(AuthzEnv env) {
+ role = env.slot(NAME+".role");
+ }
+
+ @Override
+ public String[] headers() {
+ return headers;
+ }
+
+ @Override
+ public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+ final String pRole = trans.get(role, null);
+ Cells rv = Cells.EMPTY;
+ if(pRole!=null) {
+ try {
+ rv = gui.clientAsUser(trans.getUserPrincipal(), new Retryable() {
+ @Override
+ public Cells code(Rcli> client) throws CadiException, ConnectException, APIException {
+ ArrayList rv = new ArrayList();
+ rv.add(new AbsCell[]{new TextCell("Role:"),new TextCell(pRole)});
+
+ TimeTaken tt = trans.start("AAF Role Details",Env.REMOTE);
+ try {
+
+ Future fr = client.read("/authz/roles/"+pRole,gui.rolesDF);
+ if(fr.get(AuthGUI.TIMEOUT)) {
+ tt.done();
+ tt = trans.start("Load Data", Env.SUB);
+ Role role = fr.value.getRole().get(0);
+ String desc = (role.getDescription()!=null?role.getDescription():BLANK);
+ rv.add(new AbsCell[]{new TextCell("Description:"),new TextCell(desc)});
+ boolean first=true;
+ for(Pkey r : role.getPerms()) {
+ if(first){
+ first=false;
+ rv.add(new AbsCell[] {
+ new TextCell("Associated Permissions:"),
+ new TextCell(r.getType() +
+ " | " + r.getInstance() +
+ " | " + r.getAction()
+ )
+ });
+ } else {
+ rv.add(new AbsCell[] {
+ AbsCell.Null,
+ new TextCell(r.getType() +
+ " | " + r.getInstance() +
+ " | " + r.getAction()
+ )
+ });
+ }
+ }
+ String historyLink = RoleHistory.HREF
+ + "?role=" + pRole;
+ rv.add(new AbsCell[] {new RefCell("See History",historyLink)});
+ } else {
+ rv.add(new AbsCell[] {new TextCell("*** Data Unavailable ***")});
+ }
+ } finally {
+ tt.done();
+ }
+ return new Cells(rv,null);
+ }
+ });
+ } catch (Exception e) {
+ trans.error().log(e);
+ }
+ }
+ return rv;
+ }
+ }
+}
+
\ No newline at end of file
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/RoleHistory.java b/authz-gui/src/main/java/com/att/authz/gui/pages/RoleHistory.java
new file mode 100644
index 00000000..85311329
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/RoleHistory.java
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Comparator;
+import java.util.List;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.History;
+import aaf.v2_0.History.Item;
+
+
+public class RoleHistory extends Page {
+ static final String NAME="RoleHistory";
+ static final String HREF = "/gui/roleHistory";
+ static final String FIELDS[] = {"role","dates"};
+ static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
+ static enum Month { JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY,
+ AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER };
+
+ public RoleHistory(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env,NAME,HREF, FIELDS,
+ new BreadCrumbs(breadcrumbs),
+ new Table("History", gui.env.newTransNoAvg(),new Model(gui.env()),"class=std"),
+ new NamedCode(true, "content") {
+ @Override
+ public void code(final Cache cache, final HTMLGen hgen) throws APIException, IOException {
+ final Slot role = gui.env.slot(NAME+".role");
+ cache.dynamic(hgen, new DynamicCode() {
+ @Override
+ public void code(AuthGUI gui, AuthzTrans trans, Cache cache, HTMLGen hgen) throws APIException, IOException {
+ String obRole = trans.get(role, null);
+
+ // Use Javascript to make the table title more descriptive
+ hgen.js()
+ .text("var caption = document.querySelector(\".title\");")
+ .text("caption.innerHTML='History for Role [ " + obRole + " ]';")
+ .done();
+
+ // Use Javascript to change Link Target to our last visited Detail page
+ String lastPage = RoleDetail.HREF + "?role=" + obRole;
+ hgen.js()
+ .text("alterLink('roledetail', '"+lastPage + "');")
+ .done();
+
+ hgen.br();
+ hgen.leaf("a", "href=#advanced_search","onclick=divVisibility('advanced_search');").text("Advanced Search").end()
+ .divID("advanced_search", "style=display:none");
+ hgen.incr("table");
+
+ addDateRow(hgen,"Start Date");
+ addDateRow(hgen,"End Date");
+ hgen.incr("tr").incr("td");
+ hgen.tagOnly("input", "type=button","value=Get History",
+ "onclick=datesURL('"+HREF+"?role=" + obRole+"');");
+ hgen.end().end();
+ hgen.end();
+ hgen.end();
+ }
+ });
+ }
+ }
+
+ );
+
+ }
+
+ private static void addDateRow(HTMLGen hgen, String s) {
+ hgen
+ .incr("tr")
+ .incr("td")
+ .incr("label", "for=month", "required").text(s+"*").end()
+ .end()
+ .incr("td")
+ .incr("select", "name=month"+s.substring(0, s.indexOf(' ')), "id=month"+s.substring(0, s.indexOf(' ')), "required")
+ .incr("option", "value=").text("Month").end();
+ for (Month m : Month.values()) {
+ if (Calendar.getInstance().get(Calendar.MONTH) == m.ordinal()) {
+ hgen.incr("option", "selected", "value="+(m.ordinal()+1)).text(m.name()).end();
+ } else {
+ hgen.incr("option", "value="+(m.ordinal()+1)).text(m.name()).end();
+ }
+ }
+ hgen.end()
+ .end()
+ .incr("td")
+ .tagOnly("input","type=number","id=year"+s.substring(0, s.indexOf(' ')),"required",
+ "value="+Calendar.getInstance().get(Calendar.YEAR), "min=1900",
+ "max="+Calendar.getInstance().get(Calendar.YEAR),
+ "placeholder=Year").end()
+ .end();
+ }
+
+
+ /**
+ * Implement the Table Content for History
+ *
+ *
+ */
+ private static class Model implements Table.Data {
+ private static final String CSP_ATT_COM = "@csp.att.com";
+ private static final String[] headers = new String[] {"Date","User","Memo"};
+ private Slot role;
+ private Slot dates;
+
+ public Model(AuthzEnv env) {
+ role = env.slot(NAME+".role");
+ dates = env.slot(NAME+".dates");
+ }
+
+ @Override
+ public String[] headers() {
+ return headers;
+ }
+
+ @Override
+ public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+ final String oName = trans.get(role,null);
+ final String oDates = trans.get(dates,null);
+
+ Cells rv = Cells.EMPTY;
+ if(oName!=null) {
+
+ try {
+ rv = gui.clientAsUser(trans.getUserPrincipal(), new Retryable() {
+ @Override
+ public Cells code(Rcli> client) throws CadiException, ConnectException, APIException {
+ ArrayList rv = new ArrayList();
+ TimeTaken tt = trans.start("AAF Get History for Namespace ["+oName+"]",Env.REMOTE);
+ String msg = null;
+ try {
+ if (oDates != null) {
+ client.setQueryParams("yyyymm="+oDates);
+ }
+ Future fh = client.read("/authz/hist/role/"+oName,gui.historyDF);
+ if (fh.get(AuthGUI.TIMEOUT)) {
+ tt.done();
+ tt = trans.start("Load History Data", Env.SUB);
+ List
- histItems = fh.value.getItem();
+
+ java.util.Collections.sort(histItems, new Comparator
- () {
+ @Override
+ public int compare(Item o1, Item o2) {
+ return o2.getTimestamp().compare(o1.getTimestamp());
+ }
+ });
+
+ for (Item i : histItems) {
+ String user = i.getUser();
+ AbsCell userCell = (user.endsWith(CSP_ATT_COM)?
+ new RefCell(user,WEBPHONE + user.substring(0,user.indexOf('@'))):new TextCell(user));
+
+ rv.add(new AbsCell[] {
+ new TextCell(i.getTimestamp().toGregorianCalendar().getTime().toString()),
+ userCell,
+ new TextCell(i.getMemo())
+ });
+ }
+ } else {
+ if (fh.code()==403) {
+ rv.add(new AbsCell[] {new TextCell("You may not view History of Permission [" + oName + "]", "colspan = 3", "class=center")});
+ } else {
+ rv.add(new AbsCell[] {new TextCell("*** Data Unavailable ***", "colspan = 3", "class=center")});
+ }
+ }
+ } finally {
+ tt.done();
+ }
+ return new Cells(rv,msg);
+ }
+ });
+ } catch (Exception e) {
+ trans.error().log(e);
+ }
+ }
+ return rv;
+ }
+ }
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/RolesShow.java b/authz-gui/src/main/java/com/att/authz/gui/pages/RolesShow.java
new file mode 100644
index 00000000..8b264dfe
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/RolesShow.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.util.Chrono;
+
+import aaf.v2_0.UserRole;
+import aaf.v2_0.UserRoles;
+
+
+/**
+ * Page content for My Roles
+ *
+ *
+ */
+public class RolesShow extends Page {
+ public static final String HREF = "/gui/myroles";
+ private static final String DATE_TIME_FORMAT = "yyyy-MM-dd";
+ private static SimpleDateFormat expiresDF;
+
+ static {
+ expiresDF = new SimpleDateFormat(DATE_TIME_FORMAT);
+ }
+
+ public RolesShow(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env, "MyRoles",HREF, NO_FIELDS,
+ new BreadCrumbs(breadcrumbs),
+ new Table("Roles",gui.env.newTransNoAvg(),new Model(), "class=std"));
+ }
+
+ /**
+ * Implement the Table Content for Permissions by User
+ *
+ *
+ */
+ private static class Model implements Table.Data {
+ private static final String[] headers = new String[] {"Role","Expires","Remediation","Actions"};
+
+ @Override
+ public String[] headers() {
+ return headers;
+ }
+
+ @Override
+ public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+ Cells rv = Cells.EMPTY;
+
+ try {
+ rv = gui.clientAsUser(trans.getUserPrincipal(), new Retryable() {
+ @Override
+ public Cells code(Rcli> client) throws CadiException, ConnectException, APIException {
+ ArrayList rv = new ArrayList();
+ TimeTaken tt = trans.start("AAF Roles by User",Env.REMOTE);
+ try {
+ Future fur = client.read("/authz/userRoles/user/"+trans.user(),gui.userrolesDF);
+ if (fur.get(5000)) {
+ if(fur.value != null) for (UserRole u : fur.value.getUserRole()) {
+ if(u.getExpires().compare(Chrono.timeStamp()) < 0) {
+ AbsCell[] sa = new AbsCell[] {
+ new TextCell(u.getRole() + "*", "class=expired"),
+ new TextCell(expiresDF.format(u.getExpires().toGregorianCalendar().getTime()),"class=expired"),
+ new RefCell("Extend",
+ UserRoleExtend.HREF + "?user="+trans.user()+"&role="+u.getRole(),
+ new String[]{"class=expired"}),
+ new RefCell("Remove",
+ UserRoleRemove.HREF + "?user="+trans.user()+"&role="+u.getRole(),
+ new String[]{"class=expired"})
+
+ };
+ rv.add(sa);
+ } else {
+ AbsCell[] sa = new AbsCell[] {
+ new RefCell(u.getRole(),
+ RoleDetail.HREF+"?role="+u.getRole()),
+ new TextCell(expiresDF.format(u.getExpires().toGregorianCalendar().getTime())),
+ AbsCell.Null,
+ new RefCell("Remove",
+ UserRoleRemove.HREF + "?user="+trans.user()+"&role="+u.getRole())
+ };
+ rv.add(sa);
+ }
+ }
+ }
+
+ } finally {
+ tt.done();
+ }
+ return new Cells(rv,null);
+ }
+ });
+ } catch (Exception e) {
+ trans.error().log(e);
+ }
+ return rv;
+ }
+ }
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/UserRoleExtend.java b/authz-gui/src/main/java/com/att/authz/gui/pages/UserRoleExtend.java
new file mode 100644
index 00000000..e54787b9
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/UserRoleExtend.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+public class UserRoleExtend extends Page {
+ public static final String HREF = "/gui/urExtend";
+ static final String NAME = "Extend User Role";
+ static final String fields[] = {"user","role"};
+
+ public UserRoleExtend(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env,NAME, HREF, fields,
+ new BreadCrumbs(breadcrumbs),
+ new NamedCode(true, "content") {
+ @Override
+ public void code(final Cache cache, final HTMLGen hgen) throws APIException, IOException {
+ final Slot sUser = gui.env.slot(NAME+".user");
+ final Slot sRole = gui.env.slot(NAME+".role");
+
+
+ cache.dynamic(hgen, new DynamicCode() {
+ @Override
+ public void code(AuthGUI gui, AuthzTrans trans, Cache cache, HTMLGen hgen) throws APIException, IOException {
+ final String user = trans.get(sUser, "");
+ final String role = trans.get(sRole, "");
+
+ TimeTaken tt = trans.start("Request to extend user role",Env.REMOTE);
+ try {
+ gui.clientAsUser(trans.getUserPrincipal(), new Retryable() {
+ @Override
+ public Void code(Rcli> client)throws CadiException, ConnectException, APIException {
+ Future fv = client.setQueryParams("request=true").update("/authz/userRole/extend/"+user+"/"+role);
+ if(fv.get(5000)) {
+ // not sure if we'll ever hit this
+ hgen.p("Extended User ["+ user+"] in Role [" +role+"]");
+ } else {
+ if (fv.code() == 202 ) {
+ hgen.p("User ["+ user+"] in Role [" +role+"] Extension sent for Approval");
+ } else {
+ gui.writeError(trans, fv, hgen);
+ }
+ }
+ return null;
+ }
+ });
+ } catch (Exception e) {
+ trans.error().log(e);
+ e.printStackTrace();
+ } finally {
+ tt.done();
+ }
+
+
+ }
+ });
+ }
+
+ });
+ }
+}
+
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/UserRoleRemove.java b/authz-gui/src/main/java/com/att/authz/gui/pages/UserRoleRemove.java
new file mode 100644
index 00000000..fd2123c2
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/UserRoleRemove.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+public class UserRoleRemove extends Page {
+ public static final String HREF = "/gui/urRemove";
+ static final String NAME = "Remove User Role";
+ static final String fields[] = {"user","role"};
+
+ public UserRoleRemove(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env,NAME, HREF, fields,
+ new BreadCrumbs(breadcrumbs),
+ new NamedCode(true, "content") {
+ @Override
+ public void code(final Cache cache, final HTMLGen hgen) throws APIException, IOException {
+ final Slot sUser = gui.env.slot(NAME+".user");
+ final Slot sRole = gui.env.slot(NAME+".role");
+
+
+ cache.dynamic(hgen, new DynamicCode() {
+ @Override
+ public void code(AuthGUI gui, AuthzTrans trans, Cache cache, HTMLGen hgen) throws APIException, IOException {
+ final String user = trans.get(sUser, "");
+ final String role = trans.get(sRole, "");
+
+ TimeTaken tt = trans.start("Request a user role delete",Env.REMOTE);
+ try {
+ gui.clientAsUser(trans.getUserPrincipal(), new Retryable() {
+ @Override
+ public Void code(Rcli> client) throws CadiException, ConnectException, APIException {
+ Future fv = client.setQueryParams("request=true").delete(
+ "/authz/userRole/"+user+"/"+role,Void.class);
+
+ if(fv.get(5000)) {
+ // not sure if we'll ever hit this
+ hgen.p("User ["+ user+"] Removed from Role [" +role+"]");
+ } else {
+ if (fv.code() == 202 ) {
+ hgen.p("User ["+ user+"] Removal from Role [" +role+"] sent for Approval");
+ } else {
+ gui.writeError(trans, fv, hgen);
+ }
+ }
+ return null;
+ }
+ });
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ tt.done();
+ }
+ }
+ });
+ }
+
+ });
+ }
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/WebCommand.java b/authz-gui/src/main/java/com/att/authz/gui/pages/WebCommand.java
new file mode 100644
index 00000000..7c7bdb2d
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/WebCommand.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.inno.env.APIException;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+public class WebCommand extends Page {
+ public static final String HREF = "/gui/cui";
+
+ public WebCommand(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env, "Web Command Client",HREF, NO_FIELDS,
+ new BreadCrumbs(breadcrumbs),
+ new NamedCode(true, "content") {
+ @Override
+ public void code(Cache cache, HTMLGen hgen) throws APIException, IOException {
+ hgen.leaf("p","id=help_msg")
+ .text("Questions about this page? ")
+ .leaf("a", "href=http://wiki.web.att.com/display/aaf/Web+CUI+Usage", "target=_blank")
+ .text("Click here")
+ .end()
+ .text(". Type 'help' below for a list of AAF commands")
+ .end()
+
+ .divID("console_and_options");
+ hgen.divID("console_area");
+ hgen.end(); //console_area
+
+ hgen.divID("options_link", "class=closed");
+ hgen.img("src=../../theme/options_down.png", "onclick=handleDivHiding('options',this);",
+ "id=options_img", "alt=Options", "title=Options")
+ .end(); //options_link
+
+ hgen.divID("options");
+ cache.dynamic(hgen, new DynamicCode() {
+ @Override
+ public void code(AuthGUI state, AuthzTrans trans, Cache cache, HTMLGen xgen)
+ throws APIException, IOException {
+ switch(browser(trans,trans.env().slot(getBrowserType()))) {
+ case ie:
+ case ieOld:
+ // IE doesn't support file save
+ break;
+ default:
+ xgen.img("src=../../theme/AAFdownload.png", "onclick=saveToFile();",
+ "alt=Save log to file", "title=Save log to file");
+ }
+// xgen.img("src=../../theme/AAFemail.png", "onclick=emailLog();",
+// "alt=Email log to me", "title=Email log to me");
+ xgen.img("src=../../theme/AAF_font_size.png", "onclick=handleDivHiding('text_slider',this);",
+ "id=fontsize_img", "alt=Change text size", "title=Change text size");
+ xgen.img("src=../../theme/AAF_details.png", "onclick=selectOption(this,0);",
+ "id=details_img", "alt=Turn on/off details mode", "title=Turn on/off details mode");
+ xgen.img("src=../../theme/AAF_maximize.png", "onclick=maximizeConsole(this);",
+ "id=maximize_img", "alt=Maximize Console Window", "title=Maximize Console Window");
+ }
+ });
+
+ hgen.divID("text_slider");
+ hgen.tagOnly("input", "type=button", "class=change_font", "onclick=buttonChangeFontSize('dec')", "value=-")
+ .tagOnly("input", "id=text_size_slider", "type=range", "min=75", "max=200", "value=100",
+ "oninput=changeFontSize(this.value)", "onchange=changeFontSize(this.value)", "title=Change Text Size")
+ .tagOnly("input", "type=button", "class=change_font", "onclick=buttonChangeFontSize('inc')", "value=+")
+ .end(); //text_slider
+
+ hgen.end(); //options
+ hgen.end(); //console_and_options
+
+ hgen.divID("input_area");
+ hgen.tagOnly("input", "type=text", "id=command_field",
+ "autocomplete=off", "autocorrect=off", "autocapitalize=off", "spellcheck=false",
+ "onkeypress=keyPressed()", "placeholder=Type your AAFCLI commands here", "autofocus")
+ .tagOnly("input", "id=submit", "type=button", "value=Submit",
+ "onclick=http('put','../../gui/cui',getCommand(),callCUI);")
+ .end();
+
+ Mark callCUI = new Mark();
+ hgen.js(callCUI);
+ hgen.text("function callCUI(resp) {")
+ .text("moveCommandToDiv();")
+ .text("printResponse(resp);")
+ .text("}");
+ hgen.end(callCUI);
+
+ }
+ });
+
+ }
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/table/AbsCell.java b/authz-gui/src/main/java/com/att/authz/gui/table/AbsCell.java
new file mode 100644
index 00000000..eb91c22a
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/table/AbsCell.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.table;
+
+import com.att.xgen.html.HTMLGen;
+
+public abstract class AbsCell {
+ private static final String[] NONE = new String[0];
+ protected static final String[] CENTER = new String[]{"class=center"};
+
+ /**
+ * Write Cell Data with HTMLGen generator
+ * @param hgen
+ */
+ public abstract void write(HTMLGen hgen);
+
+ public final static AbsCell Null = new AbsCell() {
+ @Override
+ public void write(final HTMLGen hgen) {
+ }
+ };
+
+ public String[] attrs() {
+ return NONE;
+ }
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/table/ButtonCell.java b/authz-gui/src/main/java/com/att/authz/gui/table/ButtonCell.java
new file mode 100644
index 00000000..4c270cfc
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/table/ButtonCell.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.table;
+
+import com.att.xgen.html.HTMLGen;
+
+public class ButtonCell extends AbsCell {
+ private String[] attrs;
+
+ public ButtonCell(String value, String ... attributes) {
+ attrs = new String[2+attributes.length];
+ attrs[0]="type=button";
+ attrs[1]="value="+value;
+ System.arraycopy(attributes, 0, attrs, 2, attributes.length);
+ }
+ @Override
+ public void write(HTMLGen hgen) {
+ hgen.incr("input",true,attrs).end();
+
+ }
+
+ @Override
+ public String[] attrs() {
+ return AbsCell.CENTER;
+ }
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/table/RadioCell.java b/authz-gui/src/main/java/com/att/authz/gui/table/RadioCell.java
new file mode 100644
index 00000000..b4fa6440
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/table/RadioCell.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.table;
+
+import com.att.xgen.html.HTMLGen;
+
+public class RadioCell extends AbsCell {
+ private String[] attrs;
+
+ public RadioCell(String name, String radioClass, String value, String ... attributes) {
+ attrs = new String[4+attributes.length];
+ attrs[0]="type=radio";
+ attrs[1]="name="+name;
+ attrs[2]="class="+radioClass;
+ attrs[3]="value="+value;
+ System.arraycopy(attributes, 0, attrs, 4, attributes.length);
+ }
+
+ @Override
+ public void write(HTMLGen hgen) {
+ hgen.incr("input",true,attrs).end();
+ }
+
+ @Override
+ public String[] attrs() {
+ return AbsCell.CENTER;
+ }
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/table/RefCell.java b/authz-gui/src/main/java/com/att/authz/gui/table/RefCell.java
new file mode 100644
index 00000000..49719837
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/table/RefCell.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.table;
+
+import static com.att.xgen.html.HTMLGen.A;
+
+import com.att.xgen.html.HTMLGen;
+
+/**
+ * Write a Reference Link into a Cell
+ *
+ */
+public class RefCell extends AbsCell {
+ public final String name;
+ public final String href;
+ private String[] attrs;
+
+ public RefCell(String name, String href, String... attributes) {
+ attrs = new String[attributes.length];
+ System.arraycopy(attributes, 0, attrs, 0, attributes.length);
+ this.name = name;
+ this.href = href;
+ }
+
+ @Override
+ public void write(HTMLGen hgen) {
+ hgen.leaf(A,"href="+href).text(name);
+ }
+
+ @Override
+ public String[] attrs() {
+ return attrs;
+ }
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/table/TextAndRefCell.java b/authz-gui/src/main/java/com/att/authz/gui/table/TextAndRefCell.java
new file mode 100644
index 00000000..1c25361b
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/table/TextAndRefCell.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.table;
+
+import static com.att.xgen.html.HTMLGen.A;
+
+import com.att.xgen.html.HTMLGen;
+
+public class TextAndRefCell extends RefCell {
+
+ private String text;
+
+ public TextAndRefCell(String text, String name, String href, String[] attributes) {
+ super(name, href, attributes);
+ this.text = text;
+ }
+
+ @Override
+ public void write(HTMLGen hgen) {
+ hgen.text(text);
+ hgen.leaf(A,"href="+href).text(name);
+ }
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/table/TextCell.java b/authz-gui/src/main/java/com/att/authz/gui/table/TextCell.java
new file mode 100644
index 00000000..d0987920
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/table/TextCell.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.table;
+
+import com.att.xgen.html.HTMLGen;
+
+/**
+ * Write Simple Text into a Cell
+ *
+ */
+public class TextCell extends AbsCell {
+ public final String name;
+ private String[] attrs;
+
+ public TextCell(String name, String... attributes) {
+ attrs = new String[attributes.length];
+ System.arraycopy(attributes, 0, attrs, 0, attributes.length);
+ this.name = name;
+ }
+
+ @Override
+ public void write(HTMLGen hgen) {
+ hgen.text(name);
+ }
+
+ @Override
+ public String[] attrs() {
+ return attrs;
+ }
+}
diff --git a/authz-gui/theme/AAF_details.png b/authz-gui/theme/AAF_details.png
new file mode 100644
index 00000000..5c187459
Binary files /dev/null and b/authz-gui/theme/AAF_details.png differ
diff --git a/authz-gui/theme/AAF_font_size.png b/authz-gui/theme/AAF_font_size.png
new file mode 100644
index 00000000..466cbfbc
Binary files /dev/null and b/authz-gui/theme/AAF_font_size.png differ
diff --git a/authz-gui/theme/AAF_maximize.png b/authz-gui/theme/AAF_maximize.png
new file mode 100644
index 00000000..706603bb
Binary files /dev/null and b/authz-gui/theme/AAF_maximize.png differ
diff --git a/authz-gui/theme/AAFdownload.png b/authz-gui/theme/AAFdownload.png
new file mode 100644
index 00000000..cebd9522
Binary files /dev/null and b/authz-gui/theme/AAFdownload.png differ
diff --git a/authz-gui/theme/AAFemail.png b/authz-gui/theme/AAFemail.png
new file mode 100644
index 00000000..6d487769
Binary files /dev/null and b/authz-gui/theme/AAFemail.png differ
diff --git a/authz-gui/theme/aaf5.css b/authz-gui/theme/aaf5.css
new file mode 100644
index 00000000..920bdab7
--- /dev/null
+++ b/authz-gui/theme/aaf5.css
@@ -0,0 +1,524 @@
+/*
+ Standard CSS for AAF
+*/
+
+html {
+ height: 100%;
+}
+
+body {
+ background-image:url('t_bubbles.jpg');
+ background-color: #FFFFFF;
+ background-repeat:no-repeat;
+ background-position: right top;
+ background-size:15em 4.3em;
+ color:#606060;
+ font-family: Verdana,Arial,Helvetica,sans-serif;
+ overflow: scroll;
+ }
+
+header h1,p {
+ margin: 4px auto;
+}
+
+header h1 {
+ display: inline;
+}
+
+header {
+ display: block;
+ color: #F13099;
+}
+
+p#version {
+ margin:0;
+ display:inline;
+ font-size: 0.75em;
+ float:right;
+ color: orange;
+ padding-right:4.2em;
+}
+
+header hr {
+ margin: 0;
+}
+
+hr {
+ border: 1px solid #C0C0C0;
+}
+
+#breadcrumbs {
+ padding: 5px 0 12px 0;
+}
+
+
+#breadcrumbs ul {
+ color: #DFEFFC;
+ margin: 0;
+ list-style-type:none;
+ padding: 0;
+}
+
+#breadcrumbs li {
+ border-width:2px;
+ margin: 3px 1px;
+ padding: 2px 9px;
+ border-style:solid;
+ border-top-left-radius: .8em;
+ border-bottom-left-radius: .8em;
+ background-color:#80C337;
+ display:inline;
+}
+
+#breadcrumbs a {
+ text-decoration:none;
+ color: white;
+}
+
+caption {
+ color:#FF7241;
+ text-align: center;
+ font-size:1.3em;
+ font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
+}
+
+#Pages {
+ padding: 3px 2px 10px 4px;
+ background: linear-gradient(to right, #147AB3,#FFFFFF);
+}
+
+#Pages h3,
+#Pages h4,
+h5{
+ color: #909090;
+}
+
+form {
+ padding: 10px;
+ margin: 4px;
+}
+
+
+form input[id],select#myroles {
+ margin: 4px 0;
+ width: 150%;
+}
+
+form label {
+ margin: 4px 0;
+}
+
+form label[required] {
+ color: red;
+}
+
+form input[type=submit], form input[type=reset] {
+ font-size: 1.0em;
+ margin: 12px 0 0px 0;
+ color: #F13099;
+}
+
+p.preamble, p.notfound,.expedite_request {
+ display: block;
+ margin: 30px 0px 10px 0px;
+ font: italic bold 20px/30px Georgia, serif;
+ font-size: 110%;
+ color: #0079B8;
+}
+.expedite_request {
+ margin-top: 0;
+ color: #FF7241;
+}
+
+.subtext {
+ margin-left: 10px;
+ font-size: 75%;
+ font-style: italic;
+}
+
+#Pages a {
+ display:block;
+ font-weight:bold;
+ color:#FFFFFF;
+ background-color:#80C337;
+ text-decoration:none;
+ border-top-right-radius: .8em;
+ border-bottom-right-radius: .8em;
+ border-top-left-radius: .2em;
+ border-bottom-left-radius: .2em;
+ padding: 3px 40px 3px 10px;
+ margin: 4px;
+ width: 50%;
+}
+
+#footer {
+ background-color: #FF7200;
+ color: #FFFFFF;
+ text-align:right;
+ font-size: 60%;
+ padding: 5px;
+ position:fixed;
+ bottom: 0px;
+ left: 0px;
+ right: 0px;
+}
+
+/*
+ Standard Table, with Alternating Colors
+*/
+div.std {
+ vertical-align: top;
+}
+
+div.std table, div.stdform table {
+ position: relative;
+ border-collapse:collapse;
+ table-layout:auto;
+ left: 1.3%;
+ width: 98%;
+ margin-top: 5px;
+ bottom: 4px;
+ border-radius: 4px;
+}
+
+div.std td, div.stdform td {
+ font-size:.9em;
+}
+
+.center {
+ text-align: center;
+}
+
+.right {
+ text-align: right;
+ padding-right: 4px;
+}
+
+p.double {
+ line-height: 2em;
+}
+
+p.api_comment {
+ font-size: .9em;
+ text-indent: 6px;
+}
+
+p.api_contentType {
+ font-size: .8em;
+ text-indent: 6px;
+}
+
+p.api_label {
+ font-size: .9em;
+ font-style: italic;
+}
+
+div.std h1, div.std h2, div.std h3, div.std h4, div.std h5 {
+ text-indent: 7px;
+}
+
+div.std td {
+ border:1px solid #A6C9E2;
+}
+
+div.std th, div.stdform th {
+ background-color:#6FA7D1;
+ color:#FFFFFF;
+ }
+
+div.std tr.alt, div.stdform tr.alt {
+ background-color:#DFEFFC;
+}
+
+div.std a, div.stdform a {
+ /*color: #606060;*/
+ color: #147AB3;
+}
+
+td.head {
+ font-weight:bold;
+ text-align: center;
+}
+
+td.head a {
+ color:blue;
+}
+
+/*
+ A Table representing 1 or more columns of text, i.e. Detail lists
+*/
+div.detail table {
+ width: 100%;
+}
+
+div.detail caption {
+ border-bottom: solid 1px #C0C0C0;
+}
+
+/*
+ Approval Form select all
+
+*/
+.selectAllButton {
+ background: transparent;
+ border:none;
+ color:blue;
+ text-decoration:underline;
+ font-weight:bold;
+ cursor:pointer;
+}
+
+
+/*
+ Begin Web Command Styling
+*/
+#console_and_options {
+ position:relative;
+}
+
+.maximized {
+ position:absolute;
+ top:0px;
+ bottom:50px;
+ left:0px;
+ right:0px;
+ z-index:1000;
+ background-color:white;
+}
+
+#console_area {
+ -webkit-border-radius: 15px;
+ -moz-border-radius: 15px;
+ border-radius: 15px;
+ background-color: black;
+ color: white;
+ font-family: "Lucida Console", Monaco, monospace;
+ overflow-y: scroll;
+ height: 300px;
+ min-width: 600px;
+ padding: 5px;
+ resize: vertical;
+}
+
+.command,.bold {
+ font-weight: bold;
+}
+
+.command:before {
+ content: "> ";
+}
+
+.response{
+ font-style: italic;
+ font-size: 150%;
+}
+
+#input_area {
+ margin-top: 10px;
+ clear: both;
+}
+
+#command_field, #submit {
+ font-size: 125%;
+ background-color: #333333;
+ color: white;
+ font-family: "Lucida Console", Monaco, monospace;
+ -webkit-border-radius: 1em;
+ -moz-border-radius: 1em;
+ border-radius: 1em;
+}
+
+#command_field {
+ width: 75%;
+ padding-left: 1em;
+}
+
+#submit {
+ background-color: #80C337;
+ padding: 0 5%;
+ float: right;
+}
+
+/*
+ Options Menu Styling for Web Command
+*/
+#options_link {
+ -webkit-border-radius: 0 0 20% 20%;
+ -moz-border-radius: 0 0 20% 20%;
+ border-radius: 0 0 20% 20%;
+ -webkit-transition: opacity 0.5s ease-in-out;
+ -moz-transition: opacity 0.5s ease-in-out;
+ -ms-transition: opacity 0.5s ease-in-out;
+ -o-transition: opacity 0.5s ease-in-out;
+ transition: opacity 0.5s ease-in-out;
+}
+
+.closed {
+ opacity: 0.5;
+ filter: alpha(opacity=50);
+}
+
+#options_link:hover, .open {
+ opacity: 1.0;
+ filter: alpha(opacity=100);
+}
+
+#options_link, #options {
+ background: white;
+ position:absolute;
+ top:0;
+ right:2em;
+ padding:0.1em;
+}
+
+#options > img {
+ cursor: pointer;
+ float: right;
+ padding: 0.2em;
+}
+
+.selected {
+ border: 3px solid orange;
+}
+
+#options, #text_slider {
+ display:none;
+ padding:0.5em;
+ -webkit-border-radius: 0 0 0 10px;
+ -moz-border-radius: 0 0 0 10px;
+ border-radius: 0 0 0 10px;
+}
+#text_slider {
+ clear:both;
+}
+
+/*
+ Button styling for changing text size
+*/
+.change_font {
+ border-top: 1px solid #96d1f8;
+ background: #65a9d7;
+ background: -webkit-gradient(linear, left top, left bottom, from(#3e779d), to(#65a9d7));
+ background: -webkit-linear-gradient(top, #3e779d, #65a9d7);
+ background: -moz-linear-gradient(top, #3e779d, #65a9d7);
+ background: -ms-linear-gradient(top, #3e779d, #65a9d7);
+ background: -o-linear-gradient(top, #3e779d, #65a9d7);
+ padding: 0 2px;
+ -webkit-border-radius: 50%;
+ -moz-border-radius: 50%;
+ border-radius: 50%;
+ -webkit-box-shadow: rgba(0,0,0,1) 0 1px 0;
+ -moz-box-shadow: rgba(0,0,0,1) 0 1px 0;
+ box-shadow: rgba(0,0,0,1) 0 1px 0;
+ text-shadow: rgba(0,0,0,.4) 0 1px 0;
+ color: white;
+ font-size: 14px;
+ font-family: monospace;
+ text-decoration: none;
+ vertical-align: middle;
+}
+.change_font:hover {
+ border-top-color: #28597a;
+ background: #28597a;
+ color: #ccc;
+}
+
+/*
+ Text Size Slider styling
+*/
+
+input[type=range] {
+ -webkit-appearance: none;
+ width: 60%;
+ margin: 0;
+}
+input[type=range]:focus {
+ outline: none;
+}
+input[type=range]::-webkit-slider-runnable-track {
+ width: 100%;
+ height: 4px;
+ cursor: pointer;
+ box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
+ background: #3071a9;
+ border-radius: 0.6px;
+ border: 0.5px solid #010101;
+}
+input[type=range]::-webkit-slider-thumb {
+ box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
+ border: 1px solid #000000;
+ height: 16px;
+ width: 16px;
+ border-radius: 30px;
+ background: #efffff;
+ cursor: pointer;
+ -webkit-appearance: none;
+ margin-top: -7.15px;
+}
+input[type=range]:focus::-webkit-slider-runnable-track {
+ background: #367ebd;
+}
+input[type=range]::-moz-range-track {
+ width: 100%;
+ height: 2.7px;
+ cursor: pointer;
+ box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
+ background: #3071a9;
+ border-radius: 0.6px;
+ border: 0.5px solid #010101;
+}
+input[type=range]::-moz-range-thumb {
+ box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
+ border: 1px solid #000000;
+ height: 16px;
+ width: 16px;
+ border-radius: 30px;
+ background: #efffff;
+ cursor: pointer;
+}
+input[type=range]::-ms-track {
+ width: 100%;
+ height: 2.7px;
+ cursor: pointer;
+ background: transparent;
+ border-color: transparent;
+ color: transparent;
+}
+input[type=range]::-ms-fill-lower {
+ background: #2a6495;
+ border: 0.5px solid #010101;
+ border-radius: 1.2px;
+ box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
+}
+input[type=range]::-ms-fill-upper {
+ background: #3071a9;
+ border: 0.5px solid #010101;
+ border-radius: 1.2px;
+ box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
+}
+input[type=range]::-ms-thumb {
+ box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
+ border: 1px solid #000000;
+ height: 16px;
+ width: 16px;
+ border-radius: 30px;
+ background: #efffff;
+ cursor: pointer;
+ height: 2.7px;
+}
+input[type=range]:focus::-ms-fill-lower {
+ background: #3071a9;
+}
+input[type=range]:focus::-ms-fill-upper {
+ background: #367ebd;
+}
+.expired {
+ color: red;
+ background-color: pink;
+}
+.blank_line {
+ padding: 10px;
+}
+#filterByUser input {
+ display: inline;
+}
diff --git a/authz-gui/theme/aaf5Desktop.css b/authz-gui/theme/aaf5Desktop.css
new file mode 100644
index 00000000..b4aa02f8
--- /dev/null
+++ b/authz-gui/theme/aaf5Desktop.css
@@ -0,0 +1,92 @@
+/*
+ Modifications for Desktop
+*/
+body {
+ background-size:23em 4.7em;
+}
+
+
+#breadcrumbs a:visited, #breadcrumbs a:link {
+ transition: padding .5s;
+}
+
+#breadcrumbs a:hover {
+ padding: 2px 2px 2px 30px;
+ transition: padding .5s;
+}
+
+#breadcrumbs, #inner {
+ margin: 3px;
+ width: 77%;
+ float: left;
+ min-width:500px;
+ background-color: #FFFFFF;
+
+}
+
+#breadcrumbs li {
+ box-shadow: 3px 3px 2px #888888;
+}
+
+#Pages {
+ margin: 20px;
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#147AB3', endColorstr='#ffffff',GradientType=1 ); /*linear gradient for IE 6-9*/
+}
+
+#Pages a:visited, #Pages a:link {
+ padding: 3px 40px 3px 10px;
+ transition: padding .5s;
+ margin: 6px;
+ box-shadow: 3px 3px 2px #888888;
+}
+
+#Pages a:hover {
+ padding: 4px 80px 4px 15px;
+ transition: box-shadow padding .5s;
+ box-shadow: 4px 4px 3px #888888;
+}
+
+
+#inner {
+ padding: 7px;
+ background: #FFFFFF;
+ overflow: hidden;
+}
+
+div.std, form {
+ border: solid 2px #D0D0D0;
+ border-radius: 5px;
+ box-shadow: 10px 10px 5px #888888;
+}
+
+div.detail {
+ border: solid 2px #C0C0C0;
+ border-radius: 14px;
+ box-shadow: 10px 10px 5px #888888;
+}
+
+#nav {
+ display: inline-block;
+ position: absolute;
+ right: 2%;
+ left: 81%;
+}
+
+#nav h2 {
+ color: #FF7200;
+ font-size: 1.2em;
+ font-family: Verdana,Arial,Helvetica,sans-serif;
+ font-style: italic;
+ font-weight: normal;
+
+}
+
+#nav ul {
+ font-style:italic;
+ font-size: .8em;
+ font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
+ color: #067ab4;
+ list-style-type: square;
+ margin: 0;
+ padding: 0;
+}
diff --git a/authz-gui/theme/aaf5iPhone.css b/authz-gui/theme/aaf5iPhone.css
new file mode 100644
index 00000000..c356983b
--- /dev/null
+++ b/authz-gui/theme/aaf5iPhone.css
@@ -0,0 +1,38 @@
+/*
+ Modifications for iPhone
+*/
+body {
+ zoom: 210%;
+}
+
+#breadcrumbs {
+ font-size: .9em;
+}
+
+
+div.std table {
+ margin: 0 0 20px 0;
+ zoom: 130%
+}
+
+
+div.stdform th {
+ font-size: 9px;
+}
+
+#content input {
+ font-size: 1.3em;
+}
+
+
+#Pages a {
+ font-size: 1.3em;
+ width: 75%;
+ height:35px;
+}
+
+#nav {
+ display: none;
+}
+
+
diff --git a/authz-gui/theme/aafOldIE.css b/authz-gui/theme/aafOldIE.css
new file mode 100644
index 00000000..5910c5cf
--- /dev/null
+++ b/authz-gui/theme/aafOldIE.css
@@ -0,0 +1,162 @@
+/*
+ Modifications for non-html5 IE
+*/
+body {
+ background-size:23em 4.7em;
+}
+
+
+body h1 {
+ margin: 4px auto;
+ color: #F13099;
+}
+
+#footer {
+ background-color: #FF7200;
+ color: #FFFFFF;
+ text-align:right;
+ font-size: 60%;
+ padding: 5px;
+ position:fixed;
+ bottom: 0px;
+ left: 0px;
+ right: 0px;
+}
+
+#breadcrumbs a:visited, #breadcrumbs a:link {
+ transition: padding .5s;
+}
+
+#breadcrumbs a:hover {
+ padding: 2px 2px 2px 30px;
+ transition: padding .5s;
+}
+
+#breadcrumbs, #content {
+ margin: 3px;
+}
+
+#breadcrumbs, #inner {
+ margin: 3px;
+ width: 77%;
+ float: left;
+ min-width:500px;
+ background-color: #FFFFFF;
+}
+
+
+#breadcrumbs li {
+ box-shadow: 3px 3px 2px #888888;
+}
+
+#inner {
+ padding: 10px;
+ overflow: hidden;
+}
+
+#inner form {
+ border: solid 2px #D0D0D0;
+}
+
+#inner form input[id] {
+ margin: 4px 0;
+}
+
+#inner form label {
+ margin: 4px 0;
+}
+
+#inner form label[required] {
+ color: red;
+}
+
+#inner form input[type=submit] {
+ font-size: 1.0em;
+ margin: 12px 0 0px 0;
+ color: #F13099;
+}
+
+p.preamble, p.notfound {
+ display: block;
+ margin: 30px 0px 10px 0px;
+ font: italic bold 20px/30px Georgia, serif;
+ font-size: 110%;
+ color: #0079B8;
+}
+
+
+#Pages {
+ margin: 20px;
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#147AB3', endColorstr='#ffffff',GradientType=1 ); /*linear gradient for IE 6-9*/
+}
+
+#Pages a:visited, #Pages a:link {
+ display: block;
+ padding: 3px 40px 3px 10px;
+ transition: padding .5s;
+ margin: 6px;
+ box-shadow: 3px 3px 2px #888888;
+ background-color: #98bf21;
+ text-decoration: none;
+ color: white;
+ font-weight: bold;
+}
+
+#Pages a:hover {
+ padding: 4px 80px 4px 20px;
+ transition: box-shadow padding 1s;
+ box-shadow: 4px 4px 3px #888888;
+}
+
+tr {
+ font-size: .9em;
+}
+
+tr.alt {
+ background-color: #EEF0F0;
+}
+
+#nav {
+
+ display: block;
+ position: absolute;
+ top: 175px;
+ right: 2%;
+ left: 81%;
+ z-index=1;
+ clear: both;
+}
+
+
+#nav h2 {
+ color: #FF7200;
+ font-size: 1.2em;
+ font-family: Verdana,Arial,Helvetica,sans-serif;
+ font-style: italic;
+ font-weight: normal;
+
+}
+
+#nav ul {
+ font-style:italic;
+ font-size: .8em;
+ font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
+ color: #067ab4;
+ list-style-type: square;
+ margin: 0;
+ padding: 0;
+}
+
+div.std {
+ border: solid 2px #D0D0D0;
+ border-radius: 5px;
+ box-shadow: 10px 10px 5px #888888;
+}
+
+
+div.detail {
+ border: solid 2px #C0C0C0;
+ border-radius: 14px;
+ box-shadow: 10px 10px 5px #888888;
+}
+
diff --git a/authz-gui/theme/aaf_1_0.xsd b/authz-gui/theme/aaf_1_0.xsd
new file mode 100644
index 00000000..a71e2ea1
--- /dev/null
+++ b/authz-gui/theme/aaf_1_0.xsd
@@ -0,0 +1,150 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/authz-gui/theme/aaf_2_0.xsd b/authz-gui/theme/aaf_2_0.xsd
new file mode 100644
index 00000000..95c8ff9e
--- /dev/null
+++ b/authz-gui/theme/aaf_2_0.xsd
@@ -0,0 +1,394 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/authz-gui/theme/comm.js b/authz-gui/theme/comm.js
new file mode 100644
index 00000000..5a1ac4d8
--- /dev/null
+++ b/authz-gui/theme/comm.js
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+function http(meth, sURL, sInput, func) {
+ if (sInput != "") {
+ var http;
+ if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
+ http=new XMLHttpRequest();
+ } else {// code for IE6, IE5
+ http=new ActiveXObject('Microsoft.XMLHTTP');
+ }
+
+ http.onreadystatechange=function() {
+ if(http.readyState==4 && http.status == 200) {
+ func(http.responseText)
+ }
+ // Probably want Exception code too.
+ }
+
+ http.open(meth,sURL,false);
+ http.setRequestHeader('Content-Type','text/plain;charset=UTF-8');
+ http.send(sInput);
+ }
+}
\ No newline at end of file
diff --git a/authz-gui/theme/common.js b/authz-gui/theme/common.js
new file mode 100644
index 00000000..e9af8fef
--- /dev/null
+++ b/authz-gui/theme/common.js
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+Object.defineProperty(Element.prototype, 'outerHeight', {
+ 'get': function(){
+ var height = this.clientHeight;
+ height += getStyle(this,'marginTop');
+ height += getStyle(this,'marginBottom');
+ height += getStyle(this,'borderTopWidth');
+ height += getStyle(this,'borderBottomWidth');
+ return height;
+ }
+});
+
+if (document.addEventListener) {
+ document.addEventListener('DOMContentLoaded', function () {
+ var height = document.querySelector("#footer").outerHeight;
+ document.querySelector("#inner").setAttribute("style",
+ "margin-bottom:" + height.toString()+ "px");
+ });
+} else {
+ window.attachEvent("onload", function () {
+ var height = document.querySelector("#footer").outerHeight;
+ document.querySelector("#inner").setAttribute("style",
+ "margin-bottom:" + height.toString()+ "px");
+ });
+}
+
+
+
+function getStyle(el, prop) {
+ var result = el.currentStyle ? el.currentStyle[prop] :
+ document.defaultView.getComputedStyle(el,"")[prop];
+ if (parseInt(result,10))
+ return parseInt(result,10);
+ else
+ return 0;
+}
+
+function divVisibility(divID) {
+ var element = document.querySelector("#"+divID);
+ if (element.style.display=="block")
+ element.style.display="none";
+ else
+ element.style.display="block";
+}
+
+function datesURL(histPage) {
+ var validated=true;
+ var yearStart = document.querySelector('#yearStart').value;
+ var yearEnd = document.querySelector('#yearEnd').value;
+ var monthStart = document.querySelector('#monthStart').value;
+ var monthEnd = document.querySelector('#monthEnd').value;
+ if (monthStart.length == 1) monthStart = 0 + monthStart;
+ if (monthEnd.length == 1) monthEnd = 0 + monthEnd;
+
+ validated &= validateYear(yearStart);
+ validated &= validateYear(yearEnd);
+ validated &= validateMonth(monthStart);
+ validated &= validateMonth(monthEnd);
+
+ if (validated) window.location=histPage+"&dates="+yearStart+monthStart+"-"+yearEnd+monthEnd;
+ else alert("Please correct your date selections");
+}
+
+function userFilter(approvalPage) {
+ var user = document.querySelector('#userTextBox').value;
+ if (user != "")
+ window.location=approvalPage+"?user="+user;
+ else
+ window.location=approvalPage;
+}
+
+function validateYear(year) {
+ var today = new Date();
+ if (year >= 1900 && year <= today.getFullYear()) return true;
+ else return false;
+}
+
+function validateMonth(month) {
+ if (month) return true;
+ else return false;
+}
+
+function alterLink(breadcrumbToFind, newTarget) {
+ var breadcrumbs = document.querySelector("#breadcrumbs").getElementsByTagName("A");
+ for (var i=0; i< breadcrumbs.length;i++) {
+ var breadcrumbHref = breadcrumbs[i].getAttribute('href');
+ if (breadcrumbHref.indexOf(breadcrumbToFind)>-1)
+ breadcrumbs[i].setAttribute('href', newTarget);
+ }
+}
+
+// clipBoardData object not cross-browser supported. Only IE it seems
+function copyToClipboard(controlId) {
+ var control = document.getElementById(controlId);
+ if (control == null) {
+ alert("ERROR - control not found - " + controlId);
+ } else {
+ var controlValue = control.href;
+ window.clipboardData.setData("text/plain", controlValue);
+ alert("Copied text to clipboard : " + controlValue);
+ }
+}
diff --git a/authz-gui/theme/console.js b/authz-gui/theme/console.js
new file mode 100644
index 00000000..e35becff
--- /dev/null
+++ b/authz-gui/theme/console.js
@@ -0,0 +1,275 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+function getCommand() {
+ if(typeof String.prototype.trim !== 'function') {
+ String.prototype.trim = function() {
+ return this.replace(/^\s+|\s+$/g, '');
+ };
+ }
+
+ var cmds = [];
+ cmds = document.querySelector("#command_field").value.split(" ");
+ var cleanCmd = "";
+ if (document.querySelector("#details_img").getAttribute("class") == "selected")
+ cleanCmd += "set details=true ";
+ for (var i = 0; i < cmds.length;i++) {
+ var trimmed = cmds[i].trim();
+ if (trimmed != "")
+ cleanCmd += trimmed + " ";
+ }
+
+ return cleanCmd.trim();
+}
+
+function moveCommandToDiv() {
+
+ var textInput = document.querySelector("#command_field");
+ var content = document.createTextNode(textInput.value);
+ var parContent = document.createElement("p");
+ var consoleDiv = document.querySelector("#console_area");
+ var commandCount = consoleDiv.querySelectorAll(".command").length;
+ parContent.setAttribute("class", "command");
+ parContent.appendChild(content);
+ consoleDiv.appendChild(parContent);
+
+ textInput.value = "";
+}
+
+function printResponse(response) {
+ var parContent = document.createElement("p");
+ parContent.setAttribute("class", "response");
+ var preTag = document.createElement("pre");
+ parContent.appendChild(preTag);
+ var content = document.createTextNode(response);
+ preTag.appendChild(content);
+ var consoleDiv = document.querySelector("#console_area");
+ consoleDiv.appendChild(parContent);
+
+ consoleDiv.scrollTop = consoleDiv.scrollHeight;
+}
+
+function clearHistory() {
+ var consoleDiv = document.querySelector("#console_area");
+ var curr;
+ while (curr=consoleDiv.firstChild) {
+ consoleDiv.removeChild(curr);
+ }
+ document.querySelector("#command_field").value = "";
+ currentCmd = 0;
+}
+
+function buttonChangeFontSize(direction) {
+ var slider = document.querySelector("#text_size_slider");
+ var currentSize = parseInt(slider.value);
+ var newSize;
+ if (direction == "inc") {
+ newSize = currentSize + 10;
+ } else {
+ newSize = currentSize - 10;
+ }
+ if (newSize > slider.max) newSize = parseInt(slider.max);
+ if (newSize < slider.min) newSize = parseInt(slider.min);
+ slider.value = newSize;
+ changeFontSize(newSize);
+}
+
+function changeFontSize(size) {
+ var consoleDiv = document.querySelector("#console_area");
+ consoleDiv.style.fontSize = size + "%";
+}
+
+function handleDivHiding(id, img) {
+ var options_link = document.querySelector("#options_link");
+ var divHeight = toggleVisibility(document.querySelector("#"+id));
+
+ if (id == 'options') {
+ if (options_link.getAttribute("class") == "open") {
+ changeImg(document.querySelector("#options_img"), "../../theme/options_down.png");
+ options_link.setAttribute("class", "closed");
+ } else {
+ changeImg(document.querySelector("#options_img"), "../../theme/options_up.png");
+ options_link.setAttribute("class", "open");
+ }
+ moveToggleImg(options_link, divHeight);
+ } else { //id=text_slider
+ selectOption(img,divHeight);
+ }
+
+}
+
+function selectOption(img, divHeight) {
+ var options_link = document.querySelector("#options_link");
+ var anySelected;
+ if (img.getAttribute("class") != "selected") {
+ anySelected = document.querySelectorAll(".selected").length>0;
+ if (anySelected == false)
+ divHeight += 4;
+ img.setAttribute("class", "selected");
+ } else {
+ img.setAttribute("class", "");
+ anySelected = document.querySelectorAll(".selected").length>0;
+ if (anySelected == false)
+ divHeight -= 4;
+
+ }
+
+ moveToggleImg(options_link, divHeight);
+}
+
+function toggleVisibility(element) {
+ var divHeight;
+ if(element.style.display == 'block') {
+ divHeight = 0 - element.clientHeight;
+ element.style.display = 'none';
+ } else {
+ element.style.display = 'block';
+ divHeight = element.clientHeight;
+ }
+ return divHeight;
+}
+
+function moveToggleImg(element, height) {
+ var curTop = (element.style.top == "" ? 0 : parseInt(element.style.top));
+ element.style.top = curTop + height;
+}
+
+function changeImg(img, loc) {
+ img.src = loc;
+}
+
+var currentCmd = 0;
+function keyPressed() {
+ document.querySelector("#command_field").onkeyup=function(e) {
+ if (!e) e = window.event;
+ var keyCode = e.which || e.keyCode;
+ if (keyCode == 38 || keyCode == 40 || keyCode == 13 || keyCode == 27) {
+ var cmdHistoryList = document.querySelectorAll(".command");
+ switch (keyCode) {
+ case 13:
+ // press enter
+
+ if (getCommand().toLowerCase()=="clear") {
+ clearHistory();
+ } else {
+ currentCmd = cmdHistoryList.length + 1;
+ document.querySelector("#submit").click();
+ }
+ break;
+
+ case 27:
+ //press escape
+ currentCmd = cmdHistoryList.length;
+ document.querySelector("#command_field").value = "";
+ break;
+
+ case 38:
+ // press arrow up
+ if (currentCmd != 0)
+ currentCmd -= 1;
+ if (cmdHistoryList.length != 0)
+ document.querySelector("#command_field").value = cmdHistoryList[currentCmd].innerHTML;
+ break;
+ case 40:
+ // press arrow down
+ var cmdText = "";
+ currentCmd = (currentCmd == cmdHistoryList.length) ? currentCmd : currentCmd + 1;
+ if (currentCmd < cmdHistoryList.length)
+ cmdText = cmdHistoryList[currentCmd].innerHTML;
+
+ document.querySelector("#command_field").value = cmdText;
+ break;
+ }
+ }
+ }
+}
+
+function saveToFile() {
+ var commands = document.querySelectorAll(".command");
+ var responses = document.querySelectorAll(".response");
+ var textToWrite = "";
+ for (var i = 0; i < commands.length; i++) {
+ textToWrite += "> " + commands[i].innerHTML + "\r\n";
+ textToWrite += prettyResponse(responses[i].firstChild.innerHTML);
+ }
+
+ var ie = navigator.userAgent.match(/MSIE\s([\d.]+)/);
+ var ie11 = navigator.userAgent.match(/Trident\/7.0/) && navigator.userAgent.match(/rv:11/);
+ var ieVer=(ie ? ie[1] : (ie11 ? 11 : -1));
+
+// if (ie && ieVer<10) {
+// console.log("No blobs on IE ver<10");
+// return;
+// }
+
+ var textFileAsBlob = new Blob([textToWrite], {type:'text/plain'});
+ var fileName = "AAFcommands.log";
+
+ if (ieVer >= 10) {
+// window.navigator.msSaveBlob(textFileAsBlob, fileName);
+ window.navigator.msSaveOrOpenBlob(textFileAsBlob, fileName);
+ } else {
+ var downloadLink = document.createElement("a");
+ downloadLink.download = fileName;
+ downloadLink.innerHTML = "Download File";
+ if (window.webkitURL != null) {
+ // Chrome allows the link to be clicked
+ // without actually adding it to the DOM.
+ downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
+ } else {
+ // Firefox requires the link to be added to the DOM
+ // before it can be clicked.
+ downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
+ downloadLink.onclick = destroyClickedElement;
+ downloadLink.style.display = "none";
+ document.body.appendChild(downloadLink);
+ }
+
+ downloadLink.click();
+ }
+}
+
+function prettyResponse(response) {
+ var lines = response.split('\n');
+ var cleanResponse = "";
+ for (var i=0; i < lines.length; i++) {
+ cleanResponse += lines[i] + "\r\n";
+ }
+ cleanResponse = cleanResponse.replace(/(<)/g,"<").replace(/(>)/g,">");
+ return cleanResponse;
+}
+
+function destroyClickedElement(event){
+ document.body.removeChild(event.target);
+}
+
+function fakePlaceholder() {
+ document.querySelector("#command_field").setAttribute("value", "Type your AAFCLI commands here");
+}
+
+function maximizeConsole(img) {
+ var footer = document.querySelector("#footer");
+ var console_area = document.querySelector("#console_area");
+ var content = document.querySelector("#content");
+ var input_area = document.querySelector("#input_area");
+ var help_msg = document.querySelector("#help_msg");
+ var console_space = document.documentElement.clientHeight;
+ console_space -= input_area.outerHeight;
+ console_space -= help_msg.outerHeight;
+ var height = getStyle(console_area,'paddingTop') + getStyle(console_area,'paddingBottom');
+ console_space -= height;
+
+
+ if (content.getAttribute("class") != "maximized") {
+ content.setAttribute("class", "maximized");
+ footer.style.display="none";
+ console_area.style.resize="none";
+ console_area.style.height=console_space.toString()+"px";
+ } else {
+ content.removeAttribute("class");
+ footer.style.display="";
+ console_area.style.resize="vertical";
+ console_area.style.height="300px";
+ }
+ selectOption(img,0);
+}
diff --git a/authz-gui/theme/favicon.ico b/authz-gui/theme/favicon.ico
new file mode 100644
index 00000000..3aea2722
Binary files /dev/null and b/authz-gui/theme/favicon.ico differ
diff --git a/authz-gui/theme/options_down.png b/authz-gui/theme/options_down.png
new file mode 100644
index 00000000..a20e8269
Binary files /dev/null and b/authz-gui/theme/options_down.png differ
diff --git a/authz-gui/theme/options_up.png b/authz-gui/theme/options_up.png
new file mode 100644
index 00000000..7414dab5
Binary files /dev/null and b/authz-gui/theme/options_up.png differ
diff --git a/authz-gui/theme/t_bubbles.jpg b/authz-gui/theme/t_bubbles.jpg
new file mode 100644
index 00000000..ecff55ea
Binary files /dev/null and b/authz-gui/theme/t_bubbles.jpg differ
--
cgit 1.2.3-korg