Remove Tabs, per Jococo
[aaf/authz.git] / auth / auth-batch / src / main / java / org / onap / aaf / auth / batch / helpers / UserRole.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.io.IOException;
25 import java.io.PrintStream;
26 import java.util.ArrayList;
27 import java.util.Date;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.SortedMap;
31 import java.util.TreeMap;
32
33 import org.onap.aaf.auth.dao.cass.UserRoleDAO;
34 import org.onap.aaf.auth.dao.cass.UserRoleDAO.Data;
35 import org.onap.aaf.auth.env.AuthzTrans;
36 import org.onap.aaf.cadi.CadiException;
37 import org.onap.aaf.cadi.util.CSV;
38 import org.onap.aaf.misc.env.Env;
39 import org.onap.aaf.misc.env.TimeTaken;
40 import org.onap.aaf.misc.env.Trans;
41 import org.onap.aaf.misc.env.util.Chrono;
42
43 import com.datastax.driver.core.ResultSet;
44 import com.datastax.driver.core.Row;
45 import com.datastax.driver.core.Session;
46 import com.datastax.driver.core.SimpleStatement;
47 import com.datastax.driver.core.Statement;
48
49 public class UserRole implements Cloneable, CacheChange.Data  {
50
51     public static final String UR = "ur";
52     public static final String APPROVE_UR = "ur";
53
54     private static final String SEPARATOR = "\",\"";
55
56     // CACHE Calling
57     private static final String LOG_FMT = "%s UserRole - %s: %s-%s (%s, %s) expiring %s";
58     private static final String REPLAY_FMT = "%s|%s|%s|%s|%s\n";
59     private static final String DELETE_FMT = "# %s\n"+ REPLAY_FMT;
60
61     private static final List<UserRole> data = new ArrayList<>();
62     private static final SortedMap<String,List<UserRole>> byUser = new TreeMap<>();
63     private static final SortedMap<String,List<UserRole>> byRole = new TreeMap<>();
64     private static final CacheChange<UserRole> cache = new CacheChange<>();
65     private static PrintStream urDelete = System.out;
66     private static PrintStream urRecover = System.err;
67     private static int totalLoaded;
68     private int deleted;
69     private Data urdd;
70
71     public static final Creator<UserRole> v2_0_11 = new Creator<UserRole>() {
72         @Override
73         public UserRole create(Row row) {
74             return new UserRole(row.getString(0), row.getString(1), row.getString(2),row.getString(3),row.getTimestamp(4));
75         }
76
77         @Override
78         public String select() {
79             return "select user,role,ns,rname,expires from authz.user_role";
80         }
81     };
82
83     public UserRole(String user, String ns, String rname, Date expires) {    
84         urdd = new UserRoleDAO.Data();
85         urdd.user = user;
86         urdd.role = ns + '.' + rname;
87         urdd.ns = ns;
88         urdd.rname = rname;
89         urdd.expires = expires;
90     }
91
92     public UserRole(String user, String role, String ns, String rname, Date expires) {
93         urdd = new UserRoleDAO.Data();
94         urdd.user = user;
95         urdd.role = role;
96         urdd.ns = ns;
97         urdd.rname = rname;
98         urdd.expires = expires;
99     }
100
101     public static List<UserRole> getData() {
102         return data;
103     }
104
105     public static SortedMap<String, List<UserRole>> getByUser() {
106         return byUser;
107     }
108
109     public static SortedMap<String, List<UserRole>> getByRole() {
110         return byRole;
111     }
112
113     public static void load(Trans trans, Session session, Creator<UserRole> creator) {
114         load(trans,session,creator,null,new DataLoadVisitor());
115     }
116     
117     public static void load(Trans trans, Session session, Creator<UserRole> creator, Visitor<UserRole> visitor ) {
118         load(trans,session,creator,null,visitor);
119     }
120
121     public static void loadOneRole(Trans trans, Session session, Creator<UserRole> creator, String role, Visitor<UserRole> visitor) {
122         load(trans,session,creator,"role='" + role +"' ALLOW FILTERING;",visitor);
123     }
124     
125     public static void loadOneUser(Trans trans, Session session, Creator<UserRole> creator, String user, Visitor<UserRole> visitor ) {
126         load(trans,session,creator,"user='"+ user +'\'',visitor);
127     }
128
129     public static void load(Trans trans, CSV csv, Creator<UserRole> creator, Visitor<UserRole> visitor) throws IOException, CadiException {
130 //        public UserRole(String user, String role, String ns, String rname, Date expires) {
131         csv.visit( row -> {
132             visitor.visit(new UserRole(row.get(1),row.get(2),row.get(3),row.get(4),
133                 new Date(Long.parseLong(row.get(6)))));
134         });
135     }
136     
137     private static void load(Trans trans, Session session, Creator<UserRole> creator, String where, Visitor<UserRole> visitor) {
138         String query = creator.query(where);
139         trans.debug().log( "query: " + query );
140         TimeTaken tt = trans.start("Read UserRoles", Env.REMOTE);
141
142         ResultSet results;
143         try {
144             Statement stmt = new SimpleStatement( query );
145             results = session.execute(stmt);
146         } finally {
147             tt.done();
148         }
149         try {
150             tt = trans.start("Load UserRole", Env.SUB);
151             try {
152                 iterateResults(creator, results.iterator(), visitor);
153             } finally {
154                 tt.done();
155             }
156         } finally {
157             trans.debug().log("Loaded",totalLoaded,"UserRoles");
158         }
159     }
160
161     private static void iterateResults(Creator<UserRole> creator, Iterator<Row> iter, Visitor<UserRole> visit ) {
162         Row row;
163         while (iter.hasNext()) {
164             ++totalLoaded;
165             row = iter.next();
166             UserRole ur = creator.create(row);
167             visit.visit(ur);
168         }
169     }
170
171     public static class DataLoadVisitor implements Visitor<UserRole> {
172         @Override
173         public void visit(UserRole ur) {
174             data.add(ur);
175
176             List<UserRole> lur = byUser.get(ur.urdd.user);
177             if (lur==null) {
178                 lur = new ArrayList<>();
179                 byUser.put(ur.urdd.user, lur);
180             }
181             lur.add(ur);
182
183             lur = byRole.get(ur.urdd.role);
184             if (lur==null) {
185                 lur = new ArrayList<>();
186                 byRole.put(ur.urdd.role, lur);
187             }
188             lur.add(ur);
189         }
190     }
191     
192     public int totalLoaded() {
193         return totalLoaded;
194     }
195     
196     public int deleted() {
197         return deleted;
198     }
199     
200     @Override
201     public void expunge() {
202         data.remove(this);
203         
204         List<UserRole> lur = byUser.get(urdd.user);
205         if (lur!=null) {
206             lur.remove(this);
207         }
208     
209         lur = byRole.get(urdd.role);
210         if (lur!=null) {
211             lur.remove(this);
212         }
213     }
214     
215     public static void setDeleteStream(PrintStream ds) {
216         urDelete = ds;
217     }
218
219     public static void setRecoverStream(PrintStream ds) {
220         urRecover = ds;
221     }
222
223     public static long count(Trans trans, Session session) {
224         String query = "select count(*) from authz.user_role LIMIT 1000000;";
225         trans.info().log( "query: " + query );
226         TimeTaken tt = trans.start("Count Namespaces", Env.REMOTE);
227         ResultSet results;
228         try {
229             Statement stmt = new SimpleStatement(query).setReadTimeoutMillis(12000);
230             results = session.execute(stmt);
231             return results.one().getLong(0);
232         } finally {
233             tt.done();
234         }
235     }
236
237     public UserRoleDAO.Data urdd() {
238         return urdd;
239     }
240     
241     public String user() {
242         return urdd.user;
243     }
244     
245     public String role() {
246         return urdd.role;
247     }
248     
249     public String ns() {
250         return urdd.ns;
251     }
252     
253     public String rname() {
254         return urdd.rname;
255     }
256     
257     public Date expires() {
258         return urdd.expires;
259     }
260     
261     public void expires(Date time) {
262         urdd.expires = time;
263     }
264
265     public String toString() {
266         return "\"" + urdd.user + SEPARATOR + urdd.role + SEPARATOR + urdd.ns + SEPARATOR + urdd.rname + SEPARATOR
267             + Chrono.dateOnlyStamp(urdd.expires);
268     }
269
270     public static UserRole get(String u, String r) {
271         List<UserRole> lur = byUser.get(u);
272         if (lur!=null) {
273             for (UserRole ur : lur) {
274
275                 if (ur.urdd.role.equals(r)) {
276                     return ur;
277                 }
278             }
279         }
280         return null;
281     }
282
283     // SAFETY - DO NOT DELETE USER ROLES DIRECTLY FROM BATCH FILES!!!
284     // We write to a file, and validate.  If the size is iffy, we email Support
285     public void delayDelete(AuthzTrans trans, String text, boolean dryRun) {
286         String dt = Chrono.dateTime(urdd.expires);
287         if (dryRun) {
288             trans.info().printf(LOG_FMT,text,"Would Delete",urdd.user,urdd.role,urdd.ns,urdd.rname,dt);
289         } else {
290             trans.info().printf(LOG_FMT,text,"Staged Deletion",urdd.user,urdd.role,urdd.ns,urdd.rname,dt);
291         }
292         urDelete.printf(DELETE_FMT,text,urdd.user,urdd.role,dt,urdd.ns,urdd.rname);
293         urRecover.printf(REPLAY_FMT,urdd.user,urdd.role,dt,urdd.ns,urdd.rname);
294
295         cache.delayedDelete(this);
296         ++deleted;
297     }
298     
299
300     /**
301      * Calls expunge() for all deleteCached entries
302      */
303     public static void resetLocalData() {
304         cache.resetLocalData();
305     }
306     
307     public void row(final CSV.Writer csvw, String tag) {
308         csvw.row(tag,user(),role(),ns(),rname(),Chrono.dateOnlyStamp(expires()),expires().getTime());
309     }
310
311     public void row(final CSV.Writer csvw, String tag, String reason) {
312         csvw.row(tag,user(),role(),ns(),rname(),Chrono.dateOnlyStamp(expires()),expires().getTime(),reason);
313     }
314     
315     public static Data row(List<String> row) {
316         Data data = new Data();
317         data.user = row.get(1);
318         data.role = row.get(2);
319         data.ns = row.get(3);
320         data.rname = row.get(4);
321         data.expires = new Date(Long.parseLong(row.get(6)));
322         return data;
323     }
324
325     public static void batchDelete(StringBuilder sb, List<String> row) {
326         sb.append("DELETE from authz.user_role WHERE user='");
327         sb.append(row.get(1));
328         sb.append("' AND role='");
329         sb.append(row.get(2));
330         sb.append("';\n");
331     }
332
333     public static void batchExtend(StringBuilder sb, List<String> row, Date newDate ) {
334         sb.append("UPDATE authz.user_role SET expires='");
335         sb.append(Chrono.dateTime(newDate));
336         sb.append("' WHERE user='");
337         sb.append(row.get(1));
338         sb.append("' AND role='");
339         sb.append(row.get(2));
340         sb.append("';\n");
341     }
342
343     public void batchExtend(StringBuilder sb, Date newDate) {
344         sb.append("UPDATE authz.user_role SET expires='");
345         sb.append(Chrono.dateTime(newDate));
346         sb.append("' WHERE user='");
347         sb.append(user());
348         sb.append("' AND role='");
349         sb.append(role());
350         sb.append("';\n");
351     }
352     
353     public void batchUpdateExpires(StringBuilder sb) {
354         sb.append("UPDATE authz.user_role SET expires='");
355         sb.append(Chrono.dateTime(expires()));
356         sb.append("' WHERE user='");
357         sb.append(user());
358         sb.append("' AND role='");
359         sb.append(role());
360         sb.append("';\n");
361     }
362
363     public static String histMemo(String fmt, List<String> row) {
364         String reason;
365         if(row.size()>7) { // Reason included
366             reason = String.format("%s removed from %s because %s", 
367                     row.get(1),row.get(2),row.get(7));
368         } else {
369             reason = String.format(fmt, row.get(1),row.get(2), row.get(5));
370         }
371         return reason;
372     }
373
374     public static String histSubject(List<String> row) {
375         return row.get(1) + '|' + row.get(2);    
376     }
377
378     public static void clear() {
379         data.clear();
380         byUser.clear();
381         byRole.clear();
382         cache.resetLocalData();
383         
384     }
385 }