Update Fixes from testing
[aaf/authz.git] / auth / auth-batch / src / main / java / org / onap / aaf / auth / batch / helpers / Cred.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.helpers;
23
24 import java.text.SimpleDateFormat;
25 import java.util.ArrayList;
26 import java.util.Date;
27 import java.util.GregorianCalendar;
28 import java.util.HashSet;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Set;
32 import java.util.TreeMap;
33
34 import org.onap.aaf.auth.dao.cass.CredDAO;
35 import org.onap.aaf.auth.dao.hl.Question;
36 import org.onap.aaf.cadi.util.CSV;
37 import org.onap.aaf.misc.env.Env;
38 import org.onap.aaf.misc.env.TimeTaken;
39 import org.onap.aaf.misc.env.Trans;
40 import org.onap.aaf.misc.env.util.Chrono;
41
42 import com.datastax.driver.core.ResultSet;
43 import com.datastax.driver.core.Row;
44 import com.datastax.driver.core.Session;
45 import com.datastax.driver.core.SimpleStatement;
46 import com.datastax.driver.core.Statement;
47
48 public class Cred  {
49     public static final TreeMap<String,Cred> data = new TreeMap<>();
50     public static final TreeMap<String,List<Cred>> byNS = new TreeMap<>();
51
52     public final String id;
53     public final List<Instance> instances;
54     public final String ns;
55     
56     public Cred(String id) {
57         this.id = id;
58         instances = new ArrayList<>();
59         ns=Question.domain2ns(id);
60     }
61     
62     public static class Instance {
63         public final int type;
64         public final Date expires,written;
65         public final Integer other;
66         public final String tag;
67         public List<Note> notes;
68
69         
70         public Instance(int type, Date expires, Integer other, long written, String tag) {
71             this.type = type;
72             this.expires = expires;
73             this.other = other;
74             this.written = new Date(written);
75             this.tag = tag;
76         }
77         
78         /**
79          * Usually returns Null...
80          * @return
81          */
82         public List<Note> notes() {
83             return notes;
84         }
85         
86         public void addNote(int level, String note) {
87             if(notes==null) {
88                 notes=new ArrayList<>();
89             } 
90             notes.add(new Note(level,note));
91         }
92         
93         public String toString() {
94             return expires.toString() + ": " + type + ' ' + tag;
95         }
96     }
97     
98     public static class Note {
99         public final int level;
100         public final String note;
101         
102         public Note(int level, String note) {
103             this.level = level;
104             this.note = note;
105         }
106     }
107     public Date last(final int ... types) {
108         Date last = null;
109         for (Instance i : instances) {
110             if (types.length>0) { // filter by types, if requested
111                 boolean quit = true;
112                 for (int t : types) {
113                     if (t==i.type) {
114                         quit=false;
115                         break;
116                     }
117                 }
118                 if (quit) {
119                     continue;
120                 }
121             }
122             if (last==null || i.expires.after(last)) {
123                 last = i.expires;
124             }
125         }
126         return last;
127     }
128
129     
130     public Set<Integer> types() {
131         Set<Integer> types = new HashSet<>();
132         for (Instance i : instances) {
133             types.add(i.type);
134         }
135         return types;
136     }
137
138     public static void load(Trans trans, Session session, int ... types ) {
139         load(trans, session,"select id, type, expires, other, writetime(cred), tag from authz.cred;",types);
140     }
141
142     public static void loadOneNS(Trans trans, Session session, String ns,int ... types ) {
143         load(trans, session,"select id, type, expires, other, writetime(cred), tag from authz.cred WHERE ns='" + ns + "';", types);
144     }
145
146     private static void load(Trans trans, Session session, String query, int ...types) {
147
148         trans.info().log( "query: " + query );
149         TimeTaken tt = trans.start("Read Creds", Env.REMOTE);
150        
151         ResultSet results;
152         try {
153             Statement stmt = new SimpleStatement( query );
154             results = session.execute(stmt);
155         } finally {
156             tt.done();
157         }
158         int count = 0;
159         try {
160             Iterator<Row> iter = results.iterator();
161             Row row;
162             tt = trans.start("Load Credentials", Env.SUB);
163             try {
164                 while (iter.hasNext()) {
165                     ++count;
166                     row = iter.next();
167                     int type = row.getInt(1);
168                     if (types.length>0) { // filter by types, if requested
169                         boolean hastype = false;
170                         for (int t : types) {
171                             if (t==type) {
172                                 hastype=true;
173                                 break;
174                             }
175                         }
176                         if (!hastype) {
177                             continue;
178                         }
179                     }
180                     add(row.getString(0), row.getInt(1),row.getTimestamp(2),row.getInt(3),row.getLong(4),
181                             row.getString(5));
182                 }
183             } finally {
184                 tt.done();
185             }
186         } finally {
187             trans.info().log("Found",count,"creds");
188         }
189     }
190
191     public static void add(
192             final String id, 
193             final int type,
194             final Date timestamp,
195             final int other,
196             final long written,
197             final String tag
198             ) {
199         Cred cred = data.get(id);
200         if (cred==null) {
201             cred = new Cred(id);
202             data.put(id, cred);
203         }
204         cred.instances.add(new Instance(type, timestamp, other, written/1000,tag));
205         
206         List<Cred> lscd = byNS.get(cred.ns);
207         if (lscd==null) {
208             byNS.put(cred.ns, (lscd=new ArrayList<>()));
209         }
210         boolean found = false;
211         for (Cred c : lscd) {
212             if (c.id.equals(cred.id)) {
213                 found=true;
214                 break;
215             }
216         }
217         if (!found) {
218             lscd.add(cred);
219         }
220     }
221
222
223     /** 
224      * Count entries in Cred data.
225      * Note, as opposed to other methods, need to load the whole cred table for the Types.
226      * @param numbuckets 
227      * @return
228      */
229     public static CredCount count(int numbuckets) {
230         CredCount cc = new CredCount(numbuckets);
231         for (Cred c : data.values()) {
232             for (Instance ci : c.instances) {
233                 cc.inc(ci.type,ci.written, ci.expires);
234             }
235         }
236         return cc;
237     }
238
239     public static class CredCount {
240         public int raw[];
241         public int basic_auth[];
242         public int basic_auth_256[];
243         public int cert[];
244         public int x509Added[];
245         public int x509Expired[];
246         public Date dates[];
247         
248         public CredCount(int numbuckets) {
249             raw = new int[numbuckets];
250             basic_auth = new int[numbuckets];
251             basic_auth_256 = new int[numbuckets];
252             cert = new int[numbuckets];
253             x509Added = new int[numbuckets];
254             x509Expired = new int[numbuckets];
255             dates = new Date[numbuckets];
256             GregorianCalendar gc = new GregorianCalendar();
257             dates[0]=gc.getTime(); // now
258             gc.set(GregorianCalendar.DAY_OF_MONTH, 1);
259             gc.set(GregorianCalendar.HOUR, 0);
260             gc.set(GregorianCalendar.MINUTE, 0);
261             gc.set(GregorianCalendar.SECOND,0);
262             gc.set(GregorianCalendar.MILLISECOND,0);
263             gc.add(GregorianCalendar.MILLISECOND, -1); // last milli of month
264             for (int i=1;i<numbuckets;++i) {
265                 dates[i] = gc.getTime();
266                 gc.add(GregorianCalendar.MONTH, -1);
267             }
268             
269         }
270         
271         public void inc(int type, Date start, Date expires) {
272             for (int i=0;i<dates.length-1;++i) {
273                 if (start.before(dates[i])) {
274                     if (type==CredDAO.CERT_SHA256_RSA) {
275                         if (start.after(dates[i+1])) {
276                             ++x509Added[i];
277                         }
278                     }
279                     if (expires.after(dates[i])) {
280                         switch(type) {
281                             case CredDAO.RAW:
282                                 ++raw[i];
283                                 break;
284                             case CredDAO.BASIC_AUTH:
285                                 ++basic_auth[i];
286                                 break;
287                             case CredDAO.BASIC_AUTH_SHA256:
288                                 ++basic_auth_256[i];
289                                 break;
290                             case CredDAO.CERT_SHA256_RSA:
291                                 ++cert[i];
292                                 break;
293                         }
294                     }
295                 }
296             }
297         }
298
299         public long authCount(int idx) {
300             return (long)basic_auth[idx]+basic_auth_256[idx];
301         }
302         
303         public long x509Count(int idx) {
304             return cert[idx];
305         }
306
307     }
308     
309     public void row(final CSV.Writer csvw, final Instance inst) {
310         csvw.row("cred",id,ns,Integer.toString(inst.type),Chrono.dateOnlyStamp(inst.expires),
311                 inst.expires.getTime(),inst.tag);
312     }
313
314     public void row(final CSV.Writer csvw, final Instance inst, final String reason) {
315         csvw.row("cred",id,ns,Integer.toString(inst.type),Chrono.dateOnlyStamp(inst.expires),
316                 inst.expires.getTime(),inst.tag,reason);
317     }
318
319     static SimpleDateFormat sdf =  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss+SSSS");
320     public static void batchDelete(StringBuilder sb, List<String> row) {
321         Long l = Long.parseLong(row.get(5));
322         String date = sdf.format(new Date(l));
323         sb.append("DELETE from authz.cred WHERE id='");
324         sb.append(row.get(1));
325         sb.append("' AND type=");
326         sb.append(Integer.parseInt(row.get(3)));
327         // Note: We have to work with long, because Expires is part of Key... can't easily do date.
328         sb.append(" AND expires='");
329         sb.append(date);
330         sb.append("';\n");
331 //        sb.append(" AND expires=dateof(maxtimeuuid(");
332 //        sb.append(row.get(5));
333 //        sb.append("));\n");
334         
335     }
336
337     public String toString() {
338         StringBuilder sb = new StringBuilder(id);
339         sb.append('[');
340         for (Instance i : instances) {
341             sb.append('{');
342             sb.append(i.type);
343             sb.append(",\"");
344             sb.append(i.expires);
345             sb.append("\"}");
346         }
347         sb.append(']');
348         return sb.toString();
349     }
350
351     /* (non-Javadoc)
352      * @see java.lang.Object#hashCode()
353      */
354     @Override
355     public int hashCode() {
356         return id.hashCode();
357     }
358
359     /* (non-Javadoc)
360      * @see java.lang.Object#equals(java.lang.Object)
361      */
362     @Override
363     public boolean equals(Object obj) {
364         return id.equals(obj);
365     }
366
367
368     public static String histSubject(List<String> row) {
369         return row.get(1);
370     }
371
372
373     public static String histMemo(String fmt, String orgName, List<String> row) {
374         String reason;
375         if(row.size()>5) { // Reason included
376             reason = row.get(5);
377         } else {
378             reason = String.format(fmt, row.get(1),orgName,row.get(4));
379         }
380         return reason;
381     }
382
383
384     public static void clear() {
385         data.clear();
386         byNS.clear();
387     }
388 }