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