7ed26ce546d7ca7e67d9df1ac848d75be6cb626e
[aaf/authz.git] / auth / auth-batch / src / main / java / org / onap / aaf / auth / batch / reports / Expiring.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
4  * ===========================================================================
5  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6  *
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
12  * 
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  * 
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====================================================
21  *
22  */
23
24 package org.onap.aaf.auth.batch.reports;
25
26 import java.io.File;
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;
36 import java.util.Map;
37 import java.util.Set;
38 import java.util.TreeMap;
39
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;
57
58
59 public class Expiring extends Batch {
60     
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;
66         private File logDir;
67         private ExpireRange expireRange;
68         private Date deleteDate;
69         
70         public Expiring(AuthzTrans trans) throws APIException, IOException, OrganizationException {
71         super(trans.env());
72         trans.info().log("Starting Connection Process");
73         
74         TimeTaken tt0 = trans.start("Cassandra Initialization", Env.SUB);
75         try {
76             TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE);
77             try {
78                 session = cluster.connect();
79             } finally {
80                 tt.done();
81             }
82             
83             // Load Cred.  We don't follow Visitor, because we have to gather up everything into Identity Anyway
84             Cred.load(trans, session);
85
86             minOwners=1;
87
88             // Create Intermediate Output 
89             writerList = new HashMap<>();
90             logDir = new File(logDir());
91             logDir.mkdirs();
92             
93             expireRange = new ExpireRange(trans.env().access());
94             String sdate = Chrono.dateOnlyStamp(expireRange.now);
95             for( List<Range> lr : expireRange.ranges.values()) {
96                 for(Range r : lr ) {
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();
105                         }
106                         trans.init().log("Creating File:",file.getAbsolutePath());
107                         }
108                 }
109             }
110             
111         } finally {
112             tt0.done();
113         }
114     }
115
116     @Override
117     protected void run(AuthzTrans trans) {
118                 try {
119                         File file = new File(logDir, EXPIRED_OWNERS + Chrono.dateOnlyStamp(expireRange.now) + CSV);
120                         final CSV ownerCSV = new CSV(file);
121
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());
128                                         if (urs == null) {
129                                                 urs = new HashSet<UserRole>();
130                                                 owners.put(ur.role(), urs);
131                                         }
132                                         urs.add(ur);
133                                 } else {
134                                         writeAnalysis(trans,ur);
135                                 }
136                         });
137
138                         // Now Process Owners, one owner Role at a time, ensuring one is left,
139                         // preferably
140                         // a good one. If so, process the others as normal. Otherwise, write
141                         // ExpiredOwners
142                         // report
143                         if (!owners.values().isEmpty()) {
144                                 // Lazy Create file
145                                 CSV.Writer expOwner = null;
146                                 try {
147                                         for (Set<UserRole> sur : owners.values()) {
148                                                 int goodOwners = 0;
149                                                 for (UserRole ur : sur) {
150                                                         if (ur.expires().after(expireRange.now)) {
151                                                                 ++goodOwners;
152                                                         }
153                                                 }
154
155                                                 for (UserRole ur : sur) {
156                                                         if (goodOwners >= minOwners) {
157                                                                 writeAnalysis(trans, ur);
158                                                         } else {
159                                                                 if (expOwner == null) {
160                                                                         expOwner = ownerCSV.writer();
161                                                                         expOwner.row(INFO,EXPIRED_OWNERS,Chrono.dateOnlyStamp(expireRange.now),2);
162                                                                 }
163                                                                 expOwner.row("owner",ur.role(), ur.user(), Chrono.dateOnlyStamp(ur.expires()));
164                                                         }
165                                                 }
166                                         }
167                                 } finally {
168                                         if(expOwner!=null) {
169                                                 expOwner.close();
170                                         }
171                                 }
172                         }
173                         
174                         trans.info().log("Checking for Expired Credentials");
175                         
176                         for (Cred cred : Cred.data.values()) {
177                         List<Instance> linst = cred.instances;
178                         if(linst!=null) {
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)) {
186                                                         lastBath = inst;
187                                                 }
188                                         } else {
189                                                 writeAnalysis(trans, cred, inst);
190                                         }
191                                 }
192                                 if(lastBath!=null) {
193                                         writeAnalysis(trans, cred, lastBath);
194                                 }
195                         }
196                         }
197                         
198                         trans.info().log("Checking for Expired X509s");
199                         X509.load(trans, session, new Visitor<X509>() {
200                                 @Override
201                                 public void visit(X509 x509) {
202                                         try {
203                                                 for(Certificate cert : Factory.toX509Certificate(x509.x509)) {
204                                                         writeAnalysis(trans, x509, (X509Certificate)cert);
205                                                 }
206                                         } catch (CertificateException | IOException e) {
207                                                 trans.error().log(e, "Error Decrypting X509");
208                                         }
209                                         
210                                 }
211                         });
212                 } catch (FileNotFoundException e) {
213                         trans.info().log(e);
214                 }
215         }
216     
217  
218         private void writeAnalysis(AuthzTrans trans, UserRole ur) {
219                 Range r = expireRange.getRange("ur", ur.expires());
220                 if(r!=null) {
221                         CSV.Writer cw = writerList.get(r.name());
222                         if(cw!=null) {
223                                 ur.row(cw);
224                         }
225                 }
226         }
227     
228     private void writeAnalysis(AuthzTrans trans, Cred cred, Instance inst) {
229         if(cred!=null && inst!=null) {
230                         Range r = expireRange.getRange("cred", inst.expires);
231                         if(r!=null) {
232                                 CSV.Writer cw = writerList.get(r.name());
233                                 if(cw!=null) {
234                                         cred.row(cw,inst);
235                                 }
236                         }
237         }
238         }
239
240     private void writeAnalysis(AuthzTrans trans, X509 x509, X509Certificate x509Cert) throws IOException {
241                 Range r = expireRange.getRange("x509", x509Cert.getNotAfter());
242                 if(r!=null) {
243                         CSV.Writer cw = writerList.get(r.name());
244                         if(cw!=null) {
245                                 x509.row(cw,x509Cert);
246                         }
247                 }
248         }
249
250     /*
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())) {
256                         current.add(ur);
257                 }
258         }
259         if(current.isEmpty()) {
260                 trans.warn().log(ns,"has no current owners");
261                 current = owners;
262         }
263         
264         List<String> email = new ArrayList<>();
265         for(UserRole ur : current) {
266                 Identity id;
267                 int i=0;
268                 boolean go = true;
269                 try {
270                         id = org.getIdentity(trans, ur.user());
271                         do {
272                                 if(id!=null) {
273                                                 email.add(id.email());
274                                                 if(i<levels) {
275                                                         id = id.responsibleTo();
276                                                 } else {
277                                                         go = false;
278                                                 }
279                                 } else {
280                                         go = false;
281                                 }
282                         } while(go);
283                         } catch (OrganizationException e) {
284                                 trans.error().log(e);
285                         }
286         }
287         
288         return email.toArray(new String[email.size()]);
289     }
290 */
291     
292         @Override
293     protected void _close(AuthzTrans trans) {
294         session.close();
295         for(CSV.Writer cw : writerList.values()) {
296                 cw.close();
297         }
298     }
299
300 }