diff options
Diffstat (limited to 'authz-batch/src/main')
59 files changed, 5318 insertions, 0 deletions
diff --git a/authz-batch/src/main/config/authBatch.props b/authz-batch/src/main/config/authBatch.props new file mode 100644 index 00000000..cfe75e32 --- /dev/null +++ b/authz-batch/src/main/config/authBatch.props @@ -0,0 +1,36 @@ +## +## AUTHZ Batch (authz-batch) Properties +## +## DISCOVERY (DME2) Parameters on the Command Line +AFT_LATITUDE=_AFT_LATITUDE_ +AFT_LONGITUDE=_AFT_LONGITUDE_ +AFT_ENVIRONMENT=_AFT_ENVIRONMENT_ +DEPLOYED_VERSION=_ARTIFACT_VERSION_ + + +DRY_RUN=false + +## Pull in common/security properties + +cadi_prop_files=_COMMON_DIR_/com.att.aaf.props;_COMMON_DIR_/com.att.aaf.common.props + + +## ------------------------------------- +## Batch specific Settings +## ------------------------------------- +SPECIAL_NAMES=testunused,testid,unknown + + +## ---------------------------------------------- +## Email Server settings +## ---------------------------------------------- +#Sender's email ID needs to be mentioned +mailFromUserId=DL-aaf-support@att.com +mailHost=smtp.it.att.com + +ALERT_TO_ADDRESS=DL-aaf-support@att.com + +PASSWORD_RESET_URL=_AUTHZ_GUI_URL_/gui/passwd +APPROVALS_URL=_AUTHZ_GUI_URL_/gui/approve + + diff --git a/authz-batch/src/main/config/log4j.properties b/authz-batch/src/main/config/log4j.properties new file mode 100644 index 00000000..169460c4 --- /dev/null +++ b/authz-batch/src/main/config/log4j.properties @@ -0,0 +1,84 @@ +############################################################################### +# Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. +############################################################################### +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +log4j.rootLogger=INFO,FA +log4j.logger.aspr=INFO,aspr +log4j.additivity.aspr=false +log4j.logger.authz-batch=INFO,authz-batch +log4j.logger.sync=INFO,sync +log4j.additivity.sync=false +log4j.logger.jobchange=INFO,jobchange +log4j.additivity.jobchange=false +log4j.logger.validateuser=INFO,validateuser +log4j.additivity.validateuser=false + + +log4j.appender.FA=org.apache.log4j.RollingFileAppender +log4j.appender.FA.File=${LOG4J_FILENAME_authz-batch} +log4j.appender.FA.MaxFileSize=10000KB +log4j.appender.FA.MaxBackupIndex=7 +log4j.appender.FA.layout=org.apache.log4j.PatternLayout +log4j.appender.FA.layout.ConversionPattern=%d %p [%c] - %m %n + +log4j.appender.stderr=org.apache.log4j.ConsoleAppender +log4j.appender.stderr.layout=org.apache.log4j.PatternLayout +log4j.appender.stderr.layout.ConversionPattern=%d %p [%c] - %m %n +log4j.appender.stderr.Target=System.err + +log4j.appender.authz-batch=org.apache.log4j.DailyRollingFileAppender +log4j.appender.authz-batch.encoding=UTF-8 +log4j.appender.authz-batch.layout=org.apache.log4j.PatternLayout +log4j.appender.authz-batch.layout.ConversionPattern=%d [%p] %m %n +log4j.appender.authz-batch.File=${LOG4J_FILENAME_authz-batch} +log4j.appender.authz-batch.DatePattern='.'yyyy-MM + +log4j.appender.aspr=org.apache.log4j.DailyRollingFileAppender +log4j.appender.aspr.encoding=UTF-8 +log4j.appender.aspr.layout=org.apache.log4j.PatternLayout +log4j.appender.aspr.layout.ConversionPattern=%d [%p] %m %n +log4j.appender.aspr.File=${LOG4J_FILENAME_aspr} +log4j.appender.aspr.DatePattern='.'yyyy-MM + + +log4j.appender.jobchange=org.apache.log4j.RollingFileAppender +log4j.appender.jobchange.File=${LOG4J_FILENAME_jobchange} +log4j.appender.jobchange.MaxFileSize=10000KB +log4j.appender.jobchange.MaxBackupIndex=7 +log4j.appender.jobchange.layout=org.apache.log4j.PatternLayout +log4j.appender.jobchange.layout.ConversionPattern=%d %p [%c] - %m %n + +log4j.appender.validateuser=org.apache.log4j.RollingFileAppender +log4j.appender.validateuser.File=${LOG4J_FILENAME_validateuser} +log4j.appender.validateuser.MaxFileSize=10000KB +log4j.appender.validateuser.MaxBackupIndex=7 +log4j.appender.validateuser.layout=org.apache.log4j.PatternLayout +log4j.appender.validateuser.layout.ConversionPattern=%d %p [%c] - %m %n + +log4j.appender.sync=org.apache.log4j.DailyRollingFileAppender +log4j.appender.sync.encoding=UTF-8 +log4j.appender.sync.layout=org.apache.log4j.PatternLayout +log4j.appender.sync.layout.ConversionPattern=%d [%p] %m %n +log4j.appender.sync.File=${LOG4J_FILENAME_sync} +log4j.appender.sync.DatePattern='.'yyyy-MM + +# General Apache libraries +log4j.logger.org.apache=WARN + diff --git a/authz-batch/src/main/java/com/att/authz/Batch.java b/authz-batch/src/main/java/com/att/authz/Batch.java new file mode 100644 index 00000000..f812d310 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/Batch.java @@ -0,0 +1,471 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.lang.reflect.Constructor; +import java.net.InetAddress; +import java.net.URL; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.text.SimpleDateFormat; +import java.util.GregorianCalendar; +import java.util.HashSet; +import java.util.Properties; +import java.util.Set; +import java.util.TimeZone; + +import org.apache.log4j.Logger; + +import com.att.authz.env.AuthzEnv; +import com.att.authz.env.AuthzTrans; +import com.att.authz.org.Organization; +import com.att.authz.org.OrganizationException; +import com.att.authz.org.OrganizationFactory; +import com.att.dao.CassAccess; +import com.att.inno.env.APIException; +import com.att.inno.env.Env; +import com.att.inno.env.StaticSlot; +import com.att.inno.env.TimeTaken; +import com.att.inno.env.impl.Log4JLogTarget; +import com.att.inno.env.log4j.LogFileNamer; +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.Statement; + +public abstract class Batch { + private static StaticSlot ssargs; + + protected static final String STARS = "*****"; + + protected final Cluster cluster; + protected static AuthzEnv env; + protected static Session session; + protected static Logger aspr; + private static Set<String> specialNames = null; + protected static boolean dryRun; + protected static String batchEnv; + + public static final String CASS_ENV = "CASS_ENV"; + protected final static String PUNT="punt"; + protected final static String VERSION="VERSION"; + public final static String GUI_URL="GUI_URL"; + + protected final static String ORA_URL="ora_url"; + protected final static String ORA_PASSWORD="ora_password"; + + + + protected Batch(AuthzEnv env) throws APIException, IOException { + // TODO - Property Driven Organization +// try { +// // att = new ATT(env); +// } catch (OrganizationException e) { +// throw new APIException(e); +// } + + // Be able to change Environments + // load extra properties, i.e. + // PERF.cassandra.clusters=.... + batchEnv = env.getProperty(CASS_ENV); + if(batchEnv != null) { + batchEnv = batchEnv.trim(); + env.info().log("Redirecting to ",batchEnv,"environment"); + String str; + for(String key : new String[]{ + CassAccess.CASSANDRA_CLUSTERS, + CassAccess.CASSANDRA_CLUSTERS_PORT, + CassAccess.CASSANDRA_CLUSTERS_USER_NAME, + CassAccess.CASSANDRA_CLUSTERS_PASSWORD, + VERSION,GUI_URL,PUNT, + // TEMP + ORA_URL, ORA_PASSWORD + }) { + if((str = env.getProperty(batchEnv+'.'+key))!=null) { + env.setProperty(key, str); + } + } + } + + // Setup for Dry Run + cluster = CassAccess.cluster(env,batchEnv); + env.info().log("cluster name - ",cluster.getClusterName()); + String dryRunStr = env.getProperty( "DRY_RUN" ); + if ( dryRunStr == null || dryRunStr.equals("false") ) { + dryRun = false; + } else { + dryRun = true; + env.info().log("dryRun set to TRUE"); + } + + // Special names to allow behaviors beyond normal rules + String names = env.getProperty( "SPECIAL_NAMES" ); + if ( names != null ) + { + env.info().log("Loading SPECIAL_NAMES"); + specialNames = new HashSet<String>(); + for (String s :names.split(",") ) + { + env.info().log("\tspecial: " + s ); + specialNames.add( s.trim() ); + } + } + } + + protected abstract void run(AuthzTrans trans); + protected abstract void _close(AuthzTrans trans); + + public String[] args() { + return (String[])env.get(ssargs); + } + + public boolean isDryRun() + { + return( dryRun ); + } + + public boolean isSpecial(String user) { + if (specialNames != null && specialNames.contains(user)) { + env.info().log("specialName: " + user); + + return (true); + } else { + return (false); + } + } + + public boolean isMechID(String user) { + if (user.matches("m[0-9][0-9][0-9][0-9][0-9]")) { + return (true); + } else { + return (false); + } + } + + protected PrintStream fallout(PrintStream _fallout, String logType) + throws IOException { + PrintStream fallout = _fallout; + if (fallout == null) { + File dir = new File("logs"); + if (!dir.exists()) { + dir.mkdirs(); + } + + File f = null; + // String os = System.getProperty("os.name").toLowerCase(); + long uniq = System.currentTimeMillis(); + + f = new File(dir, getClass().getSimpleName() + "_" + logType + "_" + + uniq + ".log"); + + fallout = new PrintStream(new FileOutputStream(f, true)); + } + return fallout; + } + + public Organization getOrgFromID(AuthzTrans trans, String user) { + Organization org; + try { + org = OrganizationFactory.obtain(trans.env(),user.toLowerCase()); + } catch (OrganizationException e1) { + trans.error().log(e1); + org=null; + } + + if (org == null) { + PrintStream fallout = null; + + try { + fallout = fallout(fallout, "Fallout"); + fallout.print("INVALID_ID,"); + fallout.println(user); + } catch (Exception e) { + env.error().log("Could not write to Fallout File", e); + } + return (null); + } + + return (org); + } + + public static Row executeDeleteQuery(Statement stmt) { + Row row = null; + if (!dryRun) { + row = session.execute(stmt).one(); + } + + return (row); + + } + + public static int acquireRunLock(String className) { + Boolean testEnv = true; + String envStr = env.getProperty("AFT_ENVIRONMENT"); + + if (envStr != null) { + if (envStr.equals("AFTPRD")) { + testEnv = false; + } + } else { + env.fatal() + .log("AFT_ENVIRONMENT property is required and was not found. Exiting."); + System.exit(1); + } + + if (testEnv) { + env.info().log("TESTMODE: skipping RunLock"); + return (1); + } + + String hostname = null; + try { + hostname = InetAddress.getLocalHost().getHostName(); + } catch (UnknownHostException e) { + e.printStackTrace(); + env.warn().log("Unable to get hostname"); + return (0); + } + + ResultSet existing = session.execute(String.format( + "select * from authz.run_lock where class = '%s'", className)); + + for (Row row : existing) { + long curr = System.currentTimeMillis(); + ByteBuffer lastRun = row.getBytesUnsafe(2); // Can I get this field + // by name? + + long interval = (1 * 60 * 1000); // @@ Create a value in props file + // for this + long prev = lastRun.getLong(); + + if ((curr - prev) <= interval) { + env.warn().log( + String.format("Too soon! Last run was %d minutes ago.", + ((curr - prev) / 1000) / 60)); + env.warn().log( + String.format("Min time between runs is %d minutes ", + (interval / 1000) / 60)); + env.warn().log( + String.format("Last ran on machine: %s at %s", + row.getString("host"), row.getDate("start"))); + return (0); + } else { + env.info().log("Delete old lock"); + deleteLock(className); + } + } + + GregorianCalendar current = new GregorianCalendar(); + + // We want our time in UTC, hence "+0000" + SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss+0000"); + fmt.setTimeZone(TimeZone.getTimeZone("UTC")); + + String cql = String + .format("INSERT INTO authz.run_lock (class,host,start) VALUES ('%s','%s','%s') IF NOT EXISTS", + className, hostname, fmt.format(current.getTime())); + + env.info().log(cql); + + Row row = session.execute(cql).one(); + if (!row.getBool("[applied]")) { + env.warn().log("Lightweight Transaction failed to write lock."); + env.warn().log( + String.format("host with lock: %s, running at %s", + row.getString("host"), row.getDate("start"))); + return (0); + } + return (1); + } + + private static void deleteLock( String className) { + Row row = session.execute( String.format( "DELETE FROM authz.run_lock WHERE class = '%s' IF EXISTS", className ) ).one(); + if (! row.getBool("[applied]")) { + env.info().log( "delete failed" ); + } + } + + private static void transferVMProps(AuthzEnv env, String ... props) { + String value; + for(String key : props) { + if((value = System.getProperty(key))!=null) { + env.setProperty(key, value); + } + } + + } + + protected int count(String str, char c) { + int count=str==null||str.isEmpty()?0:1; + for(int i=str.indexOf(c);i>=0;i=str.indexOf(c,i+1)) { + ++count; + } + return count; + } + + public final void close(AuthzTrans trans) { + _close(trans); + cluster.close(); + } + + public static void main(String[] args) { + Properties props = new Properties(); + InputStream is=null; + String filename; + String propLoc; + try { + File f = new File("etc/authBatch.props"); + try { + if(f.exists()) { + filename = f.getCanonicalPath(); + is = new FileInputStream(f); + propLoc=f.getPath(); + } else { + URL rsrc = ClassLoader.getSystemResource("authBatch.props"); + filename = rsrc.toString(); + is = rsrc.openStream(); + propLoc=rsrc.getPath(); + } + props.load(is); + } finally { + if(is==null) { + System.err.println("authBatch.props must exist in etc dir, or in Classpath"); + System.exit(1); + } + is.close(); + } + + env = new AuthzEnv(props); + + transferVMProps(env,CASS_ENV,"DRY_RUN","NS","Organization"); + + // Flow all Env Logs to Log4j, with ENV + + LogFileNamer lfn; + if((batchEnv=env.getProperty(CASS_ENV))==null) { + lfn = new LogFileNamer("logs/").noPID(); + } else { + lfn = new LogFileNamer("logs/" + batchEnv+'/').noPID(); + } + + lfn.setAppender("authz-batch"); + lfn.setAppender("aspr|ASPR"); + lfn.setAppender("sync"); + lfn.setAppender("jobchange"); + lfn.setAppender("validateuser"); + aspr = Logger.getLogger("aspr"); + Log4JLogTarget.setLog4JEnv("authz-batch", env); + if(filename!=null) { + env.init().log("Instantiated properties from",filename); + } + + + // Log where Config found + env.info().log("Configuring from",propLoc); + propLoc=null; + + Batch batch = null; + // setup ATTUser and Organization Slots before starting this: + //TODO Property Driven Organization +// env.slot(ATT.ATT_USERSLOT); +// OrganizationFactory.setDefaultOrg(env, ATT.class.getName()); + AuthzTrans trans = env.newTrans(); + + TimeTaken tt = trans.start("Total Run", Env.SUB); + try { + int len = args.length; + if(len>0) { + String toolName = args[0]; + len-=1; + if(len<0)len=0; + String nargs[] = new String[len]; + if(len>0) { + System.arraycopy(args, 1, nargs, 0, len); + } + + env.put(ssargs=env.staticSlot("ARGS"), nargs); + + /* + * Add New Batch Programs (inherit from Batch) here + */ + + if( JobChange.class.getSimpleName().equals(toolName)) { + aspr.info( "Begin jobchange processing" ); + batch = new JobChange(trans); + } + //// else if( ValidateUsers.class.getSimpleName().equals(toolName)) { + //// aspr.info( "Begin ValidateUsers processing" ); + //// batch = new ValidateUsers(trans); + // } + else if( UserRoleDataGeneration.class.getSimpleName().equals(toolName)) { + // This job duplicates User Role add/delete History items + // so that we can search them by Role. Intended as a one-time + // script! but written as batch job because Java has better + // UUID support. Multiple runs will generate multiple copies of + // these history elements! + aspr.info( "Begin User Role Data Generation Processing "); + batch = new UserRoleDataGeneration(trans); + } else { // Might be a Report, Update or Temp Batch + Class<?> cls; + String classifier = ""; + try { + cls = ClassLoader.getSystemClassLoader().loadClass("com.att.authz.update."+toolName); + classifier = "Update:"; + } catch(ClassNotFoundException e) { + try { + cls = ClassLoader.getSystemClassLoader().loadClass("com.att.authz.reports."+toolName); + classifier = "Report:"; + } catch (ClassNotFoundException e2) { + try { + cls = ClassLoader.getSystemClassLoader().loadClass("com.att.authz.temp."+toolName); + classifier = "Temp Utility:"; + } catch (ClassNotFoundException e3) { + cls = null; + } + } + } + if(cls!=null) { + Constructor<?> cnst = cls.getConstructor(new Class[]{AuthzTrans.class}); + batch = (Batch)cnst.newInstance(trans); + env.info().log("Begin",classifier,toolName); + } + } + + if(batch==null) { + trans.error().log("No Batch named",toolName,"found"); + } + /* + * End New Batch Programs (inherit from Batch) here + */ + + } + if(batch!=null) { + batch.run(trans); + } + } finally { + tt.done(); + if(batch!=null) { + batch.close(trans); + } + StringBuilder sb = new StringBuilder("Task Times\n"); + trans.auditTrail(4, sb, AuthzTrans.REMOTE); + trans.info().log(sb); + } + } catch (Exception e) { + e.printStackTrace(System.err); + // Exceptions thrown by DB aren't stopping the whole process. + System.exit(1); + } + } + + +} + diff --git a/authz-batch/src/main/java/com/att/authz/BatchException.java b/authz-batch/src/main/java/com/att/authz/BatchException.java new file mode 100644 index 00000000..72475033 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/BatchException.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz; + +public class BatchException extends Exception { + + /** + * + */ + private static final long serialVersionUID = -3877245367723491192L; + + public BatchException() { + } + + public BatchException(String message) { + super(message); + } + + public BatchException(Throwable cause) { + super(cause); + } + + public BatchException(String message, Throwable cause) { + super(message, cause); + } + + public BatchException(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + +} diff --git a/authz-batch/src/main/java/com/att/authz/CassBatch.java b/authz-batch/src/main/java/com/att/authz/CassBatch.java new file mode 100644 index 00000000..5c247245 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/CassBatch.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz; + +import java.io.IOException; + +import com.att.authz.env.AuthzTrans; +import com.att.inno.env.APIException; +import com.att.inno.env.Env; +import com.att.inno.env.TimeTaken; +import com.att.inno.env.impl.Log4JLogTarget; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.exceptions.InvalidQueryException; + +public abstract class CassBatch extends Batch { + + protected CassBatch(AuthzTrans trans, String log4JName) throws APIException, IOException { + super(trans.env()); + // Flow all Env Logs to Log4j + Log4JLogTarget.setLog4JEnv(log4JName, env); + + TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE); + try { + session = cluster.connect(); + } finally { + tt.done(); + } + } + + @Override + protected void _close(AuthzTrans trans) { + session.close(); + trans.info().log("Closed Session"); + } + + public ResultSet executeQuery(String cql) { + return executeQuery(cql,""); + } + + public ResultSet executeQuery(String cql, String extra) { + if(isDryRun() && !cql.startsWith("SELECT")) { + if(extra!=null)env.info().log("Would query" + extra + ": " + cql); + } else { + if(extra!=null)env.info().log("query" + extra + ": " + cql); + try { + return session.execute(cql); + } catch (InvalidQueryException e) { + if(extra==null) { + env.info().log("query: " + cql); + } + throw e; + } + } + return null; + } + +}
\ No newline at end of file diff --git a/authz-batch/src/main/java/com/att/authz/FileCassBatch.java b/authz-batch/src/main/java/com/att/authz/FileCassBatch.java new file mode 100644 index 00000000..d037e75f --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/FileCassBatch.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz; + +import java.io.File; +import java.io.IOException; +import java.nio.file.DirectoryIteratorException; +import java.nio.file.DirectoryStream; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +import com.att.authz.env.AuthzTrans; +import com.att.inno.env.APIException; + +public abstract class FileCassBatch extends CassBatch { + + public FileCassBatch(AuthzTrans trans, String log4jName) throws APIException, IOException { + super(trans, log4jName); + } + + protected List<File> findAllFiles(String regex) { + List<File> files = new ArrayList<File>(); + FileSystem fileSystem = FileSystems.getDefault(); + PathMatcher pathMatcher = fileSystem.getPathMatcher("glob:" + regex); + Path path = Paths.get(System.getProperty("user.dir"), "data"); + + try { + DirectoryStream<Path> directoryStream = Files.newDirectoryStream( + path, regex); + for (Path file : directoryStream) { + if (pathMatcher.matches(file.getFileName())) { + files.add(file.toFile()); + } + } + } catch (IOException ex) { + ex.printStackTrace(); + } catch (DirectoryIteratorException ex) { + ex.printStackTrace(); + } + + return files; + } + + + +} diff --git a/authz-batch/src/main/java/com/att/authz/JobChange.java b/authz-batch/src/main/java/com/att/authz/JobChange.java new file mode 100644 index 00000000..235ebacc --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/JobChange.java @@ -0,0 +1,743 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +// test for case where I'm an admin + +package com.att.authz; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import com.att.authz.env.AuthzTrans; +import com.att.authz.org.Organization; +import com.att.authz.org.OrganizationFactory; +import com.att.inno.env.APIException; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.SimpleStatement; +import com.datastax.driver.core.Statement; + +public class JobChange extends Batch +{ + private class UserRole + { + String user; + String role; + } + private class UserCred + { + String user; + String ns; + } + + private class NamespaceOwner + { + String user; + String ns; + boolean responsible; + int ownerCount; + } + + + private AuthzTrans myTrans; + + private Map<String, ArrayList<UserRole>> rolesMap = new HashMap<String, ArrayList<UserRole>>(); + private Map<String, ArrayList<NamespaceOwner>> ownersMap = new HashMap<String, ArrayList<NamespaceOwner>>(); + private Map<String, ArrayList<UserCred>> credsMap = new HashMap<String, ArrayList<UserCred>>(); + + + public static void createDirectory( String dir ) + { + File f = new File( dir ); + + if ( ! f.exists()) + { + env.info().log( "creating directory: " + dir ); + boolean result = false; + + try + { + f.mkdir(); + result = true; + } catch(SecurityException e){ + e.printStackTrace(); + } + if(result) { + System.out.println("DIR created"); + } + } + } + + public static String getJobChangeDataFile() + { + File outFile = null; + BufferedWriter writer = null; + BufferedReader reader = null; + String line; + boolean errorFlag = false; + + try + { + createDirectory( "etc" ); + + outFile = new File("etc/jobchange." + getCurrentDate() ); + if (!outFile.exists()) + { + outFile.createNewFile(); + } + else + { + return( "etc/jobchange." + getCurrentDate() ); + } + + env.info().log("Creating the local file with the webphone data"); + + + + writer = new BufferedWriter(new FileWriter( + outFile.getAbsoluteFile())); + + URL u = new URL( "ftp://thprod37.sbc.com/jobchange_Delta.dat" ); + reader = new BufferedReader(new InputStreamReader( + new BufferedInputStream(u.openStream()))); + while ((line = reader.readLine()) != null) { + writer.write(line + "\n"); + } + + writer.close(); + reader.close(); + + env.info().log("Finished fetching the data from the webphone ftp site."); + return( "etc/jobchange." + getCurrentDate() ); + + } catch (MalformedURLException e) { + env.error().log("Could not open the remote job change data file.", e); + errorFlag = true; + + } catch (IOException e) { + env.error().log( + "Error while opening or writing to the local data file.", e); + errorFlag = true; + + } catch (Exception e) { + env.error().log("Error while fetching the data file.", e); + errorFlag = true; + + } finally { + if (errorFlag) + outFile.delete(); + } + return null; + } + + public static String getCurrentDate() + { + SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd"); + Date now = new Date(); + String strDate = sdfDate.format(now); + return strDate; + } + + public void loadUsersFromCred() + { + String query = "select id,ns from authz.cred" ; + + env.info().log( "query: " + query ); + + Statement stmt = new SimpleStatement( query ); + ResultSet results = session.execute(stmt); + + Iterator<Row> iter = results.iterator(); + while( iter.hasNext() ) + { + Row row = iter.next(); + String user = row.getString( "id" ); + String ns = row.getString( "ns" ); + String simpleUser = user.substring( 0, user.indexOf( "@" ) ); + + if ( isMechID( simpleUser ) ) + { + continue; + } + else if ( credsMap.get( simpleUser ) == null ) + { + credsMap.put( simpleUser, new ArrayList<UserCred>() ); + + UserCred newEntry = new UserCred(); + newEntry.user = user; + newEntry.ns = ns; + + credsMap.get( simpleUser ).add( newEntry ); + } + else + { + UserCred newEntry = new UserCred(); + newEntry.user = user; + newEntry.ns = ns; + + credsMap.get( simpleUser ).add( newEntry ); + } + + env.debug().log( String.format( "\tUser: %s NS: %s", user, ns ) ); + } + } + + public void loadUsersFromRoles() + { + String query = "select user,role from authz.user_role" ; + + env.info().log( "query: " + query ); + + Statement stmt = new SimpleStatement( query ); + ResultSet results = session.execute(stmt); + int total=0, flagged=0; + + Iterator<Row> iter = results.iterator(); + while( iter.hasNext() ) + { + Row row = iter.next(); + String user = row.getString( "user" ); + String role = row.getString( "role" ); + String simpleUser = user.substring( 0, user.indexOf( "@" ) ); + + if ( isMechID( simpleUser ) ) + { + continue; + } + else if ( rolesMap.get( simpleUser ) == null ) + { + rolesMap.put( simpleUser, new ArrayList<UserRole>() ); + + UserRole newEntry = new UserRole(); + newEntry.user = user; + newEntry.role = role; + + rolesMap.get( simpleUser ).add( newEntry ); + } + else + { + UserRole newEntry = new UserRole(); + newEntry.user = user; + newEntry.role = role; + + rolesMap.get( simpleUser ).add( newEntry ); + } + + env.debug().log( String.format( "\tUser: %s Role: %s", user, role ) ); + + ++total; + } + env.info().log( String.format( "rows read: %d expiring: %d", total, flagged ) ); + } + + public void loadOwnersFromNS() + { + String query = "select name,admin,responsible from authz.ns" ; + + env.info().log( "query: " + query ); + + Statement stmt = new SimpleStatement( query ); + ResultSet results = session.execute(stmt); + + Iterator<Row> iter = results.iterator(); + while( iter.hasNext() ) + { + Row row = iter.next(); + Set<String> responsibles = row.getSet( "responsible", String.class ); + + for ( String user : responsibles ) + { + env.info().log( String.format( "Found responsible %s", user ) ); + String simpleUser = user.substring( 0, user.indexOf( "@" ) ); + + if ( isMechID( simpleUser ) ) + { + continue; + } + else if ( ownersMap.get( simpleUser ) == null ) + { + ownersMap.put( simpleUser, new ArrayList<NamespaceOwner>() ); + + NamespaceOwner newEntry = new NamespaceOwner(); + newEntry.user = user; + newEntry.ns = row.getString( "name" ); + newEntry.ownerCount = responsibles.size(); + newEntry.responsible = true; + ownersMap.get( simpleUser ).add( newEntry ); + } + else + { + NamespaceOwner newEntry = new NamespaceOwner(); + newEntry.user = user; + newEntry.ns = row.getString( "name" ); + newEntry.ownerCount = responsibles.size(); + newEntry.responsible = true; + ownersMap.get( simpleUser ).add( newEntry ); + } + } + Set<String> admins = row.getSet( "admin", String.class ); + + for ( String user : admins ) + { + env.info().log( String.format( "Found admin %s", user ) ); + String simpleUser = user.substring( 0, user.indexOf( "@" ) ); + + if ( isMechID( simpleUser ) ) + { + continue; + } + else if ( ownersMap.get( simpleUser ) == null ) + { + ownersMap.put( simpleUser, new ArrayList<NamespaceOwner>() ); + + NamespaceOwner newEntry = new NamespaceOwner(); + newEntry.user = user; + newEntry.ns = row.getString( "name" ); + newEntry.responsible = false; + newEntry.ownerCount = -1; // + ownersMap.get( simpleUser ).add( newEntry ); + } + else + { + NamespaceOwner newEntry = new NamespaceOwner(); + newEntry.user = user; + newEntry.ns = row.getString( "name" ); + newEntry.responsible = false; + newEntry.ownerCount = -1; // + ownersMap.get( simpleUser ).add( newEntry ); + } + } + + } + } + + /** + * Processes the specified JobChange data file obtained from Webphone. Each line is + * read and processed and any fallout is written to the specified fallout file. + * If fallout file already exists it is deleted and a new one is created. A + * comparison of the supervisor id in the job data file is done against the one returned + * by the authz service and if the supervisor Id has changed then the record is updated + * using the authz service. An email is sent to the new supervisor to approve the roles + * assigned to the user. + * + * @param fileName - name of the file to process including its path + * @param falloutFileName - the file where the fallout entries have to be written + * @param validDate - the valid effective date when the user had moved to the new supervisor + * @throws Exception + */ + public void processJobChangeDataFile(String fileName, + String falloutFileName, Date validDate) throws Exception + { + + BufferedWriter writer = null; + + try { + + env.info().log("Reading file: " + fileName ); + + FileInputStream fstream = new FileInputStream(fileName); + BufferedReader br = new BufferedReader(new InputStreamReader(fstream)); + + String strLine; + + while ((strLine = br.readLine()) != null) { + processLine( strLine, writer ); + } + + br.close(); + + + } catch (IOException e) { + env.error().log( "Error while reading from the input data file: " + e ); + throw e; + } + } + + public void handleAdminChange( String user ) + { + ArrayList<NamespaceOwner> val = ownersMap.get( user ); + + for ( NamespaceOwner r : val ) + { + env.info().log( "handleAdminChange: " + user ); + AuthzTrans trans = env.newTransNoAvg(); + + + if ( r.responsible ) + { + env.info().log( String.format( "delete from NS owner: %s, NS: %s, count: %s", + r.user, r.ns, r.ownerCount ) ); + + aspr.info( String.format( "action=DELETE_NS_OWNER, user=%s, ns=%s", + r.user, r.ns ) ); + if ( r.ownerCount < 2 ) + { + // send warning email to aaf-support, after this deletion, no owner for NS + ArrayList<String> toAddress = new ArrayList<String>(); + toAddress.add( "XXX_EMAIL" ); + + env.warn().log( "removing last owner from namespace" ); + + Organization org = null; + org = getOrgFromID( myTrans, org, toAddress.get(0) ); + + env.info().log( "calling getOrgFromID with " + toAddress.get(0) ); + + if ( org != null ) + { + try + { + aspr.info( String.format( "action=EMAIL_NO_OWNER_NS to=%s, user=%s, ns=%s", + toAddress.get(0), r.user, r.ns ) ); + org.sendEmail( trans, toAddress, + new ArrayList<String>(), + String.format( "WARNING: no owners for AAF namespace '%s'", r.ns ), // subject: + String.format( "AAF recieved a jobchange notification for user %s who was the owner of the '%s' namespace. Please identify a new owner for this namespace and update AAF.", r.user, r.ns ), // body of msg + true ); + } catch (Exception e) { + env.error().log("calling sendEmail()"); + + e.printStackTrace(); + } + } + else + { + env.error().log( "Failed getOrgFromID" ); + } + } + } + else + { + env.info().log( String.format( "delete from NS admin: %s, NS: %s", + r.user, r.ns ) ); + + aspr.info( String.format( "action=DELETE_NS_ADMIN, user=%s, ns=%s", + r.user, r.ns ) ); + } + + String field = (r.responsible == true) ? "responsible" : "admin"; + + String query = String.format( "update authz.ns set %s = %s - {'%s'} where name = '%s'", + field, field, r.user, r.ns ) ; + env.info().log( "query: " + query ); + Statement stmt = new SimpleStatement( query ); + /*Row row = */session.execute(stmt).one(); + + String attribQuery = String.format( "delete from authz.ns_attrib where ns = '%s' AND type='%s' AND name='%s'", + r.ns, field, r.user); + env.info().log( "ns_attrib query: " + attribQuery); + Statement attribStmt = new SimpleStatement( attribQuery ); + /*Row attribRow = */session.execute(attribStmt).one(); + + } + } + + public void handleRoleChange( String user ) + { + ArrayList<UserRole> val = rolesMap.get( user ); + + for ( UserRole r : val ) + { + env.info().log( "handleRoleChange: " + user ); + + env.info().log( String.format( "delete from %s from user_role: %s", + r.user, r.role ) ); + + aspr.info( String.format( "action=DELETE_FROM_ROLE, user=%s, role=%s", + r.user, r.role ) ); + + + String query = String.format( "delete from authz.user_role where user = '%s' and role = '%s'", + r.user, r.role ); + + env.info().log( "query: " + query ); + + Statement stmt = new SimpleStatement( query ); + /* Row row = */ session.execute(stmt).one(); + + } + } + + public void handleCredChange( String user ) + { + ArrayList<UserCred> val = credsMap.get( user ); + + for ( UserCred r : val ) + { + env.info().log( "handleCredChange: " + user ); + + env.info().log( String.format( "delete user %s cred from ns: %s", + r.user, r.ns ) ); + + aspr.info( String.format( "action=DELETE_FROM_CRED, user=%s, ns=%s", + r.user, r.ns ) ); + + String query = String.format( "delete from authz.cred where id = '%s'", + r.user ); + + env.info().log( "query: " + query ); + + Statement stmt = new SimpleStatement( query ); + /*Row row = */session.execute(stmt).one(); + + } + + } + + public boolean processLine(String line, BufferedWriter writer) throws IOException + { + SimpleDateFormat sdfDate = new SimpleDateFormat("yyyyMMdd"); + boolean errorFlag = false; + String errorMsg = ""; + + try + { + String[] phoneInfo = line.split( "\\|" ); + + if ((phoneInfo != null) && (phoneInfo.length >= 8) + && (!phoneInfo[0].startsWith("#"))) + { + String user = phoneInfo[0]; + String newSupervisor = phoneInfo[7]; + Date effectiveDate = sdfDate.parse(phoneInfo[8].trim()); + + env.debug().log( String.format( "checking user: %s, newSupervisor: %s, date: %s", + user, newSupervisor, effectiveDate ) ); + + // Most important case, user is owner of a namespace + // + if ( ownersMap.get( user ) != null ) + { + env.info().log( String.format( "Found %s as a namespace admin/owner", user ) ); + handleAdminChange( user ); + } + + if ( credsMap.get( user ) != null ) + { + env.info().log( String.format( "Found %s in cred table", user ) ); + handleCredChange( user ); + } + + if ( rolesMap.get( user ) != null ) + { + env.info().log( String.format( "Found %s in a role ", user ) ); + handleRoleChange( user ); + } + } + + else if (phoneInfo[0].startsWith("#")) + { + return true; + } + else + { + env.warn().log("Can't parse. Skipping the line." + line); + errorFlag = true; + } + } catch (Exception e) { + errorFlag = true; + errorMsg = e.getMessage(); + env.error().log( "Error while processing line:" + line + e ); + e.printStackTrace(); + } finally { + if (errorFlag) { + env.info().log( "Fallout enrty being written for line:" + line ); + writer.write(line + "|Failed to update supervisor for user:" + errorMsg + "\n"); + } + } + return true; + } + + + public JobChange(AuthzTrans trans) throws APIException, IOException { + super( trans.env() ); + myTrans = trans; + session = cluster.connect(); + } + + public Organization getOrgFromID( AuthzTrans trans, Organization _org, String user ) { + Organization org = _org; + if ( org == null || ! user.endsWith( org.getRealm() ) ) { + int idx = user.lastIndexOf('.'); + if ( idx > 0 ) + idx = user.lastIndexOf( '.', idx-1 ); + + org = null; + if ( idx > 0 ) { + try { + org = OrganizationFactory.obtain( trans.env(), user.substring( idx+1 ) ); + } catch (Exception e) { + trans.error().log(e,"Failure Obtaining Organization"); + } + } + + if ( org == null ) { + PrintStream fallout = null; + + try { + fallout= fallout(fallout, "Fallout"); + fallout.print("INVALID_ID,"); + fallout.println(user); + } catch (Exception e) { + env.error().log("Could not write to Fallout File",e); + } + return( null ); + } + } + return( org ); + } + + public void dumpOwnersMap() + { + for ( Map.Entry<String, ArrayList<NamespaceOwner>> e : ownersMap.entrySet() ) + { + String key = e.getKey(); + ArrayList<NamespaceOwner> values = e.getValue(); + + env.info().log( "ns user: " + key ); + + for ( NamespaceOwner r : values ) + { + env.info().log( String.format( "\tNS-user: %s, NS-name: %s, ownerCount: %d", + r.user, r.ns, r.ownerCount ) ); + + } + } + } + + public void dumpRolesMap() + { + for ( Map.Entry<String, ArrayList<UserRole>> e : rolesMap.entrySet() ) + { + String key = e.getKey(); + ArrayList<UserRole> values = e.getValue(); + + env.info().log( "user: " + key ); + + for ( UserRole r : values ) + { + env.info().log( String.format( "\trole-user: %s, role-name: %s", + r.user, r.role ) ); + } + } + } + public void dumpCredMap() + { + for ( Map.Entry<String, ArrayList<UserCred>> e : credsMap.entrySet() ) + { + String key = e.getKey(); + ArrayList<UserCred> values = e.getValue(); + + env.info().log( "user: " + key ); + + for ( UserCred r : values ) + { + env.info().log( String.format( "\tcred-user: %s, ns: %s", + r.user, r.ns ) ); + } + + } + } + + @Override + protected void run (AuthzTrans trans) + { + if ( acquireRunLock( this.getClass().getName() ) != 1 ) { + env.warn().log( "Cannot acquire run lock, exiting" ); + System.exit( 1 ); + } + + try { +// Map<String,EmailMsg> email = new HashMap<String,EmailMsg>(); + + try + { + String workingDir = System.getProperty("user.dir"); + env.info().log( "Process jobchange file. PWD is " + workingDir ); + + loadUsersFromRoles(); + loadOwnersFromNS(); + loadUsersFromCred(); + + dumpRolesMap(); + dumpOwnersMap(); + dumpCredMap(); + + String fname = getJobChangeDataFile(); + + if ( fname == null ) + { + env.warn().log("getJobChangedatafile returned null"); + } + else + { + env.info().log("done with FTP"); + } + processJobChangeDataFile( fname, "fallout", null ); + } + catch (Exception e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (SecurityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +/* + private class EmailMsg { + private boolean urgent = false; + public String url; + public Organization org; + public String summary; + + public EmailMsg() { + org = null; + summary = ""; + } + + public boolean getUrgent() { + return( this.urgent ); + } + + public void setUrgent( boolean val ) { + this.urgent = val; + } + public void setOrg( Organization newOrg ) { + this.org = newOrg; + } + public Organization getOrg() { + return( this.org ); + } + } +*/ + @Override + protected void _close(AuthzTrans trans) { + session.close(); + } +} + + diff --git a/authz-batch/src/main/java/com/att/authz/UserRoleDataGeneration.java b/authz-batch/src/main/java/com/att/authz/UserRoleDataGeneration.java new file mode 100644 index 00000000..f638a001 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/UserRoleDataGeneration.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz; + +import java.io.IOException; +import java.util.Iterator; +import java.util.Random; +import java.util.UUID; + +import com.att.authz.env.AuthzTrans; +import com.att.inno.env.APIException; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.SimpleStatement; +import com.datastax.driver.core.Statement; + +public class UserRoleDataGeneration extends Batch { + + protected UserRoleDataGeneration(AuthzTrans trans) throws APIException, IOException { + super(trans.env()); + session = cluster.connect(); + + } + + @Override + protected void run(AuthzTrans trans) { + + String query = "select * from authz.history" ; + + env.info().log( "query: " + query ); + + Statement stmt = new SimpleStatement( query ); + ResultSet results = session.execute(stmt); + int total=0; + + Iterator<Row> iter = results.iterator(); + + Random rand = new Random(); + + int min = 1; + int max = 32; + + while( iter.hasNext() ) { + Row row = iter.next(); + if (row.getString("target").equals("user_role")) { + int randomNum = rand.nextInt((max - min) + 1) + min; + + String newId = modifiedTimeuid(row.getUUID("id").toString(), randomNum); + String subject = row.getString("subject"); + String newSubject = subject.split("\\|")[1]; + + String newInsert = insertStmt(row, newId, "role", newSubject); + Statement statement = new SimpleStatement(newInsert); + session.executeAsync(statement); + + total++; + } + } + + env.info().log(total+ " history elements inserted for user roles"); + + } + + private String insertStmt(Row row, String newId, String newTarget, String newSubject) { + StringBuilder sb = new StringBuilder(); + sb.append("INSERT INTO authz.history (id,action,memo,reconstruct,subject,target,user,yr_mon) VALUES ("); + sb.append(newId+","); + sb.append("'"+row.getString("action")+"',"); + sb.append("'"+row.getString("memo")+"',"); + sb.append("null,"); + sb.append("'"+newSubject+"',"); + sb.append("'"+newTarget+"',"); + sb.append("'"+row.getString("user")+"',"); + sb.append(row.getInt("yr_mon")); + sb.append(")"); + + return sb.toString(); + } + + private String modifiedTimeuid(String origTimeuuid, int rand) { + UUID uuid = UUID.fromString(origTimeuuid); + + long bottomBits = uuid.getLeastSignificantBits(); + long newBottomBits = bottomBits + (1 << rand); + if (newBottomBits - bottomBits == 0) + env.info().log("Duplicate!\t"+uuid + " not duplicated for role history function."); + + UUID newUuid = new UUID(uuid.getMostSignificantBits(),newBottomBits); + return newUuid.toString(); + } + + @Override + protected void _close(AuthzTrans trans) { + session.close(); + aspr.info( "End UserRoleDataGeneration processing" ); + + } + +} diff --git a/authz-batch/src/main/java/com/att/authz/actions/Action.java b/authz-batch/src/main/java/com/att/authz/actions/Action.java new file mode 100644 index 00000000..f69bb22a --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/actions/Action.java @@ -0,0 +1,11 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.actions; + +import com.att.authz.env.AuthzTrans; +import com.att.authz.layer.Result; + +public interface Action<T,RV> { + public Result<RV> exec(AuthzTrans trans, T ur); +}
\ No newline at end of file diff --git a/authz-batch/src/main/java/com/att/authz/actions/ActionDAO.java b/authz-batch/src/main/java/com/att/authz/actions/ActionDAO.java new file mode 100644 index 00000000..4e951f81 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/actions/ActionDAO.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.actions; + +import java.io.IOException; + +import com.att.authz.env.AuthzTrans; +import com.att.dao.CassAccess; +import com.att.dao.aaf.hl.Function; +import com.att.dao.aaf.hl.Question; +import com.att.inno.env.APIException; +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.Session; + +public abstract class ActionDAO<T,RV> implements Action<T,RV> { + protected final Question q; + protected final Function f; + private boolean clean; + + public ActionDAO(AuthzTrans trans, Cluster cluster) throws APIException, IOException { + q = new Question(trans, cluster, CassAccess.KEYSPACE, false); + f = new Function(trans,q); + clean = true; + } + + public ActionDAO(AuthzTrans trans, ActionDAO<?,?> predecessor) { + q = predecessor.q; + f = new Function(trans,q); + clean = false; + } + + public Session getSession(AuthzTrans trans) throws APIException, IOException { + return q.historyDAO.getSession(trans); + } + + public void close(AuthzTrans trans) { + if(clean) { + q.close(trans); + } + } + +} diff --git a/authz-batch/src/main/java/com/att/authz/actions/ActionPuntDAO.java b/authz-batch/src/main/java/com/att/authz/actions/ActionPuntDAO.java new file mode 100644 index 00000000..fb94ab30 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/actions/ActionPuntDAO.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.actions; + +import java.io.IOException; +import java.security.SecureRandom; +import java.util.Date; +import java.util.GregorianCalendar; + +import com.att.authz.env.AuthzTrans; +import com.att.inno.env.APIException; +import com.datastax.driver.core.Cluster; + +public abstract class ActionPuntDAO<T, RV> extends ActionDAO<T, RV> { + private static final SecureRandom random = new SecureRandom(); + private int months, range; + protected static final Date now = new Date(); + + public ActionPuntDAO(AuthzTrans trans, Cluster cluster, int months, int range) throws APIException, IOException { + super(trans, cluster); + this.months = months; + this.range = range; + } + + public ActionPuntDAO(AuthzTrans trans, ActionDAO<?, ?> predecessor, int months, int range) { + super(trans, predecessor); + this.months = months; + this.range = range; + } + + + protected Date puntDate() { + GregorianCalendar temp = new GregorianCalendar(); + temp.setTime(now); + if(range>0) { + int forward = months+Math.abs(random.nextInt()%range); + temp.add(GregorianCalendar.MONTH, forward); + temp.add(GregorianCalendar.DAY_OF_MONTH, (random.nextInt()%30)-15); + } + return temp.getTime(); + + } + +} diff --git a/authz-batch/src/main/java/com/att/authz/actions/CredDelete.java b/authz-batch/src/main/java/com/att/authz/actions/CredDelete.java new file mode 100644 index 00000000..7d5fd1ef --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/actions/CredDelete.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.actions; + +import java.io.IOException; + +import com.att.authz.env.AuthzTrans; +import com.att.authz.layer.Result; +import com.att.dao.aaf.cass.CredDAO; +import com.att.inno.env.APIException; +import com.att.inno.env.util.Chrono; +import com.datastax.driver.core.Cluster; + +public class CredDelete extends ActionDAO<CredDAO.Data,Void> { + + public CredDelete(AuthzTrans trans, Cluster cluster) throws APIException, IOException { + super(trans, cluster); + } + + public CredDelete(AuthzTrans trans, ActionDAO<?,?> adao) { + super(trans, adao); + } + + @Override + public Result<Void> exec(AuthzTrans trans, CredDAO.Data cred) { + Result<Void> rv = q.credDAO.delete(trans, cred, true); // need to read for undelete + trans.info().log("Deleted:",cred.id,CredPrint.type(cred.type),Chrono.dateOnlyStamp(cred.expires)); + return rv; + } +}
\ No newline at end of file diff --git a/authz-batch/src/main/java/com/att/authz/actions/CredPrint.java b/authz-batch/src/main/java/com/att/authz/actions/CredPrint.java new file mode 100644 index 00000000..ff3f7ff2 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/actions/CredPrint.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.actions; + +import com.att.authz.env.AuthzTrans; +import com.att.authz.layer.Result; +import com.att.dao.aaf.cass.CredDAO; +import com.att.inno.env.util.Chrono; + +public class CredPrint implements Action<CredDAO.Data,Void> { + private String text; + + public CredPrint(String text) { + this.text = text; + } + + @Override + public Result<Void> exec(AuthzTrans trans, CredDAO.Data cred) { + trans.info().log(text,cred.id,type(cred.type),Chrono.dateOnlyStamp(cred.expires)); + return Result.ok(); + } + + + public static String type(int type) { + switch(type) { + case CredDAO.BASIC_AUTH: // 1 + return "OLD"; + case CredDAO.BASIC_AUTH_SHA256: // 2 + return "U/P"; + case CredDAO.CERT_SHA256_RSA: // 200 + return "Cert"; + default: + return "Unknown"; + } + } + +}
\ No newline at end of file diff --git a/authz-batch/src/main/java/com/att/authz/actions/CredPunt.java b/authz-batch/src/main/java/com/att/authz/actions/CredPunt.java new file mode 100644 index 00000000..195dc67e --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/actions/CredPunt.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.actions; + +import java.io.IOException; +import java.util.Date; +import java.util.List; + +import com.att.authz.env.AuthzTrans; +import com.att.authz.layer.Result; +import com.att.dao.aaf.cass.CredDAO; +import com.att.inno.env.APIException; +import com.att.inno.env.util.Chrono; +import com.datastax.driver.core.Cluster; + +public class CredPunt extends ActionPuntDAO<CredDAO.Data,Void> { + + public CredPunt(AuthzTrans trans, Cluster cluster, int months, int range) throws IOException, APIException { + super(trans,cluster,months,range); + } + + public CredPunt(AuthzTrans trans, ActionDAO<?,?> adao, int months, int range) throws IOException { + super(trans, adao, months,range); + } + + public Result<Void> exec(AuthzTrans trans, CredDAO.Data cdd) { + Result<Void> rv = null; + Result<List<CredDAO.Data>> read = q.credDAO.read(trans, cdd); + if(read.isOKhasData()) { + for(CredDAO.Data data : read.value) { + Date from = data.expires; + data.expires = puntDate(); + if(data.expires.before(from)) { + trans.error().printf("Error: %s is before %s", Chrono.dateOnlyStamp(data.expires), Chrono.dateOnlyStamp(from)); + } else { + rv = q.credDAO.update(trans, data); + trans.info().log("Updated Cred",cdd.id, CredPrint.type(cdd.type), "from",Chrono.dateOnlyStamp(from),"to",Chrono.dateOnlyStamp(data.expires)); + } + } + } + if(rv==null) { + rv=Result.err(read); + } + return rv; + } +}
\ No newline at end of file diff --git a/authz-batch/src/main/java/com/att/authz/actions/Email.java b/authz-batch/src/main/java/com/att/authz/actions/Email.java new file mode 100644 index 00000000..df491df3 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/actions/Email.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.actions; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import com.att.authz.env.AuthzTrans; +import com.att.authz.layer.Result; +import com.att.authz.org.Organization; + +public class Email implements Action<Organization,Void>{ + protected final List<String> toList; + protected final List<String> ccList; + private final String[] defaultCC; + protected String subject; + private String preamble; + private Message msg; + private String sig; + protected String lineIndent=" "; + + + public Email(String ... defaultCC) { + toList = new ArrayList<String>(); + this.defaultCC = defaultCC; + ccList = new ArrayList<String>(); + clear(); + } + + public Email clear() { + toList.clear(); + ccList.clear(); + for(String s: defaultCC) { + ccList.add(s); + } + return this; + } + + + public void indent(String indent) { + lineIndent = indent; + } + + public void preamble(String format, Object ... args) { + preamble = String.format(format, args); + } + + public Email addTo(Collection<String> users) { + toList.addAll(users); + return this; + } + + public Email addTo(String email) { + toList.add(email); + return this; + } + + + public Email subject(String format, Object ... args) { + subject = String.format(format, args); + return this; + } + + + public Email signature(String format, Object ... args) { + sig = String.format(format, args); + return this; + } + + public void msg(Message msg) { + this.msg = msg; + } + + @Override + public Result<Void> exec(AuthzTrans trans, Organization org) { + StringBuilder sb = new StringBuilder(); + if(preamble!=null) { + sb.append(lineIndent); + sb.append(preamble); + sb.append("\n\n"); + } + + if(msg!=null) { + msg.msg(sb,lineIndent); + sb.append("\n"); + } + + if(sig!=null) { + sb.append(sig); + sb.append("\n"); + } + + return exec(trans,org,sb); + } + + protected Result<Void> exec(AuthzTrans trans, Organization org, StringBuilder sb) { + try { + /* int status = */ + org.sendEmail(trans, + toList, + ccList, + subject, + sb.toString(), + false); + } catch (Exception e) { + return Result.err(Result.ERR_ActionNotCompleted,e.getMessage()); + } + return Result.ok(); + + } +} diff --git a/authz-batch/src/main/java/com/att/authz/actions/EmailPrint.java b/authz-batch/src/main/java/com/att/authz/actions/EmailPrint.java new file mode 100644 index 00000000..5b356ce1 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/actions/EmailPrint.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.actions; + +import java.io.PrintStream; + +import com.att.authz.env.AuthzTrans; +import com.att.authz.layer.Result; +import com.att.authz.org.Organization; + +public class EmailPrint extends Email { + + public EmailPrint(String... defaultCC) { + super(defaultCC); + } + + /* (non-Javadoc) + * @see com.att.authz.actions.Email#exec(com.att.authz.org.Organization, java.lang.StringBuilder) + */ + @Override + protected Result<Void> exec(AuthzTrans trans, Organization org, StringBuilder msg) { + PrintStream out = System.out; + boolean first = true; + out.print("To: "); + for(String s: toList) { + if(first) {first = false;} + else {out.print(',');} + out.print(s); + } + out.println(); + + first = true; + out.print("CC: "); + for(String s: ccList) { + if(first) {first = false;} + else {out.print(',');} + out.print(s); + } + out.println(); + + out.print("Subject: "); + out.println(subject); + out.println(); + + out.println(msg); + return Result.ok(); + + } + +} diff --git a/authz-batch/src/main/java/com/att/authz/actions/FADelete.java b/authz-batch/src/main/java/com/att/authz/actions/FADelete.java new file mode 100644 index 00000000..4ce11e54 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/actions/FADelete.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.actions; + +import java.io.IOException; +import java.util.List; + +import com.att.authz.env.AuthzTrans; +import com.att.authz.helpers.Future; +import com.att.authz.layer.Result; +import com.att.dao.aaf.cass.ApprovalDAO; +import com.att.dao.aaf.cass.FutureDAO; +import com.att.inno.env.APIException; +import com.att.inno.env.util.Chrono; +import com.datastax.driver.core.Cluster; + +public class FADelete extends ActionDAO<Future,Void> { + public FADelete(AuthzTrans trans, Cluster cluster) throws APIException, IOException { + super(trans, cluster); + } + + public FADelete(AuthzTrans trans, ActionDAO<?,?> adao) { + super(trans, adao); + } + + @Override + public Result<Void> exec(AuthzTrans trans, Future f) { + FutureDAO.Data fdd = new FutureDAO.Data(); + fdd.id=f.id; + Result<Void> rv = q.futureDAO.delete(trans, fdd, true); // need to read for undelete + if(rv.isOK()) { + trans.info().log("Deleted:",f.id,f.memo,"expiring on",Chrono.dateOnlyStamp(f.expires)); + } else { + trans.info().log("Failed to Delete Approval"); + } + + Result<List<ApprovalDAO.Data>> ral = q.approvalDAO.readByTicket(trans, f.id); + if(ral.isOKhasData()) { + for(ApprovalDAO.Data add : ral.value) { + rv = q.approvalDAO.delete(trans, add, false); + if(rv.isOK()) { + trans.info().log("Deleted: Approval",add.id,"on ticket",add.ticket,"for",add.approver); + } else { + trans.info().log("Failed to Delete Approval"); + } + } + } + return rv; + } + +}
\ No newline at end of file diff --git a/authz-batch/src/main/java/com/att/authz/actions/FAPrint.java b/authz-batch/src/main/java/com/att/authz/actions/FAPrint.java new file mode 100644 index 00000000..a687dc1b --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/actions/FAPrint.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.actions; + +import com.att.authz.env.AuthzTrans; +import com.att.authz.helpers.Future; +import com.att.authz.layer.Result; +import com.att.inno.env.util.Chrono; + +public class FAPrint implements Action<Future,Void> { + private String text; + + public FAPrint(String text) { + this.text = text; + } + + @Override + public Result<Void> exec(AuthzTrans trans, Future f) { + trans.info().log(text,f.id,f.memo,"expiring on",Chrono.dateOnlyStamp(f.expires)); + return Result.ok(); + } +}
\ No newline at end of file diff --git a/authz-batch/src/main/java/com/att/authz/actions/Key.java b/authz-batch/src/main/java/com/att/authz/actions/Key.java new file mode 100644 index 00000000..89b7c6f8 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/actions/Key.java @@ -0,0 +1,8 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.actions; + +public interface Key<HELPER> { + public String key(HELPER H); +} diff --git a/authz-batch/src/main/java/com/att/authz/actions/Message.java b/authz-batch/src/main/java/com/att/authz/actions/Message.java new file mode 100644 index 00000000..2aca4eac --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/actions/Message.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.actions; + +import java.util.ArrayList; +import java.util.List; + +public class Message { + public final List<String> lines; + + public Message() { + lines = new ArrayList<String>(); + } + + public void clear() { + lines.clear(); + } + + public void line(String format, Object ... args) { + lines.add(String.format(format, args)); + } + + public void msg(StringBuilder sb, String lineIndent) { + if(lines.size()>0) { + for(String line : lines) { + sb.append(lineIndent); + sb.append(line); + sb.append('\n'); + } + } + } +} diff --git a/authz-batch/src/main/java/com/att/authz/actions/URAdd.java b/authz-batch/src/main/java/com/att/authz/actions/URAdd.java new file mode 100644 index 00000000..3e254e9f --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/actions/URAdd.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.actions; + +import java.io.IOException; + +import com.att.authz.env.AuthzTrans; +import com.att.authz.helpers.UserRole; +import com.att.authz.layer.Result; +import com.att.dao.aaf.cass.UserRoleDAO; +import com.att.dao.aaf.cass.UserRoleDAO.Data; +import com.att.inno.env.APIException; +import com.att.inno.env.util.Chrono; +import com.datastax.driver.core.Cluster; + +public class URAdd extends ActionDAO<UserRole,UserRoleDAO.Data> { + public URAdd(AuthzTrans trans, Cluster cluster) throws APIException, IOException { + super(trans, cluster); + } + + public URAdd(AuthzTrans trans, ActionDAO<?,?> adao) { + super(trans, adao); + } + + @Override + public Result<Data> exec(AuthzTrans trans, UserRole ur) { + UserRoleDAO.Data urd = new UserRoleDAO.Data(); + urd.user = ur.user; + urd.role = ur.role; + urd.ns=ur.ns; + urd.rname = ur.rname; + urd.expires = ur.expires; + Result<Data> rv = q.userRoleDAO.create(trans, urd); + trans.info().log("Added:",ur.role,ur.user,"on",Chrono.dateOnlyStamp(ur.expires)); + return rv; + } + +}
\ No newline at end of file diff --git a/authz-batch/src/main/java/com/att/authz/actions/URDelete.java b/authz-batch/src/main/java/com/att/authz/actions/URDelete.java new file mode 100644 index 00000000..064b6dce --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/actions/URDelete.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.actions; + +import java.io.IOException; + +import com.att.authz.env.AuthzTrans; +import com.att.authz.helpers.UserRole; +import com.att.authz.layer.Result; +import com.att.dao.aaf.cass.UserRoleDAO; +import com.att.inno.env.APIException; +import com.att.inno.env.util.Chrono; +import com.datastax.driver.core.Cluster; + +public class URDelete extends ActionDAO<UserRole,Void> { + public URDelete(AuthzTrans trans, Cluster cluster) throws APIException, IOException { + super(trans, cluster); + } + + public URDelete(AuthzTrans trans, ActionDAO<?,?> adao) { + super(trans, adao); + } + + @Override + public Result<Void> exec(AuthzTrans trans, UserRole ur) { + UserRoleDAO.Data urd = new UserRoleDAO.Data(); + urd.user = ur.user; + urd.role = ur.role; + Result<Void> rv = q.userRoleDAO.delete(trans, urd, true); // need to read for undelete + trans.info().log("Deleted:",ur.role,ur.user,"on",Chrono.dateOnlyStamp(ur.expires)); + return rv; + } + +}
\ No newline at end of file diff --git a/authz-batch/src/main/java/com/att/authz/actions/URFutureApprove.java b/authz-batch/src/main/java/com/att/authz/actions/URFutureApprove.java new file mode 100644 index 00000000..3401080c --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/actions/URFutureApprove.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.actions; + +import java.io.IOException; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.List; + +import com.att.authz.env.AuthzTrans; +import com.att.authz.helpers.UserRole; +import com.att.authz.layer.Result; +import com.att.authz.org.Organization.Expiration; +import com.att.authz.org.Organization.Identity; +import com.att.dao.aaf.cass.FutureDAO; +import com.att.dao.aaf.cass.NsDAO; +import com.att.dao.aaf.hl.Function; +import com.att.dao.aaf.hl.Question; +import com.att.inno.env.APIException; +import com.att.inno.env.util.Chrono; +import com.datastax.driver.core.Cluster; + +public class URFutureApprove extends ActionDAO<UserRole, List<Identity>> implements Action<UserRole,List<Identity>>, Key<UserRole> { + private final Date start, expires; + + public URFutureApprove(AuthzTrans trans, Cluster cluster) throws APIException, IOException { + super(trans,cluster); + GregorianCalendar gc = new GregorianCalendar(); + start = gc.getTime(); + expires = trans.org().expiration(gc, Expiration.Future).getTime(); + } + + public URFutureApprove(AuthzTrans trans, ActionDAO<?,?> adao) { + super(trans, adao); + GregorianCalendar gc = new GregorianCalendar(); + start = gc.getTime(); + expires = trans.org().expiration(gc, Expiration.Future).getTime(); + } + + @Override + public Result<List<Identity>> exec(AuthzTrans trans, UserRole ur) { + Result<NsDAO.Data> rns = q.deriveNs(trans, ur.ns); + if(rns.isOK()) { + + FutureDAO.Data data = new FutureDAO.Data(); + data.id=null; // let Create function assign UUID + data.target=Function.FOP_USER_ROLE; + + data.memo = key(ur); + data.start = start; + data.expires = expires; + try { + data.construct = ur.to().bytify(); + } catch (IOException e) { + return Result.err(e); + } + Result<List<Identity>> rapprovers = f.createFuture(trans, data, Function.FOP_USER_ROLE, ur.user, rns.value, "U"); + return rapprovers; + } else { + return Result.err(rns); + } + } + + @Override + public String key(UserRole ur) { + String expire; + if(expires.before(start)) { + expire = "' - EXPIRED "; + } else { + expire = "' - expiring "; + } + + if(Question.OWNER.equals(ur.rname)) { + return "Re-Validate Ownership for AAF Namespace '" + ur.ns + expire + Chrono.dateOnlyStamp(ur.expires); + } else if(Question.ADMIN.equals(ur.rname)) { + return "Re-Validate as Administrator for AAF Namespace '" + ur.ns + expire + Chrono.dateOnlyStamp(ur.expires); + } else { + return "Re-Approval in Role '" + ur.role + expire + Chrono.dateOnlyStamp(ur.expires); + } + } + +}
\ No newline at end of file diff --git a/authz-batch/src/main/java/com/att/authz/actions/URFuturePrint.java b/authz-batch/src/main/java/com/att/authz/actions/URFuturePrint.java new file mode 100644 index 00000000..812aa81e --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/actions/URFuturePrint.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.actions; + +import java.util.ArrayList; +import java.util.List; + +import com.att.authz.env.AuthzTrans; +import com.att.authz.helpers.UserRole; +import com.att.authz.layer.Result; +import com.att.authz.org.Organization.Identity; +import com.att.inno.env.util.Chrono; + + +public class URFuturePrint implements Action<UserRole,List<Identity>> { + private String text; + private final static List<Identity> rv = new ArrayList<Identity>(); + + public URFuturePrint(String text) { + this.text = text; + } + + @Override + public Result<List<Identity>> exec(AuthzTrans trans, UserRole ur) { + trans.info().log(text,ur.user,"to",ur.role,"on",Chrono.dateOnlyStamp(ur.expires)); + return Result.ok(rv); + }}
\ No newline at end of file diff --git a/authz-batch/src/main/java/com/att/authz/actions/URPrint.java b/authz-batch/src/main/java/com/att/authz/actions/URPrint.java new file mode 100644 index 00000000..a643851e --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/actions/URPrint.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.actions; + +import com.att.authz.env.AuthzTrans; +import com.att.authz.helpers.UserRole; +import com.att.authz.layer.Result; +import com.att.inno.env.util.Chrono; + +public class URPrint implements Action<UserRole,Void> { + private String text; + + public URPrint(String text) { + this.text = text; + } + + @Override + public Result<Void> exec(AuthzTrans trans, UserRole ur) { + trans.info().log(text,ur.user,"to",ur.role,"expiring on",Chrono.dateOnlyStamp(ur.expires)); + return Result.ok(); + } + +}
\ No newline at end of file diff --git a/authz-batch/src/main/java/com/att/authz/actions/URPunt.java b/authz-batch/src/main/java/com/att/authz/actions/URPunt.java new file mode 100644 index 00000000..803fdb94 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/actions/URPunt.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.actions; + +import java.io.IOException; +import java.util.Date; +import java.util.List; + +import com.att.authz.env.AuthzTrans; +import com.att.authz.helpers.UserRole; +import com.att.authz.layer.Result; +import com.att.dao.aaf.cass.UserRoleDAO; +import com.att.dao.aaf.cass.UserRoleDAO.Data; +import com.att.inno.env.APIException; +import com.att.inno.env.util.Chrono; +import com.datastax.driver.core.Cluster; + +public class URPunt extends ActionPuntDAO<UserRole,Void> { + public URPunt(AuthzTrans trans, Cluster cluster, int months, int range) throws APIException, IOException { + super(trans,cluster, months, range); + } + + public URPunt(AuthzTrans trans, ActionDAO<?,?> adao, int months, int range) { + super(trans, adao, months, range); + } + + public Result<Void> exec(AuthzTrans trans, UserRole ur) { + Result<List<Data>> read = q.userRoleDAO.read(trans, ur.user, ur.role); + if(read.isOK()) { + for(UserRoleDAO.Data data : read.value) { + Date from = data.expires; + data.expires = puntDate(); + if(data.expires.before(from)) { + trans.error().printf("Error: %s is before %s", Chrono.dateOnlyStamp(data.expires), Chrono.dateOnlyStamp(from)); + } else { + q.userRoleDAO.update(trans, data); + trans.info().log("Updated User",ur.user,"and Role", ur.role, "from",Chrono.dateOnlyStamp(from),"to",Chrono.dateOnlyStamp(data.expires)); + } + } + return Result.ok(); + } else { + return Result.err(read); + } + } +}
\ No newline at end of file diff --git a/authz-batch/src/main/java/com/att/authz/entryConverters/AafEntryConverter.java b/authz-batch/src/main/java/com/att/authz/entryConverters/AafEntryConverter.java new file mode 100644 index 00000000..4f05f203 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/entryConverters/AafEntryConverter.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.entryConverters; + +import java.util.Set; + +public abstract class AafEntryConverter { + + protected String formatSet(Set<String> set) { + if (set==null || set.isEmpty()) return ""; + StringBuilder sb = new StringBuilder(); + int curr = 0; + sb.append("{"); + for (String s : set) { + sb.append("'"); + sb.append(s); + sb.append("'"); + if (set.size() != curr + 1) { + sb.append(","); + } + curr++; + } + sb.append("}"); + return sb.toString(); + } + +} diff --git a/authz-batch/src/main/java/com/att/authz/entryConverters/CredEntryConverter.java b/authz-batch/src/main/java/com/att/authz/entryConverters/CredEntryConverter.java new file mode 100644 index 00000000..96c88122 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/entryConverters/CredEntryConverter.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.entryConverters; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; + +import com.att.dao.aaf.cass.CredDAO; +import com.datastax.driver.core.utils.Bytes; +import com.googlecode.jcsv.writer.CSVEntryConverter; + +public class CredEntryConverter extends AafEntryConverter implements CSVEntryConverter<CredDAO.Data> { + private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ssZ"; + + @Override + public String[] convertEntry(CredDAO.Data cd) { + String[] columns = new String[5]; + + columns[0] = cd.id; + columns[1] = String.valueOf(cd.type); + DateFormat df = new SimpleDateFormat(DATE_FORMAT); + columns[2] = df.format(cd.expires); + columns[3] = Bytes.toHexString(cd.cred); + columns[4] = (cd.ns==null)?"":cd.ns; + + return columns; + } +} diff --git a/authz-batch/src/main/java/com/att/authz/entryConverters/NsEntryConverter.java b/authz-batch/src/main/java/com/att/authz/entryConverters/NsEntryConverter.java new file mode 100644 index 00000000..e9cd91c4 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/entryConverters/NsEntryConverter.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.entryConverters; + +import com.att.dao.aaf.cass.NsDAO; +import com.googlecode.jcsv.writer.CSVEntryConverter; + +public class NsEntryConverter extends AafEntryConverter implements CSVEntryConverter<NsDAO.Data> { + + @Override + public String[] convertEntry(NsDAO.Data nsd) { + String[] columns = new String[5]; + + columns[0] = nsd.name; + // JG changed from "scope" to "type" + columns[1] = String.valueOf(nsd.type); + //TODO Chris: need to look at this +// columns[2] = formatSet(nsd.admin); +// columns[3] = formatSet(nsd.responsible); +// columns[4] = nsd.description==null?"":nsd.description; + columns[5] = nsd.description==null?"":nsd.description; + + return columns; + } + +} diff --git a/authz-batch/src/main/java/com/att/authz/entryConverters/PermEntryConverter.java b/authz-batch/src/main/java/com/att/authz/entryConverters/PermEntryConverter.java new file mode 100644 index 00000000..afabdfdf --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/entryConverters/PermEntryConverter.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.entryConverters; + +import com.att.dao.aaf.cass.PermDAO; +import com.googlecode.jcsv.writer.CSVEntryConverter; + +public class PermEntryConverter extends AafEntryConverter implements CSVEntryConverter<PermDAO.Data> { + + @Override + public String[] convertEntry(PermDAO.Data pd) { + String[] columns = new String[6]; + + columns[0] = pd.ns; + columns[1] = pd.type; + columns[2] = pd.instance; + columns[3] = pd.action; + columns[4] = formatSet(pd.roles); + columns[5] = pd.description==null?"":pd.description; + + return columns; + } +} diff --git a/authz-batch/src/main/java/com/att/authz/entryConverters/RoleEntryConverter.java b/authz-batch/src/main/java/com/att/authz/entryConverters/RoleEntryConverter.java new file mode 100644 index 00000000..51389bd3 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/entryConverters/RoleEntryConverter.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.entryConverters; + +import com.att.dao.aaf.cass.RoleDAO; +import com.googlecode.jcsv.writer.CSVEntryConverter; + +public class RoleEntryConverter extends AafEntryConverter implements CSVEntryConverter<RoleDAO.Data> { + + @Override + public String[] convertEntry(RoleDAO.Data rd) { + String[] columns = new String[4]; + + columns[0] = rd.ns; + columns[1] = rd.name; + columns[2] = formatSet(rd.perms); + columns[3] = rd.description==null?"":rd.description; + + return columns; + } + +} diff --git a/authz-batch/src/main/java/com/att/authz/entryConverters/UserRoleEntryConverter.java b/authz-batch/src/main/java/com/att/authz/entryConverters/UserRoleEntryConverter.java new file mode 100644 index 00000000..0b2a956e --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/entryConverters/UserRoleEntryConverter.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.entryConverters; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; + +import com.att.dao.aaf.cass.UserRoleDAO; +import com.googlecode.jcsv.writer.CSVEntryConverter; + +public class UserRoleEntryConverter extends AafEntryConverter implements CSVEntryConverter<UserRoleDAO.Data> { + private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ssZ"; + + @Override + public String[] convertEntry(UserRoleDAO.Data urd) { + String[] columns = new String[3]; + + columns[0] = urd.user; + columns[1] = urd.role; + DateFormat df = new SimpleDateFormat(DATE_FORMAT); + columns[2] = df.format(urd.expires); + + return columns; + } +} diff --git a/authz-batch/src/main/java/com/att/authz/helpers/Approver.java b/authz-batch/src/main/java/com/att/authz/helpers/Approver.java new file mode 100644 index 00000000..0cac97bc --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/helpers/Approver.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.helpers; + +import java.util.HashMap; +import java.util.Map; + +import com.att.authz.actions.Message; +import com.att.authz.org.Organization; + +public class Approver { + public String name; + public Organization org; + public Map<String, Integer> userRequests; + + public Approver(String approver, Organization org) { + this.name = approver; + this.org = org; + userRequests = new HashMap<String, Integer>(); + } + + public void addRequest(String user) { + if (userRequests.get(user) == null) { + userRequests.put(user, 1); + } else { + Integer curCount = userRequests.remove(user); + userRequests.put(user, curCount+1); + } + } + + /** + * @param sb + * @return + */ + public void build(Message msg) { + msg.clear(); + msg.line("You have %d total pending approvals from the following users:", userRequests.size()); + for (Map.Entry<String, Integer> entry : userRequests.entrySet()) { + msg.line(" %s (%d)",entry.getKey(),entry.getValue()); + } + } + +} diff --git a/authz-batch/src/main/java/com/att/authz/helpers/Creator.java b/authz-batch/src/main/java/com/att/authz/helpers/Creator.java new file mode 100644 index 00000000..1fe513e8 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/helpers/Creator.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.helpers; + +import com.datastax.driver.core.Row; + +public abstract class Creator<T> { + public abstract T create(Row row); + public abstract String select(); + + public String query(String where) { + StringBuilder sb = new StringBuilder(select()); + if(where!=null) { + sb.append(" WHERE "); + sb.append(where); + } + sb.append(';'); + return sb.toString(); + } + + +}
\ No newline at end of file diff --git a/authz-batch/src/main/java/com/att/authz/helpers/Cred.java b/authz-batch/src/main/java/com/att/authz/helpers/Cred.java new file mode 100644 index 00000000..39691df9 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/helpers/Cred.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.helpers; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.TreeMap; + +import com.att.inno.env.Env; +import com.att.inno.env.TimeTaken; +import com.att.inno.env.Trans; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.SimpleStatement; +import com.datastax.driver.core.Statement; + +public class Cred { + public static final TreeMap<String,Cred> data = new TreeMap<String,Cred>(); + + public final String id; + public final List<Instance> instances; + + public Cred(String id) { + this.id = id; + instances = new ArrayList<Instance>(); + } + + public static class Instance { + public final int type; + public final Date expires; + public final Integer other; + + public Instance(int type, Date expires, Integer other) { + this.type = type; + this.expires = expires; + this.other = other; + } + } + + public Date last(final int type) { + Date last = null; + for(Instance i : instances) { + if(i.type==type && (last==null || i.expires.after(last))) { + last = i.expires; + } + } + return last; + } + + + public Set<Integer> types() { + Set<Integer> types = new HashSet<Integer>(); + for(Instance i : instances) { + types.add(i.type); + } + return types; + } + + public static void load(Trans trans, Session session ) { + load(trans, session,"select id, type, expires, other from authz.cred;"); + + } + + public static void loadOneNS(Trans trans, Session session, String ns ) { + load(trans, session,"select id, type, expires, other from authz.cred WHERE ns='" + ns + "';"); + } + + private static void load(Trans trans, Session session, String query) { + + trans.info().log( "query: " + query ); + TimeTaken tt = trans.start("Read Creds", Env.REMOTE); + + ResultSet results; + try { + Statement stmt = new SimpleStatement( query ); + results = session.execute(stmt); + } finally { + tt.done(); + } + int count = 0; + try { + Iterator<Row> iter = results.iterator(); + Row row; + tt = trans.start("Load Roles", Env.SUB); + try { + while(iter.hasNext()) { + ++count; + row = iter.next(); + String id = row.getString(0); + Cred cred = data.get(id); + if(cred==null) { + cred = new Cred(id); + data.put(id, cred); + } + cred.instances.add(new Instance(row.getInt(1), row.getDate(2), row.getInt(3))); + } + } finally { + tt.done(); + } + } finally { + trans.info().log("Found",count,"creds"); + } + + + } + public String toString() { + StringBuilder sb = new StringBuilder(id); + sb.append('['); + for(Instance i : instances) { + sb.append('{'); + sb.append(i.type); + sb.append(",\""); + sb.append(i.expires); + sb.append("\"}"); + } + sb.append(']'); + return sb.toString(); + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return id.hashCode(); + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + return id.equals(obj); + } + +}
\ No newline at end of file diff --git a/authz-batch/src/main/java/com/att/authz/helpers/Future.java b/authz-batch/src/main/java/com/att/authz/helpers/Future.java new file mode 100644 index 00000000..13ee8222 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/helpers/Future.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.helpers; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.TreeMap; +import java.util.UUID; + +import com.att.inno.env.Env; +import com.att.inno.env.TimeTaken; +import com.att.inno.env.Trans; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.SimpleStatement; +import com.datastax.driver.core.Statement; + +public class Future { + public static final List<Future> data = new ArrayList<Future>(); + public static final TreeMap<String,List<Future>> byMemo = new TreeMap<String,List<Future>>(); + + public final UUID id; + public final String memo, target; + public final Date start, expires; + public Future(UUID id, String memo, String target, Date start, Date expires) { + this.id = id; + this.memo = memo; + this.target = target; + this.start = start; + this.expires = expires; + } + + public static void load(Trans trans, Session session, Creator<Future> creator) { + trans.info().log( "query: " + creator.select() ); + ResultSet results; + TimeTaken tt = trans.start("Load Futures", Env.REMOTE); + try { + Statement stmt = new SimpleStatement(creator.select()); + results = session.execute(stmt); + } finally { + tt.done(); + } + + int count = 0; + tt = trans.start("Process Futures", Env.SUB); + try { + for(Row row : results.all()) { + ++count; + Future f = creator.create(row); + data.add(f); + + List<Future> lf = byMemo.get(f.memo); + if(lf == null) { + lf = new ArrayList<Future>(); + byMemo.put(f.memo, lf); + } + lf.add(f); + + } + } finally { + trans.info().log("Found",count,"Futures"); + } + } + + public static Creator<Future> v2_0_15 = new Creator<Future>() { + @Override + public Future create(Row row) { + return new Future(row.getUUID(0),row.getString(1),row.getString(2), + row.getDate(3),row.getDate(4)); + } + + @Override + public String select() { + return "select id,memo,target,start,expires from authz.future"; + } + }; + + public static void delete(List<Future> fl) { + if(fl==null || fl.isEmpty()) { + return; + } + for(Future f : fl) { + data.remove(f); + } + // Faster to start over, then look for entries. + byMemo.clear(); + for(Future f : data) { + List<Future> lf = byMemo.get(f.memo); + if(lf == null) { + lf = new ArrayList<Future>(); + byMemo.put(f.memo, lf); + } + lf.add(f); + } + } +} diff --git a/authz-batch/src/main/java/com/att/authz/helpers/InputIterator.java b/authz-batch/src/main/java/com/att/authz/helpers/InputIterator.java new file mode 100644 index 00000000..02fdc166 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/helpers/InputIterator.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.helpers; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.PrintStream; +import java.util.Iterator; + +public class InputIterator implements Iterable<String> { + private BufferedReader in; + private final PrintStream out; + private final String prompt, instructions; + + public InputIterator(BufferedReader in, PrintStream out, String prompt, String instructions) { + this.in = in; + this.out = out; + this.prompt = prompt; + this.instructions = instructions; + } + + @Override + public Iterator<String> iterator() { + out.println(instructions); + return new Iterator<String>() { + String input; + @Override + public boolean hasNext() { + out.append(prompt); + try { + input = in.readLine(); + } catch (IOException e) { + input = null; + return false; + } + return input.length()>0; + } + + @Override + public String next() { + return input; + } + + @Override + public void remove() { + } + }; + } +} + diff --git a/authz-batch/src/main/java/com/att/authz/helpers/MiscID.java b/authz-batch/src/main/java/com/att/authz/helpers/MiscID.java new file mode 100644 index 00000000..c60a97a1 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/helpers/MiscID.java @@ -0,0 +1,169 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.helpers; + +import java.util.Map; +import java.util.TreeMap; + +import com.att.authz.BatchException; +import com.att.inno.env.Env; +import com.att.inno.env.TimeTaken; +import com.att.inno.env.Trans; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.SimpleStatement; +import com.datastax.driver.core.Statement; + +public class MiscID { + public static final TreeMap<String,MiscID> data = new TreeMap<String,MiscID>(); + /* + Sample Record + aad890|mj9030|20040902|20120207 + + **** Field Definitions **** + MISCID - AT&T Miscellaneous ID - Non-User ID (Types: Internal Mechanized ID, External Mechanized ID, Datagate ID, Customer ID, Vendor ID, Exchange Mail ID, CLEC ID, Specialized ID, Training ID) + SPONSOR_ATTUID - ATTUID of MiscID Sponsor (Owner) + CREATE_DATE - Date when MiscID was created + LAST_RENEWAL_DATE - Date when MiscID Sponsorship was last renewed + */ + public String id,sponsor,created,renewal; + + private static final String fieldString = "id,created,sponsor,renewal"; + + /** + * Load a Row of Strings (from CSV file). + * + * Be CAREFUL that the Row lists match the Fields above!!! If this changes, change + * 1) This Object + * 2) DB "suits.cql" + * 3) Alter existing Tables + * @param row + * @throws BatchException + * @throws IllegalAccessException + * @throws IllegalArgumentException + */ + public void set(String row []) throws BatchException { + if(row.length<4) {throw new BatchException("Row of MiscID_XRef is too short");} + id = row[0]; + sponsor = row[1]; + created = row[2]; + renewal = row[3]; + } + + public void set(Row row) { + id = row.getString(0); + sponsor = row.getString(1); + created = row.getString(2); + renewal = row.getString(3); + } + + + public static void load(Trans trans, Session session ) { + load(trans, session,"SELECT " + fieldString + " FROM authz.miscid;",data); + } + + public static void load(Trans trans, Session session, Map<String,MiscID> map ) { + load(trans, session,"SELECT " + fieldString + " FROM authz.miscid;",map); + } + + public static void loadOne(Trans trans, Session session, String id ) { + load(trans, session,"SELECT " + fieldString + " FROM authz.miscid WHERE id ='" + id + "';", data); + } + + public static void load(Trans trans, Session session, String query, Map<String,MiscID> map) { + trans.info().log( "query: " + query ); + TimeTaken tt = trans.start("Read MiscID", Env.REMOTE); + + ResultSet results; + try { + Statement stmt = new SimpleStatement( query ); + results = session.execute(stmt); + } finally { + tt.done(); + } + int count = 0; + try { + tt = trans.start("Load Map", Env.SUB); + try { + for( Row row : results.all()) { + MiscID miscID = new MiscID(); + miscID.set(row); + data.put(miscID.id,miscID); + ++count; + } + } finally { + tt.done(); + } + } finally { + trans.info().log("Found",count,"miscID records"); + } + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return id.hashCode(); + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if(obj!=null && obj instanceof MiscID) { + return id.equals(((MiscID)obj).id); + } + return false; + } + + public StringBuilder insertStmt() throws IllegalArgumentException, IllegalAccessException { + StringBuilder sb = new StringBuilder("INSERT INTO authz.miscid ("); + sb.append(fieldString); + sb.append(") VALUES ('"); + sb.append(id); + sb.append("','"); + sb.append(sponsor); + sb.append("','"); + sb.append(created); + sb.append("','"); + sb.append(renewal); + sb.append("')"); + return sb; + } + + public StringBuilder updateStmt(MiscID source) { + StringBuilder sb = null; + if(id.equals(source.id)) { + sb = addField(sb,"sponser",sponsor,source.sponsor); + sb = addField(sb,"created",created,source.created); + sb = addField(sb,"renewal",renewal,source.renewal); + } + if(sb!=null) { + sb.append(" WHERE id='"); + sb.append(id); + sb.append('\''); + } + return sb; + } + + private StringBuilder addField(StringBuilder sb, String name, String a, String b) { + if(!a.equals(b)) { + if(sb==null) { + sb = new StringBuilder("UPDATE authz.miscid SET "); + } else { + sb.append(','); + } + sb.append(name); + sb.append("='"); + sb.append(b); + sb.append('\''); + } + return sb; + } + + +}
\ No newline at end of file diff --git a/authz-batch/src/main/java/com/att/authz/helpers/NS.java b/authz-batch/src/main/java/com/att/authz/helpers/NS.java new file mode 100644 index 00000000..a97b2d2b --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/helpers/NS.java @@ -0,0 +1,134 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.helpers; + +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; + +import com.att.inno.env.Env; +import com.att.inno.env.TimeTaken; +import com.att.inno.env.Trans; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.SimpleStatement; +import com.datastax.driver.core.Statement; + +public class NS implements Comparable<NS> { + public final static Map<String,NS> data = new TreeMap<String,NS>(); + + public final String name, description, parent; + public final int scope,type; + + public NS(String name, String description, String parent, int type, int scope) { + this.name = name; + this.description = description; + this.parent = parent; + this.scope = scope; + this.type = type; + } + + public static void load(Trans trans, Session session, Creator<NS> creator) { + load(trans,session, + "select name, description, parent, type, scope from authz.ns;" + ,creator); + } + + public static void loadOne(Trans trans, Session session, Creator<NS> creator, String ns) { + load(trans,session, + ("select name, description, parent, type, scope from authz.ns WHERE name='"+ns+"';") + ,creator + ); + } + + private static void load(Trans trans, Session session, String query, Creator<NS> creator) { + trans.info().log( "query: " + query ); + ResultSet results; + TimeTaken tt; + + tt = trans.start("Read Namespaces", Env.REMOTE); + try { + Statement stmt = new SimpleStatement( query ); + results = session.execute(stmt); + } finally { + tt.done(); + } + + + try { + Iterator<Row> iter = results.iterator(); + Row row; + tt = trans.start("Load Namespaces", Env.SUB); + try { + while(iter.hasNext()) { + row = iter.next(); + NS ns = creator.create(row); + data.put(ns.name,ns); + } + } finally { + tt.done(); + } + } finally { + trans.info().log("Found",data.size(),"Namespaces"); + } + + } + + public String toString() { + return name; + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return name.hashCode(); + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + return name.equals(obj); + } + + @Override + public int compareTo(NS o) { + return name.compareTo(o.name); + } + + public static class NSSplit { + public String ns; + public String other; + public NSSplit(String s, int dot) { + ns = s.substring(0,dot); + other = s.substring(dot+1); + } + } + public static NSSplit deriveParent(String dotted) { + if(dotted==null)return null; + for(int idx = dotted.lastIndexOf('.');idx>=0; idx=dotted.lastIndexOf('.',idx-1)) { + if(data.get(dotted.substring(0, idx))!=null) { + return new NSSplit(dotted,idx); + } + } + return null; + } + + public static Creator<NS> v2_0_11 = new Creator<NS> () { + @Override + public NS create(Row row) { + return new NS(row.getString(0),row.getString(1), row.getString(2),row.getInt(3),row.getInt(4)); + } + + @Override + public String select() { + return "SELECT name, description, parent, type, scope FROM authz.ns "; + } + }; + +}
\ No newline at end of file diff --git a/authz-batch/src/main/java/com/att/authz/helpers/Notification.java b/authz-batch/src/main/java/com/att/authz/helpers/Notification.java new file mode 100644 index 00000000..279e5881 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/helpers/Notification.java @@ -0,0 +1,273 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.helpers; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.TreeMap; + +import com.att.authz.actions.Message; +import com.att.authz.env.AuthzTrans; +import com.att.authz.org.EmailWarnings; +import com.att.authz.org.Organization; +import com.att.authz.org.Organization.Notify; +import com.att.authz.org.Organization.Identity; +import com.att.authz.org.OrganizationException; +import com.att.authz.org.OrganizationFactory; +import com.att.inno.env.Env; +import com.att.inno.env.TimeTaken; +import com.att.inno.env.Trans; +import com.att.inno.env.util.Chrono; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.SimpleStatement; +import com.datastax.driver.core.Statement; + +public class Notification { + + public static final TreeMap<String,List<Notification>> data = new TreeMap<String,List<Notification>>(); + public static final long now = System.currentTimeMillis(); + + public final String user; + public final Notify type; + public final Date last; + public final int checksum; + public Message msg; + private int current; + public Organization org; + public int count; + private long graceEnds,lastdays; + + private Notification(String user, int type, Date last, int checksum) { + this.user = user; + this.type = Notify.from(type); + this.last = last; + this.checksum = checksum; + current = 0; + count = 0; + } + + private Notification(String user, Notify type, Date last, int checksum) { + this.user = user; + this.type = type; + this.last = last; + this.checksum = checksum; + current = 0; + count = 0; + } + + public static void load(Trans trans, Session session, Creator<Notification> creator ) { + trans.info().log( "query: " + creator.select() ); + TimeTaken tt = trans.start("Load Notify", Env.REMOTE); + + ResultSet results; + try { + Statement stmt = new SimpleStatement(creator.select()); + results = session.execute(stmt); + } finally { + tt.done(); + } + int count = 0; + tt = trans.start("Process Notify", Env.SUB); + + try { + for(Row row : results.all()) { + ++count; + try { + Notification not = creator.create(row); + List<Notification> ln = data.get(not.user); + if(ln==null) { + ln = new ArrayList<Notification>(); + data.put(not.user, ln); + } + ln.add(not); + } finally { + tt.done(); + } + } + } finally { + tt.done(); + trans.info().log("Found",count,"Notify Records"); + } + } + + public static Notification get(String user, Notify type) { + List<Notification> ln = data.get(user); + if(ln!=null) { + for(Notification n : ln) { + if(type.equals(n.type)) { + return n; + } + } + } + return null; + } + + private static Notification getOrCreate(String user, Notify type) { + List<Notification> ln = data.get(user); + Notification n = null; + if(ln==null) { + ln = new ArrayList<Notification>(); + data.put(user, ln); + } else { + for(Notification n2 : ln) { + if(type.equals(n2.type)) { + n=n2; + break; + } + } + } + if(n==null) { + n = new Notification(user, type, new Date(), 0); + ln.add(n); + } + return n; + } + + public static Notification add(AuthzTrans trans, UserRole ur) { + Notification n = getOrCreate(ur.user,Notify.RoleExpiration); + if(n.org==null) { + try { + n.org = OrganizationFactory.obtain(trans.env(), ur.ns); + } catch (OrganizationException e) { + trans.error().log(ur.ns, " does not have a Namespace"); + } + } + + if(n.count==0) { + EmailWarnings ew = n.org.emailWarningPolicy(); + n.graceEnds = ew.roleEmailInterval(); + n.lastdays = ew.emailUrgentWarning(); + } + ++n.count; + + /* + StringBuilder sb = new StringBuilder(); + sb.append("ID: "); + sb.append(ur.user); + User ouser; + try { + ouser = n.org.getUser(trans, ur.user); + if(ouser!=null) { + sb.append(" ("); + sb.append(ouser.fullName()); + sb.append(')'); + } + } catch (Exception e) { + } + sb.append(" Role: "); + sb.append(ur.role); + sb.append(" Expire"); + if(now<ur.expires.getTime()) { + sb.append("s: "); + } else { + sb.append("d: "); + } + sb.append(Chrono.dateOnlyStamp(ur.expires)); + sb.append("\n If you wish to extend, type\n"); + sb.append("\trole user extend "); + sb.append(ur.role); + sb.append(' '); + sb.append(ur.user); + sb.append("\n If you wish to delete, type\n"); + sb.append("\trole user del "); + sb.append(ur.role); + sb.append(' '); + sb.append(ur.user); + sb.append('\n'); + n.msg.add(sb.toString()); + n.current=0; + */ + return n; + } + + public static Notification addApproval(AuthzTrans trans, Identity ou) { + Notification n = getOrCreate(ou.id(),Notify.Approval); + if(n.org==null) { + n.org = ou.org(); + } + if(n.count==0) { // first time. + EmailWarnings ew = n.org.emailWarningPolicy(); + n.graceEnds = ew.apprEmailInterval(); + n.lastdays = ew.emailUrgentWarning(); + } + ++n.count; + return n; + } + + public static Creator<Notification> v2_0_14 = new Creator<Notification>() { + @Override + public Notification create(Row row) { + return new Notification(row.getString(0), row.getInt(1), row.getDate(2),row.getInt(3)); + } + + @Override + public String select() { + return "select user,type,last,checksum from authz.notify"; + } + }; + + public void set(Message msg) { + this.msg = msg; + } + + public int checksum() { + if(current==0) { + for(String l : msg.lines) { + for(byte b : l.getBytes()) { + current+=b; + } + } + } + return current; + } + + public boolean update(AuthzTrans trans, Session session, boolean dryRun) { + String update = update(); + if(update!=null) { + if(dryRun) { + trans.info().log(update); + } else { + session.execute(update); + } + return true; // Updated info, expect to notify + } + return false; + } + + /** + * Returns an Update String for CQL if there is data. + * + * Returns null if nothing to update + * @return + */ + private String update() { + // If this has been done before, there is no change in checkSum and the last time notified is within GracePeriod + if(checksum!=0 && checksum()==checksum && now < last.getTime()+graceEnds && now > last.getTime()+lastdays) { + return null; + } else { + return "UPDATE authz.notify SET last = '" + + Chrono.dateOnlyStamp(last) + + "', checksum=" + + current + + " WHERE user='" + + user + + "' AND type=" + + type.getValue() + + ";"; + } + } + +// public void text(Email email) { +// for(String s : msg) { +// email.line(s); +// } +// } +// + public String toString() { + return "\"" + user + "\",\"" + type.name() + "\",\"" + Chrono.dateOnlyStamp(last); + } +}
\ No newline at end of file diff --git a/authz-batch/src/main/java/com/att/authz/helpers/NsAttrib.java b/authz-batch/src/main/java/com/att/authz/helpers/NsAttrib.java new file mode 100644 index 00000000..33de9d85 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/helpers/NsAttrib.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.helpers; + +import java.util.ArrayList; +import java.util.List; +import java.util.TreeMap; + +import com.att.inno.env.Env; +import com.att.inno.env.TimeTaken; +import com.att.inno.env.Trans; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.SimpleStatement; +import com.datastax.driver.core.Statement; + +public class NsAttrib { + public static final List<NsAttrib> data = new ArrayList<NsAttrib>(); + public static final TreeMap<String,List<NsAttrib>> byKey = new TreeMap<String,List<NsAttrib>>(); + public static final TreeMap<String,List<NsAttrib>> byNS = new TreeMap<String,List<NsAttrib>>(); + + public final String ns,key,value; + + public NsAttrib(String ns, String key, String value) { + this.ns = ns; + this.key = key; + this.value = value; + } + + public static void load(Trans trans, Session session, Creator<NsAttrib> creator ) { + trans.info().log( "query: " + creator.select() ); + ResultSet results; + TimeTaken tt = trans.start("Load NsAttributes", Env.REMOTE); + try { + Statement stmt = new SimpleStatement(creator.select()); + results = session.execute(stmt); + } finally { + tt.done(); + } + int count = 0; + tt = trans.start("Process NsAttributes", Env.SUB); + + try { + for(Row row : results.all()) { + ++count; + NsAttrib ur = creator.create(row); + data.add(ur); + + List<NsAttrib> lna = byKey.get(ur.key); + if(lna==null) { + lna = new ArrayList<NsAttrib>(); + byKey.put(ur.key, lna); + } + lna.add(ur); + + lna = byNS.get(ur.ns); + if(lna==null) { + lna = new ArrayList<NsAttrib>(); + byNS.put(ur.ns, lna); + } + lna.add(ur); + } + } finally { + tt.done(); + trans.info().log("Found",count,"NS Attributes"); + } + } + + public static Creator<NsAttrib> v2_0_11 = new Creator<NsAttrib>() { + @Override + public NsAttrib create(Row row) { + return new NsAttrib(row.getString(0), row.getString(1), row.getString(2)); + } + + @Override + public String select() { + return "select ns,key,value from authz.ns_attrib"; + } + }; + + + public String toString() { + return "\"" + ns + "\",\"" + key + "\",\"" + value; + } + +}
\ No newline at end of file diff --git a/authz-batch/src/main/java/com/att/authz/helpers/Perm.java b/authz-batch/src/main/java/com/att/authz/helpers/Perm.java new file mode 100644 index 00000000..39092791 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/helpers/Perm.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.helpers; + +import java.util.Iterator; +import java.util.Set; +import java.util.TreeMap; + +import com.att.inno.env.Env; +import com.att.inno.env.TimeTaken; +import com.att.inno.env.Trans; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.SimpleStatement; +import com.datastax.driver.core.Statement; + +public class Perm implements Comparable<Perm> { + public static final TreeMap<Perm,Set<String>> data = new TreeMap<Perm,Set<String>>(); + public static final TreeMap<String,Perm> keys = new TreeMap<String,Perm>(); + + public final String ns, type, instance, action,description; + private String fullType = null, fullPerm = null, encode = null; + public final Set<String> roles; + + public String encode() { + if(encode == null) { + encode = ns + '|' + type + '|' + instance + '|' + action; + } + return encode; + } + + public String fullType() { + if(fullType==null) { + fullType = ns + '.' + type; + } + return fullType; + } + + public String fullPerm() { + if(fullPerm==null) { + fullPerm = ns + '.' + type + '|' + instance + '|' + action; + } + return fullPerm; + } + + public Perm(String ns, String type, String instance, String action, String description, Set<String> roles) { + this.ns = ns; + this.type = type; + this.instance = instance; + this.action = action; + this.description = description; + // 2.0.11 +// this.full = encode();//ns+'.'+type+'|'+instance+'|'+action; + this.roles = roles; + } + + public static void load(Trans trans, Session session) { + load(trans, session, "select ns, type, instance, action, description, roles from authz.perm;"); + } + + public static void loadOneNS(Trans trans, Session session, String ns) { + load(trans, session, "select ns, type, instance, action, description, roles from authz.perm WHERE ns='" + ns + "';"); + + } + + private static void load(Trans trans, Session session, String query) { + // + trans.info().log( "query: " + query ); + TimeTaken tt = trans.start("Read Perms", Env.REMOTE); + ResultSet results; + try { + Statement stmt = new SimpleStatement( query ); + results = session.execute(stmt); + } finally { + tt.done(); + } + + try { + Iterator<Row> iter = results.iterator(); + Row row; + tt = trans.start("Load Perms", Env.SUB); + try { + while(iter.hasNext()) { + row = iter.next(); + Perm pk = new Perm(row.getString(0),row.getString(1),row.getString(2),row.getString(3), row.getString(4), row.getSet(5,String.class)); + keys.put(pk.encode(), pk); + data.put(pk,pk.roles); + } + } finally { + tt.done(); + } + } finally { + trans.info().log("Found",data.size(),"perms"); + } + } + + public String toString() { + return encode(); + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return encode().hashCode(); + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + return encode().equals(obj); + } + + @Override + public int compareTo(Perm o) { + return encode().compareTo(o.encode()); + } + +}
\ No newline at end of file diff --git a/authz-batch/src/main/java/com/att/authz/helpers/Role.java b/authz-batch/src/main/java/com/att/authz/helpers/Role.java new file mode 100644 index 00000000..f599d561 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/helpers/Role.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.helpers; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.TreeMap; + +import com.att.inno.env.Env; +import com.att.inno.env.TimeTaken; +import com.att.inno.env.Trans; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.SimpleStatement; +import com.datastax.driver.core.Statement; + +public class Role implements Comparable<Role> { + public static final TreeMap<Role,Set<String>> data = new TreeMap<Role,Set<String>>(); + public static final TreeMap<String,Role> keys = new TreeMap<String,Role>(); + + public final String ns, name, description; + private String full, encode; + public final Set<String> perms; + + public Role(String full) { + ns = name = description = ""; + this.full = full; + perms = new HashSet<String>(); + } + + public Role(String ns, String name, String description,Set<String> perms) { + this.ns = ns; + this.name = name; + this.description = description; + this.full = null; + this.encode = null; + this.perms = perms; + } + + public String encode() { + if(encode==null) { + encode = ns + '|' + name; + } + return encode; + } + + public String fullName() { + if(full==null) { + full = ns + '.' + name; + } + return full; + } + + public static void load(Trans trans, Session session ) { + load(trans,session,"select ns, name, description, perms from authz.role;"); + } + + public static void loadOneNS(Trans trans, Session session, String ns ) { + load(trans,session,"select ns, name, description, perms from authz.role WHERE ns='" + ns + "';"); + } + + private static void load(Trans trans, Session session, String query) { + trans.info().log( "query: " + query ); + TimeTaken tt = trans.start("Read Roles", Env.REMOTE); + + ResultSet results; + try { + Statement stmt = new SimpleStatement( query ); + results = session.execute(stmt); + } finally { + tt.done(); + } + + try { + Iterator<Row> iter = results.iterator(); + Row row; + tt = trans.start("Load Roles", Env.SUB); + try { + while(iter.hasNext()) { + row = iter.next(); + Role rk =new Role(row.getString(0),row.getString(1), row.getString(2),row.getSet(3,String.class)); + keys.put(rk.encode(), rk); + data.put(rk,rk.perms); + } + } finally { + tt.done(); + } + } finally { + trans.info().log("Found",data.size(),"roles"); + } + + + } + public String toString() { + return encode(); + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return encode().hashCode(); + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + return encode().equals(obj); + } + + @Override + public int compareTo(Role o) { + return encode().compareTo(o.encode()); + } + + public static String fullName(String role) { + return role.replace('|', '.'); + } +}
\ No newline at end of file diff --git a/authz-batch/src/main/java/com/att/authz/helpers/UserRole.java b/authz-batch/src/main/java/com/att/authz/helpers/UserRole.java new file mode 100644 index 00000000..65abc0f6 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/helpers/UserRole.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.helpers; + +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.TreeMap; + +import com.att.dao.aaf.cass.UserRoleDAO; +import com.att.inno.env.Env; +import com.att.inno.env.TimeTaken; +import com.att.inno.env.Trans; +import com.att.inno.env.util.Chrono; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.SimpleStatement; +import com.datastax.driver.core.Statement; + +public class UserRole implements Cloneable { + public static final List<UserRole> data = new ArrayList<UserRole>(); + public static final TreeMap<String,List<UserRole>> byUser = new TreeMap<String,List<UserRole>>(); + public static final TreeMap<String,List<UserRole>> byRole = new TreeMap<String,List<UserRole>>(); + + public final String user, role, ns, rname; + public final Date expires; + + public UserRole(String user, String ns, String rname, Date expires) { + this.user = user; + this.role = ns + '.' + rname; + this.ns = ns; + this.rname = rname; + this.expires = expires; + } + + public UserRole(String user, String role, String ns, String rname, Date expires) { + this.user = user; + this.role = role; + this.ns = ns; + this.rname = rname; + this.expires = expires; + } + + public static void load(Trans trans, Session session, Creator<UserRole> creator ) { + load(trans,session,creator,null); + } + + public static void loadOneRole(Trans trans, Session session, Creator<UserRole> creator, String role) { + load(trans,session,creator,"role='" + role +"' ALLOW FILTERING;"); + } + + public static void loadOneUser(Trans trans, Session session, Creator<UserRole> creator, String user ) { + load(trans,session,creator,"role='"+ user +"';"); + } + + private static void load(Trans trans, Session session, Creator<UserRole> creator, String where) { + String query = creator.query(where); + trans.info().log( "query: " + query ); + TimeTaken tt = trans.start("Read UserRoles", Env.REMOTE); + + ResultSet results; + try { + Statement stmt = new SimpleStatement( query ); + results = session.execute(stmt); + } finally { + tt.done(); + } + int count = 0; + try { + Iterator<Row> iter = results.iterator(); + Row row; + tt = trans.start("Load UserRole", Env.SUB); + try { + while(iter.hasNext()) { + ++count; + row = iter.next(); + UserRole ur = creator.create(row); + data.add(ur); + + List<UserRole> lur = byUser.get(ur.user); + if(lur==null) { + lur = new ArrayList<UserRole>(); + byUser.put(ur.user, lur); + } + lur.add(ur); + + lur = byRole.get(ur.role); + if(lur==null) { + lur = new ArrayList<UserRole>(); + byRole.put(ur.role, lur); + } + lur.add(ur); + } + } finally { + tt.done(); + } + } finally { + trans.info().log("Found",count,"UserRoles"); + } + + + } + + public static Creator<UserRole> v2_0_11 = new Creator<UserRole>() { + @Override + public UserRole create(Row row) { + return new UserRole(row.getString(0), row.getString(1), row.getString(2),row.getString(3),row.getDate(4)); + } + + @Override + public String select() { + return "select user,role,ns,rname,expires from authz.user_role"; + } + }; + + public UserRoleDAO.Data to() { + UserRoleDAO.Data urd = new UserRoleDAO.Data(); + urd.user = user; + urd.role = role; + urd.ns = ns; + urd.rname = rname; + urd.expires = expires; + return urd; + } + + public String toString() { + return "\"" + user + "\",\"" + role + "\",\"" + ns + "\",\"" + rname + "\",\""+ Chrono.dateOnlyStamp(expires); + } + +}
\ No newline at end of file diff --git a/authz-batch/src/main/java/com/att/authz/reports/ApprNotify.java b/authz-batch/src/main/java/com/att/authz/reports/ApprNotify.java new file mode 100644 index 00000000..38567747 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/reports/ApprNotify.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.reports; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import com.att.authz.Batch; +import com.att.authz.actions.Email; +import com.att.authz.actions.Message; +import com.att.authz.env.AuthzTrans; +import com.att.authz.helpers.Approver; +import com.att.authz.helpers.Notification; +import com.att.authz.layer.Result; +import com.att.authz.org.Organization; +import com.att.authz.org.Organization.Identity; +import com.att.authz.org.OrganizationException; +import com.att.authz.org.OrganizationFactory; +import com.att.dao.CassAccess; +import com.att.dao.aaf.cass.ApprovalDAO; +import com.att.dao.aaf.cass.ApprovalDAO.Data; +import com.att.inno.env.APIException; + +public class ApprNotify extends Batch { + private final ApprovalDAO apprDAO; + private Result<List<Data>> rladd; + private Email email; + + public ApprNotify(AuthzTrans trans) throws APIException, IOException { + super(trans.env()); + apprDAO = new ApprovalDAO(trans, cluster, CassAccess.KEYSPACE); + session = apprDAO.getSession(trans); + rladd = apprDAO.readByStatus(trans,"pending"); + if(isDryRun()) { + email = new Email();//EmailPrint(); + } else { + email = new Email(); + } + email.subject("AAF Approval Notification (ENV: %s)",batchEnv); + email.preamble("AAF is the AT&T System for Fine-Grained Authorizations. " + + "You are being asked to Approve in the %s environment before AAF Actions can be taken. \n\n" + + " Please follow this link:\n\n\t%s/approve" + ,batchEnv,env.getProperty(GUI_URL)); + + Notification.load(trans, session, Notification.v2_0_14); + } + + @Override + protected void run(AuthzTrans trans) { + if(rladd.isOK()) { + if(rladd.isEmpty()) { + trans.warn().log("No Pending Approvals to Process"); + } else { + Organization org=null; + //Map<String,Organization> users = new HashMap<String,Organization>(); + Map<String,Approver> users = new TreeMap<String,Approver>(); + + for(Data data : rladd.value) { + // We've already seen this approver. Simply add the new request to him. + try { + Approver approver = users.get(data.approver); + if(approver==null) { + org = OrganizationFactory.obtain(trans.env(), data.approver); + approver = new Approver(data.approver, org); + users.put(data.approver, approver); + } + approver.addRequest(data.user); + } catch (OrganizationException e) { + trans.error().log(e); + } + } + + // Notify + Message msg = new Message(); + for(Approver approver : users.values()) { + try { + Notification n = Notification.addApproval(trans, org.getIdentity(trans, approver.name)); + approver.build(msg); + n.set(msg); + if(n.update(trans, session, isDryRun())) { + Identity user = n.org.getIdentity(trans, approver.name); + email.clear(); + email.addTo(user.email()); + email.msg(msg); + email.exec(trans, n.org); + } + } catch (OrganizationException e) { + trans.error().log(e); + } + } + } + } else { + trans.error().log('[',rladd.status,']',rladd.details); + } + } + + @Override + protected void _close(AuthzTrans trans) { + apprDAO.close(trans); + } + + + +} diff --git a/authz-batch/src/main/java/com/att/authz/reports/CheckCred.java b/authz-batch/src/main/java/com/att/authz/reports/CheckCred.java new file mode 100644 index 00000000..f9d2cfaf --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/reports/CheckCred.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.reports; + +import java.io.IOException; + +import com.att.authz.Batch; +import com.att.authz.env.AuthzTrans; +import com.att.authz.helpers.Cred; +import com.att.authz.helpers.Cred.Instance; +import com.att.inno.env.APIException; +import com.att.inno.env.Env; +import com.att.inno.env.TimeTaken; +import com.att.inno.env.util.Chrono; + +public class CheckCred extends Batch{ + + public CheckCred(AuthzTrans trans) throws APIException, IOException { + super(trans.env()); + TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE); + try { + session = cluster.connect(); + } finally { + tt.done(); + } + + Cred.load(trans, session); + } + + @Override + protected void run(AuthzTrans trans) { + String query; + for(Cred cred : Cred.data.values()) { + for(Instance inst : cred.instances) { + if(inst.other==0) { + if(dryRun) { + trans.warn().log("Ensuring 'other' is numeric"); + } else { + query = "UPDATE authz.cred SET other=0 WHERE " + + "id='" + cred.id + + "' AND type=" + inst.type + + " AND expires='" + Chrono.dateStamp(inst.expires) + + "';"; + session.execute(query); + trans.warn().log("resetting 'other'",query); + } + } + } + } + + } + /* + /// Evaluate + for(UserRole urKey : UserRole.data) { + NSSplit nss = NS.deriveParent(urKey.role); + if(nss==null && NS.data.size()>0 ) { // there is no Namespace for this UserRole + if(dryRun) { + trans.warn().printf("Would delete %s %s, which has no corresponding Namespace",urKey.user,urKey.role); + } else { + query = "DELETE FROM authz.user_role WHERE " + + "user='" + urKey.user + + "' AND role='" + urKey.role + + "';"; + session.execute(query); + trans.warn().printf("Deleting %s %s, which has no corresponding Namespace",urKey.user,urKey.role); + } + } else if(urKey.ns == null || urKey.rname == null || !urKey.role.equals(urKey.ns+'.'+urKey.rname)) { + if(dryRun) { + trans.warn().log(urKey,"needs to be split and added to Record (", urKey.ns, urKey.rname,")"); + } else { + query = "UPDATE authz.user_role SET ns='" + nss.ns + + "', rname='" + nss.other + + "' WHERE " + + "user='" + urKey.user + + "' AND role='" + urKey.role + + "';"; + session.execute(query); + trans.warn().log("Setting ns and rname",query); + } + } + } + } + */ + @Override + protected void _close(AuthzTrans trans) { + session.close(); + aspr.info("End " + this.getClass().getSimpleName() + " processing" ); + } +} diff --git a/authz-batch/src/main/java/com/att/authz/reports/CheckNS.java b/authz-batch/src/main/java/com/att/authz/reports/CheckNS.java new file mode 100644 index 00000000..36bcd348 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/reports/CheckNS.java @@ -0,0 +1,425 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.reports; + +import java.io.IOException; +import java.util.List; + +import com.att.authz.Batch; +import com.att.authz.env.AuthzTrans; +import com.att.authz.helpers.NS; +import com.att.authz.helpers.NsAttrib; +import com.att.authz.helpers.Perm; +import com.att.authz.helpers.Role; +import com.att.dao.aaf.cass.NsType; +import com.att.inno.env.APIException; +import com.att.inno.env.Env; +import com.att.inno.env.TimeTaken; + +public class CheckNS extends Batch{ + + public CheckNS(AuthzTrans trans) throws APIException, IOException { + super(trans.env()); + TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE); + try { + session = cluster.connect(); + } finally { + tt.done(); + } + NS.load(trans, session,NS.v2_0_11); + Role.load(trans, session); + Perm.load(trans, session); + NsAttrib.load(trans, session, NsAttrib.v2_0_11); + } + + @Override + protected void run(AuthzTrans trans) { + + String msg; + String query; + trans.info().log(STARS, msg = "Checking for NS type mis-match", STARS); + TimeTaken tt = trans.start(msg, Env.SUB); + try { + for(NS ns : NS.data.values()) { + if(ns.description==null) { + trans.warn().log("Namepace description is null. Changing to empty string."); + if(dryRun) { + trans.warn().log("Namepace description is null. Changing to empty string"); + } else { + query = "UPDATE authz.ns SET description='' WHERE name='" + ns.name +"';"; + session.execute(query); + } + } + int scope = count(ns.name,'.'); + NsType nt; + switch(scope) { + case 0: + nt = NsType.DOT; + break; + case 1: + nt = NsType.ROOT; + break; + case 2: + nt = NsType.COMPANY; + break; + default: + nt = NsType.APP; + break; + } + if(ns.type!=nt.type || ns.scope !=scope) { + if(dryRun) { + trans.warn().log("Namepace",ns.name,"has no type. Should change to ",nt.name()); + } else { + query = "UPDATE authz.ns SET type=" + nt.type + ", scope=" + scope + " WHERE name='" + ns.name +"';"; + trans.warn().log("Namepace",ns.name,"changing to",nt.name()+":",query); + session.execute(query); + } + } + } + } finally { + tt.done(); + } + + + trans.info().log(STARS, msg = "Checking for NS admin/owner mis-match", STARS); + tt = trans.start(msg, Env.SUB); + try { + /// Evaluate + for(NS nk : NS.data.values()) { + //String name; + String roleAdmin = nk.name+"|admin"; + String roleAdminPrev = nk.name+".admin"; + String roleOwner = nk.name+"|owner"; + String roleOwnerPrev = nk.name+".owner"; + String permAll = nk.name+"|access|*|*"; + String permAllPrev = nk.name+".access|*|*"; + String permRead = nk.name+"|access|*|read"; + String permReadPrev = nk.name+".access|*|read"; + // Admins + + Role rk = Role.keys.get(roleAdmin); // accomodate new role key + // Role Admin should exist + if(rk==null) { + if(dryRun) { + trans.warn().log(nk.name + " is missing role: " + roleAdmin); + } else { + query = "INSERT INTO authz.role(ns, name, description, perms) VALUES ('" + + nk.name + + "','admin','Automatic Administration'," + + "{'" + nk.name + "|access|*|*'});"; + session.execute(query); + env.info().log(query); + + + if(Role.keys.get(roleAdminPrev)!=null) { + query = "UPDATE authz.role set perms = perms + " + + "{'" + roleAdminPrev + "'} " + + "WHERE ns='"+ nk.name + "' AND " + + "name='admin'" + + ";"; + session.execute(query); + env.info().log(query); + } + } + } else { + // Role Admin should be linked to Perm All + if(!rk.perms.contains(permAll)) { + if(dryRun) { + trans.warn().log(roleAdmin,"is not linked to",permAll); + } else { + query = "UPDATE authz.role set perms = perms + " + + "{'" + nk.name + "|access|*|*'} " + + "WHERE ns='"+ nk.name + "' AND " + + "name='admin'" + + ";"; + session.execute(query); + env.info().log(query); + + if(rk.perms.contains(permAllPrev)) { + query = "UPDATE authz.role set perms = perms - " + + "{'" + nk.name + ".access|*|*'} " + + "WHERE ns='"+ nk.name + "' AND " + + "name='admin'" + + ";"; + session.execute(query); + env.info().log(query); + } + } + } + // Role Admin should not be linked to Perm Read + if(rk.perms.contains(permRead)) { + if(dryRun) { + trans.warn().log(roleAdmin,"should not be linked to",permRead); + } else { + query = "UPDATE authz.role set perms = perms - " + + "{'" + nk.name + "|access|*|read'} " + + "WHERE ns='"+ nk.name + "' AND " + + "name='admin'" + + ";"; + session.execute(query); + env.info().log(query); + } + } + } + + Perm pk = Perm.keys.get(permAll); + if(pk==null) { + trans.warn().log(nk.name + " is missing perm: " + permAll); + if(!dryRun) { + query = "INSERT INTO authz.perm(ns, type,instance,action,description, roles) VALUES ('" + + nk.name + + "','access','*','*','Namespace Write'," + + "{'" + nk.name + "|admin'});"; + session.execute(query); + env.info().log(query); + + } + } else { + // PermALL should be linked to Role Admin + if(!pk.roles.contains(roleAdmin)) { + trans.warn().log(permAll,"is not linked to",roleAdmin); + if(!dryRun) { + query = "UPDATE authz.perm set roles = roles + " + + "{'" + nk.name + "|admin'} WHERE " + + "ns='"+ pk.ns + "' AND " + + "type='access' AND instance='*' and action='*'" + + ";"; + session.execute(query); + env.info().log(query); + + if(pk.roles.contains(roleAdminPrev)) { + query = "UPDATE authz.perm set roles = roles - " + + "{'" + nk.name + ".admin'} WHERE " + + "ns='"+ pk.ns + "' AND " + + "type='access' AND instance='*' and action='*'" + + ";"; + session.execute(query); + env.info().log(query); + + } + } + } + + // PermALL should be not linked to Role Owner + if(pk.roles.contains(roleOwner)) { + trans.warn().log(permAll,"should not be linked to",roleOwner); + if(!dryRun) { + query = "UPDATE authz.perm set roles = roles - " + + "{'" + nk.name + "|owner'} WHERE " + + "ns='"+ pk.ns + "' AND " + + "type='access' AND instance='*' and action='*'" + + ";"; + session.execute(query); + env.info().log(query); + } + } + + } + + + + // Owner + rk = Role.keys.get(roleOwner); + if(rk==null) { + trans.warn().log(nk.name + " is missing role: " + roleOwner); + if(!dryRun) { + query = "INSERT INTO authz.role(ns, name, description, perms) VALUES('" + + nk.name + + "','owner','Automatic Owners'," + + "{'" + nk.name + "|access|*|read'});"; + session.execute(query); + env.info().log(query); + + } + } else { + // Role Owner should be linked to permRead + if(!rk.perms.contains(permRead)) { + trans.warn().log(roleOwner,"is not linked to",permRead); + if(!dryRun) { + query = "UPDATE authz.role set perms = perms + " + + "{'" + nk.name + "|access|*|read'} " + + "WHERE ns='"+ nk.name + "' AND " + + "name='owner'" + + ";"; + session.execute(query); + env.info().log(query); + + if(rk.perms.contains(permReadPrev)) { + query = "UPDATE authz.role set perms = perms - " + + "{'" + nk.name + ".access|*|read'} " + + "WHERE ns='"+ nk.name + "' AND " + + "name='owner'" + + ";"; + session.execute(query); + env.info().log(query); + + } + } + } + // Role Owner should not be linked to PermAll + if(rk.perms.contains(permAll)) { + trans.warn().log(roleAdmin,"should not be linked to",permAll); + if(!dryRun) { + query = "UPDATE authz.role set perms = perms - " + + "{'" + nk.name + "|access|*|*'} " + + "WHERE ns='"+ nk.name + "' AND " + + "name='admin'" + + ";"; + session.execute(query); + env.info().log(query); + } + } + + } + + pk = Perm.keys.get(permRead); + if(pk==null) { + trans.warn().log(nk.name + " is missing perm: " + permRead); + if(!dryRun) { + query = "INSERT INTO authz.perm(ns, type,instance,action,description, roles) VALUES ('" + + nk.name + + "','access','*','read','Namespace Read'," + + "{'" + nk.name + "|owner'});"; + session.execute(query); + env.info().log(query); + } + } else { + // PermRead should be linked to roleOwner + if(!pk.roles.contains(roleOwner)) { + trans.warn().log(permRead, "is not linked to", roleOwner); + if(!dryRun) { + query = "UPDATE authz.perm set roles = roles + " + + "{'" + nk.name + "|owner'} WHERE " + + "ns='"+ pk.ns + "' AND " + + "type='access' AND instance='*' and action='read'" + + ";"; + session.execute(query); + env.info().log(query); + + if(pk.roles.contains(roleOwnerPrev)) { + query = "UPDATE authz.perm set roles = roles - " + + "{'" + nk.name + ".owner'} WHERE " + + "ns='"+ pk.ns + "' AND " + + "type='access' AND instance='*' and action='read'" + + ";"; + session.execute(query); + env.info().log(query); + + } + } + } + // PermRead should be not linked to RoleAdmin + if(pk.roles.contains(roleAdmin)) { + if(dryRun) { + trans.warn().log(permRead,"should not be linked to",roleAdmin); + } else { + query = "UPDATE authz.perm set roles = roles - " + + "{'" + nk.name + "|admin'} WHERE " + + "ns='"+ pk.ns + "' AND " + + "type='access' AND instance='*' and action='read'" + + ";"; + session.execute(query); + env.info().log(query); + } + } + } + + + int dot = nk.name.lastIndexOf('.'); + String parent; + if(dot<0) { + parent = "."; + } else { + parent = nk.name.substring(0, dot); + } + + if(!parent.equals(nk.parent)) { + if(dryRun) { + trans.warn().log(nk.name + " is missing namespace data"); + } else { + query = "UPDATE authz.ns SET parent='"+parent+"'" + + " WHERE name='" + nk.name + "';"; + session.execute(query); + env.info().log(query); + } + } + + // During Migration: + List<NsAttrib> swm = NsAttrib.byNS.get(nk.name); + boolean hasSwmV1 = false; + if(swm!=null) {for(NsAttrib na : swm) { + if("swm".equals(na.key) && "v1".equals(na.value)) { + hasSwmV1=true; + break; + } + }} + String roleMem = nk.name+"|member"; + Role rm = Role.keys.get(roleMem); // Accommodate new role key + if(rm==null && hasSwmV1) { + query = "INSERT INTO authz.role(ns, name, description, perms) VALUES ('" + + nk.name + + "','member','Member'," + + "{'" + nk.name + "|access|*|read'});"; + session.execute(query); + query = "UPDATE authz.role set perms = perms + " + + "{'" + nk.name + "|access|*|read'} " + + "WHERE ns='"+ nk.name + "' AND " + + "name='member'" + + ";"; + session.execute(query); + env.info().log(query); + } + if(rm!=null) { + if(!rm.perms.contains(permRead)) { + if(isDryRun()) { + env.info().log(nk.name+"|member needs " + nk.name + "|access|*|read"); + } else { + query = "UPDATE authz.perm set roles = roles + " + + "{'" + nk.name + "|member'} WHERE " + + "ns='"+ pk.ns + "' AND " + + "type='access' AND instance='*' and action='read'" + + ";"; + session.execute(query); + env.info().log(query); + query = "UPDATE authz.role set perms = perms + " + + "{'" + nk.name + "|access|*|read'" + + (hasSwmV1?",'"+nk.name+"|swm.star|*|*'":"") + + "} " + + "WHERE ns='"+ nk.name + "' AND " + + "name='member'" + + ";"; + session.execute(query); + env.info().log(query); + if(hasSwmV1) { + query = "UPDATE authz.perm set roles = roles + " + + "{'" + nk.name + "|member'} WHERE " + + "ns='"+ pk.ns + "' AND " + + "type='swm.star' AND instance='*' and action='*'" + + ";"; + session.execute(query); + env.info().log(query); + } + } + } + } + + + + // Best Guess Owner + +// owner = Role.keys.get(ns.) + } + } finally { + tt.done(); + } + + } + + + @Override + protected void _close(AuthzTrans trans) { + session.close(); + aspr.info("End " + this.getClass().getSimpleName() + " processing" ); + } +} diff --git a/authz-batch/src/main/java/com/att/authz/reports/CheckRolePerm.java b/authz-batch/src/main/java/com/att/authz/reports/CheckRolePerm.java new file mode 100644 index 00000000..ef3d933c --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/reports/CheckRolePerm.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.reports; + +import java.io.IOException; +import java.util.Set; + +import com.att.authz.Batch; +import com.att.authz.env.AuthzTrans; +import com.att.authz.helpers.NS; +import com.att.authz.helpers.Perm; +import com.att.authz.helpers.Role; +import com.att.inno.env.APIException; +import com.att.inno.env.Env; +import com.att.inno.env.TimeTaken; +import com.att.inno.env.util.Split; + +public class CheckRolePerm extends Batch{ + + public CheckRolePerm(AuthzTrans trans) throws APIException, IOException { + super(trans.env()); + TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE); + try { + session = cluster.connect(); + } finally { + tt.done(); + } + NS.load(trans,session,NS.v2_0_11); + Role.load(trans, session); + Perm.load(trans, session); + } + + @Override + protected void run(AuthzTrans trans) { + // Run for Roles + trans.info().log("Checking for Role/Perm mis-match"); + + String query; + /// Evaluate from Role side + for(Role roleKey : Role.data.keySet()) { + for(String perm : Role.data.get(roleKey)) { + Perm pk = Perm.keys.get(perm); + if(pk==null) { + NS ns=null; + String msg = perm + " in role " + roleKey.fullName() + " does not exist"; + String newPerm; + String[] s = Split.split('|', perm); + if(s.length==3) { + int i; + String find = s[0]; + for(i=find.lastIndexOf('.');ns==null && i>=0;i=find.lastIndexOf('.', i-1)) { + ns = NS.data.get(find.substring(0,i)); + } + if(ns==null) { + newPerm = perm; + } else { + newPerm = ns.name + '|' + s[0].substring(i+1) + '|' + s[1] + '|' + s[2]; + } + } else { + newPerm = perm; + } + if(dryRun) { + if(ns==null) { + trans.warn().log(msg, "- would remove role from perm;"); + } else { + trans.warn().log(msg, "- would update role in perm;"); + } + } else { + if(ns!=null) { + query = "UPDATE authz.role SET perms = perms + {'" + + newPerm + "'}" + + (roleKey.description==null?", description='clean'":"") + + " WHERE " + + "ns='" + roleKey.ns + + "' AND name='" + roleKey.name + "';"; + trans.warn().log("Fixing role in perm",query); + session.execute(query); + } + + query = "UPDATE authz.role SET perms = perms - {'" + + perm.replace("'", "''") + "'}" + + (roleKey.description==null?", description='clean'":"") + + " WHERE " + + "ns='" + roleKey.ns + + "' AND name='" + roleKey.name + "';"; + session.execute(query); + trans.warn().log(msg, "- removing role from perm"); +// env.info().log( "query: " + query ); + } + } else { + Set<String> p_roles = Perm.data.get(pk); + if(p_roles!=null && !p_roles.contains(roleKey.encode())) { + String msg = perm + " does not have role: " + roleKey; + if(dryRun) { + trans.warn().log(msg,"- should add this role to this perm;"); + } else { + query = "update authz.perm set roles = roles + {'" + + roleKey.encode() + "'}" + + (pk.description==null?", description=''":"") + + " WHERE " + + "ns='" + pk.ns + + "' AND type='" + pk.type + + "' AND instance='" + pk.instance + + "' AND action='" + pk.action + + "';"; + session.execute(query); + trans.warn().log(msg,"- adding perm to role"); + } + + } + } + } + } + + for(Perm permKey : Perm.data.keySet()) { + for(String role : Perm.data.get(permKey)) { + Role rk = Role.keys.get(role); + if(rk==null) { + String s = role + " in perm " + permKey.encode() + " does not exist"; + if(dryRun) { + trans.warn().log(s,"- would remove perm from role;"); + } else { + query = "update authz.perm set roles = roles - {'" + + role.replace("'","''") + "'}" + + (permKey.description==null?", description='clean'":"") + + " WHERE " + + "ns='" + permKey.ns + + "' AND type='" + permKey.type + + "' AND instance='" + permKey.instance + + "' AND action='" + permKey.action + "';"; + session.execute(query); + trans.warn().log(s,"- removing role from perm"); + } + } else { + Set<String> r_perms = Role.data.get(rk); + if(r_perms!=null && !r_perms.contains(permKey.encode())) { + String s ="Role '" + role + "' does not have perm: '" + permKey + '\''; + if(dryRun) { + trans.warn().log(s,"- should add this perm to this role;"); + } else { + query = "update authz.role set perms = perms + {'" + + permKey.encode() + "'}" + + (rk.description==null?", description=''":"") + + " WHERE " + + "ns='" + rk.ns + + "' AND name='" + rk.name + "';"; + session.execute(query); + trans.warn().log(s,"- adding role to perm"); + } + } + } + } + } + + } + + + @Override + protected void _close(AuthzTrans trans) { + session.close(); + aspr.info("End " + this.getClass().getSimpleName() + " processing" ); + } +} diff --git a/authz-batch/src/main/java/com/att/authz/reports/CheckUR.java b/authz-batch/src/main/java/com/att/authz/reports/CheckUR.java new file mode 100644 index 00000000..99a2ae5d --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/reports/CheckUR.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.reports; + +import java.io.IOException; + +import com.att.authz.Batch; +import com.att.authz.env.AuthzTrans; +import com.att.authz.helpers.NS; +import com.att.authz.helpers.NS.NSSplit; +import com.att.authz.helpers.UserRole; +import com.att.inno.env.APIException; +import com.att.inno.env.Env; +import com.att.inno.env.TimeTaken; + +public class CheckUR extends Batch{ + + public CheckUR(AuthzTrans trans) throws APIException, IOException { + super(trans.env()); + TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE); + try { + session = cluster.connect(); + } finally { + tt.done(); + } + NS.load(trans, session,NS.v2_0_11); + UserRole.load(trans, session,UserRole.v2_0_11); + } + + @Override + protected void run(AuthzTrans trans) { + trans.info().log("Get All Namespaces"); + + + String query; + + /// Evaluate + for(UserRole urKey : UserRole.data) { + NSSplit nss = NS.deriveParent(urKey.role); + if(nss==null && NS.data.size()>0 ) { // there is no Namespace for this UserRole + if(dryRun) { + trans.warn().printf("Would delete %s %s, which has no corresponding Namespace",urKey.user,urKey.role); + } else { + query = "DELETE FROM authz.user_role WHERE " + + "user='" + urKey.user + + "' AND role='" + urKey.role + + "';"; + session.execute(query); + trans.warn().printf("Deleting %s %s, which has no corresponding Namespace",urKey.user,urKey.role); + } + } else if(urKey.ns == null || urKey.rname == null || !urKey.role.equals(urKey.ns+'.'+urKey.rname)) { + if(dryRun) { + trans.warn().log(urKey,"needs to be split and added to Record (", urKey.ns, urKey.rname,")"); + } else { + query = "UPDATE authz.user_role SET ns='" + nss.ns + + "', rname='" + nss.other + + "' WHERE " + + "user='" + urKey.user + + "' AND role='" + urKey.role + + "';"; + session.execute(query); + trans.warn().log("Setting ns and rname",query); + } + } + } + } + + @Override + protected void _close(AuthzTrans trans) { + session.close(); + aspr.info("End " + this.getClass().getSimpleName() + " processing" ); + } +} diff --git a/authz-batch/src/main/java/com/att/authz/reports/Expiring.java b/authz-batch/src/main/java/com/att/authz/reports/Expiring.java new file mode 100644 index 00000000..eb420433 --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/reports/Expiring.java @@ -0,0 +1,235 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.reports; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.List; + +import com.att.authz.Batch; +import com.att.authz.actions.Action; +import com.att.authz.actions.ActionDAO; +import com.att.authz.actions.CredDelete; +import com.att.authz.actions.CredPrint; +import com.att.authz.actions.FADelete; +import com.att.authz.actions.FAPrint; +import com.att.authz.actions.Key; +import com.att.authz.actions.URDelete; +import com.att.authz.actions.URFutureApprove; +import com.att.authz.actions.URFuturePrint; +import com.att.authz.actions.URPrint; +import com.att.authz.env.AuthzTrans; +import com.att.authz.helpers.Cred; +import com.att.authz.helpers.Cred.Instance; +import com.att.authz.helpers.Future; +import com.att.authz.helpers.Notification; +import com.att.authz.helpers.UserRole; +import com.att.authz.layer.Result; +import com.att.authz.org.Organization.Identity; +import com.att.dao.aaf.cass.CredDAO; +import com.att.inno.env.APIException; +import com.att.inno.env.Env; +import com.att.inno.env.TimeTaken; + +public class Expiring extends Batch { + + private final Action<UserRole,Void> urDelete,urPrint; + private final Action<UserRole,List<Identity>> urFutureApprove; + private final Action<CredDAO.Data,Void> crDelete,crPrint; + private final Action<Future,Void> faDelete; +// private final Email email; + private final Key<UserRole> memoKey; + + public Expiring(AuthzTrans trans) throws APIException, IOException { + super(trans.env()); + trans.info().log("Starting Connection Process"); + TimeTaken tt0 = trans.start("Cassandra Initialization", Env.SUB); + try { + urPrint = new URPrint("Expired:"); + crPrint = new CredPrint("Expired:"); + + URFutureApprove ufr = new URFutureApprove(trans,cluster); + memoKey = ufr; + + if(isDryRun()) { + urDelete = new URPrint("Would Delete:"); + // While Testing +// urFutureApprove = ufr; + urFutureApprove = new URFuturePrint("Would setup Future/Approvals"); + crDelete = new CredPrint("Would Delete:"); + faDelete = new FAPrint("Would Delete:"); +// email = new EmailPrint(); + + TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE); + try { + session = cluster.connect(); + } finally { + tt.done(); + } + + } else { + TimeTaken tt = trans.start("Connect to Cluster with DAOs", Env.REMOTE); + try { + ActionDAO<UserRole,Void> adao; + urDelete = adao = new URDelete(trans, cluster); + urFutureApprove = new URFutureApprove(trans,adao); + faDelete = new FADelete(trans, adao); + + crDelete = new CredDelete(trans, adao); +// email = new Email(); + TimeTaken tt2 = trans.start("Connect to Cluster", Env.REMOTE); + try { + session = adao.getSession(trans); + } finally { + tt2.done(); + } + } finally { + tt.done(); + } + } + + UserRole.load(trans, session, UserRole.v2_0_11); + Cred.load(trans, session); + Notification.load(trans, session, Notification.v2_0_14); + Future.load(trans,session,Future.v2_0_15); + } finally { + tt0.done(); + } + } + + @Override + protected void run(AuthzTrans trans) { + // Setup Date boundaries + Date now = new Date(); + GregorianCalendar gc = new GregorianCalendar(); + gc.setTime(now); + gc.add(GregorianCalendar.MONTH, 1); + Date future = gc.getTime(); + gc.setTime(now); + gc.add(GregorianCalendar.MONTH, -1); + Date tooLate = gc.getTime(); + int count = 0, deleted=0; + +// List<Notification> ln = new ArrayList<Notification>(); + TimeTaken tt; + + // Run for Expired Futures + trans.info().log("Checking for Expired Futures"); + tt = trans.start("Delete old Futures", Env.REMOTE); + try { + List<Future> delf = new ArrayList<Future>(); + for(Future f : Future.data) { + AuthzTrans localTrans = env.newTransNoAvg(); + if(f.expires.before(now)) { + faDelete.exec(localTrans, f); + delf.add(f); + } + } + Future.delete(delf); + } finally { + tt.done(); + } + + // Run for Roles + trans.info().log("Checking for Expired Roles"); + try { + for(UserRole ur : UserRole.data) { + AuthzTrans localTrans = env.newTransNoAvg(); + if(ur.expires.before(tooLate)) { + if("owner".equals(ur.rname)) { // don't delete Owners, even if Expired + urPrint.exec(localTrans,ur); + } else { + urDelete.exec(localTrans,ur); + ++deleted; + trans.logAuditTrail(trans.info()); + } + ++count; + } else if(ur.expires.before(future)) { + List<Future> fbm = Future.byMemo.get(memoKey.key(ur)); + if(fbm==null || fbm.isEmpty()) { + Result<List<Identity>> rapprovers = urFutureApprove.exec(localTrans, ur); + if(rapprovers.isOK()) { + for(Identity ou : rapprovers.value) { +// Notification n = Notification.addApproval(localTrans,ou); +// if(n.org==null) { +// n.org = getOrgFromID(localTrans, ur.user); +// } +// ln.add(n); + urPrint.exec(localTrans,ur); + if(isDryRun()) { + trans.logAuditTrail(trans.info()); + } + } + } + } + ++count; + } + } + } finally { + env.info().log("Found",count,"roles expiring before",future); + env.info().log("deleting",deleted,"roles expiring before",tooLate); + } + +// // Email Approval Notification +// email.subject("AAF Role Expiration Warning (ENV: %s)", batchEnv); +// email.indent(""); +// for(Notification n: ln) { +// if(n.org==null) { +// trans.error().log("No Organization for Notification"); +// } else if(n.update(trans, session, isDryRun())) { +// email.clear(); +// email.addTo(n.user); +// email.line(n.text(new StringBuilder()).toString()); +// email.exec(trans,n.org); +// } +// } + // Run for Creds + trans.info().log("Checking for Expired Credentials"); + System.out.flush(); + count = 0; + try { + CredDAO.Data crd = new CredDAO.Data(); + Date last = null; + for( Cred creds : Cred.data.values()) { + AuthzTrans localTrans = env.newTransNoAvg(); + crd.id = creds.id; + for(int type : creds.types()) { + crd.type = type; + for( Instance inst : creds.instances) { + if(inst.expires.before(tooLate)) { + crd.expires = inst.expires; + crDelete.exec(localTrans, crd); + } else if(last==null || inst.expires.after(last)) { + last = inst.expires; + } + } + if(last!=null) { + if(last.before(future)) { + crd.expires = last; + crPrint.exec(localTrans, crd); + ++count; + } + } + } + } + } finally { + env.info().log("Found",count,"current creds expiring before",future); + } + + } + + @Override + protected void _close(AuthzTrans trans) { + aspr.info("End " + this.getClass().getSimpleName() + " processing" ); + for(Action<?,?> action : new Action<?,?>[] {urDelete,crDelete}) { + if(action instanceof ActionDAO) { + ((ActionDAO<?,?>)action).close(trans); + } + } + session.close(); + } + +} diff --git a/authz-batch/src/main/java/com/att/authz/reports/NSDump.java b/authz-batch/src/main/java/com/att/authz/reports/NSDump.java new file mode 100644 index 00000000..bfed2a3f --- /dev/null +++ b/authz-batch/src/main/java/com/att/authz/reports/NSDump.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved. + *******************************************************************************/ +package com.att.authz.reports; + +import java.io.IOException; +import java.io.PrintStream; +import java.util.Date; +import java.util.List; + +import com.att.authz.Batch; +import com.att.authz.env.AuthzTrans; +import com.att.authz.helpers.Cred; +import com.att.authz.helpers.NS; +import com.att.authz.helpers.Perm; +import com.att.authz.helpers.Role; +import com.att.authz.helpers.UserRole; +import com.att.inno.env.APIException; +import com.att.inno.env.Env; +import com.att.inno.env.TimeTaken; + +public class NSDump extends Batch{ + private PrintStream out = System.out; + private final String ns, admin, owner; + + public NSDump(AuthzTrans trans) throws APIException, IOException { + super(trans.env()); + if(args().length>0) { + ns = args()[0]; + } else { + throw new APIException("NSDump requires \"NS\" parameter"); + } + admin = ns + "|admin"; + owner = ns + "|owner"; + + TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE); + try { + session = cluster.connect(); + } finally { + tt.done(); + } + + NS.loadOne(trans, session,NS.v2_0_11,ns); + Role.loadOneNS(trans, session, ns); + if(Role.data.keySet().size()>5) { + UserRole.load(trans, session,UserRole.v2_0_11); + } else { + for(Role r : Role.data.keySet()) { + UserRole.loadOneRole(trans, session, UserRole.v2_0_11, r.fullName()); + } + } + Perm.loadOneNS(trans,session,ns); + Cred.loadOneNS(trans, session, ns); + } + + @Override + protected void run(AuthzTrans trans) { + Date now = new Date(); + for(NS ns : NS.data.values()) { + out.format("# Data for Namespace [%s] - %s\n",ns.name,ns.description); + out.format("ns create %s",ns); + boolean first = true; + List<UserRole> owners = UserRole.byRole.get(owner); + if(owners!=null)for(UserRole ur : owners) { + if(first) { + out.append(' '); + first = false; + } else { + out.append(','); + } + out.append(ur.user); + } + first = true; + List<UserRole> admins = UserRole.byRole.get(admin); + if(admins!=null)for(UserRole ur : admins) { + if(first) { + out.append(' '); + first = false; + } else { + out.append(','); + } + out.append(ur.user); + } + out.println(); + + // Load Creds + Date last; + for(Cred c : Cred.data.values()) { + for(int i : c.types()) { + last = c.last(i); + if(last!=null && now.before(last)) { + switch(i) { + case 1: + out.format(" user cred add %s %s\n", c.id,"new2you!"); + break; + case 200: + out.format(" # CERT needs registering for %s\n", c.id); + break; + default: + out.format(" # Unknown Type for %s\n", c.id); + } + } + } + } + + // Load Roles + for(Role r : Role.data.keySet()) { + if(!"admin".equals(r.name) && !"owner".equals(r.name)) { + out.format(" role create %s\n",r.fullName()); + List<UserRole> lur = UserRole.byRole.get(r.fullName()); + if(lur!=null)for(UserRole ur : lur) { + if(ur.expires.after(now)) { + out.format(" request role user add %s %s\n", ur.role,ur.user); + } + } + } + } + + // Load Perms + for(Perm r : Perm.data.keySet()) { + out.format(" perm create %s.%s %s %s\n",r.ns,r.type,r.instance,r.action); + for(String role : r.roles) { + out.format(" request perm grant %s.%s %s %s %s\n", r.ns,r.type,r.instance,r.action,Role.fullName(role)); + } + } + + } + } + + @Override + protected void _close(AuthzTrans trans) { + session.close(); + aspr.info("End " + this.getClass().getSimpleName() + " processing" ); + } + +} diff --git a/authz-batch/src/main/scripts/SyncV1V2 b/authz-batch/src/main/scripts/SyncV1V2 new file mode 100644 index 00000000..c3a9115a --- /dev/null +++ b/authz-batch/src/main/scripts/SyncV1V2 @@ -0,0 +1,17 @@ +#!/bin/bash +JAVA_HOME=_JAVA_HOME_ +PATH=${PATH}:${JAVA_HOME}/bin +ROOT_DIR=_ROOT_DIR_ + +cd $ROOT_DIR + +CP=${ROOT_DIR}/etc +for FILE in `ls $ROOT_DIR/lib/*.jar`; do + CP=$CP:$FILE +done + +CMD="SyncV1V2" +echo $CMD >> $ROOT_DIR/cronlog +date >> $ROOT_DIR/cronlog +$JAVA_HOME/bin/java -Xmx2048m -classpath $CP com.att.authz.Batch $CMD >> $ROOT_DIR/cronlog +date >> $ROOT_DIR/cronlog diff --git a/authz-batch/src/main/scripts/SyncV1V2daily b/authz-batch/src/main/scripts/SyncV1V2daily new file mode 100644 index 00000000..5c89d04d --- /dev/null +++ b/authz-batch/src/main/scripts/SyncV1V2daily @@ -0,0 +1,17 @@ +#!/bin/bash +JAVA_HOME=_JAVA_HOME_ +PATH=${PATH}:${JAVA_HOME}/bin +ROOT_DIR=_ROOT_DIR_ + +cd $ROOT_DIR + +CP=${ROOT_DIR}/etc +for FILE in `ls $ROOT_DIR/lib/*.jar`; do + CP=$CP:$FILE +done + +CMD="SyncV1V2 v1 v2" +echo $CMD >> $ROOT_DIR/cronlog +date >> $ROOT_DIR/cronlog +$JAVA_HOME/bin/java -Xmx2048m -classpath $CP com.att.authz.Batch $CMD >> $ROOT_DIR/cronlog +date >> $ROOT_DIR/cronlog diff --git a/authz-batch/src/main/scripts/SyncV2V1 b/authz-batch/src/main/scripts/SyncV2V1 new file mode 100644 index 00000000..e766218f --- /dev/null +++ b/authz-batch/src/main/scripts/SyncV2V1 @@ -0,0 +1,17 @@ +#!/bin/bash +JAVA_HOME=_JAVA_HOME_ +PATH=${PATH}:${JAVA_HOME}/bin +ROOT_DIR=_ROOT_DIR_ + +cd $ROOT_DIR + +CP=${ROOT_DIR}/etc +for FILE in `ls $ROOT_DIR/lib/*.jar`; do + CP=$CP:$FILE +done + +CMD="SyncV2V1" +echo $CMD >> $ROOT_DIR/cronlog +date >> $ROOT_DIR/cronlog +$JAVA_HOME/bin/java -Xmx2048m -classpath $CP com.att.authz.Batch $CMD >> $ROOT_DIR/cronlog +date >> $ROOT_DIR/cronlog
\ No newline at end of file diff --git a/authz-batch/src/main/scripts/SyncV2V1daily b/authz-batch/src/main/scripts/SyncV2V1daily new file mode 100644 index 00000000..8a676928 --- /dev/null +++ b/authz-batch/src/main/scripts/SyncV2V1daily @@ -0,0 +1,17 @@ +#!/bin/bash +JAVA_HOME=_JAVA_HOME_ +PATH=${PATH}:${JAVA_HOME}/bin +ROOT_DIR=_ROOT_DIR_ + +cd $ROOT_DIR + +CP=${ROOT_DIR}/etc +for FILE in `ls $ROOT_DIR/lib/*.jar`; do + CP=$CP:$FILE +done + +CMD="SyncV2V1 v2 v1" +echo $CMD >> $ROOT_DIR/cronlog +date >> $ROOT_DIR/cronlog +$JAVA_HOME/bin/java -Xmx2048m -classpath $CP com.att.authz.Batch $CMD >> $ROOT_DIR/cronlog +date >> $ROOT_DIR/cronlog
\ No newline at end of file diff --git a/authz-batch/src/main/scripts/V1daily b/authz-batch/src/main/scripts/V1daily new file mode 100644 index 00000000..9f6c4ca9 --- /dev/null +++ b/authz-batch/src/main/scripts/V1daily @@ -0,0 +1,46 @@ +#!/bin/bash +JAVA_HOME=_JAVA_HOME_ +PATH=${PATH}:${JAVA_HOME}/bin +ROOT_DIR=_ROOT_DIR_ +ENV_CONTEXT=_ENV_CONTEXT_ + +cd $ROOT_DIR + +if [ ! -e "$ROOT_DIR/data/stage" ]; then + mkdir -p $ROOT_DIR/data/stage +fi + +if [ ! -e "$ROOT_DIR/data/$ENV_CONTEXT/stage" ]; then + mkdir -p $ROOT_DIR/data/$ENV_CONTEXT + ln -s $ROOT_DIR/data/stage $ROOT_DIR/data/$ENV_CONTEXT/stage +fi + +CP=${ROOT_DIR}/etc +for FILE in `ls $ROOT_DIR/lib/*.jar`; do + CP=$CP:$FILE +done + +CMD="V1DataFile all" +echo $CMD >> $ROOT_DIR/cronlog +date >> $ROOT_DIR/cronlog +$JAVA_HOME/bin/java -Xmx2048m -classpath $CP com.att.authz.Batch $CMD >> $ROOT_DIR/cronlog +date >> $ROOT_DIR/cronlog + +cd $ROOT_DIR/data/stage +LATEST=`ls -tr v1*.dat | tail -1` +if [ "$LATEST" != "" ]; then + > ../v1.lock + cp -p $LATEST ../v1.dat + rm ../v1.lock +fi + +LATEST=`ls -tr v1*.skip | tail -1` +if [ "$LATEST" != "" ]; then + cp -p $LATEST ../v1.skip +fi + +for FILE in `ls v1* | grep -v .gz`; do + gzip $FILE +done + + diff --git a/authz-batch/src/main/scripts/V2daily b/authz-batch/src/main/scripts/V2daily new file mode 100644 index 00000000..c547a949 --- /dev/null +++ b/authz-batch/src/main/scripts/V2daily @@ -0,0 +1,46 @@ +#!/bin/bash +JAVA_HOME=_JAVA_HOME_ +PATH=${PATH}:${JAVA_HOME}/bin +ROOT_DIR=_ROOT_DIR_ +ENV_CONTEXT=_ENV_CONTEXT_ + +cd $ROOT_DIR + +if [ ! -e "$ROOT_DIR/data/stage" ]; then + mkdir -p $ROOT_DIR/data/stage +fi + +if [ ! -e "$ROOT_DIR/data/$ENV_CONTEXT/stage" ]; then + mkdir -p $ROOT_DIR/data/$ENV_CONTEXT + ln -s $ROOT_DIR/data/stage $ROOT_DIR/data/$ENV_CONTEXT/stage +fi + +CP=${ROOT_DIR}/etc +for FILE in `ls $ROOT_DIR/lib/*.jar`; do + CP=$CP:$FILE +done + +CMD="V2DataFile all" +echo $CMD >> $ROOT_DIR/cronlog +date >> $ROOT_DIR/cronlog +$JAVA_HOME/bin/java -Xmx2048m -classpath $CP com.att.authz.Batch $CMD >> $ROOT_DIR/cronlog +date >> $ROOT_DIR/cronlog + +cd $ROOT_DIR/data/stage +LATEST=`ls -tr v2*.dat | tail -1` +if [ "$LATEST" != "" ]; then + > ../v2.lock + cp -p $LATEST ../v2.dat + rm ../v2.lock +fi + +LATEST=`ls -tr v2*.skip | tail -1` +if [ "$LATEST" != "" ]; then + cp -p $LATEST ../v2.skip +fi + +for FILE in `ls v2* | grep -v .gz`; do + gzip $FILE +done + + diff --git a/authz-batch/src/main/scripts/aafbch b/authz-batch/src/main/scripts/aafbch new file mode 100644 index 00000000..fdeb22ea --- /dev/null +++ b/authz-batch/src/main/scripts/aafbch @@ -0,0 +1,21 @@ +#!/bin/bash +JAVA_HOME=_JAVA_HOME_ +PATH=${PATH}:${JAVA_HOME}/bin +ROOT_DIR=_ROOT_DIR_ +cd $ROOT_DIR + +if [ "$1" = "InnerConsistency" ]; then + CLS=com.att.authz.temp.InnerConsistency + shift +else + CLS=com.att.authz.Batch +fi + +CP=${ROOT_DIR}/etc +for FILE in `ls $ROOT_DIR/lib/*.jar`; do + CP=$CP:$FILE +done + +date +$JAVA_HOME/bin/java -Xmx2048m -classpath $CP $CLS $* +date diff --git a/authz-batch/src/main/scripts/run_batch b/authz-batch/src/main/scripts/run_batch new file mode 100644 index 00000000..c09ea0a3 --- /dev/null +++ b/authz-batch/src/main/scripts/run_batch @@ -0,0 +1,16 @@ +#!/bin/env bash + +if [[ $# < 1 ]]; then + echo "USAGE: run_batch ExpiryNotification|ApprNotify|JobChange|RoleExpiration|ValidateUsers" + exit 1; +fi + +JAVA_HOME=_JAVA_HOME_ +AAF_CP="_ROOT_DIR_/etc" +for JAR in `find _ROOT_DIR_/lib -name *.jar` ; do + AAF_CP="$AAF_CP:$JAR" +done + +$JAVA_HOME/bin/java -cp $AAF_CP com.att.authz.Batch $* + + |