1a7db0558e4d72699324b715dad828683aa841d7
[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  * 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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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====================================================
19  *
20  */
21
22 package org.onap.aaf.auth.batch.reports;
23
24 import java.io.File;
25 import java.io.FileNotFoundException;
26 import java.io.IOException;
27 import java.security.cert.Certificate;
28 import java.security.cert.CertificateException;
29 import java.security.cert.X509Certificate;
30 import java.util.Date;
31 import java.util.HashMap;
32 import java.util.HashSet;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Set;
36 import java.util.TreeMap;
37
38 import org.onap.aaf.auth.batch.Batch;
39 import org.onap.aaf.auth.batch.helpers.Cred;
40 import org.onap.aaf.auth.batch.helpers.ExpireRange;
41 import org.onap.aaf.auth.batch.helpers.UserRole;
42 import org.onap.aaf.auth.batch.helpers.Visitor;
43 import org.onap.aaf.auth.batch.helpers.X509;
44 import org.onap.aaf.auth.batch.helpers.Cred.Instance;
45 import org.onap.aaf.auth.batch.helpers.ExpireRange.Range;
46 import org.onap.aaf.auth.dao.cass.CredDAO;
47 import org.onap.aaf.auth.env.AuthzTrans;
48 import org.onap.aaf.auth.org.OrganizationException;
49 import org.onap.aaf.cadi.configure.Factory;
50 import org.onap.aaf.cadi.util.CSV;
51 import org.onap.aaf.misc.env.APIException;
52 import org.onap.aaf.misc.env.Env;
53 import org.onap.aaf.misc.env.TimeTaken;
54 import org.onap.aaf.misc.env.util.Chrono;
55
56
57 public class Expiring extends Batch {
58     
59         private static final String CSV = ".csv";
60         private static final String INFO = "info";
61         private static final String EXPIRED_OWNERS = "ExpiredOwners";
62         private int minOwners;
63         private Map<String, CSV.Writer> writerList;
64         private File logDir;
65         private ExpireRange expireRange;
66         private Date deleteDate;
67         
68         public Expiring(AuthzTrans trans) throws APIException, IOException, OrganizationException {
69         super(trans.env());
70         trans.info().log("Starting Connection Process");
71         
72         TimeTaken tt0 = trans.start("Cassandra Initialization", Env.SUB);
73         try {
74             TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE);
75             try {
76                 session = cluster.connect();
77             } finally {
78                 tt.done();
79             }
80             
81             // Load Cred.  We don't follow Visitor, because we have to gather up everything into Identity Anyway
82             Cred.load(trans, session);
83             UserRole.load(trans, session, UserRole.v2_0_11, new UserRole.DataLoadVisitor());
84
85             minOwners=1;
86
87             // Create Intermediate Output 
88             writerList = new HashMap<>();
89             logDir = new File(logDir());
90             logDir.mkdirs();
91             
92             expireRange = new ExpireRange(trans.env().access());
93             String sdate = Chrono.dateOnlyStamp(expireRange.now);
94             for( List<Range> lr : expireRange.ranges.values()) {
95                 for(Range r : lr ) {
96                         if(writerList.get(r.name())==null) {
97                         File file = new File(logDir,r.name() + sdate +CSV);
98                         CSV csv = new CSV(file);
99                         CSV.Writer cw = csv.writer(false);
100                         cw.row(INFO,r.name(),Chrono.dateOnlyStamp(expireRange.now),r.reportingLevel());
101                         writerList.put(r.name(),cw);
102                         if("Delete".equals(r.name())) {
103                                 deleteDate = r.getStart();
104                         }
105                         }
106                 }
107             }
108             
109         } finally {
110             tt0.done();
111         }
112     }
113
114     @Override
115     protected void run(AuthzTrans trans) {
116                 try {
117                         File file = new File(logDir, EXPIRED_OWNERS + Chrono.dateOnlyStamp(expireRange.now) + CSV);
118                         final CSV ownerCSV = new CSV(file);
119
120                         Map<String, Set<UserRole>> owners = new TreeMap<String, Set<UserRole>>();
121                         trans.info().log("Process UserRoles");
122                         UserRole.load(trans, session, UserRole.v2_0_11, new Visitor<UserRole>() {
123                                 @Override
124                                 public void visit(UserRole 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
139                         // Now Process Owners, one owner Role at a time, ensuring one is left,
140                         // preferably
141                         // a good one. If so, process the others as normal. Otherwise, write
142                         // ExpiredOwners
143                         // report
144                         if (!owners.values().isEmpty()) {
145                                 // Lazy Create file
146                                 CSV.Writer expOwner = null;
147                                 try {
148                                         for (Set<UserRole> sur : owners.values()) {
149                                                 int goodOwners = 0;
150                                                 for (UserRole ur : sur) {
151                                                         if (ur.expires().after(expireRange.now)) {
152                                                                 ++goodOwners;
153                                                         }
154                                                 }
155
156                                                 for (UserRole ur : sur) {
157                                                         if (goodOwners >= minOwners) {
158                                                                 writeAnalysis(trans, ur);
159                                                         } else {
160                                                                 if (expOwner == null) {
161                                                                         expOwner = ownerCSV.writer();
162                                                                         expOwner.row(INFO,EXPIRED_OWNERS,Chrono.dateOnlyStamp(expireRange.now),2);
163                                                                 }
164                                                                 expOwner.row("owner",ur.role(), ur.user(), Chrono.dateOnlyStamp(ur.expires()));
165                                                         }
166                                                 }
167                                         }
168                                 } finally {
169                                         if(expOwner!=null) {
170                                                 expOwner.close();
171                                         }
172                                 }
173                         }
174                         
175                         trans.info().log("Checking for Expired Credentials");
176                         
177                         for (Cred cred : Cred.data.values()) {
178                         List<Instance> linst = cred.instances;
179                         if(linst!=null) {
180                                 Instance lastBath = null;
181                                 for(Instance inst : linst) {
182                                         // Special Behavior: only eval the LAST Instance
183                                         if (inst.type == CredDAO.BASIC_AUTH || inst.type == CredDAO.BASIC_AUTH_SHA256) {
184                                                 if(deleteDate!=null && inst.expires.before(deleteDate)) {
185                                                         writeAnalysis(trans, cred, inst); // will go to Delete
186                                                 } else if(lastBath==null || lastBath.expires.before(inst.expires)) {
187                                                         lastBath = inst;
188                                                 }
189                                         } else {
190                                                 writeAnalysis(trans, cred, inst);
191                                         }
192                                 }
193                                 if(lastBath!=null) {
194                                         writeAnalysis(trans, cred, lastBath);
195                                 }
196                         }
197                         }
198                         
199                         trans.info().log("Checking for Expired X509s");
200                         X509.load(trans, session, new Visitor<X509>() {
201                                 @Override
202                                 public void visit(X509 x509) {
203                                         try {
204                                                 for(Certificate cert : Factory.toX509Certificate(x509.x509)) {
205                                                         writeAnalysis(trans, x509, (X509Certificate)cert);
206                                                 }
207                                         } catch (CertificateException | IOException e) {
208                                                 trans.error().log(e, "Error Decrypting X509");
209                                         }
210                                         
211                                 }
212                         });
213                 } catch (FileNotFoundException e) {
214                         trans.info().log(e);
215                 }
216         }
217     
218  
219         private void writeAnalysis(AuthzTrans trans, UserRole ur) {
220                 Range r = expireRange.getRange("ur", ur.expires());
221                 if(r!=null) {
222                         CSV.Writer cw = writerList.get(r.name());
223                         if(cw!=null) {
224                                 ur.row(cw);
225                         }
226                 }
227         }
228     
229     private void writeAnalysis(AuthzTrans trans, Cred cred, Instance inst) {
230         if(cred!=null && inst!=null) {
231                         Range r = expireRange.getRange("cred", inst.expires);
232                         if(r!=null) {
233                                 CSV.Writer cw = writerList.get(r.name());
234                                 if(cw!=null) {
235                                         cred.row(cw,inst);
236                                 }
237                         }
238         }
239         }
240
241     private void writeAnalysis(AuthzTrans trans, X509 x509, X509Certificate x509Cert) throws IOException {
242                 Range r = expireRange.getRange("x509", x509Cert.getNotAfter());
243                 if(r!=null) {
244                         CSV.Writer cw = writerList.get(r.name());
245                         if(cw!=null) {
246                                 x509.row(cw,x509Cert);
247                         }
248                 }
249         }
250
251     /*
252     private String[] contacts(final AuthzTrans trans, final String ns, final int levels) {
253         List<UserRole> owners = UserRole.getByRole().get(ns+".owner");
254         List<UserRole> current = new ArrayList<>();
255         for(UserRole ur : owners) {
256                 if(expireRange.now.before(ur.expires())) {
257                         current.add(ur);
258                 }
259         }
260         if(current.isEmpty()) {
261                 trans.warn().log(ns,"has no current owners");
262                 current = owners;
263         }
264         
265         List<String> email = new ArrayList<>();
266         for(UserRole ur : current) {
267                 Identity id;
268                 int i=0;
269                 boolean go = true;
270                 try {
271                         id = org.getIdentity(trans, ur.user());
272                         do {
273                                 if(id!=null) {
274                                                 email.add(id.email());
275                                                 if(i<levels) {
276                                                         id = id.responsibleTo();
277                                                 } else {
278                                                         go = false;
279                                                 }
280                                 } else {
281                                         go = false;
282                                 }
283                         } while(go);
284                         } catch (OrganizationException e) {
285                                 trans.error().log(e);
286                         }
287         }
288         
289         return email.toArray(new String[email.size()]);
290     }
291 */
292     
293         @Override
294     protected void _close(AuthzTrans trans) {
295         session.close();
296         for(CSV.Writer cw : writerList.values()) {
297                 cw.close();
298         }
299     }
300
301 }