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.security.cert.Certificate;
28 import java.security.cert.CertificateException;
29 import java.security.cert.X509Certificate;
30 import java.util.ArrayList;
31 import java.util.Collection;
32 import java.util.Date;
33 import java.util.GregorianCalendar;
35 import org.onap.aaf.auth.cmd.AAFcli;
36 import org.onap.aaf.auth.env.AuthzEnv;
37 import org.onap.aaf.auth.env.AuthzTrans;
38 import org.onap.aaf.auth.gui.AAF_GUI;
39 import org.onap.aaf.auth.gui.BreadCrumbs;
40 import org.onap.aaf.auth.gui.Page;
41 import org.onap.aaf.auth.gui.SlotCode;
42 import org.onap.aaf.auth.gui.Table;
43 import org.onap.aaf.auth.gui.Table.Cells;
44 import org.onap.aaf.auth.gui.table.AbsCell;
45 import org.onap.aaf.auth.gui.table.TextCell;
46 import org.onap.aaf.cadi.CadiException;
47 import org.onap.aaf.cadi.client.Future;
48 import org.onap.aaf.cadi.client.Rcli;
49 import org.onap.aaf.cadi.client.Retryable;
50 import org.onap.aaf.cadi.configure.Factory;
51 import org.onap.aaf.cadi.util.FQI;
52 import org.onap.aaf.misc.env.APIException;
53 import org.onap.aaf.misc.env.Env;
54 import org.onap.aaf.misc.env.TimeTaken;
55 import org.onap.aaf.misc.env.util.Chrono;
56 import org.onap.aaf.misc.xgen.Cache;
57 import org.onap.aaf.misc.xgen.DynamicCode;
58 import org.onap.aaf.misc.xgen.Mark;
59 import org.onap.aaf.misc.xgen.html.HTMLGen;
61 import certman.v1_0.Artifacts;
62 import certman.v1_0.Artifacts.Artifact;
63 import certman.v1_0.CertInfo;
65 public class CMArtifactShow extends Page {
67 public static final String HREF = "/gui/cmarti";
68 public static final String NAME = "ArtifactsShow";
69 private static ArtiTable arti;
70 public static SlotCode<AuthzTrans> slotCode;
71 private enum Params{id,ns};
74 public CMArtifactShow(final AAF_GUI gui, Page ... breadcrumbs) throws APIException, IOException {
75 super(gui.env, NAME, HREF, Params.values() ,
76 new BreadCrumbs(breadcrumbs),
77 arti = new ArtiTable(gui.env)
79 // Setting so we can get access to HTMLGen clone and Slots
80 arti.set(this,slotCode);
83 private static class ArtiTable extends Table<AAF_GUI, AuthzTrans> {
84 private static Model model;
85 private SlotCode<AuthzTrans> sc;
87 public ArtiTable(AuthzEnv env) {
88 super((String)null,env.newTransNoAvg(),model = new Model(),
89 slotCode = new SlotCode<AuthzTrans>(false,env,NAME,Params.values()) {
91 public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
92 cache.dynamic(hgen, new DynamicCode<HTMLGen,AAF_GUI,AuthzTrans>() {
94 public void code(AAF_GUI state, AuthzTrans trans, final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
96 hgen.js(js).function("newArtifact")
97 .text("machine=document.getElementById('machine');")
99 +CMArtiChangeForm.HREF+
100 "?id="+get(trans, Params.id,"")+
101 "&ns="+get(trans, Params.ns,"")+
102 "&machine='+machine.value,'_self');"
104 hgen.leaf("input","id=machine","style=margin:1em 1em 1em 1em;width:30%").end();
105 hgen.leaf(HTMLGen.A,"class=greenbutton","href=javascript:newArtifact()","style=color:white;").text("New FQDN").end();
113 public void set(CMArtifactShow cmArtifactShow, SlotCode<AuthzTrans> sc) {
115 model.set(cmArtifactShow,sc);
119 protected String title(AuthzTrans trans) {
120 StringBuilder sb = new StringBuilder("X509 Certificates");
121 if (sc!=null) { // initialized
123 String id = sc.get(trans,Params.id,"");
125 if (id.indexOf('@')<0) {
127 sb.append(FQI.reverseDomain(sc.get(trans, Params.ns,"missingDomain")));
130 return sb.toString();
134 * Implement the table content for Cred Detail
139 private static class Model implements Table.Data<AAF_GUI,AuthzTrans> {
140 private CMArtifactShow cas;
141 private SlotCode<AuthzTrans> sc;
143 // Covering for Constructor Order
144 private void set(CMArtifactShow cas, SlotCode<AuthzTrans> sc) {
149 private static final String[] headers = new String[]{"FQDN","Directory","CA","Renews","Expires",""};
151 public String[] headers() {
156 public Cells get(final AuthzTrans trans, final AAF_GUI gui) {
157 String str = sc.get(trans,Params.id, null);
161 final String id = str.indexOf('@')>=0?str:str + '@' + FQI.reverseDomain(sc.get(trans,Params.ns, ""));
162 final ArrayList<AbsCell[]> rv = new ArrayList<>();
163 final TimeTaken tt = trans.start("AAF X509 Details",Env.REMOTE);
165 gui.cmClientAsUser(trans.getUserPrincipal(),new Retryable<Void>() {
167 public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {
168 Future<CertInfo> fuCI = client.read("/cert/id/"+id,gui.certInfoDF);
169 Future<Artifacts> fuArt = client.read("/cert/artifacts?mechid="+id, gui.artifactsDF);
171 X509Certificate[] lc;
172 if (fuCI.get(AAFcli.timeout())) {
173 TimeTaken tt1 = trans.start("x509Certificate", Env.SUB);
175 Collection<? extends Certificate> xcs = Factory.toX509Certificate(fuCI.value.getCerts());
176 lc = new X509Certificate[xcs.size()];
178 } catch (CertificateException e) {
179 trans.error().log(e,"Bad Certificate entry");
180 throw new CadiException(e);
186 trans.error().log("Cannot retrieve Certificates for " + id);
188 if (fuArt.get(AAFcli.timeout())) {
189 for (Artifact arti : fuArt.value.getArtifact()) {
190 StringWriter sw = new StringWriter();
191 HTMLGen hgen = cas.clone(sw);
192 Mark mark = new Mark();
193 hgen.leaf(HTMLGen.A,"class=button",
194 "href="+CMArtiChangeForm.HREF+"?id="+arti.getMechid() +"&machine="+arti.getMachine()+"&ns="+arti.getNs())
199 for (X509Certificate xc : lc) {
200 if (xc.getSubjectDN().getName().contains("CN="+arti.getMachine())) {
201 if (last==null || last.before(xc.getNotAfter())) {
202 last = xc.getNotAfter();
207 GregorianCalendar renew;
209 renew = new GregorianCalendar();
211 renew.add(GregorianCalendar.DAY_OF_MONTH,arti.getRenewDays()*-1);
216 rv.add(new AbsCell[] {
217 new TextCell(arti.getMachine(),"style=width:20%;"),
218 new TextCell(arti.getDir(),"style=width:25%;"),
219 new TextCell(arti.getCa(),"style=width:2%;text-align:center;"),
220 new TextCell(renew==null?
221 arti.getRenewDays().toString() + " days before Exp":
222 Chrono.dateOnlyStamp(renew),"style=width:6%;text-align:center;"),
223 new TextCell(last==null?"None Deployed":Chrono.dateOnlyStamp(last),"style=width:5%;text-align:center;"),
224 new TextCell(sw.toString(),"style=width:10%;text-align:center;")
228 rv.add(new AbsCell[] {new TextCell("*** Data Unavailable ***")});
233 } catch (Exception e) {
238 return new Cells(rv,null);
242 public void prefix(AAF_GUI state, AuthzTrans trans, final Cache<HTMLGen> cache, final HTMLGen hgen) {
246 public void postfix(AAF_GUI state, AuthzTrans trans, final Cache<HTMLGen> cache, final HTMLGen hgen) {