11eacd4e789f856383b0410b579f0e1a63ada9a2
[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 ExpireRange expireRange;
67         private Date deleteDate;
68         
69         public Expiring(AuthzTrans trans) throws APIException, IOException, OrganizationException {
70         super(trans.env());
71         trans.info().log("Starting Connection Process");
72         
73         TimeTaken tt0 = trans.start("Cassandra Initialization", Env.SUB);
74         try {
75             TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE);
76             try {
77                 session = cluster.connect();
78             } finally {
79                 tt.done();
80             }
81             
82             // Load Cred.  We don't follow Visitor, because we have to gather up everything into Identity Anyway
83             Cred.load(trans, session);
84
85             minOwners=1;
86
87             // Create Intermediate Output 
88             writerList = new HashMap<>();
89             
90             expireRange = new ExpireRange(trans.env().access());
91             String sdate = Chrono.dateOnlyStamp(expireRange.now);
92             for( List<Range> lr : expireRange.ranges.values()) {
93                 for(Range r : lr ) {
94                         if(writerList.get(r.name())==null) {
95                         File file = new File(logDir(),r.name() + sdate +CSV);
96                         CSV csv = new CSV(file);
97                         CSV.Writer cw = csv.writer(false);
98                         cw.row(INFO,r.name(),Chrono.dateOnlyStamp(expireRange.now),r.reportingLevel());
99                         writerList.put(r.name(),cw);
100                         if("Delete".equals(r.name())) {
101                                 deleteDate = r.getEnd();
102                         }
103                         trans.init().log("Creating File:",file.getAbsolutePath());
104                         }
105                 }
106             }
107             
108         } finally {
109             tt0.done();
110         }
111     }
112
113     @Override
114     protected void run(AuthzTrans trans) {
115                 try {
116                         File file = new File(logDir(), EXPIRED_OWNERS + Chrono.dateOnlyStamp(expireRange.now) + CSV);
117                         final CSV ownerCSV = new CSV(file);
118
119                         Map<String, Set<UserRole>> owners = new TreeMap<String, Set<UserRole>>();
120                         trans.info().log("Process UserRoles");
121                         UserRole.load(trans, session, UserRole.v2_0_11, ur -> {
122                                 // Cannot just delete owners, unless there is at least one left. Process later
123                                 if ("owner".equals(ur.rname())) {
124                                         Set<UserRole> urs = owners.get(ur.role());
125                                         if (urs == null) {
126                                                 urs = new HashSet<UserRole>();
127                                                 owners.put(ur.role(), urs);
128                                         }
129                                         urs.add(ur);
130                                 } else {
131                                         writeAnalysis(trans,ur);
132                                 }
133                         });
134
135                         // Now Process Owners, one owner Role at a time, ensuring one is left,
136                         // preferably
137                         // a good one. If so, process the others as normal. Otherwise, write
138                         // ExpiredOwners
139                         // report
140                         if (!owners.values().isEmpty()) {
141                                 // Lazy Create file
142                                 CSV.Writer expOwner = null;
143                                 try {
144                                         for (Set<UserRole> sur : owners.values()) {
145                                                 int goodOwners = 0;
146                                                 for (UserRole ur : sur) {
147                                                         if (ur.expires().after(expireRange.now)) {
148                                                                 ++goodOwners;
149                                                         }
150                                                 }
151
152                                                 for (UserRole ur : sur) {
153                                                         if (goodOwners >= minOwners) {
154                                                                 writeAnalysis(trans, ur);
155                                                         } else {
156                                                                 if (expOwner == null) {
157                                                                         expOwner = ownerCSV.writer();
158                                                                         expOwner.row(INFO,EXPIRED_OWNERS,Chrono.dateOnlyStamp(expireRange.now),2);
159                                                                 }
160                                                                 expOwner.row("owner",ur.role(), ur.user(), Chrono.dateOnlyStamp(ur.expires()));
161                                                         }
162                                                 }
163                                         }
164                                 } finally {
165                                         if(expOwner!=null) {
166                                                 expOwner.close();
167                                         }
168                                 }
169                         }
170                         
171                         trans.info().log("Checking for Expired Credentials");
172                         
173                         for (Cred cred : Cred.data.values()) {
174                         List<Instance> linst = cred.instances;
175                         if(linst!=null) {
176                                 Instance lastBath = null;
177                                 for(Instance inst : linst) {
178                                         // Special Behavior: only eval the LAST Instance
179                                         if (inst.type == CredDAO.BASIC_AUTH || inst.type == CredDAO.BASIC_AUTH_SHA256) {
180                                                 if(deleteDate!=null && inst.expires.before(deleteDate)) {
181                                                         writeAnalysis(trans, cred, inst); // will go to Delete
182                                                 } else if(lastBath==null || lastBath.expires.before(inst.expires)) {
183                                                         lastBath = inst;
184                                                 }
185                                         } else {
186                                                 writeAnalysis(trans, cred, inst);
187                                         }
188                                 }
189                                 if(lastBath!=null) {
190                                         writeAnalysis(trans, cred, lastBath);
191                                 }
192                         }
193                         }
194                         
195                         trans.info().log("Checking for Expired X509s");
196                         X509.load(trans, session, x509 -> {
197                                 try {
198                                         for(Certificate cert : Factory.toX509Certificate(x509.x509)) {
199                                                 writeAnalysis(trans, x509, (X509Certificate)cert);
200                                         }
201                                 } catch (CertificateException | IOException e) {
202                                         trans.error().log(e, "Error Decrypting X509");
203                                 }
204
205                         });
206                 } catch (FileNotFoundException e) {
207                         trans.info().log(e);
208                 }
209         }
210     
211  
212         private void writeAnalysis(AuthzTrans trans, UserRole ur) {
213                 Range r = expireRange.getRange("ur", ur.expires());
214                 if(r!=null) {
215                         CSV.Writer cw = writerList.get(r.name());
216                         if(cw!=null) {
217                                 ur.row(cw);
218                         }
219                 }
220         }
221     
222     private void writeAnalysis(AuthzTrans trans, Cred cred, Instance inst) {
223         if(cred!=null && inst!=null) {
224                         Range r = expireRange.getRange("cred", inst.expires);
225                         if(r!=null) {
226                                 CSV.Writer cw = writerList.get(r.name());
227                                 if(cw!=null) {
228                                         cred.row(cw,inst);
229                                 }
230                         }
231         }
232         }
233
234     private void writeAnalysis(AuthzTrans trans, X509 x509, X509Certificate x509Cert) throws IOException {
235                 Range r = expireRange.getRange("x509", x509Cert.getNotAfter());
236                 if(r!=null) {
237                         CSV.Writer cw = writerList.get(r.name());
238                         if(cw!=null) {
239                                 x509.row(cw,x509Cert);
240                         }
241                 }
242         }
243
244     /*
245     private String[] contacts(final AuthzTrans trans, final String ns, final int levels) {
246         List<UserRole> owners = UserRole.getByRole().get(ns+".owner");
247         List<UserRole> current = new ArrayList<>();
248         for(UserRole ur : owners) {
249                 if(expireRange.now.before(ur.expires())) {
250                         current.add(ur);
251                 }
252         }
253         if(current.isEmpty()) {
254                 trans.warn().log(ns,"has no current owners");
255                 current = owners;
256         }
257         
258         List<String> email = new ArrayList<>();
259         for(UserRole ur : current) {
260                 Identity id;
261                 int i=0;
262                 boolean go = true;
263                 try {
264                         id = org.getIdentity(trans, ur.user());
265                         do {
266                                 if(id!=null) {
267                                                 email.add(id.email());
268                                                 if(i<levels) {
269                                                         id = id.responsibleTo();
270                                                 } else {
271                                                         go = false;
272                                                 }
273                                 } else {
274                                         go = false;
275                                 }
276                         } while(go);
277                         } catch (OrganizationException e) {
278                                 trans.error().log(e);
279                         }
280         }
281         
282         return email.toArray(new String[email.size()]);
283     }
284 */
285     
286         @Override
287     protected void _close(AuthzTrans trans) {
288         session.close();
289         for(CSV.Writer cw : writerList.values()) {
290                 cw.close();
291         }
292     }
293
294 }