diff options
author | Instrumental <jonathan.gathman@att.com> | 2019-02-10 09:54:15 -0600 |
---|---|---|
committer | Instrumental <jonathan.gathman@att.com> | 2019-02-10 10:09:21 -0600 |
commit | b24f7e097f17761a5c1b02c4dbfe6ee7d78836dd (patch) | |
tree | 74d883936a21a07a2e0c718ec6a7f456b4d18cab /auth/auth-batch/src/main/java/org | |
parent | 39596f5b6d2c67d8c2b357243ecfb2dd6d746796 (diff) |
Add Cred Reporting Mailer
Issue-ID: AAF-740,AAF-753,AAF-754
Change-Id: If2efc6ffbfa9897581ea00eb148fa61d793b058e
Signed-off-by: Instrumental <jonathan.gathman@att.com>
Diffstat (limited to 'auth/auth-batch/src/main/java/org')
7 files changed, 176 insertions, 79 deletions
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/Batch.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/Batch.java index 543564d9..1c65c058 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/Batch.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/Batch.java @@ -90,6 +90,7 @@ public abstract class Batch { public static final String GUI_URL="GUI_URL"; protected final Organization org; + protected String version; protected Batch(AuthzEnv env) throws APIException, IOException, OrganizationException { if (batchEnv != null) { @@ -143,6 +144,8 @@ public abstract class Batch { } } } + + version = env.getProperty(VERSION,Config.AAF_DEFAULT_API_VERSION); } protected abstract void run(AuthzTrans trans); diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/approvalsets/URApprovalSet.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/approvalsets/URApprovalSet.java index b6767d4a..e1c75bf3 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/approvalsets/URApprovalSet.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/approvalsets/URApprovalSet.java @@ -55,7 +55,7 @@ public class URApprovalSet extends ApprovalSet { } Result<NsDAO.Data> n = dv.ns(trans, urdd.ns); if(n.notOKorIsEmpty()) { - throw new CadiException(String.format("Namespace '%s' does not exist: %s", urdd.ns)); + throw new CadiException(String.format("Namespace '%s' does not exist: %s", urdd.ns,r.details)); } UserRoleDAO.Data found = null; Result<List<Data>> lur = dv.ursByRole(trans, urdd.role); @@ -68,7 +68,7 @@ public class URApprovalSet extends ApprovalSet { } } if(found==null) { - throw new CadiException(String.format("User '%s' in Role '%s' does not exist: %s", urdd.user,urdd.role)); + throw new CadiException(String.format("User '%s' in Role '%s' does not exist: %s", urdd.user,urdd.role,r.details)); } // Primarily, Owners are responsible, unless it's owned by self diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Cred.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Cred.java index c4a9b0db..8a5dfea1 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Cred.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Cred.java @@ -62,16 +62,23 @@ public class Cred { public final int type; public final Date expires,written; public final Integer other; + public final String tag; + public final Integer attn; + public final String notes; + - public Instance(int type, Date expires, Integer other, long written) { + public Instance(int type, Date expires, Integer other, long written, String tag, int attn, String notes) { this.type = type; this.expires = expires; this.other = other; this.written = new Date(written); + this.tag = tag; + this.attn = attn; + this.notes = notes; } public String toString() { - return expires.toString() + ": " + type; + return expires.toString() + ": " + type + ' ' + notes; } } @@ -107,12 +114,12 @@ public class Cred { } public static void load(Trans trans, Session session, int ... types ) { - load(trans, session,"select id, type, expires, other, writetime(cred) from authz.cred;",types); + load(trans, session,"select id, type, expires, other, writetime(cred), tag, attn, notes from authz.cred;",types); } public static void loadOneNS(Trans trans, Session session, String ns,int ... types ) { - load(trans, session,"select id, type, expires, other, writetime(cred) from authz.cred WHERE ns='" + ns + "';"); + load(trans, session,"select id, type, expires, other, writetime(cred), tag, attn, notes from authz.cred WHERE ns='" + ns + "';"); } private static void load(Trans trans, Session session, String query, int ...types) { @@ -149,7 +156,8 @@ public class Cred { continue; } } - add(row.getString(0), row.getInt(1),row.getTimestamp(2),row.getInt(3),row.getLong(4)); + add(row.getString(0), row.getInt(1),row.getTimestamp(2),row.getInt(3),row.getLong(4), + row.getString(5),row.getInt(6),row.getString(7)); } } finally { tt.done(); @@ -164,14 +172,17 @@ public class Cred { final int type, final Date timestamp, final int other, - final long written + final long written, + final String tag, + final int attn, + final String notes ) { Cred cred = data.get(id); if (cred==null) { cred = new Cred(id); data.put(id, cred); } - cred.instances.add(new Instance(type, timestamp, other, written/1000)); + cred.instances.add(new Instance(type, timestamp, other, written/1000,tag,attn,notes)); List<Cred> lscd = byNS.get(cred.ns); if (lscd==null) { @@ -277,7 +288,8 @@ public class Cred { } public void row(final CSV.Writer csvw, final Instance inst) { - csvw.row("cred",id,ns,Integer.toString(inst.type),Chrono.dateOnlyStamp(inst.expires),inst.expires.getTime()); + csvw.row("cred",id,ns,Integer.toString(inst.type),Chrono.dateOnlyStamp(inst.expires), + inst.expires.getTime(),inst.tag,inst.attn,inst.notes); } diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/Notify.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/Notify.java index f8d98882..7fd26747 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/Notify.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/Notify.java @@ -21,7 +21,6 @@ import java.io.BufferedReader; import java.io.File; -import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; import java.lang.reflect.Constructor; @@ -42,22 +41,29 @@ import org.onap.aaf.cadi.CadiException; import org.onap.aaf.cadi.client.Holder; import org.onap.aaf.cadi.util.CSV; import org.onap.aaf.misc.env.APIException; +import org.onap.aaf.misc.env.util.Chrono; public class Notify extends Batch { + private static final String HTML_CSS = "HTML_CSS"; private final Mailer mailer; - private final String mailFrom; private final String header; private final String footer; private List<File> notifyFile; + public final String guiURL; + private int maxEmails; + private int indent; public Notify(AuthzTrans trans) throws APIException, IOException, OrganizationException { super(trans.env()); String mailerCls = env.getProperty("MAILER"); - mailFrom = env.getProperty("MAIL_FROM"); + String mailFrom = env.getProperty("MAIL_FROM"); String header_html = env.getProperty("HEADER_HTML"); String footer_html = env.getProperty("FOOTER_HTML"); - if(mailerCls==null || mailFrom==null || header_html==null || footer_html==null) { - throw new APIException("Notify requires MAILER, MAILER_FROM, HEADER_HTML and FOOTER_HTML properties"); + String maxEmails = env.getProperty("MAX_EMAIL"); + guiURL = env.getProperty("GUI_URL"); + this.maxEmails = maxEmails==null?1:Integer.parseInt(maxEmails); + if(mailerCls==null || mailFrom==null || guiURL==null || header_html==null || footer_html==null) { + throw new APIException("Notify requires MAILER, MAILER_FROM, GUI_URL, HEADER_HTML and FOOTER_HTML properties"); } try { Class<?> mailc = Class.forName(mailerCls); @@ -75,11 +81,32 @@ public class Notify extends Batch { sb.append(line); sb.append('\n'); } - header = sb.toString(); + String html_css = env.getProperty(HTML_CSS); + int hc = sb.indexOf(HTML_CSS); + if(hc!=0 && html_css!=null) { + header = sb.replace(hc,hc+HTML_CSS.length(), html_css).toString(); + } else { + header = sb.toString(); + } } finally { br.close(); } + + + // Establish index from header + int lastTag = header.lastIndexOf('<'); + if(lastTag>0) { + int prevCR = header.lastIndexOf('\n',lastTag); + if(prevCR>0) { + indent = lastTag-prevCR; + } else { + indent = 6; //arbitrary + } + } + + + sb.setLength(0); br = new BufferedReader(new FileReader(footer_html)); try { while((line=br.readLine())!=null) { @@ -101,6 +128,18 @@ public class Notify extends Batch { for(int i=0;i<args().length;++i) { notifyFile.add(new File(logDir, args()[i])); } + } else { + String fmt = "%s"+Chrono.dateOnlyStamp()+".csv"; + File file; + for(NotifyBody nb : NotifyBody.getAll()) { + file = new File(logDir,String.format(fmt, nb.name())); + if(file.exists()) { + trans.info().printf("Processing %s",file.getCanonicalPath()); + notifyFile.add(file); + } else { + trans.info().printf("No Files found for %s",nb.name()); + } + } } } @@ -119,6 +158,7 @@ public class Notify extends Batch { final Set<String> errorSet = new HashSet<>(); try { + EMAILTYPE: for(File f : notifyFile) { CSV csv = new CSV(env.access(),f); try { @@ -150,7 +190,6 @@ public class Notify extends Batch { toList.clear(); ccList.clear(); try { - String bodyS = nb.body(noAvg, notify, id); Identity identity = trans.org().getIdentity(noAvg, id); if(!identity.isPerson()) { identity = identity.responsibleTo(); @@ -165,11 +204,19 @@ public class Notify extends Batch { } } } + + StringBuilder content = new StringBuilder(); + content.append(String.format(header,version,Identity.mixedCase(identity.firstName()))); + + nb.body(noAvg, content, indent, notify, id); + content.append(footer); - mailer.sendEmail(noAvg, dryRun, mailFrom, toList, ccList, subject, - String.format(header,"2.1.9",Identity.mixedCase(identity.firstName()))+ - bodyS + - footer, urgent); + if(!mailer.sendEmail(noAvg, dryRun, toList, ccList, subject,content.toString(), urgent)) { + trans.error().log("Mailer failed to send Mail"); + } + if(maxEmails>0 && mailer.count()>=maxEmails) { + break EMAILTYPE; + } } catch (OrganizationException e) { trans.error().log(e); } diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/AbsCredBody.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/AbsCredBody.java deleted file mode 100644 index 6dd5bb25..00000000 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/AbsCredBody.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * ============LICENSE_START==================================================== - * org.onap.aaf - * =========================================================================== - * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. - * - * Modifications Copyright (C) 2018 IBM. - * =========================================================================== - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END==================================================== - * - */ -package org.onap.aaf.auth.batch.reports.bodies; - -import java.util.List; - -public abstract class AbsCredBody extends NotifyBody { - - public AbsCredBody(final String name) { - super("cred",name); - } - - @Override - public String user(List<String> row) { - if( (row != null) && row.size()>1) { - return row.get(1); - } - return null; - } -} diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/NotifyBody.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/NotifyBody.java index 429ea6d2..453c2f2f 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/NotifyBody.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/NotifyBody.java @@ -30,6 +30,7 @@ import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -41,6 +42,7 @@ import org.onap.aaf.cadi.Access; import org.onap.aaf.misc.env.APIException; public abstract class NotifyBody { + private static final String DUPL = "<td style=\"text-indent: 4em;\">''</td>"; private static final Map<String,NotifyBody> bodyMap = new HashMap<>(); protected Map<String,List<List<String>>> rows; @@ -105,7 +107,7 @@ public abstract class NotifyBody { * @param row * @return */ - public abstract String body(AuthzTrans trans, Notify n, String id); + public abstract boolean body(AuthzTrans trans, StringBuilder sb, int indent, Notify n, String id); /** * Return "null" if user not found in row... Code will handle. @@ -127,7 +129,11 @@ public abstract class NotifyBody { * */ public static Collection<NotifyBody> getAll() { - return bodyMap.values(); + // Note: The same Notify Body is entered several times with different keys. + // Therefore, need a Set of Values, not all the Values. + Set<NotifyBody> set = new HashSet<>(); + set.addAll(bodyMap.values()); + return set; } /** @@ -140,14 +146,10 @@ public abstract class NotifyBody { ClassLoader cl = Thread.currentThread().getContextClassLoader(); Package pkg = NotifyBody.class.getPackage(); String path = pkg.getName().replace('.', '/'); -// Enumeration<URL> urls = cl.getResources(path); -// while(urls.hasMoreElements()) { -// URL url = urls.nextElement(); URL url = cl.getResource(path); if(url == null) { throw new APIException("Cannot load resources from " + path); } - System.out.println(url); File dir; try { dir = new File(url.toURI()); @@ -180,6 +182,25 @@ public abstract class NotifyBody { } } } -// } } + + + protected void println(StringBuilder sb, int indent, Object ... objs) { + for(int i=0;i<indent;++i) { + sb.append(' '); + } + for(Object o : objs) { + sb.append(o.toString()); + } + sb.append('\n'); + } + + protected void printCell(StringBuilder sb, int indent, String current, String prev) { + if(current.equals(prev)) { + println(sb,indent,DUPL); + } else { + println(sb,indent,"<td>",current,"</td>"); + } + } + } diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/NotifyCredBody.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/NotifyCredBody.java index db96d50a..2369582d 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/NotifyCredBody.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/NotifyCredBody.java @@ -27,10 +27,11 @@ import org.onap.aaf.auth.batch.reports.Notify; import org.onap.aaf.auth.env.AuthzTrans; import org.onap.aaf.cadi.Access; -public class NotifyCredBody extends AbsCredBody { +public abstract class NotifyCredBody extends NotifyBody { + private final String explanation; public NotifyCredBody(Access access, String name) throws IOException { - super(name); + super("cred",name); // Default explanation = "The following Credentials are expiring on the dates shown. " @@ -38,17 +39,70 @@ public class NotifyCredBody extends AbsCredBody { } @Override - public String body(AuthzTrans trans, Notify n, String id) { - StringBuilder sb = new StringBuilder(); - sb.append(explanation); - sb.append("<br>"); - sb.append("<tr>\n" + - "<th>Role</th>\n" + - "<th>Expires</th>\n" + - "</tr>\n"); + public boolean body(AuthzTrans trans, StringBuilder sb, int indent, Notify n, String id) { + println(sb,indent,explanation); + println(sb,indent,"<br><br>"); + println(sb,indent,"<table>"); + indent+=2; + println(sb,indent,"<tr>"); + indent+=2; + println(sb,indent,"<th>Fully Qualified ID</th>"); + println(sb,indent,"<th>Type</th>"); + println(sb,indent,"<th>Details</th>"); + println(sb,indent,"<th>Expires</th>"); + println(sb,indent,"<th>Cred Detail Page</th>"); + indent-=2; + println(sb,indent,"</tr>"); + String theid, type, info, gui, expires, notes; + String p_theid=null, p_type=null, p_gui=null, p_expires=null; for(List<String> row : rows.get(id)) { + theid=row.get(1); + switch(row.get(3)) { + case "1": + case "2": + type = "Password"; + case "200": + type = "x509 (Certificate)"; + break; + default: + type = "Unknown, see AAF GUI"; + break; + } + gui = "<a href=\""+n.guiURL+"/creddetail?ns="+row.get(2)+"\">"+row.get(2)+"</a>"; + expires = row.get(4); + info = row.get(6); + notes = row.get(8); + if(notes!=null && !notes.isEmpty()) { + info += "<br>" + notes; + } + println(sb,indent,"<tr>"); + indent+=2; + printCell(sb,indent,theid,p_theid); + printCell(sb,indent,type,p_type); + printCell(sb,indent,info,null); + printCell(sb,indent,expires,p_expires); + printCell(sb,indent,gui,p_gui); + indent-=2; + println(sb,indent,"</tr>"); + p_theid=theid; + p_type=type; + p_gui=gui; + p_expires=expires; + } + indent-=2; + println(sb,indent,"</table>"); + + return true; + } + + @Override + public String user(List<String> row) { + if( (row != null) && row.size()>1) { + return row.get(1); } - return sb.toString(); + return null; } + + } |