diff options
6 files changed, 111 insertions, 117 deletions
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URFutureApproveExec.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URFutureApproveExec.java index 635efef0..acbadca7 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URFutureApproveExec.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URFutureApproveExec.java @@ -75,7 +75,7 @@ public class URFutureApproveExec extends ActionDAO<List<Approval>, OP_STATUS, Fu new Lookup<UserRoleDAO.Data>() { @Override public UserRoleDAO.Data get(AuthzTrans trans, Object ... keys) { - List<UserRole> lur = UserRole.byUser.get(keys[0]); + List<UserRole> lur = UserRole.getByUser().get(keys[0]); if(lur!=null) { for(UserRole ur : lur) { if(ur.role().equals(keys[1])) { diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/UserRole.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/UserRole.java index a289fe00..288211e6 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/UserRole.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/UserRole.java @@ -7,9 +7,9 @@ * Licensed 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. @@ -26,6 +26,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; +import java.util.SortedMap; import java.util.TreeMap; import org.onap.aaf.auth.actions.URDelete; @@ -44,16 +45,36 @@ import com.datastax.driver.core.SimpleStatement; import com.datastax.driver.core.Statement; public class UserRole implements Cloneable, CacheChange.Data { - public static final List<UserRole> data = new ArrayList<>(); - public static final TreeMap<String,List<UserRole>> byUser = new TreeMap<>(); - public static final TreeMap<String,List<UserRole>> byRole = new TreeMap<>(); - private final static CacheChange<UserRole> cache = new CacheChange<>(); - private static PrintStream urDelete=System.out,urRecover=System.err; + + private static final String SEPARATOR = "\",\""; + + // CACHE Calling + private static final String LOG_FMT = "%s UserRole - %s: %s-%s (%s, %s) expiring %s"; + private static final String REPLAY_FMT = "%s|%s|%s|%s|%s\n"; + private static final String DELETE_FMT = "# %s\n"+ REPLAY_FMT; + + private static final List<UserRole> data = new ArrayList<>(); + private static final SortedMap<String,List<UserRole>> byUser = new TreeMap<>(); + private static final SortedMap<String,List<UserRole>> byRole = new TreeMap<>(); + private static final CacheChange<UserRole> cache = new CacheChange<>(); + private static PrintStream urDelete = System.out; + private static PrintStream urRecover = System.err; private static int totalLoaded; - private static int deleted; - + private int deleted; private Data urdd; + public static final 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.getTimestamp(4)); + } + + @Override + public String select() { + return "select user,role,ns,rname,expires from authz.user_role"; + } + }; + public UserRole(String user, String ns, String rname, Date expires) { urdd = new UserRoleDAO.Data(); urdd.user = user; @@ -72,6 +93,18 @@ public class UserRole implements Cloneable, CacheChange.Data { urdd.expires = expires; } + public static List<UserRole> getData() { + return data; + } + + public static SortedMap<String, List<UserRole>> getByUser() { + return byUser; + } + + public static SortedMap<String, List<UserRole>> getByRole() { + return byRole; + } + public static void load(Trans trans, Session session, Creator<UserRole> creator ) { load(trans,session,creator,null); } @@ -87,9 +120,9 @@ public class UserRole implements Cloneable, CacheChange.Data { 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; + TimeTaken tt = trans.start("Read UserRoles", Env.REMOTE); + + ResultSet results; try { Statement stmt = new SimpleStatement( query ); results = session.execute(stmt); @@ -97,30 +130,9 @@ public class UserRole implements Cloneable, CacheChange.Data { tt.done(); } try { - Iterator<Row> iter = results.iterator(); - Row row; tt = trans.start("Load UserRole", Env.SUB); try { - while(iter.hasNext()) { - ++totalLoaded; - row = iter.next(); - UserRole ur = creator.create(row); - data.add(ur); - - List<UserRole> lur = byUser.get(ur.urdd.user); - if(lur==null) { - lur = new ArrayList<>(); - byUser.put(ur.urdd.user, lur); - } - lur.add(ur); - - lur = byRole.get(ur.urdd.role); - if(lur==null) { - lur = new ArrayList<>(); - byRole.put(ur.urdd.role, lur); - } - lur.add(ur); - } + iterateResults(creator, results.iterator()); } finally { tt.done(); } @@ -128,7 +140,31 @@ public class UserRole implements Cloneable, CacheChange.Data { trans.info().log("Loaded",totalLoaded,"UserRoles"); } } - + + private static void iterateResults(Creator<UserRole> creator, Iterator<Row> iter ) { + Row row; + while(iter.hasNext()) { + ++totalLoaded; + row = iter.next(); + UserRole ur = creator.create(row); + data.add(ur); + + List<UserRole> lur = byUser.get(ur.urdd.user); + if(lur==null) { + lur = new ArrayList<>(); + byUser.put(ur.urdd.user, lur); + } + lur.add(ur); + + lur = byRole.get(ur.urdd.role); + if(lur==null) { + lur = new ArrayList<>(); + byRole.put(ur.urdd.role, lur); + } + lur.add(ur); + } + } + public int totalLoaded() { return totalLoaded; } @@ -174,26 +210,13 @@ public class UserRole implements Cloneable, CacheChange.Data { } } - - 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.getTimestamp(4)); - } - - @Override - public String select() { - return "select user,role,ns,rname,expires from authz.user_role"; - } - }; - public UserRoleDAO.Data urdd() { return urdd; } public String user() { return urdd.user; - }; + } public String role() { return urdd.role; @@ -215,16 +238,16 @@ public class UserRole implements Cloneable, CacheChange.Data { urdd.expires = time; } - - public String toString() { - return "\"" + urdd.user + "\",\"" + urdd.role + "\",\"" + urdd.ns + "\",\"" + urdd.rname + "\",\""+ Chrono.dateOnlyStamp(urdd.expires); + return "\"" + urdd.user + SEPARATOR + urdd.role + SEPARATOR + urdd.ns + SEPARATOR + urdd.rname + SEPARATOR + + Chrono.dateOnlyStamp(urdd.expires); } public static UserRole get(String u, String r) { List<UserRole> lur = byUser.get(u); if(lur!=null) { for(UserRole ur : lur) { + if(ur.urdd.role.equals(r)) { return ur; } @@ -232,23 +255,18 @@ public class UserRole implements Cloneable, CacheChange.Data { } return null; } - - // CACHE Calling - private static final String logfmt = "%s UserRole - %s: %s-%s (%s, %s) expiring %s"; - private static final String replayfmt = "%s|%s|%s|%s|%s\n"; - private static final String deletefmt = "# %s\n"+replayfmt; - + // SAFETY - DO NOT DELETE USER ROLES DIRECTLY FROM BATCH FILES!!! // We write to a file, and validate. If the size is iffy, we email Support public void delayDelete(AuthzTrans trans, String text, boolean dryRun) { String dt = Chrono.dateTime(urdd.expires); if(dryRun) { - trans.info().printf(logfmt,text,"Would Delete",urdd.user,urdd.role,urdd.ns,urdd.rname,dt); + trans.info().printf(LOG_FMT,text,"Would Delete",urdd.user,urdd.role,urdd.ns,urdd.rname,dt); } else { - trans.info().printf(logfmt,text,"Staged Deletion",urdd.user,urdd.role,urdd.ns,urdd.rname,dt); + trans.info().printf(LOG_FMT,text,"Staged Deletion",urdd.user,urdd.role,urdd.ns,urdd.rname,dt); } - urDelete.printf(deletefmt,text,urdd.user,urdd.role,dt,urdd.ns,urdd.rname); - urRecover.printf(replayfmt,urdd.user,urdd.role,dt,urdd.ns,urdd.rname); + urDelete.printf(DELETE_FMT,text,urdd.user,urdd.role,dt,urdd.ns,urdd.rname); + urRecover.printf(REPLAY_FMT,urdd.user,urdd.role,dt,urdd.ns,urdd.rname); cache.delayedDelete(this); ++deleted; @@ -278,5 +296,4 @@ public class UserRole implements Cloneable, CacheChange.Data { cache.resetLocalData(); } - }
\ No newline at end of file diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/reports/ExpiringNext.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/reports/ExpiringNext.java index 8e0257fd..67282915 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/reports/ExpiringNext.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/reports/ExpiringNext.java @@ -76,7 +76,7 @@ public class ExpiringNext extends Batch { List<String> expiring = new ArrayList<>(); trans.info().log("Checking for Expired UserRoles"); - for(UserRole ur : UserRole.data) { + for(UserRole ur : UserRole.getData()) { if(ur.expires().after(now)) { if(ur.expires().before(twoWeeks)) { expiring.add(Chrono.dateOnlyStamp(ur.expires()) + ":\t" + ur.user() + '\t' + ur.role()); diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/update/Expiring.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/update/Expiring.java index f3388326..e12a452a 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/update/Expiring.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/update/Expiring.java @@ -305,7 +305,7 @@ public class Expiring extends Batch { // Make sure Owner Role exists String owner = role.ns + ".owner"; if(Role.byName.containsKey(owner)) { - List<UserRole> lur = UserRole.byRole.get(owner); + List<UserRole> lur = UserRole.getByRole().get(owner); if(lur != null) { for(UserRole ur : lur) { if(ur.user().equals(app.getApprover())) { @@ -360,7 +360,7 @@ public class Expiring extends Batch { // Run for User Roles trans.info().log("Checking for Expired User Roles"); try { - for(UserRole ur : UserRole.data) { + for(UserRole ur : UserRole.getData()) { if(org.getIdentity(noAvg, ur.user())==null) { // if not part of Organization; if(isSpecial(ur.user())) { trans.info().log(ur.user(),"is not part of organization, but may not be deleted"); @@ -421,11 +421,11 @@ public class Expiring extends Batch { if(UserRole.sizeForDeletion()>0) { count+=UserRole.sizeForDeletion(); double onePercent = 0.01; - if(((double)UserRole.sizeForDeletion())/UserRole.data.size() > onePercent) { + if(((double)UserRole.sizeForDeletion())/UserRole.getData().size() > onePercent) { Message msg = new Message(); try { msg.line("Found %d of %d UserRoles marked for Deletion in file %s", - delayedURDeletes,UserRole.data.size(),deletesFile.getCanonicalPath()); + delayedURDeletes,UserRole.getData().size(),deletesFile.getCanonicalPath()); } catch (IOException e) { msg.line("Found %d of %d UserRoles marked for Deletion.\n", delayedURDeletes); diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/update/NotifyCredExpiring.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/update/NotifyCredExpiring.java index c9f04f73..fe8f16d9 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/update/NotifyCredExpiring.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/update/NotifyCredExpiring.java @@ -142,7 +142,7 @@ public class NotifyCredExpiring extends Batch { for(Cred c : es.getValue()) { last = c.last(CredDAO.BASIC_AUTH,CredDAO.BASIC_AUTH_SHA256); if(last!=null && last.after(tooLate) && last.before(early)) { - List<UserRole> ownerURList = UserRole.byRole.get(es.getKey()+".owner"); + List<UserRole> ownerURList = UserRole.getByRole().get(es.getKey()+".owner"); if(ownerURList!=null) { for(UserRole ur:ownerURList) { String owner = ur.user(); diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/service/CMService.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/service/CMService.java index dee788e4..376ae1b1 100644 --- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/service/CMService.java +++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/service/CMService.java @@ -74,15 +74,16 @@ public class CMService { public static final String REQUEST = "request"; public static final String RENEW = "renew"; public static final String DROP = "drop"; -// public static final String SANS = "san"; public static final String IPS = "ips"; public static final String DOMAIN = "domain"; + + private static final String CERTMAN = ".certman"; + private static final String ACCESS = ".access"; private static final String[] NO_NOTES = new String[0]; private final CertDAO certDAO; private final CredDAO credDAO; private final ArtiDAO artiDAO; -// private DAO<AuthzTrans, ?>[] daos; private AAF_CM certman; // @SuppressWarnings("unchecked") @@ -94,11 +95,7 @@ public class CMService { certDAO = new CertDAO(trans, hd, cid); credDAO = new CredDAO(trans, hd, cid); artiDAO = new ArtiDAO(trans, hd, cid); - -// daos =(DAO<AuthzTrans, ?>[]) new DAO<?,?>[] { -// hd,cid,certDAO,credDAO,artiDAO -// }; -// + this.certman = certman; } @@ -119,7 +116,7 @@ public class CMService { // Disallow non-AAF CA without special permission - if(!ca.getName().equals("aaf") && !trans.fish( new AAFPermission(mechNS+".certman", ca.getName(), REQUEST))) { + if(!"aaf".equals(ca.getName()) && !trans.fish( new AAFPermission(mechNS+CERTMAN, ca.getName(), REQUEST))) { return Result.err(Status.ERR_Denied, "'%s' does not have permission to request Certificates from Certificate Authority '%s'", trans.user(),ca.getName()); } @@ -135,7 +132,7 @@ public class CMService { InetAddress primary = null; // Organize incoming information to get to appropriate Artifact - if(fqdns.size()>=1) { + if(!fqdns.isEmpty()) { // Accept domain wild cards, but turn into real machines // Need *domain.com:real.machine.domain.com:san.machine.domain.com:... if(fqdns.get(0).startsWith("*")) { // Domain set @@ -146,16 +143,16 @@ public class CMService { //TODO check for Permission in Add Artifact? String domain = fqdns.get(0).substring(1); fqdns.remove(0); - if(fqdns.size()>=1) { - InetAddress ia = InetAddress.getByName(fqdns.get(0)); - if(ia==null) { - return Result.err(Result.ERR_Denied, "Request not made from matching IP matching domain"); - } else if(ia.getHostName().endsWith(domain)) { - primary = ia; - } - } else { - return Result.err(Result.ERR_Denied, "Requests using domain require machine declaration"); - } + if(fqdns.isEmpty()) { + return Result.err(Result.ERR_Denied, "Requests using domain require machine declaration"); + } + + InetAddress ia = InetAddress.getByName(fqdns.get(0)); + if(ia==null) { + return Result.err(Result.ERR_Denied, "Request not made from matching IP matching domain"); + } else if(ia.getHostName().endsWith(domain)) { + primary = ia; + } } else { for(String cn : req.value.fqdns) { @@ -180,7 +177,6 @@ public class CMService { if(primary==null) { return Result.err(Result.ERR_Denied, "Request not made from matching IP (%s)",trans.ip()); -// return Result.err(Result.ERR_BadData,"Calling Machine does not match DNS lookup for %s",req.value.fqdns.get(0)); } ArtiDAO.Data add = null; @@ -247,25 +243,10 @@ public class CMService { } // Policy 7: Caller must be the MechID or have specifically delegated permissions - if(!(trans.user().equals(req.value.mechid) || trans.fish(new AAFPermission(mechNS + ".certman", ca.getName() , "request")))) { + if(!(trans.user().equals(req.value.mechid) || trans.fish(new AAFPermission(mechNS + CERTMAN, ca.getName() , REQUEST)))) { return Result.err(Status.ERR_Denied, "%s must have access to modify x509 certs in NS %s",trans.user(),mechNS); } - // Policy 8: SANs only allowed by Exception... need permission - // 7/25/2017 - SAN Permission no longer required. CSO -// if(fqdns.size()>1 && !certman.aafLurPerm.fish( -// new Principal() { -// @Override -// public String getName() { -// return req.value.mechid; -// } -// }, -// new AAFPermission(ca.getPermType(), ca.getName(), SANS))) { -// if(notes==null) {notes = new ArrayList<>();} -// notes.add("Warning: Subject Alternative Names only allowed by Permission: Get CSO Exception."); -// return Result.err(Status.ERR_Denied, "%s must have a CSO Exception to work with SAN",trans.user()); -// } - // Make sure Primary is the first in fqdns if(fqdns.size()>1) { for(int i=0;i<fqdns.size();++i) { @@ -295,9 +276,6 @@ public class CMService { return Result.err(Result.ERR_ActionNotCompleted,"x509 Certificate not signed by CA"); } trans.info().printf("X509 Subject: %s", x509ac.getX509().getSubjectDN()); -// for(String s: x509ac.getTrustChain()) { -// trans.warn().printf("Trust Cert: \n%s", s); -// } X509Certificate x509 = x509ac.getX509(); CertDAO.Data cdd = new CertDAO.Data(); @@ -349,7 +327,7 @@ public class CMService { String ns = Question.domain2ns(mechID); try { if( trans.user().equals(mechID) - || trans.fish(new AAFPermission(ns + ".access", "*", "read")) + || trans.fish(new AAFPermission(ns + ACCESS, "*", "read")) || (trans.org().validate(trans,Organization.Policy.OWNS_MECHID,null,mechID))==null) { return certDAO.readID(trans, mechID); } else { @@ -496,9 +474,9 @@ public class CMService { } add = data.value.get(0); if( trans.user().equals(add.mechid) - || trans.fish(new AAFPermission(add.ns + ".access", "*", "read")) - || trans.fish(new AAFPermission(add.ns+".certman",add.ca,"read")) - || trans.fish(new AAFPermission(add.ns+".certman",add.ca,"request")) + || trans.fish(new AAFPermission(add.ns + ACCESS, "*", "read")) + || trans.fish(new AAFPermission(add.ns+CERTMAN,add.ca,"read")) + || trans.fish(new AAFPermission(add.ns+CERTMAN,add.ca,"request")) || (trans.org().validate(trans,Organization.Policy.OWNS_MECHID,null,add.mechid))==null) { return data; } else { @@ -516,7 +494,7 @@ public class CMService { String ns = FQI.reverseDomain(mechid); String reason; - if(trans.fish(new AAFPermission(ns + ".access", "*", "read")) + if(trans.fish(new AAFPermission(ns + ACCESS, "*", "read")) || (reason=trans.org().validate(trans,Organization.Policy.OWNS_MECHID,null,mechid))==null) { return artiDAO.readByMechID(trans, mechid); } else { @@ -547,8 +525,7 @@ public class CMService { // TODO do some checks? - Result<List<ArtiDAO.Data>> rv = artiDAO.readByNs(trans, ns); - return rv; + return artiDAO.readByNs(trans, ns); } @@ -646,7 +623,7 @@ public class CMService { String ns = FQI.reverseDomain(add.mechid); - if(trans.fish(new AAFPermission(ns + ".access", "*", "write")) + if(trans.fish(new AAFPermission(ns + ACCESS, "*", "write")) || trans.user().equals(sponsor)) { return artiDAO.delete(trans, add, false); } |