2 * ============LICENSE_START====================================================
4 * ===========================================================================
5 * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
7 * Modifications Copyright (C) 2019 IBM.
8 * ===========================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 * ============LICENSE_END====================================================
24 package org.onap.aaf.auth.batch.reports;
27 import java.io.FileNotFoundException;
28 import java.io.IOException;
29 import java.security.cert.Certificate;
30 import java.security.cert.CertificateException;
31 import java.security.cert.X509Certificate;
32 import java.util.Date;
33 import java.util.HashMap;
34 import java.util.HashSet;
35 import java.util.List;
38 import java.util.TreeMap;
40 import org.onap.aaf.auth.batch.Batch;
41 import org.onap.aaf.auth.batch.helpers.Cred;
42 import org.onap.aaf.auth.batch.helpers.ExpireRange;
43 import org.onap.aaf.auth.batch.helpers.UserRole;
44 import org.onap.aaf.auth.batch.helpers.Visitor;
45 import org.onap.aaf.auth.batch.helpers.X509;
46 import org.onap.aaf.auth.batch.helpers.Cred.Instance;
47 import org.onap.aaf.auth.batch.helpers.ExpireRange.Range;
48 import org.onap.aaf.auth.dao.cass.CredDAO;
49 import org.onap.aaf.auth.env.AuthzTrans;
50 import org.onap.aaf.auth.org.OrganizationException;
51 import org.onap.aaf.cadi.configure.Factory;
52 import org.onap.aaf.cadi.util.CSV;
53 import org.onap.aaf.misc.env.APIException;
54 import org.onap.aaf.misc.env.Env;
55 import org.onap.aaf.misc.env.TimeTaken;
56 import org.onap.aaf.misc.env.util.Chrono;
59 public class Expiring extends Batch {
61 private static final String CSV = ".csv";
62 private static final String INFO = "info";
63 private static final String EXPIRED_OWNERS = "ExpiredOwners";
64 private int minOwners;
65 private Map<String, CSV.Writer> writerList;
67 private ExpireRange expireRange;
68 private Date deleteDate;
70 public Expiring(AuthzTrans trans) throws APIException, IOException, OrganizationException {
72 trans.info().log("Starting Connection Process");
74 TimeTaken tt0 = trans.start("Cassandra Initialization", Env.SUB);
76 TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE);
78 session = cluster.connect();
83 // Load Cred. We don't follow Visitor, because we have to gather up everything into Identity Anyway
84 Cred.load(trans, session);
88 // Create Intermediate Output
89 writerList = new HashMap<>();
90 logDir = new File(logDir());
93 expireRange = new ExpireRange(trans.env().access());
94 String sdate = Chrono.dateOnlyStamp(expireRange.now);
95 for( List<Range> lr : expireRange.ranges.values()) {
97 if(writerList.get(r.name())==null) {
98 File file = new File(logDir,r.name() + sdate +CSV);
99 CSV csv = new CSV(file);
100 CSV.Writer cw = csv.writer(false);
101 cw.row(INFO,r.name(),Chrono.dateOnlyStamp(expireRange.now),r.reportingLevel());
102 writerList.put(r.name(),cw);
103 if("Delete".equals(r.name())) {
104 deleteDate = r.getEnd();
106 trans.init().log("Creating File:",file.getAbsolutePath());
117 protected void run(AuthzTrans trans) {
119 File file = new File(logDir, EXPIRED_OWNERS + Chrono.dateOnlyStamp(expireRange.now) + CSV);
120 final CSV ownerCSV = new CSV(file);
122 Map<String, Set<UserRole>> owners = new TreeMap<String, Set<UserRole>>();
123 trans.info().log("Process UserRoles");
124 UserRole.load(trans, session, UserRole.v2_0_11, ur -> {
125 // Cannot just delete owners, unless there is at least one left. Process later
126 if ("owner".equals(ur.rname())) {
127 Set<UserRole> urs = owners.get(ur.role());
129 urs = new HashSet<UserRole>();
130 owners.put(ur.role(), urs);
134 writeAnalysis(trans,ur);
138 // Now Process Owners, one owner Role at a time, ensuring one is left,
140 // a good one. If so, process the others as normal. Otherwise, write
143 if (!owners.values().isEmpty()) {
145 CSV.Writer expOwner = null;
147 for (Set<UserRole> sur : owners.values()) {
149 for (UserRole ur : sur) {
150 if (ur.expires().after(expireRange.now)) {
155 for (UserRole ur : sur) {
156 if (goodOwners >= minOwners) {
157 writeAnalysis(trans, ur);
159 if (expOwner == null) {
160 expOwner = ownerCSV.writer();
161 expOwner.row(INFO,EXPIRED_OWNERS,Chrono.dateOnlyStamp(expireRange.now),2);
163 expOwner.row("owner",ur.role(), ur.user(), Chrono.dateOnlyStamp(ur.expires()));
174 trans.info().log("Checking for Expired Credentials");
176 for (Cred cred : Cred.data.values()) {
177 List<Instance> linst = cred.instances;
179 Instance lastBath = null;
180 for(Instance inst : linst) {
181 // Special Behavior: only eval the LAST Instance
182 if (inst.type == CredDAO.BASIC_AUTH || inst.type == CredDAO.BASIC_AUTH_SHA256) {
183 if(deleteDate!=null && inst.expires.before(deleteDate)) {
184 writeAnalysis(trans, cred, inst); // will go to Delete
185 } else if(lastBath==null || lastBath.expires.before(inst.expires)) {
189 writeAnalysis(trans, cred, inst);
193 writeAnalysis(trans, cred, lastBath);
198 trans.info().log("Checking for Expired X509s");
199 X509.load(trans, session, new Visitor<X509>() {
201 public void visit(X509 x509) {
203 for(Certificate cert : Factory.toX509Certificate(x509.x509)) {
204 writeAnalysis(trans, x509, (X509Certificate)cert);
206 } catch (CertificateException | IOException e) {
207 trans.error().log(e, "Error Decrypting X509");
212 } catch (FileNotFoundException e) {
218 private void writeAnalysis(AuthzTrans trans, UserRole ur) {
219 Range r = expireRange.getRange("ur", ur.expires());
221 CSV.Writer cw = writerList.get(r.name());
228 private void writeAnalysis(AuthzTrans trans, Cred cred, Instance inst) {
229 if(cred!=null && inst!=null) {
230 Range r = expireRange.getRange("cred", inst.expires);
232 CSV.Writer cw = writerList.get(r.name());
240 private void writeAnalysis(AuthzTrans trans, X509 x509, X509Certificate x509Cert) throws IOException {
241 Range r = expireRange.getRange("x509", x509Cert.getNotAfter());
243 CSV.Writer cw = writerList.get(r.name());
245 x509.row(cw,x509Cert);
251 private String[] contacts(final AuthzTrans trans, final String ns, final int levels) {
252 List<UserRole> owners = UserRole.getByRole().get(ns+".owner");
253 List<UserRole> current = new ArrayList<>();
254 for(UserRole ur : owners) {
255 if(expireRange.now.before(ur.expires())) {
259 if(current.isEmpty()) {
260 trans.warn().log(ns,"has no current owners");
264 List<String> email = new ArrayList<>();
265 for(UserRole ur : current) {
270 id = org.getIdentity(trans, ur.user());
273 email.add(id.email());
275 id = id.responsibleTo();
283 } catch (OrganizationException e) {
284 trans.error().log(e);
288 return email.toArray(new String[email.size()]);
293 protected void _close(AuthzTrans trans) {
295 for(CSV.Writer cw : writerList.values()) {