2 * ============LICENSE_START====================================================
4 * ===========================================================================
5 * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6 * ===========================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END====================================================
22 package org.onap.aaf.auth.gui.pages;
24 import java.io.IOException;
25 import java.io.StringWriter;
26 import java.net.ConnectException;
27 import java.util.ArrayList;
28 import java.util.Collections;
29 import java.util.Comparator;
30 import java.util.HashMap;
31 import java.util.HashSet;
32 import java.util.List;
34 import java.util.Map.Entry;
37 import javax.xml.datatype.XMLGregorianCalendar;
39 import org.onap.aaf.auth.cmd.AAFcli;
40 import org.onap.aaf.auth.env.AuthzTrans;
41 import org.onap.aaf.auth.gui.AAF_GUI;
42 import org.onap.aaf.auth.gui.BreadCrumbs;
43 import org.onap.aaf.auth.gui.Page;
44 import org.onap.aaf.auth.gui.SlotCode;
45 import org.onap.aaf.auth.gui.Table;
46 import org.onap.aaf.auth.gui.Table.Cells;
47 import org.onap.aaf.auth.gui.table.AbsCell;
48 import org.onap.aaf.auth.gui.table.TableData;
49 import org.onap.aaf.auth.gui.table.TextCell;
50 import org.onap.aaf.cadi.CadiException;
51 import org.onap.aaf.cadi.client.Future;
52 import org.onap.aaf.cadi.client.Rcli;
53 import org.onap.aaf.cadi.client.Retryable;
54 import org.onap.aaf.cadi.util.FQI;
55 import org.onap.aaf.misc.env.APIException;
56 import org.onap.aaf.misc.env.Env;
57 import org.onap.aaf.misc.env.TimeTaken;
58 import org.onap.aaf.misc.env.util.Chrono;
59 import org.onap.aaf.misc.xgen.Cache;
60 import org.onap.aaf.misc.xgen.DynamicCode;
61 import org.onap.aaf.misc.xgen.Mark;
62 import org.onap.aaf.misc.xgen.html.HTMLGen;
64 import aaf.v2_0.Users;
65 import aaf.v2_0.Users.User;
66 import certman.v1_0.Artifacts;
67 import certman.v1_0.Artifacts.Artifact;
69 public class CredDetail extends Page {
71 public static final String HREF = "/gui/creddetail";
72 public static final String NAME = "CredDetail";
73 private static Model model;
74 private static SlotCode<AuthzTrans> slotCode;
78 public CredDetail(final AAF_GUI gui, Page ... breadcrumbs) throws APIException, IOException {
79 super(gui.env, NAME, HREF, Params.values(),
80 new BreadCrumbs(breadcrumbs),
81 new Table<AAF_GUI,AuthzTrans>("Cred Details",gui.env.newTransNoAvg(),model = new Model(),
82 slotCode = new SlotCode<AuthzTrans>(false,gui.env,NAME,Params.values()) {
84 public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
85 cache.dynamic(hgen, new DynamicCode<HTMLGen,AAF_GUI,AuthzTrans>() {
87 public void code(AAF_GUI state, AuthzTrans trans, final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
88 String ns = get(trans, Params.ns,"");
89 String domain = FQI.reverseDomain(ns);
90 Mark js = new Mark(), fn=new Mark();
91 hgen.js(js).function(fn,"newArtifact")
92 .text("id=document.getElementById('id');")
93 .text("if (id.value=='') {alert('Enter the id in box');} else {")
94 .text("window.open('"+CMArtiChangeForm.HREF+"?id='+id.value+'&ns="+ns+"','_self');}"
97 .function("newPassword")
98 .text("id=document.getElementById('id');")
99 .text("if (id.value=='') {alert('Enter the id in box');} else {")
100 .text("window.open('"+PassChangeForm.HREF+"?id='+id.value+'@"+domain+"&ns="+ns+"','_self');}"
103 hgen.leaf("i","style=margin:1em 0em 1em 1em;").text("ID:").end()
104 .leaf("input","id=id","style=width:10%;").end().text("@").text(domain).br()
105 .leaf(HTMLGen.A,"class=greenbutton","href=javascript:newArtifact()","style=color:white;margin:1.2em 0em 1em 1em;").text("As Cert Artifact").end()
106 .leaf(HTMLGen.A,"class=greenbutton","href=javascript:newPassword()","style=color:white;margin:1.2em 0em 1em 1em;").text("w/Password").end()
114 // Setting so we can get access to HTMLGen clone
115 model.set(this,slotCode);
121 * Implement the table content for Cred Detail
126 private static class Model extends TableData<AAF_GUI,AuthzTrans> {
127 private static final String STYLE_WIDTH_5 = "style=width:5%;";
128 private static final String STYLE_WIDTH_10 = "style=width:10%;";
129 private static final String STYLE_WIDTH_15 = "style=width:15%;";
130 private static final String STYLE_WIDTH_20 = "style=width:20%;";
131 private static final String STYLE_WIDTH_70 = "style=width:70%;";
132 private SlotCode<AuthzTrans> sc;
133 private CredDetail cd;
134 // Covering for Constructor Order
135 private void set(CredDetail credDetail, SlotCode<AuthzTrans> slotCode) {
141 public void prefix(AAF_GUI state, AuthzTrans trans, final Cache<HTMLGen> cache, final HTMLGen hgen) {
145 public Cells get(final AuthzTrans trans, final AAF_GUI gui) {
146 final String ns = sc.get(trans, Params.ns, "");
147 final String id = sc.get(trans, Params.id, "");
151 final ArrayList<AbsCell[]> rv = new ArrayList<>();
152 final TimeTaken tt = trans.start("AAF Cred Details",Env.REMOTE);
155 la = gui.cmClientAsUser(trans.getUserPrincipal(), new Retryable<List<Artifact>>() {
157 public List<Artifact> code(Rcli<?> client)throws CadiException, ConnectException, APIException {
158 Future<Artifacts> fa = client.read("/cert/artifacts?ns="+ns,gui.artifactsDF);
159 if (fa.get(AAFcli.timeout())) {
160 return fa.value.getArtifact();
167 final Set<String> lns = new HashSet<>();
169 for (Artifact a : la){
170 lns.add(a.getMechid());
173 gui.clientAsUser(trans.getUserPrincipal(),new Retryable<Void>() {
175 public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {
176 Future<Users> fu = client.read("/authn/creds/ns/"+ns,gui.getDF(Users.class));
177 if (fu.get(AAFcli.timeout())) {
178 // Organize User entries
179 Map<String,List<Map<Integer,List<User>>>> users = new HashMap<>();
181 List<Map<Integer,List<User>>> lmu=null;
182 Map<Integer, List<User>> mu = null;
183 List<User> lu = null;
185 for (User u : fu.value.getUser()) {
186 if (u.getType() == 200) {
187 lns.remove(u.getId());
189 lmu = users.get(u.getId());
191 lmu=new ArrayList<>();
192 users.put(u.getId(),lmu);
195 for (Map<Integer,List<User>> xmu : lmu) {
196 if (xmu.containsKey(u.getType())) {
206 lu = mu.get(u.getType());
208 lu = new ArrayList<>();
209 mu.put(u.getType(),lu);
215 for (Entry<String, List<Map<Integer, List<User>>>> ulm : users.entrySet()) {
216 String key = "cred_"+count++;
217 StringWriter buttons = new StringWriter();
218 HTMLGen hgen = cd.clone(buttons);
219 hgen.leaf("button","onclick=divVisibility('"+key+"');","class=button").text("Expand").end();
220 hgen.leaf(HTMLGen.A,"class=button","class=greenbutton","href="+CredHistory.HREF+"?user="+ulm.getKey()).text("History").end();
222 StringWriter creds = new StringWriter();
223 hgen = cd.clone(creds);
224 Mark div = hgen.divID(key,ulm.getKey().equals(id)?"":"style=display:none;");
225 for (Map<Integer, List<User>> miu : ulm.getValue()) {
226 Mark utable = new Mark();
227 hgen.leaf(utable,HTMLGen.TABLE);
229 Mark uRow = new Mark();
231 boolean first = true;
233 for ( Entry<Integer, List<User>> es : miu.entrySet()) {
234 Collections.sort(es.getValue(),new Comparator<User>() {
236 public int compare(User u1, User u2) {
237 int rv = u1.getType().compareTo(u2.getType());
238 return rv==0?u2.getExpires().compare(u1.getExpires()):rv;
242 XMLGregorianCalendar oldest=null, newest=null;
244 for (User u: es.getValue()) {
248 // Need to compile entries for Certificates on this screen
249 if (es.getKey()==200) {
251 if (oldest==null || oldest.compare(u.getExpires())<0) {
252 oldest = u.getExpires();
254 if (newest==null || newest.compare(u.getExpires())<0) {
255 newest = u.getExpires();
258 hgen.leaf(uRow,HTMLGen.TR);
260 hgen.leaf(HTMLGen.TD,cls="class=detailFirst",STYLE_WIDTH_10);
261 switch(es.getKey()) {
263 case 2: hgen.text("Password");
265 case 10: hgen.text("Certificate"); break;
268 hgen.leaf(HTMLGen.TD,cls="class=detail",STYLE_WIDTH_10+"text-align:center;").text("\"");
271 hgen.incr(HTMLGen.TD,cls,STYLE_WIDTH_20);
275 "href="+PassDeleteAction.HREF+
278 "&date="+u.getExpires().toXMLFormat() +
279 "&type="+u.getType())
280 .text("Delete").end();
281 if (first && es.getKey()<10) { // Change Password Screen
282 hgen.leaf(HTMLGen.A,"class=button","href="+PassChangeForm.HREF+"?id="+id+"&ns="+ns)
287 hgen.end().leaf(HTMLGen.TD,cls,STYLE_WIDTH_70)
288 .text(Chrono.niceDateStamp(u.getExpires()) + ", TAG ID: " + u.getTag())
294 if (xcnt>0) { // print compilations, if any, of Certificate
295 hgen.leaf(uRow,HTMLGen.TR)
296 .leaf(HTMLGen.TD,cls="class=detailFirst",STYLE_WIDTH_10).text("x509").end()
297 .leaf(HTMLGen.TD, cls,STYLE_WIDTH_20)
298 .leaf(HTMLGen.A,"class=button","href="+CMArtifactShow.HREF+"?id="+id+"&ns="+ns)
301 .leaf(HTMLGen.TD, cls,STYLE_WIDTH_70).text(String.format(
302 xcnt>0?"%d Certificate%s, ranging from %s to %s"
306 Chrono.niceDateStamp(oldest),
307 Chrono.niceDateStamp(newest)))
318 rv.add(new AbsCell[] {
319 new TextCell(ulm.getKey(),STYLE_WIDTH_15),
320 new TextCell(buttons.toString(),STYLE_WIDTH_5),
321 new TextCell(creds.toString(),STYLE_WIDTH_70)
325 for (String missing : lns) {
326 StringWriter buttons = new StringWriter();
327 HTMLGen hgen = cd.clone(buttons);
328 hgen.leaf(HTMLGen.A,"class=button","href="+CMArtifactShow.HREF+"?id="+missing+"&ns="+ns)
331 rv.add(new AbsCell[] {
332 new TextCell(missing,STYLE_WIDTH_15),
333 new TextCell(buttons.toString(),STYLE_WIDTH_5),
334 new TextCell("No X509 Credential Instantiated")
339 rv.add(new AbsCell[] {new TextCell("*** Data Unavailable ***")});
344 } catch (Exception e) {
349 return new Cells(rv,null);
353 public void postfix(AAF_GUI state, AuthzTrans trans, final Cache<HTMLGen> cache, final HTMLGen hgen) {