640efae704855e87f52ba61479a208e509404bcb
[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)&&(start.after(dates[i+1]))) {
275                             ++x509Added[i];
276                          }
277                     if (expires.after(dates[i])) {
278                         switch(type) {
279                             case CredDAO.RAW:
280                                 ++raw[i];
281                                 break;
282                             case CredDAO.BASIC_AUTH:
283                                 ++basic_auth[i];
284                                 break;
285                             case CredDAO.BASIC_AUTH_SHA256:
286                                 ++basic_auth_256[i];
287                                 break;
288                             case CredDAO.CERT_SHA256_RSA:
289                                 ++cert[i];
290                                 break;
291                         }
292                     }
293                 }
294             }
295         }
296
297         public long authCount(int idx) {
298             return (long)basic_auth[idx]+basic_auth_256[idx];
299         }
300         
301         public long x509Count(int idx) {
302             return cert[idx];
303         }
304
305     }
306     
307     public void row(final CSV.Writer csvw, final Instance inst) {
308         csvw.row("cred",id,ns,Integer.toString(inst.type),Chrono.dateOnlyStamp(inst.expires),
309                 inst.expires.getTime(),inst.tag);
310     }
311
312     public void row(final CSV.Writer csvw, final Instance inst, final String reason) {
313         csvw.row("cred",id,ns,Integer.toString(inst.type),Chrono.dateOnlyStamp(inst.expires),
314                 inst.expires.getTime(),inst.tag,reason);
315     }
316
317     static SimpleDateFormat sdf =  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss+SSSS");
318     public static void batchDelete(StringBuilder sb, List<String> row) {
319         Long l = Long.parseLong(row.get(5));
320         String date = sdf.format(new Date(l));
321         sb.append("DELETE from authz.cred WHERE id='");
322         sb.append(row.get(1));
323         sb.append("' AND type=");
324         sb.append(Integer.parseInt(row.get(3)));
325         // Note: We have to work with long, because Expires is part of Key... can't easily do date.
326         sb.append(" AND expires='");
327         sb.append(date);
328         sb.append("';\n");
329 //        sb.append(" AND expires=dateof(maxtimeuuid(");
330 //        sb.append(row.get(5));
331 //        sb.append("));\n");
332         
333     }
334
335     public String toString() {
336         StringBuilder sb = new StringBuilder(id);
337         sb.append('[');
338         for (Instance i : instances) {
339             sb.append('{');
340             sb.append(i.type);
341             sb.append(",\"");
342             sb.append(i.expires);
343             sb.append("\"}");
344         }
345         sb.append(']');
346         return sb.toString();
347     }
348
349     /* (non-Javadoc)
350      * @see java.lang.Object#hashCode()
351      */
352     @Override
353     public int hashCode() {
354         return id.hashCode();
355     }
356
357     /* (non-Javadoc)
358      * @see java.lang.Object#equals(java.lang.Object)
359      */
360     @Override
361     public boolean equals(Object obj) {
362         return id.equals(obj);
363     }
364
365
366     public static String histSubject(List<String> row) {
367         return row.get(1);
368     }
369
370
371     public static String histMemo(String fmt, String orgName, List<String> row) {
372         String reason;
373         if(row.size()>5) { // Reason included
374             reason = row.get(5);
375         } else {
376             reason = String.format(fmt, row.get(1),orgName,row.get(4));
377         }
378         return reason;
379     }
380
381
382     public static void clear() {
383         data.clear();
384         byNS.clear();
385     }
386 }