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