data.memo = row.getString(2);
data.start = row.getTimestamp(3);
data.expires = row.getTimestamp(4);
- data.construct = row.getBytes(5);
- data.target_key = row.getString(6);
- data.target_date = row.getTimestamp(7);
+ data.target_key = row.getString(5);
+ data.target_date = row.getTimestamp(6);
+ data.construct = row.getBytes(7);
return data;
}
obj[++idx] = data.memo;
obj[++idx] = data.start;
obj[++idx] = data.expires;
- obj[++idx] = data.construct;
obj[++idx] = data.target_key;
obj[++idx] = data.target_date;
+ obj[++idx] = data.construct;
}
}
public static final String TABLE = "ns";
public static final String TABLE_ATTRIB = "ns_attrib";
public static final int CACHE_SEG = 0x40; // yields segment 0x0-0x3F
+ public static final int USER = 0;
public static final int ROOT = 1;
public static final int COMPANY=2;
public static final int APP = 3;
}
public String fullType() {
- return ns + '.' + type;
+ StringBuilder sb = new StringBuilder();
+ if(ns==null) {
+ sb.append('.');
+ } else {
+ sb.append(ns);
+ sb.append(ns.indexOf('@')<0?'.':':');
+ }
+ sb.append(type);
+ return sb.toString();
}
public String fullPerm() {
- return ns + '.' + type + '|' + instance + '|' + action;
+ StringBuilder sb = new StringBuilder();
+ if(ns==null) {
+ sb.append("null.");
+ } else {
+ sb.append(ns);
+ sb.append(ns.indexOf('@')<0?'.':':');
+ }
+ sb.append(type);
+ sb.append('|');
+ sb.append(instance);
+ sb.append('|');
+ sb.append(action);
+ return sb.toString();
}
public String encode() {
Data rv = new PermDAO.Data();
if (rdns.isOKhasData()) {
switch(s.length) {
+ case 4:
+ rv.ns=s[0];
+ rv.type=s[1];
+ rv.instance=s[2];
+ rv.action=s[3];
+ break;
case 3:
+ rv.ns=s[0];
rv.type=s[1];
rv.instance=s[2];
rv.action=s[3];
break;
case 2:
+ rv.ns=s[0];
rv.type=s[1];
rv.instance=s[2];
rv.action=STAR;
break;
default:
+ rv.ns=s[0];
rv.type=s[1];
rv.instance = STAR;
rv.action = STAR;
}
public String fullName() {
- return ns + '.' + name;
+ StringBuilder sb = new StringBuilder();
+ if(ns==null) {
+ sb.append('.');
+ } else {
+ sb.append(ns);
+ sb.append(ns.indexOf('@')<0?'.':':');
+ }
+ sb.append(name);
+ return sb.toString();
}
public String encode() {
* @return
*/
public static Result<Data> decode(AuthzTrans trans, Question q, String r) {
- String[] ss = Split.splitTrim('|', r,2);
Data data = new Data();
- if (ss[1]==null) { // older 1 part encoding must be evaluated for NS
- Result<NsSplit> nss = q.deriveNsSplit(trans, ss[0]);
- if (nss.notOK()) {
- return Result.err(nss);
- }
- data.ns=nss.value.ns;
- data.name=nss.value.name;
- } else { // new 4 part encoding
- data.ns=ss[0];
- data.name=ss[1];
- }
+ if(r.indexOf('@')>=0) {
+ int colon = r.indexOf(':');
+ if(colon<0) {
+ return Result.err(Result.ERR_BadData, "%s is not a valid Role",r);
+ } else {
+ data.ns=r.substring(0, colon);
+ data.name=r.substring(++colon);
+ }
+ } else {
+ String[] ss = Split.splitTrim('|', r,2);
+ if (ss[1]==null) { // older 1 part encoding must be evaluated for NS
+ Result<NsSplit> nss = q.deriveNsSplit(trans, ss[0]);
+ if (nss.notOK()) {
+ return Result.err(nss);
+ }
+ data.ns=nss.value.ns;
+ data.name=nss.value.name;
+ } else { // new 4 part encoding
+ data.ns=ss[0];
+ data.name=ss[1];
+ }
+ }
return Result.ok(data);
}
} else if (!fullperm.roles.isEmpty()) {
return Result
.err(Status.ERR_DependencyExists,
- "Permission [%s.%s|%s|%s] cannot be deleted as it is attached to 1 or more roles.",
- fullperm.ns, fullperm.type, fullperm.instance, fullperm.action);
+ "Permission [%s] cannot be deleted as it is attached to 1 or more roles.",
+ fullperm.fullPerm());
}
}
private final CacheInfoDAO cacheInfoDAO;
private final int cldays;
+ private final boolean alwaysSpecial;
public Question(AuthzTrans trans, Cluster cluster, String keyspace) throws APIException, IOException {
PERMS = trans.slot("USER_PERMS");
AbsCassDAO.primePSIs(trans);
cldays = Integer.parseInt(trans.getProperty(Config.AAF_CRED_WARN_DAYS, Config.AAF_CRED_WARN_DAYS_DFT));
+
+ alwaysSpecial = Boolean.parseBoolean(trans.getProperty("aaf_always_special", Boolean.FALSE.toString()));
}
public void startTimers(AuthzEnv env) {
return permDAO.readByType(trans, nss.value.ns, nss.value.name);
}
- public Result<List<PermDAO.Data>> getPermsByName(AuthzTrans trans,
- String type, String instance, String action) {
- Result<NsSplit> nss = deriveNsSplit(trans, type);
- if (nss.notOK()) {
- return Result.err(nss);
- }
- return permDAO.read(trans, nss.value.ns, nss.value.name, instance,action);
+ public Result<List<PermDAO.Data>> getPermsByName(AuthzTrans trans, String type, String instance, String action) {
+ if(type.indexOf('@') >= 0) {
+ int colon = type.indexOf(':');
+ if(colon>=0) {
+ return permDAO.read(trans, type.substring(0, colon),type.substring(colon+1), instance,action);
+ } else {
+ return Result.err(Result.ERR_BadData, "%s is malformed",type);
+ }
+ } else {
+ Result<NsSplit> nss = deriveNsSplit(trans, type);
+ if (nss.notOK()) {
+ return Result.err(nss);
+ }
+
+ return permDAO.read(trans, nss.value.ns, nss.value.name, instance,action);
+ }
}
public Result<List<PermDAO.Data>> getPermsByRole(AuthzTrans trans, String role, boolean lookup) {
return Result.ok(perms);
}
- public Result<List<RoleDAO.Data>> getRolesByName(AuthzTrans trans,
- String role) {
+ public Result<List<RoleDAO.Data>> getRolesByName(AuthzTrans trans, String role) {
+ if(role.startsWith(trans.user()) ) {
+ if(role.endsWith(":user")) {
+ return roleDAO.read(trans,trans.user(), "user");
+ } else {
+ return Result.err(Result.ERR_BadData,"%s is a badly formatted role",role);
+ }
+ }
Result<NsSplit> nss = deriveNsSplit(trans, role);
if (nss.notOK()) {
return Result.err(nss);
if (r.isOKhasData()) {
return Result.ok(r.value.get(0));
} else {
- int dot;
- if (child==null) {
- return Result.err(Status.ERR_NsNotFound, "No Namespace");
- } else {
- dot = child.lastIndexOf('.');
- }
+ int dot = child.lastIndexOf('.');
if (dot < 0) {
return Result.err(Status.ERR_NsNotFound, "No Namespace for [%s]", child);
} else {
}
public Result<NsDAO.Data> mayUser(AuthzTrans trans, String user, RoleDAO.Data rdd, Access access) {
+ if(trans.user().equals(rdd.ns)) {
+ return Result.ok((NsDAO.Data)null);
+ }
Result<NsDAO.Data> rnsd = deriveNs(trans, rdd.ns);
if (rnsd.isOK()) {
return mayUser(trans, user, rnsd.value, rdd, access);
}
public Result<NsDAO.Data> mayUser(AuthzTrans trans, String user,PermDAO.Data pdd, Access access) {
+ if(pdd.ns.indexOf('@')>-1) {
+ if(user.equals(pdd.ns) || isGranted(trans,user,Define.ROOT_NS(),"access",pdd.instance,READ)) {
+ NsDAO.Data ndd = new NsDAO.Data();
+ ndd.name = user;
+ ndd.type = NsDAO.USER;
+ ndd.parent = "";
+ return Result.ok(ndd);
+ } else {
+ return Result.err(Result.ERR_Security,"Only a User may modify User");
+ }
+ }
Result<NsDAO.Data> rnsd = deriveNs(trans, pdd.ns);
if (rnsd.isOK()) {
return mayUser(trans, user, rnsd.value, pdd, access);
byte[] md5=Hash.hashMD5(cred);
if (Hash.compareTo(md5,dbcred)==0) {
checkLessThanDays(trans,cldays,now,cdd);
+ trans.setTag(cdd.tag);
return Result.ok(cdd.expires);
} else if (debug!=null) {
load(debug, cdd);
if (Hash.compareTo(hash,dbcred)==0) {
checkLessThanDays(trans,cldays,now,cdd);
+ trans.setTag(cdd.tag);
return Result.ok(cdd.expires);
} else if (debug!=null) {
load(debug, cdd);
} else {
if (expired==null || expired.before(cdd.expires)) {
expired = cdd.expires;
+ trans.setTag(cdd.tag);
}
}
} // end for each
- if (debug==null) {
- trans.audit().printf("No cred matches ip=%s, user=%s\n",trans.ip(),user);
- } else {
- trans.audit().printf("No cred matches ip=%s, user=%s %s\n",trans.ip(),user,debug.toString());
- }
+
if (expired!=null) {
// Note: this is only returned if there are no good Credentials
rv = Result.err(Status.ERR_Security,
- "Credentials %s from %s expired %s",trans.user(), trans.ip(), Chrono.dateTime(expired));
+ "Credentials expired %s",Chrono.utcStamp(expired));
+ } else {
+ if (debug==null && alwaysSpecial) {
+ debug = new StringBuilder();
+ }
+ if (debug!=null) {
+ debug.append(trans.env().encryptor().encrypt(new String(cred)));
+ rv = Result.err(Status.ERR_Security,String.format("invalid password - %s",debug.toString()));
+ }
}
}
} else {
return Result.err(result);
}
- return rv == null ? Result.create((Date) null, Status.ERR_Security, "Wrong credential") : rv;
+ return rv == null ? Result.err(Status.ERR_Security, "Wrong credential") : rv;
}
private void load(StringBuilder debug, Data cdd) {
- debug.append("DB Entry: user=");
+ debug.append("\nDB Entry: user=");
debug.append(cdd.id);
debug.append(",type=");
debug.append(cdd.type);
debug.append(",expires=");
debug.append(Chrono.dateTime(cdd.expires));
+ debug.append(",tag=");
+ debug.append(cdd.tag);
debug.append('\n');
}
}
try {
- String aaf_url = access.getProperty(Config.AAF_URL, null);
- if(aaf_url==null) {
- aaf_url = "https://"+Config.AAF_LOCATE_URL_TAG+"/%NS."+name;
+ String aaf_url;
+ if(name.indexOf('.')>=0) {
+ aaf_url = "https://"+Config.AAF_LOCATE_URL_TAG+'/'+name+':'+version;
+ } else {
+ aaf_url = "https://"+Config.AAF_LOCATE_URL_TAG+"/%NS."+name+':'+version;
}
RegistrationPropHolder rph = new RegistrationPropHolder(access,0);
aaf_url = rph.replacements(getClass().getSimpleName(),aaf_url, null,null);
@Override
public boolean validate(String user, Type type, byte[] pass, Object state) {
+ if(user==null || type==null || pass==null) {
+ return false;
+ }
+
try {
AuthzTrans trans;
+ boolean transfer = false;
if (state !=null) {
if (state instanceof AuthzTrans) {
trans = (AuthzTrans)state;
} else {
trans = env.newTransNoAvg();
if (state instanceof HttpServletRequest) {
- trans.set((HttpServletRequest)state);
+ trans.set((HttpServletRequest)state,null);
+ transfer=true;
}
}
} else {
trans = env.newTransNoAvg();
}
Result<Date> result = question.doesUserCredMatch(trans, user, pass);
- trans.logAuditTrail(env.info());
+ if(transfer) {
+ ((HttpServletRequest)state).setAttribute("CRED_TAG", trans.getTag());
+ }
+ trans.logAuditTrail(env.debug());
switch(result.status) {
case OK:
return true;
default:
- String ip = trans.ip()==null?"":(", ip="+trans.ip());
- env.warn().log(user, "failed password validation" + ip + ':',result.errorString());
+ String ip = trans.ip()==null?"":trans.ip();
+ env.audit().printf("user=%s,tag=%s,ip=%s,msg=\"failed password validation: %s\"",user,trans.getTag(),ip,result.errorString());
}
} catch (DAOException e) {
env.error().log(e,"Cannot validate user/pass from cassandra");
ldd.add(convert(me));
}
}
-
+
private LocateDAO.Data convert(MgmtEndpoint me) {
LocateDAO.Data out = new LocateDAO.Data();
out.name=me.getName();
// Load special data here
- // WebPhone
- env.setProperty("java.naming.provider.url","ldap://ldap.webphone.att.com:389");
- env.setProperty("com.sun.jndi.ldap.connect.pool","true");
iterations = 0;
}
@Test
- public void testWasMOdified() {
+ public void testWasModified() {
TimeTaken tt = Mockito.mock(TimeTaken.class);
Mockito.doReturn(tt).when(trans).start("RoleDAO CREATE", Env.REMOTE);
Mockito.doReturn(tt).when(trans).start("Clear Reset Deque", Env.SUB);
assertFalse(pp.match(null));
- pond = new AAFPermission("null.test", "name", "instance", "action");
- pp.match(pond);
+ pond = new AAFPermission("test.test", "test", "test", "test");
+ assertTrue(pp.match(pond));
}
}
}
boolean retVal = aafLocatorObj.validate(null, null, null, null);
- assertTrue(retVal);
+ assertFalse(retVal);
}
@Test
try {
Log4JLogIt logIt = new Log4JLogIt(args, "cm");
PropAccess propAccess = new PropAccess(logIt,args);
-
try {
- AAF_CM service = new AAF_CM(new AuthzEnv(propAccess));
- JettyServiceStarter<AuthzEnv,AuthzTrans> jss = new JettyServiceStarter<AuthzEnv,AuthzTrans>(service);
- jss.start();
+ new JettyServiceStarter<AuthzEnv,AuthzTrans>(
+ new AAF_CM(new AuthzEnv(propAccess)),true)
+ .start();
} catch (Exception e) {
propAccess.log(e);
}
public static final String ISSUING_CA = "Issuing CA";
public static final String CM_CA_PREFIX = "cm_ca.";
public static final String CM_CA_BASE_SUBJECT = ".baseSubject";
+ public static final String CM_CA_ENV_TAG = ".env_tag";
protected static final String CM_PUBLIC_DIR = "cm_public_dir";
private static final String CM_TRUST_CAS = "cm_trust_cas";
protected static final String CM_BACKUP_CAS = "cm_backup_cas";
private String[] trustedCAs;
private String[] caIssuerDNs;
private List<RDN> rdns;
+ private final boolean env_tag;
protected CA(Access access, String caName, String env) throws IOException, CertException {
trustedCAs = new String[4]; // starting array
this.name = caName;
this.env = env;
+ this.env_tag = env==null || env.isEmpty()?false:
+ Boolean.parseBoolean(access.getProperty(CM_CA_ENV_TAG, Boolean.FALSE.toString()));
permNS = CM_CA_PREFIX + name;
permType = access.getProperty(permNS + ".perm_type",null);
if (permType==null) {
return trustedCAs;
}
+ public boolean shouldAddEnvTag() {
+ return env_tag;
+ }
+
public String getEnv() {
return env;
}
} else if (primary == null) {
return Result.err(Result.ERR_Denied, "Request not made from matching IP (%s)", trans.ip());
} else {
- host = primary.getHostAddress();
+ String thost = primary.getHostName();
+ host = thost==null?primary.getHostAddress():thost;
}
ArtiDAO.Data add = null;
CSRMeta csrMeta;
try {
csrMeta = BCFactory.createCSRMeta(ca, req.value.mechid, email, fqdns);
+ csrMeta.environment(ca.getEnv());
X509andChain x509ac = ca.sign(trans, csrMeta);
if (x509ac == null) {
return Result.err(Result.ERR_ActionNotCompleted, "x509 Certificate not signed by CA");
public static void setUp() {
AuthzTrans trans = mock(AuthzTrans.class);
req = mock(HttpServletRequest.class);
+ res = mock(HttpServletResponse.class);
trans.setProperty("testTag", "UserValue");
- trans.set(req);
+ trans.set(req,res);
}
@Rule
public static void setUp() {
AuthzTrans trans = mock(AuthzTrans.class);
req = mock(HttpServletRequest.class);
+ res = mock(HttpServletResponse.class);
trans.setProperty("testTag", "UserValue");
- trans.set(req);
+ trans.set(req,res);
}
@Rule
this(access,new AuthzEnv(access.getProperties()),wtr,hman, si,ss);
}
+ public AuthzEnv env() {
+ return env;
+ }
+
public AAFcli(Access access, AuthzEnv env, Writer wtr, HMangr hman, SecurityInfoC<HttpURLConnection> si, SecuritySetter<HttpURLConnection> ss) throws APIException {
this.env = env;
this.access = access;
Thread.sleep((long)(delay+globalDelay));
}
} catch (Exception e) {
- if (expect.contains(-1)) {
+ if (expect.contains(-1)) {
pw.println(e.getMessage());
ret = -1;
} else {
private List<Cmd> cmds;
public Help(AAFcli aafcli, List<Cmd> cmds) {
- super(aafcli, "--help",
+ super(aafcli, "help",
new Param("-d (more details)", false),
new Param("command",false));
this.cmds = cmds;
import org.onap.aaf.misc.env.APIException;
public class Version extends Cmd {
+ private final String version;
-
- public Version(AAFcli aafcli) {
- super(aafcli, "--version");
+ public Version(AAFcli aafcli) {
+ super(aafcli, "version");
+ version = aafcli.access.getProperty(Config.AAF_DEPLOYED_VERSION, Config.AAF_DEFAULT_API_VERSION);
}
@Override
protected int _exec(int idx, String... args) throws CadiException, APIException, LocatorException {
pw().println("AAF Command Line Tool");
pw().print("Version: ");
- pw().println(Config.AAF_DEFAULT_API_VERSION);
+ pw().println(version);
return 200;
}
}
indent+=4;
detailLine(sb,indent,"Report Users associated with this Namespace's Roles");
sb.append('\n');
- detailLine(sb,indent,"If \"set details=true\" is specified, then all roles are printed ");
+ detailLine(sb,indent,"If \"details\" is specified, then all roles are printed ");
detailLine(sb,indent,"with the associated users and expiration dates");
indent-=4;
api(sb,indent,HttpMethods.GET,"authz/nss/<ns>",Nss.class,true);
indent+=4;
detailLine(sb,indent,"Report Users associated with this Namespace's Roles");
sb.append('\n');
- detailLine(sb,indent,"If \"set details=true\" is specified, then all roles are printed ");
+ detailLine(sb,indent,"If \"details\" is specified, then all roles are printed ");
detailLine(sb,indent,"with the associated users and expiration dates");
indent-=4;
api(sb,indent,HttpMethods.GET,"authz/nss/<ns>",Nss.class,true);
pk.setInstance(args[idx++]);
pk.setAction(args[idx++]);
- // Set "Force" if set
- setQueryParamsOn(client);
+ if(pk.getType().contains("@")) { // User Perm deletion... Must remove from hidden role
+ client.setQueryParams("force");
+ } else {
+ // Set "Force" if set
+ setQueryParamsOn(client);
+ }
Future<PermRequest> fp = client.delete(
"/authz/perm",
getDF(PermRequest.class),
}
if (aafcli.isDetailed()) {
if (sb==null) {
- sb = new StringBuilder('?');
+ sb = new StringBuilder("?");
} else {
- sb.append('&');
+ sb.append("&");
}
sb.append("ns");
}
package org.onap.aaf.auth.cmd.user;
+import java.util.List;
+
import org.onap.aaf.auth.cmd.AAFcli;
import org.onap.aaf.auth.cmd.Cmd;
import org.onap.aaf.auth.cmd.Param;
import org.onap.aaf.auth.rserv.HttpMethods;
import org.onap.aaf.cadi.CadiException;
import org.onap.aaf.cadi.LocatorException;
+import org.onap.aaf.cadi.aaf.client.ErrMessage;
import org.onap.aaf.cadi.client.Future;
import org.onap.aaf.cadi.client.Rcli;
import org.onap.aaf.cadi.client.Retryable;
import org.onap.aaf.misc.env.APIException;
import aaf.v2_0.CredRequest;
+import aaf.v2_0.Error;
public class Cred extends Cmd {
public static final String ATTEMPT_FAILED_SPECIFICS_WITHELD = "Attempt Failed. Specifics witheld.";
private static final String CRED_PATH = "/authn/cred";
private static final String[] options = {"add","del","reset","extend"/*,"clean"*/};
- public Cred(User parent) {
+ private ErrMessage em;
+// private RosettaDF<Error> errDF;
+ public Cred(User parent) throws APIException {
super(parent,"cred",
new Param(optionsToString(options),true),
new Param("id",true),
new Param("password (! D|E)",false),
new Param("entry# (if multi)",false)
);
+ em = new ErrMessage(aafcli.env());
}
@Override
if (idx>=args.length) throw new CadiException("Password Required");
cr.setPassword(args[idx++]);
}
- if (args.length>idx)
+ if (args.length>idx) {
cr.setEntry(args[idx]);
+ }
// Set Start/End commands
setStartEnd(cr);
pw().println(']');
} else if (fp.code()==202) {
pw().println("Credential Action Accepted, but requires Approvals before actualizing");
+ } else if (fp.code()==300) {
+ Error err = em.getError(fp);
+ String text = err.getText();
+ List<String> vars = err.getVariables();
+
+ // IMPORTANT! We do this backward, because it is looking for string
+ // %1 or %13. If we replace %1 first, that messes up %13
+ for(int i=vars.size()-1;i>0;--i) {
+ text = text.replace("%"+(i+1), (i<10?" ":"") + i+") " + vars.get(i));
+ }
+
+ text = text.replace("%1",vars.get(0));
+ pw().println(text);
} else if (fp.code()==406 && option==1) {
pw().println("You cannot delete this Credential");
} else {
if (!aafcli.isTest()) {
date = Chrono.dateOnlyStamp(user.getExpires());
}
- String tag=null;
- if(user.getType()<200) {
- tag = user.getTag();
- } else {
- tag = "\n\tfingerprint: " + user.getTag();
- }
+ String tag=user.getTag();
+ Integer type = user.getType();
if(tag==null) {
tag="";
+ } else if(type!=null && type>=200) {
+ tag = "\n\tfingerprint: " + tag;
}
pw().format(format,
count? (Integer.valueOf(++idx) + ") " + user.getId()): user.getId(),
package org.onap.aaf.auth.cmd.user;
-import java.util.Collections;
-import java.util.Comparator;
-
import org.onap.aaf.auth.cmd.AAFcli;
import org.onap.aaf.auth.cmd.Cmd;
import org.onap.aaf.auth.cmd.Param;
import org.onap.aaf.misc.env.APIException;
import aaf.v2_0.Users;
-import aaf.v2_0.Users.User;
/**
* p
getDF(Users.class)
);
if (fp.get(AAFcli.timeout())) {
- if (aafcli.isTest())
- Collections.sort(fp.value.getUser(), new Comparator<User>() {
- @Override
- public int compare(User u1, User u2) {
- return u1.getId().compareTo(u2.getId());
- }
- });
((org.onap.aaf.auth.cmd.user.List)parent).report(fp.value,false, HEADER,role);
if (fp.code()==404)return 200;
} else {
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Level;
import org.onap.aaf.misc.env.Env;
import org.onap.aaf.misc.env.Trans;
}
if (count>0) {
- env.info().log(Level.INFO, "Cache removed",count,"expired Cached Elements out of", total);
+ env.debug().log("Cache removed",count,"expired Cached Elements out of", total);
}
// If High (total) is reached during this period, increase the number of expired services removed for next time.
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import org.onap.aaf.auth.org.Organization;
import org.onap.aaf.cadi.Lur;
REQD_TYPE(int bit) {
this.bit = bit;
}
- };
-
- public abstract AuthzTrans set(HttpServletRequest req);
+ }
+
+ public abstract AuthzTrans set(HttpServletRequest req, HttpServletResponse resp);
public abstract HttpServletRequest hreq();
+
+ public abstract HttpServletResponse hresp();
public abstract String user();
public abstract void logAuditTrail(LogTarget lt);
public abstract Date now();
+
+ public abstract void setTag(String tag);
+
+ public abstract String getTag();
+
+ public abstract void clearCache();
+
}
\ No newline at end of file
import java.security.Principal;
-import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import org.onap.aaf.auth.rserv.TransFilter;
import org.onap.aaf.cadi.CadiException;
}
@Override
- protected AuthzTrans newTrans(HttpServletRequest req) {
+ protected AuthzTrans newTrans(HttpServletRequest req, HttpServletResponse resp) {
AuthzTrans at = env.newTrans();
at.setLur(getLur());
- at.set(req);
+ at.set(req,resp);
return at;
}
@Override
- protected TimeTaken start(AuthzTrans trans, ServletRequest request) {
- trans.set((HttpServletRequest)request);
+ protected TimeTaken start(AuthzTrans trans) {
return trans.start("Trans " + //(context==null?"n/a":context.toString()) +
" IP: " + trans.ip() +
" Port: " + trans.port()
}
@Override
- protected void tallyHo(AuthzTrans trans) {
+ protected void tallyHo(AuthzTrans trans, String target) {
Boolean b = trans.get(specialLogSlot, false);
- LogTarget lt = b?trans.warn():trans.info();
+ LogTarget lt = b?trans.warn():trans.debug();
if (lt.isLoggable()) {
// Transaction is done, now post full Audit Trail
sb.append("user=");
Principal p = trans.getUserPrincipal();
if (p==null) {
- sb.append("n/a");
+ lt=trans.warn();
+ sb.append(target);
+ sb.append("[None]");
} else {
+ lt=trans.info();
sb.append(p.getName());
if (p instanceof TrustPrincipal) {
sb.append('(');
sb.append(']');
}
}
+ String tag = trans.getTag();
+ if(tag!=null) {
+ sb.append(",tag=");
+ sb.append(tag);
+ }
sb.append(",ip=");
sb.append(trans.ip());
sb.append(",port=");
sb.append('"');
}
- trans.warn().log(sb);
+ lt.log(sb);
}
}
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import org.onap.aaf.auth.org.Organization;
import org.onap.aaf.auth.org.OrganizationFactory;
private static final String N_A = "n/a";
private static final String BLANK = "";
private HttpServletRequest hreq;
+ private HttpServletResponse hresp;
private TaggedPrincipal user;
private Lur lur;
private Organization org;
private int mask;
private Date now;
+ private String tag;
public AuthzTransImpl(AuthzEnv env) {
super(env);
org=null;
mask=0;
+ tag=null;
}
/**
* @see org.onap.aaf.auth.env.test.AuthTrans#set(javax.servlet.http.HttpServletRequest)
*/
@Override
- public AuthzTrans set(HttpServletRequest req) {
+ public AuthzTrans set(HttpServletRequest req, HttpServletResponse resp) {
hreq = req;
+ hresp = resp;
user = (TaggedPrincipal)req.getUserPrincipal();
for (REQD_TYPE rt : REQD_TYPE.values()) {
org=null;
return this;
}
+
@Override
public HttpServletRequest hreq() {
return hreq;
}
-
+
+ @Override
+ public HttpServletResponse hresp() {
+ return hresp;
+ }
+
@Override
public void setUser(TaggedPrincipal p) {
user = p;
}
return false;
}
-
+
/* (non-Javadoc)
* @see org.onap.aaf.auth.env.test.AuthzTrans#org()
*/
}
return now;
}
+
+ /*
+ * (non-Javadoc)
+ * @see org.onap.aaf.auth.env.AuthzTrans#setTag(java.lang.String)
+ */
+ @Override
+ public void setTag(String tag) {
+ this.tag = tag;
+ }
+
+ @Override
+ public String getTag() {
+ return tag;
+ }
+
+ @Override
+ public void clearCache() {
+ if (lur!=null) {
+ StringBuilder report = new StringBuilder();
+ lur.clear(user, report);
+ info().log(report);
+ }
+ }
}
package org.onap.aaf.auth.env;
-import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import org.onap.aaf.auth.rserv.TransOnlyFilter;
import org.onap.aaf.cadi.principal.TaggedPrincipal;
}
@Override
- protected AuthzTrans newTrans() {
- return env.newTrans();
+ protected AuthzTrans newTrans(HttpServletRequest req, HttpServletResponse resp) {
+ AuthzTrans trans = env.newTrans();
+ trans.set(req, resp);
+ return trans;
}
@Override
- protected TimeTaken start(AuthzTrans trans, ServletRequest request) {
- trans.set((HttpServletRequest)request);
+ protected TimeTaken start(AuthzTrans trans) {
return trans.start("Trans " + //(context==null?"n/a":context.toString()) +
" IP: " + trans.ip() +
" Port: " + trans.port()
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import org.onap.aaf.auth.org.Organization;
import org.onap.aaf.cadi.Lur;
return null;
}
@Override
- public AuthzTrans set(HttpServletRequest req) {
+ public AuthzTrans set(HttpServletRequest req, HttpServletResponse resp) {
return null;
}
public HttpServletRequest hreq() {
return null;
}
+
+ @Override
+ public HttpServletResponse hresp() {
+ return null;
+ }
+
@Override
public String user() {
return null;
}
return now;
}
+ @Override
+ public void setTag(String tag) {
+ }
+ @Override
+ public String getTag() {
+ return null;
+ }
+ @Override
+ public void clearCache() {
+ }
}
String realm = env.getProperty(Config.AAF_DEFAULT_REALM,"people.osaaf.org");
defaultOrg = cnst.newInstance(env,realm);
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException e) {
- env.warn().log("Default Organization Module not linked in",e);
+ env.init().log("Default Organization Module not linked in",e);
}
}
if (defaultOrg == null) {
typeMap.put("props", "text/plain");
typeMap.put("jks", "application/octet-stream");
+ // Fonts
+ typeMap.put("ttf","font/ttf");
+ typeMap.put("woff","font/woff");
+ typeMap.put("woff2","font/woff2");
+
+
timer = new Timer("Caching Cleanup",true);
timer.schedule(new Cleanup(content,500),60000,60000);
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.onap.aaf.auth.env.AuthzTrans;
import org.onap.aaf.cadi.Access;
import org.onap.aaf.cadi.CadiException;
import org.onap.aaf.cadi.CadiWrap;
return cadi.getLur();
}
- protected abstract TRANS newTrans(HttpServletRequest request);
- protected abstract TimeTaken start(TRANS trans, ServletRequest request);
+ protected abstract TRANS newTrans(HttpServletRequest request,HttpServletResponse response);
+ protected abstract TimeTaken start(TRANS trans);
protected abstract void authenticated(TRANS trans, Principal p);
- protected abstract void tallyHo(TRANS trans);
+ protected abstract void tallyHo(TRANS trans, String target);
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;
- TRANS trans = newTrans(req);
+ TRANS trans = newTrans(req,res);
- TimeTaken overall = start(trans,request);
+ TimeTaken overall = start(trans);
+ String target = "n/a";
try {
request.setAttribute(TRANS_TAG, trans);
CadiWrap cw = null;
try {
resp = cadi.validate(req,res,trans);
+ Object tag = req.getAttribute("CRED_TAG");
+ if(tag!=null) {
+ ((AuthzTrans)trans).setTag(tag.toString());
+ }
switch(r=resp.isAuthenticated()) {
case IS_AUTHENTICATED:
cw = new CadiWrap(req,resp,cadi.getLur());
// use
trans.checkpoint(resp.desc(),Env.ALWAYS);
if (resp.isFailedAttempt()) {
- trans.audit().log(resp.desc());
+ target = resp.getTarget();
}
}
} catch (Exception e) {
throw new ServletException(e);
} finally {
overall.done();
- tallyHo(trans);
+ tallyHo(trans,target);
}
}
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import org.onap.aaf.cadi.principal.TaggedPrincipal;
import org.onap.aaf.misc.env.TimeTaken;
- protected abstract TRANS newTrans();
- protected abstract TimeTaken start(TRANS trans, ServletRequest request);
+ protected abstract TRANS newTrans(HttpServletRequest req, HttpServletResponse resp);
+ protected abstract TimeTaken start(TRANS trans);
protected abstract void authenticated(TRANS trans, TaggedPrincipal p);
protected abstract void tallyHo(TRANS trans);
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
- TRANS trans = newTrans();
-
- TimeTaken overall = start(trans,request);
+ TRANS trans = newTrans((HttpServletRequest)request,(HttpServletResponse)response);
+ TimeTaken overall = start(trans);
try {
request.setAttribute(TransFilter.TRANS_TAG, trans);
chain.doFilter(request, response);
str = Defaults.AAF_VERSION;
env.setProperty(Config.AAF_LOCATOR_VERSION, str);
}
- app_version = str;
+ app_version = access.getProperty(Config.AAF_DEPLOYED_VERSION, str);
// Print Cipher Suites Available
if (access.willLog(Level.DEBUG)) {
private boolean do_register;
protected AbsService<ENV,TRANS> service;
protected String hostname;
+ protected final boolean secure;
- public AbsServiceStarter(final AbsService<ENV,TRANS> service) {
+ public AbsServiceStarter(final AbsService<ENV,TRANS> service, boolean secure) {
+ this.secure = secure;
this.service = service;
try {
OrganizationFactory.init(service.env);
// do_register - this is used for specialty Debug Situations. Developer can create an Instance for a remote system
// for Debugging purposes without fear that real clients will start to call your debug instance
do_register = !"TRUE".equalsIgnoreCase(access().getProperty("aaf_locate_no_register",null));
- _propertyAdjustment();
hostname = access().getProperty(Config.HOSTNAME, null);
if (hostname==null) {
try {
hostname= "cannotBeDetermined";
}
}
+ _propertyAdjustment();
}
});
if(System.getProperty("ECLIPSE", null)!=null) {
Thread.sleep(2000);
- System.out.println("Service Started in Eclipse: ");
- System.out.print(" Hit <enter> to end:");
- try {
- System.in.read();
- System.exit(0);
- } catch (IOException e) {
+ if(!app.isCancelled()) {
+ System.out.println("Service Started in Eclipse: ");
+ System.out.print(" Hit <enter> to end:\n");
+ try {
+ System.in.read();
+ System.exit(0);
+ } catch (IOException e) {
+ }
}
}
}
_start(service);
} catch (Exception e) {
e.printStackTrace();
+ shutdown();
}
}
public class JettyServiceStarter<ENV extends RosettaEnv, TRANS extends Trans> extends AbsServiceStarter<ENV,TRANS> {
- private boolean secure;
- public JettyServiceStarter(final AbsService<ENV,TRANS> service) throws OrganizationException {
- super(service);
- secure = true;
+ public JettyServiceStarter(final AbsService<ENV,TRANS> service, boolean secure) throws OrganizationException {
+ super(service, secure);
}
- /**
- * Specifically set this Service starter to Insecure (HTTP) Mode.
- * @return
- */
- public JettyServiceStarter<ENV,TRANS> insecure() {
- secure = false;
- return this;
- }
-
-
@Override
public void _propertyAdjustment() {
// System.setProperty("com.sun.management.jmxremote.port", "8081");
return this;
}
+ public final Validator permTypeWithUser(String user, String type) {
+ if (type==null) {
+ msg("Perm Type is null");
+ } else if (user==null) {
+ msg("User is null");
+ } else {
+ if(!(type.startsWith(user) && type.endsWith(":id"))) {
+ if(nob(type,NAME_CHARS)) {
+ msg("Perm Type [" + type + "] is invalid.");
+ }
+ }
+ }
+ return this;
+ }
+
public final Validator permType(String type, String ns) {
if (type==null) {
msg("Perm Type is null");
return this;
}
+ public final Validator role(String user, String role) {
+ boolean quit = false;
+ if(role==null) {
+ msg("Role is null");
+ quit = true;
+ }
+ if(user==null) {
+ msg("User is null");
+ quit = true;
+ }
+ if(!quit) {
+ if(role.startsWith(user) && role.endsWith(":user")) {
+ if(!(role.length() == user.length() + 5)) {
+ msg("Role [" + role + "] is invalid.");
+ }
+ } else if (nob(role, NAME_CHARS)) {
+ msg("Role [" + role + "] is invalid.");
+ }
+ }
+ return this;
+ }
+
+
public final Validator role(String role) {
if (nob(role, NAME_CHARS)) {
msg("Role [" + role + "] is invalid.");
public void setUp(){
authzTransImpl = new AuthzTransImpl(authzEnvMock);
req = mock(HttpServletRequest.class);
- authzTransImpl.set(req);
+ res = mock(HttpServletResponse.class);
+ authzTransImpl.set(req,res);
when(req.getParameter("request")).thenReturn("NotNull");
- authzTransImpl.set(req);
+ authzTransImpl.set(req,res);
when(req.getParameter("request")).thenReturn("");
- authzTransImpl.set(req);
+ authzTransImpl.set(req,res);
}
@Test
public void testStart() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
AuthzTransOnlyFilter aTF = new AuthzTransOnlyFilter(authzEnvMock);
Class c = aTF.getClass();
- Class[] cArg = new Class[2];
- cArg[0] = AuthzTrans.class;
- cArg[1] = ServletRequest.class; //Steps to test a protected method
- Method startMethod = c.getDeclaredMethod("start", cArg);
+ Method startMethod = c.getDeclaredMethod("start", new Class[] {AuthzTrans.class});
startMethod.setAccessible(true);
//startMethod.invoke(aTF, authzTransMock, servletRequestMock);
}
import java.security.Principal;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import org.junit.Assert;
import org.junit.Before;
@Test
public void testSet() {
HttpServletRequest req = mock(HttpServletRequest.class);
- AuthzTrans set = nullTrans.set(req);
+ HttpServletResponse res = mock(HttpServletResponse.class);
+ AuthzTrans set = nullTrans.set(req,res);
Assert.assertNull(set);
}
private class AbsServiceStarterStub extends AbsServiceStarter {
- public AbsServiceStarterStub(AbsService service) {
- super(service);
+ public AbsServiceStarterStub(AbsService service, boolean secure) {
+ super(service,secure);
// TODO Auto-generated constructor stub
}
prop.setLogLevel(Level.DEBUG);
absServiceStub = new AbsServiceStub(prop, bEnv);
- absServiceStarterStub = new AbsServiceStarterStub(absServiceStub);
+ absServiceStarterStub = new AbsServiceStarterStub(absServiceStub,true);
}
// @Test
try {
Log4JLogIt logIt = new Log4JLogIt(args, "fs");
PropAccess propAccess = new PropAccess(logIt,args);
-
- AAF_FS service = new AAF_FS(new AuthzEnv(propAccess));
- JettyServiceStarter<AuthzEnv,AuthzTrans> jss = new JettyServiceStarter<AuthzEnv,AuthzTrans>(service);
- jss.insecure().start();
+ try {
+ new JettyServiceStarter<AuthzEnv,AuthzTrans>(
+ new AAF_FS(new AuthzEnv(propAccess)),false)
+ .start();
+ } catch (Exception e) {
+ propAccess.log(e);
+ }
} catch (Exception e) {
e.printStackTrace();
}
package org.onap.aaf.auth.cui;
import java.io.PrintWriter;
+import java.util.regex.Pattern;
import javax.servlet.ServletInputStream;
+import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.onap.aaf.auth.cmd.AAFcli;
import org.onap.aaf.auth.env.AuthzTrans;
-import org.onap.aaf.auth.env.AuthzEnv;
import org.onap.aaf.auth.gui.AAF_GUI;
+import org.onap.aaf.auth.gui.Page;
import org.onap.aaf.auth.rserv.HttpCode;
import org.onap.aaf.cadi.aaf.v2_0.AAFConHttp;
import org.onap.aaf.cadi.http.HTransferSS;
public class CUI extends HttpCode<AuthzTrans, Void> {
private final AAF_GUI gui;
+ private final static Pattern userPerm = Pattern.compile("perm (create|delete).*@.*:id.*aaf.gui.*");
public CUI(AAF_GUI gui) {
}
try {
aafcli.eval(cmdStr);
+ if(userPerm.matcher(cmdStr).matches()) {
+ trans.clearCache();
+ Cookie cookie = new Cookie(Page.AAF_THEME,trans.getProperty(Page.AAF_THEME));
+ cookie.setMaxAge(-1);
+ cookie.setComment("Remove AAF GUI Theme");
+ trans.hresp().addCookie(cookie);
+ }
pw.flush();
} catch (Exception e) {
pw.flush();
import static org.onap.aaf.auth.rserv.HttpMethods.PUT;
import javax.servlet.Filter;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import org.onap.aaf.auth.cmd.Cmd;
import org.onap.aaf.auth.cui.CUI;
import org.onap.aaf.auth.gui.pages.CMArtiChangeForm;
import org.onap.aaf.auth.gui.pages.CMArtifactShow;
import org.onap.aaf.auth.gui.pages.CredDetail;
+import org.onap.aaf.auth.gui.pages.CredHistory;
import org.onap.aaf.auth.gui.pages.Home;
import org.onap.aaf.auth.gui.pages.LoginLanding;
import org.onap.aaf.auth.gui.pages.LoginLandingAction;
import org.onap.aaf.auth.gui.pages.UserRoleRemove;
import org.onap.aaf.auth.gui.pages.WebCommand;
import org.onap.aaf.auth.rserv.CachingFileAccess;
+import org.onap.aaf.auth.rserv.HttpCode;
import org.onap.aaf.auth.server.AbsService;
import org.onap.aaf.auth.server.JettyServiceStarter;
import org.onap.aaf.auth.server.Log4JLogIt;
protected final String deployedVersion;
private StaticSlot sThemeWebPath;
private StaticSlot sDefaultTheme;
-// public final String theme;
public AAF_GUI(final AuthzEnv env) throws Exception {
super(env.access(), env);
sDefaultTheme = env.staticSlot(AAF_GUI_THEME);
- env.put(sDefaultTheme, env.getProperty(AAF_GUI_THEME,"onap"));
+ String defTheme = env.getProperty(AAF_GUI_THEME,"onap");
+ env.put(sDefaultTheme, defTheme);
sThemeWebPath = env.staticSlot(CachingFileAccess.CFA_WEB_PATH);
if(env.get(sThemeWebPath)==null) {
env.put(sThemeWebPath,"theme");
}
-
+
slot_httpServletRequest = env.slot(HTTP_SERVLET_REQUEST);
- deployedVersion = access.getProperty(Config.AAF_RELEASE, "N/A:2.x");
+ deployedVersion = app_version;
// Certificate Manager
String aaf_url_cm = env.getProperty(Config.AAF_URL_CM,Config.AAF_URL_CM_DEF);
// MyNameSpace
final Page myNamespaces = new Display(this, GET, new NssShow(this, start)).page();
Page nsDetail = new Display(this, GET, new NsDetail(this, start, myNamespaces)).page();
- new Display(this, GET, new NsHistory(this, start,myNamespaces,nsDetail));
+ new Display(this, GET, new NsHistory(this, start,myNamespaces,nsDetail));
Page crdDetail = new Display(this, GET, new CredDetail(this, start, myNamespaces, nsDetail)).page();
+ new Display(this, GET, new CredHistory(this,start,myNamespaces,nsDetail,crdDetail));
Page artiShow = new Display(this, GET, new CMArtifactShow(this, start, myNamespaces, nsDetail, crdDetail)).page();
Page artiCForm = new Display(this, GET, new CMArtiChangeForm(this, start, myNamespaces, nsDetail, crdDetail,artiShow)).page();
new Display(this, POST, new CMArtiChangeAction(this, start,artiShow,artiCForm));
// Command line Mechanism
route(env, PUT, "/gui/cui", new CUI(this),"text/plain;charset=utf-8","*/*");
+ route(env, GET, "/gui/clear", new HttpCode<AuthzTrans, Void>(null, "Clear"){
+ @Override
+ public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {
+ trans.clearCache();
+ Cookie cookies[] = req.getCookies();
+ if(cookies!=null) {
+ for(Cookie c : cookies) {
+ if(c.getName().startsWith("aaf.gui.")) {
+ c.setMaxAge(0);
+ resp.addCookie(c);
+ }
+ }
+ }
+ resp.sendRedirect("/gui/home");
+ }
+ }, "text/plain;charset=utf-8","*/*");
+
///////////////////////
// WebContent Handler
///////////////////////
Log4JLogIt logIt = new Log4JLogIt(args, "gui");
PropAccess propAccess = new PropAccess(logIt,args);
- AAF_GUI service = new AAF_GUI(new AuthzEnv(propAccess));
- JettyServiceStarter<AuthzEnv,AuthzTrans> jss = new JettyServiceStarter<AuthzEnv,AuthzTrans>(service);
- jss.start();
+ try {
+ new JettyServiceStarter<AuthzEnv,AuthzTrans>(
+ new AAF_GUI(new AuthzEnv(propAccess)),true)
+ .start();
+ } catch (Exception e) {
+ propAccess.log(e);
+ }
} catch (Exception e) {
e.printStackTrace();
}
import org.onap.aaf.auth.gui.pages.Home;
import org.onap.aaf.cadi.Permission;
import org.onap.aaf.cadi.aaf.AAFPermission;
-import org.onap.aaf.cadi.client.Holder;
import org.onap.aaf.cadi.config.Config;
import org.onap.aaf.cadi.principal.TaggedPrincipal;
import org.onap.aaf.misc.env.APIException;
*
*/
public class Page extends HTMLCacheGen {
+ public static final String AAF_THEME = "aaf_theme";
public static final String AAFURL_TOOLS = "aaf_url.tools";
public static final String AAF_URL_TOOL_DOT = "aaf_url.tool.";
public static final String AAF_URL_CUIGUI = "aaf_url.cuigui"; // link to help
// Note: Only access is synchronized in "getPerm"
private final static Map<String,Map<String,Permission>> perms = new HashMap<>();
+
+ /*
+ * Relative path, Menu Name, Full Path
+ */
+ protected static final String[][] MENU_ITEMS = new String[][] {
+ {"myperms","My Permissions","/gui/myperms"},
+ {"myroles","My Roles","/gui/myroles"},
+ {"ns","My Namespaces","/gui/ns"},
+ {"approve","My Approvals","/gui/approve"},
+ {"myrequests","My Pending Requests","/gui/myrequests"},
+ // Enable later
+ // {"onboard","Onboarding"},
+ {"passwd","Password Management","/gui/passwd"},
+ {"cui","Command Prompt","/gui/cui"},
+ {"api","AAF API","/gui/api"},
+ {"clear","Clear Preferences","/gui/clear"}
+ };
public String name() {
return bcName;
private static class PageCode implements Code<HTMLGen> {
- private static final String AAF_GUI_TITLE = "aaf_gui_title";
+ private static final String AAF_GUI_THEME = "aaf.gui.theme";
+ private static final String AAF_GUI_TITLE = "aaf_gui_title";
private final ContentCode[] content;
private final Slot browserSlot;
browserSlot = env.slot(BROWSER_TYPE);
sTheme = env.staticSlot(AAF_GUI.AAF_GUI_THEME);
this.env = env;
+ getThemeFiles(env,""); //
}
private static synchronized List<String> getThemeFiles(Env env, String theme) {
themeProps = new TreeMap<>();
props = null;
} else {
- props = themeProps.get(theme);
+ props = themeProps.get(t.getName());
}
if(props==null) {
props = new Properties();
- themeProps.put(theme, props);
+ themeProps.put(t.getName(), props);
}
try {
return themes.get(theme);
}
- protected Imports getImports(Env env, Holder<String> theme, String defaultTheme, int backdots, BROWSER browser) {
- List<String> ls = getThemeFiles(env,theme.get());
+ protected Imports getImports(Env env, String theme, int backdots, BROWSER browser) {
+ List<String> ls = getThemeFiles(env,theme);
Imports imp = new Imports(backdots);
- if(ls==null) {
- theme.set(defaultTheme);
- }
- String prefix = "theme/" + theme.get() + '/';
+ String prefix = "theme/" + theme + '/';
for(String f : ls) {
if(f.endsWith(".js")) {
imp.js(prefix + f);
hgen.html();
final String title = env.getProperty(AAF_GUI_TITLE,"Authentication/Authorization Framework");
final String defaultTheme = env.get(sTheme,"onap");
- final Holder<String> hTheme = new Holder<>(defaultTheme);
Mark head = hgen.head();
hgen.leaf(TITLE).text(title).end();
@Override
public void code(AAF_GUI state, AuthzTrans trans, final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
BROWSER browser = browser(trans,browserSlot);
+ String theme = null;
Cookie[] cookies = trans.hreq().getCookies();
if(cookies!=null) {
for(Cookie c : cookies) {
- if("aaf_theme".equals(c.getName())) {
- hTheme.set(c.getValue());
+ if(AAF_GUI_THEME.equals(c.getName())) {
+ theme=c.getValue();
+ if(!(themes.containsKey(theme))) {
+ theme = defaultTheme;
+ }
+ break;
}
}
}
- hgen.imports(getImports(env,hTheme,defaultTheme,backdots,browser));
+
+ if(theme==null) {
+ for(String t : themes.keySet()) {
+ if(!t.equals(defaultTheme) && trans.fish(new AAFPermission(null,trans.user()+":id", AAF_GUI_THEME, t))) {
+ theme=t;
+ break;
+ }
+ }
+ if(theme==null) {
+ theme = defaultTheme;
+ }
+ Cookie cookie = new Cookie(AAF_GUI_THEME,theme);
+ cookie.setMaxAge(604_800); // one week
+ trans.hresp().addCookie(cookie);
+ }
+ trans.setProperty(Page.AAF_THEME, theme);
+
+ hgen.imports(getImports(env,theme,backdots,browser));
switch(browser) {
case ie:
case ieOld:
}
hgen.end(header);
-
+
+ hgen.divID("pageContent");
Mark inner = hgen.divID("inner");
// Content
for (int i=cIdx;i<content.length;++i) {
}
hgen.end(inner);
+
+ cache.dynamic(hgen, new DynamicCode<HTMLGen,AAF_GUI,AuthzTrans>() {
+ @Override
+ public void code(AAF_GUI state, AuthzTrans trans,Cache<HTMLGen> cache, HTMLGen xgen) throws APIException, IOException {
+ String theme = trans.getProperty(Page.AAF_THEME);
+ Properties props;
+ if(theme==null) {
+ props = null;
+ } else {
+ props = themeProps==null?null:themeProps.get(theme);
+ }
+
+ if(props!=null && "TRUE".equalsIgnoreCase(props.getProperty("enable_nav_btn"))) {
+ xgen.leaf("button", "id=navBtn").end();
+ }
+ }
+ });
+ // Adding "nav Hamburger button"
// Navigation - Using older Nav to work with decrepit IE versions
-
Mark nav = hgen.divID("nav");
cache.dynamic(hgen, new DynamicCode<HTMLGen,AAF_GUI,AuthzTrans>() {
@Override
public void code(AAF_GUI state, AuthzTrans trans,Cache<HTMLGen> cache, HTMLGen xgen) throws APIException, IOException {
- Properties props = themeProps==null?null:themeProps.get(hTheme.get());
- if(props!=null && "TRUE".equalsIgnoreCase(props.getProperty("main_menu_in_nav"))) {
- xgen.incr("h2").text("Navigation").end();
- Mark mark = new Mark();
- boolean selected = isSelected(trans.path(),Home.HREF);
- //trans.path().endsWith("home");
- xgen.incr(mark,HTMLGen.UL)
- .incr(HTMLGen.LI,selected?"class=selected":"")
- .incr(HTMLGen.A, "href=home")
- .text("Home")
- .end(2);
- boolean noSelection = !selected;
- for(String[] mi : Home.MENU_ITEMS) {
- //selected = trans.path().endsWith(mi[0]);
- if(noSelection) {
- selected = isSelected(trans.path(),mi[2]);
- noSelection = !selected;
- } else {
- selected = false;
- }
- xgen.incr(HTMLGen.LI,selected?"class=selected":"")
- .incr(HTMLGen.A, "href="+mi[0])
- .text(mi[1])
- .end(2);
- }
- xgen.end(mark);
+ String theme = trans.getProperty(Page.AAF_THEME);
+ Properties props;
+ if(theme==null) {
+ props = null;
+ } else {
+ props = themeProps==null?null:themeProps.get(theme);
+ }
+
+ if(props!=null) {
+ if("TRUE".equalsIgnoreCase(props.getProperty("main_menu_in_nav"))) {
+ xgen.incr("h2").text("Navigation").end();
+ Mark mark = new Mark();
+ boolean selected = isSelected(trans.path(),Home.HREF);
+ //trans.path().endsWith("home");
+ xgen.incr(mark,HTMLGen.UL)
+ .incr(HTMLGen.LI,selected?"class=selected":"")
+ .incr(HTMLGen.A, "href=home")
+ .text("Home")
+ .end(2);
+ boolean noSelection = !selected;
+ for(String[] mi : MENU_ITEMS) {
+ //selected = trans.path().endsWith(mi[0]);
+ if(noSelection) {
+ selected = isSelected(trans.path(),mi[2]);
+ noSelection = !selected;
+ } else {
+ selected = false;
+ }
+ xgen.incr(HTMLGen.LI,selected?"class=selected":"")
+ .incr(HTMLGen.A, "href="+mi[2])
+ .text(mi[1])
+ .end(2);
+ }
+ xgen.end(mark);
+ }
}
}
import org.onap.aaf.cadi.client.Future;
import org.onap.aaf.cadi.client.Rcli;
import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.cadi.config.Config;
import org.onap.aaf.misc.env.APIException;
import org.onap.aaf.misc.env.Env;
import org.onap.aaf.misc.env.TimeTaken;
public Preamble(AAF_GUI gui) {
super(false, "preamble");
- fsUrl = gui.access.getProperty("fs_url", "");
+ fsUrl = gui.access.getProperty(Config.AAF_URL_FS, "/theme");
}
@Override
arti.getSans().add(s);
}
}
- // Disallow IP entries, except by special Permission
- if (!trans.fish(getPerm(ca,"ip"))) {
- boolean ok=true;
- if (IPValidator.ip(machine)) {
- ok=false;
- }
- if (ok) {
- for (String s: arti.getSans()) {
- if (IPValidator.ip(s)) {
- ok=false;
- break;
- }
- }
- }
- if (!ok) {
- hgen.p("Policy Failure: IPs in certificates are only allowed by Exception.");
- return;
- }
- }
- // Disallow Domain based Definitions without exception
- if (machine.startsWith("*")) { // Domain set
- if (!trans.fish(getPerm(ca, "domain"))) {
- hgen.p("Policy Failure: Domain Artifact Declarations are only allowed by Exception.");
- return;
- }
+ // These checks to not apply to deletions
+ if(!CMArtiChangeForm.DELETE.equals(trans.get(sCmd, ""))) {
+ // Disallow IP entries, except by special Permission
+ if (!trans.fish(getPerm(ca,"ip"))) {
+ boolean ok=true;
+ if (IPValidator.ip(machine)) {
+ ok=false;
+ }
+ if (ok) {
+ for (String s: arti.getSans()) {
+ if (IPValidator.ip(s)) {
+ ok=false;
+ break;
+ }
+ }
+ }
+ if (!ok) {
+ hgen.p("Policy Failure: IPs in certificates are only allowed by Exception.");
+ return;
+ }
+ }
+
+ // Disallow Domain based Definitions without exception
+ if (machine.startsWith("*")) { // Domain set
+ if (!trans.fish(getPerm(ca, "domain"))) {
+ hgen.p("Policy Failure: Domain Artifact Declarations are only allowed by Exception.");
+ return;
+ }
+ }
}
arti.setMechid((String)trans.get(sID,null));
StringWriter buttons = new StringWriter();
HTMLGen hgen = cd.clone(buttons);
hgen.leaf("button","onclick=divVisibility('"+key+"');","class=button").text("Expand").end();
+ hgen.leaf(HTMLGen.A,"class=button","class=greenbutton","href="+CredHistory.HREF+"?user="+ulm.getKey()).text("History").end();
StringWriter creds = new StringWriter();
hgen = cd.clone(creds);
Chrono.niceDateStamp(oldest),
Chrono.niceDateStamp(newest)))
.end(uRow);
-
+
}
+
}
hgen.end(utable);
}
new TextCell(creds.toString(),STYLE_WIDTH_70)
});
}
+
for (String missing : lns) {
StringWriter buttons = new StringWriter();
HTMLGen hgen = cd.clone(buttons);
--- /dev/null
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.gui.pages;
+
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Comparator;
+import java.util.List;
+
+import org.onap.aaf.auth.env.AuthzEnv;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.gui.AAF_GUI;
+import org.onap.aaf.auth.gui.BreadCrumbs;
+import org.onap.aaf.auth.gui.NamedCode;
+import org.onap.aaf.auth.gui.Page;
+import org.onap.aaf.auth.gui.Table;
+import org.onap.aaf.auth.gui.Table.Cells;
+import org.onap.aaf.auth.gui.table.AbsCell;
+import org.onap.aaf.auth.gui.table.TableData;
+import org.onap.aaf.auth.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.Slot;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.xgen.Cache;
+import org.onap.aaf.misc.xgen.DynamicCode;
+import org.onap.aaf.misc.xgen.html.HTMLGen;
+
+import aaf.v2_0.History;
+import aaf.v2_0.History.Item;
+
+
+public class CredHistory extends Page {
+ static final String NAME="CredHistory";
+ static final String HREF = "/gui/credHistory";
+ static final String FIELDS[] = {"user","dates"};
+
+
+ public CredHistory(final AAF_GUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+ super(gui.env,NAME,HREF, FIELDS,
+ new BreadCrumbs(breadcrumbs),
+ new Table<AAF_GUI,AuthzTrans>("History", gui.env.newTransNoAvg(),new Model(gui.env),"class=std"),
+ new NamedCode(true, "content") {
+ @Override
+ public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+ final Slot user = gui.env.slot(NAME+".user");
+ cache.dynamic(hgen, new DynamicCode<HTMLGen, AAF_GUI, AuthzTrans>() {
+ @Override
+ public void code(final AAF_GUI gui, final AuthzTrans trans, final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+ String obUser = trans.get(user, null);
+
+ // Use Javascript to make the table title more descriptive
+ hgen.js()
+ .text("var caption = document.querySelector(\".title\");")
+ .text("caption.innerHTML='History for User [ " + obUser + " ]';")
+ .done();
+
+ // Use Javascript to change Link Target to our last visited Detail page
+ String lastPage = CredDetail.HREF + "?role=" + obUser;
+ hgen.js()
+ .text("alterLink('roledetail', '"+lastPage + "');")
+ .done();
+
+ hgen.br();
+ hgen.leaf("a", "href=#advanced_search","onclick=divVisibility('advanced_search');","class=greenbutton").text("Advanced Search").end()
+ .divID("advanced_search", "style=display:none");
+ hgen.incr("table");
+
+ addDateRow(hgen,"Start Date");
+ addDateRow(hgen,"End Date");
+ hgen.incr("tr").incr("td");
+ hgen.tagOnly("input", "type=button","value=Get History",
+ "onclick=datesURL('"+HREF+"?user=" + obUser+"');","class=greenbutton");
+ hgen.end().end();
+ hgen.end();
+ hgen.end();
+ }
+ });
+ }
+ }
+
+ );
+
+ }
+
+ private static void addDateRow(HTMLGen hgen, String s) {
+ hgen
+ .incr("tr")
+ .incr("td")
+ .incr("label", "for=month", "required").text(s+"*").end()
+ .end()
+ .incr("td")
+ .incr("select", "name=month"+s.substring(0, s.indexOf(' ')), "id=month"+s.substring(0, s.indexOf(' ')), "required")
+ .incr("option", "value=").text("Month").end();
+ for(NsHistory.Month m : NsHistory.Month.values()) {
+ if (Calendar.getInstance().get(Calendar.MONTH) == m.ordinal()) {
+ hgen.incr("option", "selected", "value="+(m.ordinal()+1)).text(m.name()).end();
+ } else {
+ hgen.incr("option", "value="+(m.ordinal()+1)).text(m.name()).end();
+ }
+ }
+ hgen.end()
+ .end()
+ .incr("td")
+ .tagOnly("input","type=number","id=year"+s.substring(0, s.indexOf(' ')),"required",
+ "value="+Calendar.getInstance().get(Calendar.YEAR), "min=1900",
+ "max="+Calendar.getInstance().get(Calendar.YEAR),
+ "placeholder=Year").end()
+ .end();
+ }
+
+
+ /**
+ * Implement the Table Content for History
+ *
+ * @author Jonathan
+ *
+ */
+ private static class Model extends TableData<AAF_GUI,AuthzTrans> {
+ private static final String[] headers = new String[] {"Date","User","Memo"};
+ private Slot user;
+ private Slot dates;
+
+ public Model(AuthzEnv env) {
+ user = env.slot(NAME+".user");
+ dates = env.slot(NAME+".dates");
+ }
+
+ @Override
+ public String[] headers() {
+ return headers;
+ }
+
+ @Override
+ public Cells get(final AuthzTrans trans, final AAF_GUI gui) {
+ final String oName = trans.get(user,null);
+ final String oDates = trans.get(dates,null);
+
+ Cells rv = Cells.EMPTY;
+ if (oName!=null) {
+
+ try {
+ rv = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Cells>() {
+ @Override
+ public Cells code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+ ArrayList<AbsCell[]> rv = new ArrayList<>();
+ TimeTaken tt = trans.start("AAF Get History for credential ["+oName+"]",Env.REMOTE);
+ String msg = null;
+ try {
+ if (oDates != null) {
+ client.setQueryParams("yyyymm="+oDates);
+ }
+ Future<History> fh = client.read("/authz/hist/subject/"+oName + "/cred",gui.getDF(History.class));
+ if (fh.get(AAF_GUI.TIMEOUT)) {
+ tt.done();
+ tt = trans.start("Load History Data", Env.SUB);
+ List<Item> histItems = fh.value.getItem();
+
+ java.util.Collections.sort(histItems, new Comparator<Item>() {
+ @Override
+ public int compare(Item o1, Item o2) {
+ return o2.getTimestamp().compare(o1.getTimestamp());
+ }
+ });
+
+ for (Item i : histItems) {
+ String user = i.getUser();
+ AbsCell userCell = new TextCell(user);
+
+ String memo = i.getMemo().replace("<script>", "<script>").replace("</script>", "</script>");
+ rv.add(new AbsCell[] {
+ new TextCell(i.getTimestamp().toGregorianCalendar().getTime().toString()),
+ userCell,
+ new TextCell(memo)
+ });
+ }
+ } else {
+ if (fh.code()==403) {
+ rv.add(new AbsCell[] {new TextCell("You may not view History of Credentiol[" + oName + "]", "colspan = 3", "class=center")});
+ } else {
+ rv.add(new AbsCell[] {new TextCell("*** Data Unavailable ***", "colspan = 3", "class=center")});
+ }
+ }
+ } finally {
+ tt.done();
+ }
+ return new Cells(rv,msg);
+ }
+ });
+ } catch (Exception e) {
+ trans.error().log(e);
+ }
+ }
+ return rv;
+ }
+ }
+
+}
public class Home extends Page {
public static final String HREF = "/gui/home";
- /*
- * Relative path, Menu Name, Full Path
- */
- public static final String[][] MENU_ITEMS = new String[][] {
- {"myperms","My Permissions","/gui/myperms"},
- {"myroles","My Roles","/gui/myroles"},
- {"ns","My Namespaces","/gui/ns"},
- {"approve","My Approvals","/gui/approve"},
- {"myrequests","My Pending Requests","/gui/myrequests"},
- // Enable later
- // {"onboard","Onboarding"},
- {"passwd","Password Management","/gui/passwd"},
- {"cui","Command Prompt","/gui/cui"},
- {"api","AAF API","/gui/api"}
- };
public Home(final AAF_GUI gui) throws APIException, IOException {
super(gui.env,"Home",HREF, NO_FIELDS, new NamedCode(false,"content") {
}
String historyLink = NsHistory.HREF
+ "?name=" + nsName;
- rv.add(new AbsCell[] {new RefCell("See History",historyLink,false)});
+ rv.add(new AbsCell[] {new RefCell("See History",historyLink,false,"class=greenbutton")});
} finally {
tt.done();
}
static final String NAME="NsHistory";
static final String HREF = "/gui/nsHistory";
static final String FIELDS[] = {"name","dates"};
- static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
static enum Month { JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY,
AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER };
.done();
hgen.br();
- hgen.leaf("a","href=#advanced_search","onclick=divVisibility('advanced_search');").text("Advanced Search").end()
+ hgen.leaf("a","href=#advanced_search","onclick=divVisibility('advanced_search');","class=greenbutton").text("Advanced Search").end()
.divID("advanced_search", "style=display:none");
hgen.incr("table");
addDateRow(hgen,"End Date");
hgen.incr("tr").incr("td");
hgen.tagOnly("input", "type=button","value=Get History",
- "onclick=datesURL('"+HREF+"?name=" + obName+"');");
+ "onclick=datesURL('"+HREF+"?name=" + obName+"');","class=greenbutton");
hgen.end().end();
hgen.end();
hgen.end();
public class PendingRequestsShow extends Page {
public static final String HREF = "/gui/myrequests";
public static final String NAME = "MyRequests";
- static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
- static final String[] FIELDS = new String[] {"as_user"}; // as_user Checked in Display
+ private static final String[] FIELDS = new String[] {"as_user"}; // as_user Checked in Display
private static final String AS_USER=NAME+".as_user";
public PendingRequestsShow(final AAF_GUI gui, final Page ... breadcrumbs) throws APIException, IOException {
final String pInstance = trans.get(instance, null);
final String pAction = trans.get(action, null);
Validator v = new Validator();
- v.permType(pType)
+ v.permTypeWithUser(trans.user(),pType)
.permInstance(pInstance)
.permAction(pAction);
String historyLink = PermHistory.HREF
+ "?type=" + pType + "&instance=" + pInstance + "&action=" + pAction;
- rv.add(new AbsCell[] {new RefCell("See History",historyLink,false)});
+ rv.add(new AbsCell[] {new RefCell("See History",historyLink,false,"class=greenbutton")});
} else {
rv.add(new AbsCell[] {new TextCell(
fp.code()==HttpStatus.NOT_FOUND_404?
static final String NAME="PermHistory";
static final String HREF = "/gui/permHistory";
static final String FIELDS[] = {"type","instance","action","dates"};
- static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
- static enum Month { JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY,
- AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER };
public PermHistory(final AAF_GUI gui, final Page ... breadcrumbs) throws APIException, IOException {
super(gui.env,NAME,HREF, FIELDS,
.done();
hgen.br();
- hgen.leaf("a", "href=#advanced_search", "onclick=divVisibility('advanced_search');").text("Advanced Search").end()
+ hgen.leaf("a", "href=#advanced_search", "onclick=divVisibility('advanced_search');","class=greenbutton").text("Advanced Search").end()
.divID("advanced_search", "style=display:none");
hgen.incr("table");
hgen.tagOnly("input", "type=button","value=Get History",
"onclick=datesURL('"+HREF+"?type=" + type
+ "&instance=" + instance
- + "&action=" + action+"');");
+ + "&action=" + action+"');","class=greenbutton");
hgen.end().end();
hgen.end();
hgen.end();
.incr("td")
.incr("select", "name=month"+s.substring(0, s.indexOf(' ')), "id=month"+s.substring(0, s.indexOf(' ')), "required")
.incr("option", "value=").text("Month").end();
- for (Month m : Month.values()) {
+ for (NsHistory.Month m : NsHistory.Month.values()) {
if (Calendar.getInstance().get(Calendar.MONTH) == m.ordinal()) {
hgen.incr("option", "selected", "value="+(m.ordinal()+1)).text(m.name()).end();
} else {
public void prefix(final AAF_GUI gui, final AuthzTrans trans, final Cache<HTMLGen> cache, final HTMLGen hgen) {
final String pRole = trans.get(sRoleName, null);
Validator v = new Validator();
- v.role(pRole);
+ if(!v.isNull("Role",pRole).err()) {
+ if(!pRole.startsWith(trans.user())) {
+ v.role(pRole);
+ }
+ }
if (v.err()) {
trans.warn().printf("Error in PermDetail Request: %s", v.errs());
return;
// History
rv.add(new AbsCell[] {
- new RefCell("See History",RoleHistory.HREF + "?role=" + pRole,false)
+ new RefCell("See History",RoleHistory.HREF + "?role=" + pRole,false,"class=greenbutton")
});
} else {
rv.add(new AbsCell[]{
static final String NAME="RoleHistory";
static final String HREF = "/gui/roleHistory";
static final String FIELDS[] = {"role","dates"};
- static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
- static enum Month { JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY,
- AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER };
+
public RoleHistory(final AAF_GUI gui, final Page ... breadcrumbs) throws APIException, IOException {
super(gui.env,NAME,HREF, FIELDS,
.done();
hgen.br();
- hgen.leaf("a", "href=#advanced_search","onclick=divVisibility('advanced_search');").text("Advanced Search").end()
+ hgen.leaf("a", "href=#advanced_search","onclick=divVisibility('advanced_search');","class=greenbutton").text("Advanced Search").end()
.divID("advanced_search", "style=display:none");
hgen.incr("table");
addDateRow(hgen,"End Date");
hgen.incr("tr").incr("td");
hgen.tagOnly("input", "type=button","value=Get History",
- "onclick=datesURL('"+HREF+"?role=" + obRole+"');");
+ "onclick=datesURL('"+HREF+"?role=" + obRole+"');","class=greenbutton");
hgen.end().end();
hgen.end();
hgen.end();
.incr("td")
.incr("select", "name=month"+s.substring(0, s.indexOf(' ')), "id=month"+s.substring(0, s.indexOf(' ')), "required")
.incr("option", "value=").text("Month").end();
- for (Month m : Month.values()) {
+ for (NsHistory.Month m : NsHistory.Month.values()) {
if (Calendar.getInstance().get(Calendar.MONTH) == m.ordinal()) {
hgen.incr("option", "selected", "value="+(m.ordinal()+1)).text(m.name()).end();
} else {
color: white;
font-family: "Lucida Console", Monaco, monospace;
overflow-y: scroll;
- height: 300px;
+ height: 600px;
min-width: 600px;
padding: 5px;
resize: vertical;
cmds = document.querySelector("#command_field").value.split(" ");
var cleanCmd = "";
if (document.querySelector("#details_img").getAttribute("class") == "selected")
- cleanCmd += "set details=true ";
+ cleanCmd += "details ";
for (var i = 0; i < cmds.length;i++) {
var trimmed = cmds[i].trim();
if (trimmed != "")
content.removeAttribute("class");
footer.style.display="";
console_area.style.resize="vertical";
- console_area.style.height="300px";
+ console_area.style.height="600px";
}
selectOption(img,0);
}
Log4JLogIt logIt = new Log4JLogIt(args, "hello");
PropAccess propAccess = new PropAccess(logIt,args);
- AAF_Hello service = new AAF_Hello(new AuthzEnv(propAccess));
- JettyServiceStarter<AuthzEnv,AuthzTrans> jss = new JettyServiceStarter<AuthzEnv,AuthzTrans>(service);
- jss.start();
+ try {
+ new JettyServiceStarter<AuthzEnv,AuthzTrans>(
+ new AAF_Hello(new AuthzEnv(propAccess)),true)
+ .start();
+ } catch (Exception e) {
+ propAccess.log(e);
+ }
} catch (Exception e) {
e.printStackTrace();
}
} catch (UnknownHostException | CadiException e) {
throw new LocatorException(e);
}
- gui_locator = AbsAAFLocator.create(rph.getPublicEntryName("gui", rph.default_container),
- Config.AAF_DEFAULT_API_VERSION);
+ String url = rph.getPublicEntryName("gui", rph.default_container);
+ gui_locator = AbsAAFLocator.create(url,Config.AAF_DEFAULT_API_VERSION);
}
return gui_locator;
}
Log4JLogIt logIt = new Log4JLogIt(args, "locate");
PropAccess propAccess = new PropAccess(logIt,args);
- AAF_Locate service = new AAF_Locate(new AuthzEnv(propAccess));
- JettyServiceStarter<AuthzEnv,AuthzTrans> jss = new JettyServiceStarter<AuthzEnv,AuthzTrans>(service);
- jss.start();
+ try {
+ new JettyServiceStarter<AuthzEnv,AuthzTrans>(
+ new AAF_Locate(new AuthzEnv(propAccess)),true)
+ .start();
+ } catch (Exception e) {
+ propAccess.log(e);
+ }
} catch (Exception e) {
e.printStackTrace();
}
package org.onap.aaf.auth.locate.service;
import java.util.List;
-import java.util.UUID;
import org.onap.aaf.auth.dao.cass.ConfigDAO;
import org.onap.aaf.auth.dao.cass.ConfigDAO.Data;
return Result.err(Result.ERR_BadData,v.errs());
}
int count = 0;
+ StringBuilder denied = null;
for (MgmtEndpoint me : meps.getMgmtEndpoint()) {
if (permToRegister) {
int dot = me.getName().lastIndexOf('.'); // Note: Validator checks for NS for getName()
- AAFPermission p = new AAFPermission(me.getName().substring(0,dot),"locator",me.getName(),"write");
- if (trans.fish(p)) {
- LocateDAO.Data data = mapper.locateData(me);
- locateDAO.update(trans, data, true);
- ++count;
- } else {
- return Result.err(Result.ERR_Denied,"May not register service (needs " + p.getKey() + ')');
+ AAFPermission p = new AAFPermission(me.getName().substring(0,dot),"locator",me.getHostname(),"write");
+ if (!trans.fish(p)) {
+ if(denied==null) {
+ denied = new StringBuilder("May not register service(s):");
+ }
+
+ denied.append("\n\t");
+ denied.append(p.getKey());
+ denied.append(')');
+ continue;
}
- } else { //TODO if (MechID is part of Namespace) {
- LocateDAO.Data data = mapper.locateData(me);
- locateDAO.update(trans, data, true);
- ++count;
}
+ LocateDAO.Data data = mapper.locateData(me);
+ locateDAO.update(trans, data, true);
+ ++count;
}
if (count>0) {
return Result.ok();
} else {
- return Result.err(Result.ERR_NotFound, "No endpoints found");
+ return denied==null?Result.err(Result.ERR_NotFound, "No endpoints found")
+ :Result.err(Result.ERR_Security,denied.toString());
}
}
return Result.err(Result.ERR_BadData,v.errs());
}
int count = 0;
+ StringBuilder denied = null;
for (MgmtEndpoint me : meps.getMgmtEndpoint()) {
- int dot = me.getName().lastIndexOf('.'); // Note: Validator checks for NS for getName()
- AAFPermission p = new AAFPermission(me.getName().substring(0,dot),"locator",me.getHostname(),"write");
- if (trans.fish(p)) {
- LocateDAO.Data data = mapper.locateData(me);
- data.port_key = UUID.randomUUID();
- locateDAO.delete(trans, data, false);
- ++count;
- } else {
- return Result.err(Result.ERR_Denied,"May not register service (needs " + p.getKey() + ')');
- }
+ if (permToRegister) {
+ int dot = me.getName().lastIndexOf('.'); // Note: Validator checks for NS for getName()
+ AAFPermission p = new AAFPermission(me.getName().substring(0,dot),"locator",me.getHostname(),"write");
+ if (!trans.fish(p)) {
+ if(denied==null) {
+ denied = new StringBuilder("May not deregister service(s):");
+ }
+
+ denied.append("\n\t");
+ denied.append(p.getKey());
+ denied.append(')');
+ continue;
+ }
+ }
+ LocateDAO.Data data = mapper.locateData(me);
+ locateDAO.delete(trans, data, true);
+ ++count;
}
if (count>0) {
return Result.ok();
} else {
- return Result.err(Result.ERR_NotFound, "No endpoints found");
+ return denied==null?Result.err(Result.ERR_NotFound, "No endpoints found")
+ :Result.err(Result.ERR_Security,denied.toString());
}
}
///// ADDED v1_1
/* (non-Javadoc)
* @see org.onap.aaf.auth.locate.service.LocateService#getConfig(org.onap.aaf.auth.env.AuthzTrans, java.lang.String, java.lang.String)
+ *
+ * Note: "id" is put in, in case we need to filter, or direct data change in the future by Permission
*/
@Override
public Result<Configuration> getConfig(AuthzTrans trans, String id, String type) {
}
}
return Result.ok(c);
- //return Result.err(Result.ERR_NotImplemented,"not done yet");
}
Log4JLogIt logIt = new Log4JLogIt(args, "oauth");
PropAccess propAccess = new PropAccess(logIt,args);
- AAF_OAuth service = new AAF_OAuth(new AuthzEnv(propAccess));
- JettyServiceStarter<AuthzEnv,AuthzTrans> jss = new JettyServiceStarter<AuthzEnv,AuthzTrans>(service);
- jss.start();
+ try {
+ new JettyServiceStarter<AuthzEnv,AuthzTrans>(
+ new AAF_OAuth(new AuthzEnv(propAccess)),true)
+ .start();
+ } catch (Exception e) {
+ propAccess.log(e);
+ }
} catch (Exception e) {
e.printStackTrace();
}
Log4JLogIt logIt = new Log4JLogIt(args, "authz");
PropAccess propAccess = new PropAccess(logIt,args);
- AbsService<AuthzEnv, AuthzTrans> service = new AAF_Service(new AuthzEnv(propAccess));
- JettyServiceStarter<AuthzEnv,AuthzTrans> jss = new JettyServiceStarter<AuthzEnv,AuthzTrans>(service);
- jss.start();
+ try {
+ new JettyServiceStarter<AuthzEnv,AuthzTrans>(
+ new AAF_Service(new AuthzEnv(propAccess)),true)
+ .start();
+ } catch (Exception e) {
+ propAccess.log(e);
+ }
} catch (Exception e) {
e.printStackTrace();
}
import org.onap.aaf.auth.common.Define;
import org.onap.aaf.auth.dao.DAOException;
+import org.onap.aaf.auth.dao.cached.CachedPermDAO;
+import org.onap.aaf.auth.dao.cached.CachedRoleDAO;
+import org.onap.aaf.auth.dao.cached.CachedUserRoleDAO;
import org.onap.aaf.auth.dao.cass.ApprovalDAO;
import org.onap.aaf.auth.dao.cass.CertDAO;
import org.onap.aaf.auth.dao.cass.CredDAO;
import org.onap.aaf.auth.dao.hl.Question;
import org.onap.aaf.auth.dao.hl.Question.Access;
import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.env.AuthzTrans.REQD_TYPE;
import org.onap.aaf.auth.layer.Result;
import org.onap.aaf.auth.org.Executor;
import org.onap.aaf.auth.org.Organization;
import org.onap.aaf.auth.service.mapper.Mapper.API;
import org.onap.aaf.auth.service.validation.ServiceValidator;
import org.onap.aaf.auth.validation.Validator;
+import org.onap.aaf.cadi.aaf.Defaults;
import org.onap.aaf.cadi.principal.BasicPrincipal;
+import org.onap.aaf.cadi.util.FQI;
import org.onap.aaf.misc.env.Env;
import org.onap.aaf.misc.env.TimeTaken;
import org.onap.aaf.misc.env.util.Chrono;
public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS>
implements AuthzService <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> {
- private Mapper <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> mapper;
+ private static final String TWO_SPACE = " ";
+ private Mapper <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> mapper;
@Override
public Mapper <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> mapper() {return mapper;}
@Override
public Result<Void> createPerm(final AuthzTrans trans,REQUEST rreq) {
final Result<PermDAO.Data> newPd = mapper.perm(trans, rreq);
- // Does Perm Type exist as a Namespace?
- if(newPd.value.type.isEmpty() || ques.nsDAO().read(trans, newPd.value.fullType()).isOKhasData()) {
- return Result.err(Status.ERR_ConflictAlreadyExists,
- "Permission Type exists as a Namespace");
- }
-
+
final ServiceValidator v = new ServiceValidator();
if (v.perm(newPd).err()) {
return Result.err(Status.ERR_BadData,v.errs());
}
-
- Result<FutureDAO.Data> fd = mapper.future(trans, PermDAO.TABLE, rreq, newPd.value,false,
- new Mapper.Memo() {
- @Override
- public String get() {
- return "Create Permission [" +
- newPd.value.fullType() + '|' +
- newPd.value.instance + '|' +
- newPd.value.action + ']';
- }
- },
- new MayChange() {
- private Result<NsDAO.Data> nsd;
- @Override
- public Result<?> mayChange() {
- if (nsd==null) {
- nsd = ques.mayUser(trans, trans.user(), newPd.value, Access.write);
- }
- return nsd;
- }
- });
- Result<List<NsDAO.Data>> nsr = ques.nsDAO().read(trans, newPd.value.ns);
- if (nsr.notOKorIsEmpty()) {
- return Result.err(nsr);
+
+ // User Permission mechanism
+ if(newPd.value.ns.indexOf('@')>0) {
+ PermDAO.Data pdd = newPd.value;
+ if(trans.user().equals(newPd.value.ns)) {
+ CachedPermDAO permDAO = ques.permDAO();
+ Result<List<PermDAO.Data>> rlpdd = permDAO.read(trans, pdd);
+ if(rlpdd.notOK()) {
+ return Result.err(rlpdd);
+ }
+ if(!rlpdd.isEmpty()) {
+ return Result.err(Result.ERR_ConflictAlreadyExists,"Permission already exists");
+ }
+
+ RoleDAO.Data rdd = new RoleDAO.Data();
+ rdd.ns = pdd.ns;
+ rdd.name = "user";
+
+ pdd.roles(true).add(rdd.fullName());
+ Result<PermDAO.Data> rpdd = permDAO.create(trans, pdd);
+ if(rpdd.notOK()) {
+ return Result.err(rpdd);
+ }
+
+ CachedRoleDAO roleDAO = ques.roleDAO();
+ Result<List<RoleDAO.Data>> rlrdd = roleDAO.read(trans, rdd);
+ if(rlrdd.notOK()) {
+ return Result.err(rlrdd);
+ } else {
+ if(!rlrdd.isEmpty()) {
+ rdd = rlrdd.value.get(0);
+ }
+ }
+
+ String eperm = pdd.encode();
+ rdd.perms(true).add(eperm);
+ Result<Void> rv = roleDAO.update(trans, rdd);
+ if(rv.notOK()) {
+ return rv;
+ }
+
+ CachedUserRoleDAO urDAO = ques.userRoleDAO();
+ UserRoleDAO.Data urdd = new UserRoleDAO.Data();
+ urdd.user = trans.user();
+ urdd.ns = rdd.ns;
+ urdd.rname = rdd.name;
+ urdd.role = rdd.fullName();
+ Result<List<UserRoleDAO.Data>> rlurdd = urDAO.read(trans, urdd);
+ if(rlurdd.notOK()) {
+ return Result.err(rlrdd);
+ } else if(rlurdd.isEmpty()) {
+ GregorianCalendar gc = trans.org().expiration(null, Expiration.UserInRole);
+ if(gc==null) {
+ return Result.err(Result.ERR_Policy,"Organzation does not grant Expiration for UserRole");
+ } else {
+ urdd.expires = gc.getTime();
+ }
+ Result<UserRoleDAO.Data> rurdd = urDAO.create(trans, urdd);
+ return Result.err(rurdd);
+ }
+ return rv;
+ } else {
+ return Result.err(Result.ERR_Security,"Only the User can create User Permissions");
+ }
+ } else {
+ // Does Perm Type exist as a Namespace?
+ if(newPd.value.type.isEmpty() || ques.nsDAO().read(trans, newPd.value.fullType()).isOKhasData()) {
+ return Result.err(Status.ERR_ConflictAlreadyExists,
+ "Permission Type exists as a Namespace");
+ }
+
+ Result<FutureDAO.Data> fd = mapper.future(trans, PermDAO.TABLE, rreq, newPd.value,false,
+ new Mapper.Memo() {
+ @Override
+ public String get() {
+ return "Create Permission [" +
+ newPd.value.fullType() + '|' +
+ newPd.value.instance + '|' +
+ newPd.value.action + ']';
+ }
+ },
+ new MayChange() {
+ private Result<NsDAO.Data> nsd;
+ @Override
+ public Result<?> mayChange() {
+ if (nsd==null) {
+ nsd = ques.mayUser(trans, trans.user(), newPd.value, Access.write);
+ }
+ return nsd;
+ }
+ });
+
+ Result<List<NsDAO.Data>> nsr = ques.nsDAO().read(trans, newPd.value.ns);
+ if (nsr.notOKorIsEmpty()) {
+ return Result.err(nsr);
+ }
+ switch(fd.status) {
+ case OK:
+ Result<String> rfc = func.createFuture(trans,fd.value,
+ newPd.value.fullType() + '|' + newPd.value.instance + '|' + newPd.value.action,
+ trans.user(),
+ nsr.value.get(0),
+ FUTURE_OP.C);
+ if (rfc.isOK()) {
+ return Result.err(Status.ACC_Future, "Perm [%s.%s|%s|%s] is saved for future processing",
+ newPd.value.ns,
+ newPd.value.type,
+ newPd.value.instance,
+ newPd.value.action);
+ } else {
+ return Result.err(rfc);
+ }
+ case Status.ACC_Now:
+ return func.createPerm(trans, newPd.value, true);
+ default:
+ return Result.err(fd);
+ }
}
- switch(fd.status) {
- case OK:
- Result<String> rfc = func.createFuture(trans,fd.value,
- newPd.value.fullType() + '|' + newPd.value.instance + '|' + newPd.value.action,
- trans.user(),
- nsr.value.get(0),
- FUTURE_OP.C);
- if (rfc.isOK()) {
- return Result.err(Status.ACC_Future, "Perm [%s.%s|%s|%s] is saved for future processing",
- newPd.value.ns,
- newPd.value.type,
- newPd.value.instance,
- newPd.value.action);
- } else {
- return Result.err(rfc);
- }
- case Status.ACC_Now:
- return func.createPerm(trans, newPd.value, true);
- default:
- return Result.err(fd);
- }
}
@ApiDoc(
return Result.err(Status.ERR_PermissionNotFound, "Permission [%s.%s|%s|%s] does not exist",
perm.ns,perm.type,perm.instance,perm.action );
}
-
+
Result<FutureDAO.Data> fd = mapper.future(trans,PermDAO.TABLE,from,perm,false,
new Mapper.Memo() {
@Override
public Result<?> mayChange() {
if (nsd==null) {
nsd = ques.mayUser(trans, trans.user(), rpd.value, Access.write);
+ if(nsd.notOK()) {
+ trans.requested(REQD_TYPE.future,true);
+ }
}
return nsd;
}
return Result.err(nsr);
}
switch(fd.status) {
- case OK:
- Result<String> rfc = func.createFuture(trans,fd.value,
- rpd.value.fullPerm(),
- trans.user(),
- nsr.value.get(0),
- FUTURE_OP.G);
- if (rfc.isOK()) {
- return Result.err(Status.ACC_Future, "Perm [%s.%s|%s|%s] is saved for future processing",
- rpd.value.ns,
- rpd.value.type,
- rpd.value.instance,
- rpd.value.action);
- } else {
- return Result.err(rfc);
- }
- case Status.ACC_Now:
- Result<Void> rv = null;
- if (createPerm!=null) {// has been validated for creating
- rv = func.createPerm(trans, createPerm, false);
- }
- if (rv==null || rv.isOK()) {
- rv = func.addPermToRole(trans, rrd.value, rpd.value, false);
- }
- return rv;
- default:
- return Result.err(fd);
+ case OK:
+ Result<String> rfc = func.createFuture(trans,fd.value,
+ rpd.value.fullPerm(),
+ trans.user(),
+ nsr.value.get(0),
+ FUTURE_OP.G);
+ if (rfc.isOK()) {
+ return Result.err(Status.ACC_Future, "Perm [%s.%s|%s|%s] is saved for future processing",
+ rpd.value.ns,
+ rpd.value.type,
+ rpd.value.instance,
+ rpd.value.action);
+ } else {
+ return Result.err(rfc);
+ }
+ case Status.ACC_Now:
+ Result<Void> rv = null;
+ if (createPerm!=null) {// has been validated for creating
+ rv = func.createPerm(trans, createPerm, false);
+ }
+ if (rv==null || rv.isOK()) {
+ rv = func.addPermToRole(trans, rrd.value, rpd.value, false);
+ }
+ return rv;
+ default:
+ return Result.err(fd);
}
}
}
private class MayChangeCred implements MayChange {
-
- private Result<NsDAO.Data> nsd;
+ private static final String EXTEND = "extend";
+ private static final String RESET = "reset";
+ private static final String DELETE = "delete";
+ private Result<NsDAO.Data> nsd;
private AuthzTrans trans;
private CredDAO.Data cred;
- public MayChangeCred(AuthzTrans trans, CredDAO.Data cred) {
+ private String action;
+ public MayChangeCred(AuthzTrans trans, CredDAO.Data cred, String action) {
this.trans = trans;
this.cred = cred;
+ this.action = action;
}
@Override
public Result<?> mayChange() {
// User can change himself (but not create)
- if (trans.user().equals(cred.id)) {
- return Result.ok();
- }
if (nsd==null) {
nsd = ques.validNSOfDomain(trans, cred.id);
}
// Get the Namespace
if (nsd.isOK()) {
- if (ques.mayUser(trans, trans.user(), nsd.value,Access.write).isOK()) {
- return Result.ok();
- }
- String user[] = Split.split('.',trans.user());
- if (user.length>2) {
- String company = user[user.length-1] + '.' + user[user.length-2];
- if (ques.isGranted(trans, trans.user(), ROOT_NS,"password",company,"reset")) {
- return Result.ok();
- }
- }
+ String ns = nsd.value.name;
+ String user = trans.user();
+ String company;
+ String temp[] = Split.split('.',ns);
+ switch(temp.length) {
+ case 0:
+ company = Defaults.AAF_NS;
+ break;
+ case 1:
+ company = temp[0];
+ break;
+ default:
+ company = temp[0] + '.' + temp[1];
+ }
+ switch(action) {
+ case DELETE:
+ if(ques.isOwner(trans, user,ns) ||
+ ques.isAdmin(trans, user,ns) ||
+ ques.isGranted(trans, user, ROOT_NS,"password",company,DELETE)) {
+ return Result.ok();
+ }
+ break;
+ case RESET:
+ case EXTEND:
+ if (ques.isGranted(trans, trans.user(), ROOT_NS,"password",company,action)) {
+ return Result.ok();
+ }
+ break;
+ }
}
- return Result.err(Status.ERR_Denied,"%s is not allowed to change %s in %s",trans.user(),cred.id,cred.ns);
+ return Result.err(Status.ERR_Denied,"%s is not allowed to %s %s in %s",trans.user(),action,cred.id,cred.ns);
}
-
}
private final long DAY_IN_MILLIS = 24*3600*1000L;
}
)
@Override
- public Result<Void> changeUserCred(final AuthzTrans trans, REQUEST from) {
+ public Result<Void> resetUserCred(final AuthzTrans trans, REQUEST from) {
final String cmdDescription = "Update User Credential";
TimeTaken tt = trans.start(cmdDescription, Env.SUB);
try {
return Result.err(Status.ERR_UserNotFound, "Credential does not exist");
}
- MayChange mc = new MayChangeCred(trans, rcred.value);
+ MayChange mc = new MayChangeCred(trans, rcred.value,MayChangeCred.RESET);
Result<?> rmc = mc.mayChange();
if (rmc.notOK()) {
return Result.err(rmc);
}
- Result<Integer> ri = selectEntryIfMultiple((CredRequest)from, rlcd.value);
+ List<CredDAO.Data> lcdd = filterList(rlcd.value,CredDAO.BASIC_AUTH, CredDAO.BASIC_AUTH_SHA256);
+
+ Result<Integer> ri = selectEntryIfMultiple((CredRequest)from, lcdd, MayChangeCred.RESET);
if (ri.notOK()) {
return Result.err(ri);
}
}
}
- /*
- * Codify the way to get Either Choice Needed or actual Integer from Credit Request
- */
- private Result<Integer> selectEntryIfMultiple(final CredRequest cr, List<CredDAO.Data> lcd) {
- int entry = 0;
- if (lcd.size() > 1) {
- String inputOption = cr.getEntry();
- if (inputOption == null) {
- String message = selectCredFromList(lcd, false);
- Object[] variables = buildVariables(lcd);
- return Result.err(Status.ERR_ChoiceNeeded, message, variables);
- } else {
- entry = Integer.parseInt(inputOption) - 1;
- }
- if (entry < 0 || entry >= lcd.size()) {
- return Result.err(Status.ERR_BadData, "User chose invalid credential selection");
- }
- }
- return Result.ok(entry);
- }
-
@ApiDoc(
method = PUT,
path = "/authn/cred/:days",
if (rlcd.notOKorIsEmpty()) {
return Result.err(Status.ERR_UserNotFound, "Credential does not exist");
}
+
+ // Only Passwords can be extended
+ List<CredDAO.Data> lcdd = filterList(rlcd.value,CredDAO.BASIC_AUTH, CredDAO.BASIC_AUTH_SHA256);
//Need to do the "Pick Entry" mechanism
- Result<Integer> ri = selectEntryIfMultiple((CredRequest)from, rlcd.value);
+ // Note, this sorts
+ Result<Integer> ri = selectEntryIfMultiple((CredRequest)from, lcdd, "extend");
if (ri.notOK()) {
return Result.err(ri);
}
- CredDAO.Data found = rlcd.value.get(ri.value);
+ CredDAO.Data found = lcdd.get(ri.value);
CredDAO.Data cd = cred.value;
// Copy over the cred
cd.id = found.id;
}
}
- private String[] buildVariables(List<CredDAO.Data> value) {
+ @ApiDoc(
+ method = DELETE,
+ path = "/authn/cred",
+ params = {},
+ expectedCode = 200,
+ errorCodes = {300,403,404,406},
+ text = { "Delete a Credential. If multiple credentials exist for this",
+ "ID, you will need to specify which entry you are deleting in the",
+ "CredRequest object."
+ }
+ )
+ @Override
+ public Result<Void> deleteUserCred(AuthzTrans trans, REQUEST from) {
+ final Result<CredDAO.Data> cred = mapper.cred(trans, from, false);
+ final Validator v = new ServiceValidator();
+ if (v.nullOrBlank("cred", cred.value.id).err()) {
+ return Result.err(Status.ERR_BadData,v.errs());
+ }
+
+ MayChange mc = new MayChangeCred(trans,cred.value,MayChangeCred.DELETE);
+ Result<?> rmc = mc.mayChange();
+ if (rmc.notOK()) {
+ return Result.err(rmc);
+ }
+
+ Result<List<CredDAO.Data>> rlcd = ques.credDAO().readID(trans, cred.value.id);
+ if (rlcd.notOKorIsEmpty()) {
+ // Empty Creds should have no user_roles.
+ Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO().readByUser(trans, cred.value.id);
+ if (rlurd.isOK()) {
+ for (UserRoleDAO.Data data : rlurd.value) {
+ ques.userRoleDAO().delete(trans, data, false);
+ }
+ }
+ return Result.err(Status.ERR_UserNotFound, "Credential does not exist");
+ }
+ boolean isLastCred = rlcd.value.size()==1;
+
+
+ int entry = 0;
+ if (!trans.requested(force)) {
+ if (rlcd.value.size() > 1) {
+ CredRequest cr = (CredRequest)from;
+ String inputOption = cr.getEntry();
+ if (inputOption == null) {
+ List<CredDAO.Data> list = filterList(rlcd.value,CredDAO.BASIC_AUTH,CredDAO.BASIC_AUTH_SHA256,CredDAO.CERT_SHA256_RSA);
+ String message = selectCredFromList(list, MayChangeCred.DELETE);
+ Object[] variables = buildVariables(list);
+ return Result.err(Status.ERR_ChoiceNeeded, message, variables);
+ } else {
+ try {
+ if (inputOption.length()>5) { // should be a date
+ Date d = Chrono.xmlDatatypeFactory.newXMLGregorianCalendar(inputOption).toGregorianCalendar().getTime();
+ entry = 0;
+ for (CredDAO.Data cd : rlcd.value) {
+ if (cd.type.equals(cr.getType()) && cd.expires.equals(d)) {
+ break;
+ }
+ ++entry;
+ }
+ } else {
+ entry = Integer.parseInt(inputOption) - 1;
+ }
+ } catch (NullPointerException e) {
+ return Result.err(Status.ERR_BadData, "Invalid Date Format for Entry");
+ } catch (NumberFormatException e) {
+ return Result.err(Status.ERR_BadData, "User chose invalid credential selection");
+ }
+ }
+ isLastCred = (entry==-1)?true:false;
+ } else {
+ isLastCred = true;
+ }
+ if (entry < -1 || entry >= rlcd.value.size()) {
+ return Result.err(Status.ERR_BadData, "User chose invalid credential selection");
+ }
+ }
+
+ Result<FutureDAO.Data> fd = mapper.future(trans,CredDAO.TABLE,from,cred.value,false,
+ () -> "Delete Credential [" +
+ cred.value.id +
+ ']',
+ mc);
+
+ Result<List<NsDAO.Data>> nsr = ques.nsDAO().read(trans, cred.value.ns);
+ if (nsr.notOKorIsEmpty()) {
+ return Result.err(nsr);
+ }
+
+ switch(fd.status) {
+ case OK:
+ Result<String> rfc = func.createFuture(trans, fd.value, cred.value.id,
+ trans.user(), nsr.value.get(0), FUTURE_OP.D);
+
+ if (rfc.isOK()) {
+ return Result.err(Status.ACC_Future, "Credential Delete [%s] is saved for future processing",cred.value.id);
+ } else {
+ return Result.err(rfc);
+ }
+ case Status.ACC_Now:
+ Result<?>udr = null;
+ if (!trans.requested(force)) {
+ if (entry<0 || entry >= rlcd.value.size()) {
+ return Result.err(Status.ERR_BadData,"Invalid Choice [" + entry + "] chosen for Delete [%s] is saved for future processing",cred.value.id);
+ }
+ udr = ques.credDAO().delete(trans, rlcd.value.get(entry),false);
+ } else {
+ for (CredDAO.Data curr : rlcd.value) {
+ udr = ques.credDAO().delete(trans, curr, false);
+ if (udr.notOK()) {
+ return Result.err(udr);
+ }
+ }
+ }
+ if (isLastCred) {
+ Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO().readByUser(trans, cred.value.id);
+ if (rlurd.isOK()) {
+ for (UserRoleDAO.Data data : rlurd.value) {
+ ques.userRoleDAO().delete(trans, data, false);
+ }
+ }
+ }
+ if (udr==null) {
+ return Result.err(Result.ERR_NotFound,"No User Data found");
+ }
+ if (udr.isOK()) {
+ return Result.ok();
+ }
+ return Result.err(udr);
+ default:
+ return Result.err(fd);
+ }
+
+ }
+
+ /*
+ * Codify the way to get Either Choice Needed or actual Integer from Credit Request
+ */
+ private Result<Integer> selectEntryIfMultiple(final CredRequest cr, List<CredDAO.Data> lcd, String action) {
+ int entry = 0;
+ if (lcd.size() > 1) {
+ String inputOption = cr.getEntry();
+ if (inputOption == null) {
+ String message = selectCredFromList(lcd, action);
+ Object[] variables = buildVariables(lcd);
+ return Result.err(Status.ERR_ChoiceNeeded, message, variables);
+ } else {
+ entry = Integer.parseInt(inputOption) - 1;
+ }
+ if (entry < 0 || entry >= lcd.size()) {
+ return Result.err(Status.ERR_BadData, "User chose invalid credential selection");
+ }
+ }
+ return Result.ok(entry);
+ }
+
+ private List<CredDAO.Data> filterList(List<CredDAO.Data> orig, Integer ... types) {
+ List<CredDAO.Data> rv = new ArrayList<>();
+ for(CredDAO.Data cdd : orig) {
+ if(cdd!=null) {
+ for(int t : types) {
+ if(t==cdd.type) {
+ rv.add(cdd);
+ }
+ }
+ }
+ }
+ return rv;
+ }
+
+ private String[] buildVariables(List<CredDAO.Data> value) {
// ensure credentials are sorted so we can fully automate Cred regression test
- Collections.sort(value, (cred1, cred2) -> cred1.expires.compareTo(cred2.expires));
+ Collections.sort(value, (cred1, cred2) ->
+ cred1.type==cred2.type?cred2.expires.compareTo(cred1.expires):
+ cred1.type<cred2.type?-1:1);
String [] vars = new String[value.size()+1];
vars[0]="Choice";
+ CredDAO.Data cdd;
for (int i = 0; i < value.size(); i++) {
- vars[i+1] = value.get(i).id + " " + value.get(i).type
- + " |" + value.get(i).expires;
+ cdd = value.get(i);
+ vars[i+1] = cdd.id + TWO_SPACE + cdd.type + TWO_SPACE + (cdd.type<10?TWO_SPACE:"")+ cdd.expires + TWO_SPACE + cdd.tag;
}
return vars;
}
- private String selectCredFromList(List<CredDAO.Data> value, boolean isDelete) {
+ private String selectCredFromList(List<CredDAO.Data> value, String action) {
StringBuilder errMessage = new StringBuilder();
- String userPrompt = isDelete?"Select which cred to delete (set force=true to delete all):":"Select which cred to update:";
+ String userPrompt = MayChangeCred.DELETE.equals(action)?
+ "Select which cred to delete (set force=true to delete all):":
+ "Select which cred to " + action + ':';
int numSpaces = value.get(0).id.length() - "Id".length();
errMessage.append(userPrompt + '\n');
- errMessage.append(" Id");
+ errMessage.append(" ID");
for (int i = 0; i < numSpaces; i++) {
errMessage.append(' ');
}
- errMessage.append(" Type Expires" + '\n');
+ errMessage.append(" Type Expires Tag " + '\n');
for (int i=0;i<value.size();++i) {
errMessage.append(" %s\n");
}
}
- @ApiDoc(
- method = DELETE,
- path = "/authn/cred",
- params = {},
- expectedCode = 200,
- errorCodes = {300,403,404,406},
- text = { "Delete a Credential. If multiple credentials exist for this",
- "ID, you will need to specify which entry you are deleting in the",
- "CredRequest object."
- }
- )
- @Override
- public Result<Void> deleteUserCred(AuthzTrans trans, REQUEST from) {
- final Result<CredDAO.Data> cred = mapper.cred(trans, from, false);
- final Validator v = new ServiceValidator();
- if (v.nullOrBlank("cred", cred.value.id).err()) {
- return Result.err(Status.ERR_BadData,v.errs());
- }
-
- Result<List<CredDAO.Data>> rlcd = ques.credDAO().readID(trans, cred.value.id);
- if (rlcd.notOKorIsEmpty()) {
- // Empty Creds should have no user_roles.
- Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO().readByUser(trans, cred.value.id);
- if (rlurd.isOK()) {
- for (UserRoleDAO.Data data : rlurd.value) {
- ques.userRoleDAO().delete(trans, data, false);
- }
- }
- return Result.err(Status.ERR_UserNotFound, "Credential does not exist");
- }
- boolean isLastCred = rlcd.value.size()==1;
-
- MayChange mc = new MayChangeCred(trans,cred.value);
- Result<?> rmc = mc.mayChange();
- if (rmc.notOK()) {
- return Result.err(rmc);
- }
-
- int entry = 0;
- if (!trans.requested(force)) {
- if (rlcd.value.size() > 1) {
- CredRequest cr = (CredRequest)from;
- String inputOption = cr.getEntry();
- if (inputOption == null) {
- String message = selectCredFromList(rlcd.value, true);
- Object[] variables = buildVariables(rlcd.value);
- return Result.err(Status.ERR_ChoiceNeeded, message, variables);
- } else {
- try {
- if (inputOption.length()>5) { // should be a date
- Date d = Chrono.xmlDatatypeFactory.newXMLGregorianCalendar(inputOption).toGregorianCalendar().getTime();
- entry = 0;
- for (CredDAO.Data cd : rlcd.value) {
- if (cd.type.equals(cr.getType()) && cd.expires.equals(d)) {
- break;
- }
- ++entry;
- }
- } else {
- entry = Integer.parseInt(inputOption) - 1;
- }
- } catch (NullPointerException e) {
- return Result.err(Status.ERR_BadData, "Invalid Date Format for Entry");
- } catch (NumberFormatException e) {
- return Result.err(Status.ERR_BadData, "User chose invalid credential selection");
- }
- }
- isLastCred = (entry==-1)?true:false;
- } else {
- isLastCred = true;
- }
- if (entry < -1 || entry >= rlcd.value.size()) {
- return Result.err(Status.ERR_BadData, "User chose invalid credential selection");
- }
- }
-
- Result<FutureDAO.Data> fd = mapper.future(trans,CredDAO.TABLE,from,cred.value,false,
- () -> "Delete Credential [" +
- cred.value.id +
- ']',
- mc);
-
- Result<List<NsDAO.Data>> nsr = ques.nsDAO().read(trans, cred.value.ns);
- if (nsr.notOKorIsEmpty()) {
- return Result.err(nsr);
- }
-
- switch(fd.status) {
- case OK:
- Result<String> rfc = func.createFuture(trans, fd.value, cred.value.id,
- trans.user(), nsr.value.get(0), FUTURE_OP.D);
-
- if (rfc.isOK()) {
- return Result.err(Status.ACC_Future, "Credential Delete [%s] is saved for future processing",cred.value.id);
- } else {
- return Result.err(rfc);
- }
- case Status.ACC_Now:
- Result<?>udr = null;
- if (!trans.requested(force)) {
- if (entry<0 || entry >= rlcd.value.size()) {
- return Result.err(Status.ERR_BadData,"Invalid Choice [" + entry + "] chosen for Delete [%s] is saved for future processing",cred.value.id);
- }
- udr = ques.credDAO().delete(trans, rlcd.value.get(entry),false);
- } else {
- for (CredDAO.Data curr : rlcd.value) {
- udr = ques.credDAO().delete(trans, curr, false);
- if (udr.notOK()) {
- return Result.err(udr);
- }
- }
- }
- if (isLastCred) {
- Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO().readByUser(trans, cred.value.id);
- if (rlurd.isOK()) {
- for (UserRoleDAO.Data data : rlurd.value) {
- ques.userRoleDAO().delete(trans, data, false);
- }
- }
- }
- if (udr==null) {
- return Result.err(Result.ERR_NotFound,"No User Data found");
- }
- if (udr.isOK()) {
- return Result.ok();
- }
- return Result.err(udr);
- default:
- return Result.err(fd);
- }
-
- }
-
-
@Override
public Result<Date> doesCredentialMatch(AuthzTrans trans, REQUEST credReq) {
TimeTaken tt = trans.start("Does Credential Match", Env.SUB);
}
}
- @ApiDoc(
- method = GET,
- path = "/authn/basicAuth",
- params = {},
- expectedCode = 200,
- errorCodes = { 403 },
- text = { "!!!! DEPRECATED without X509 Authentication STOP USING THIS API BY DECEMBER 2017, or use Certificates !!!!\n"
- + "Use /authn/validate instead\n"
- + "Note: Validate a Password using BasicAuth Base64 encoded Header. This HTTP/S call is intended as a fast"
- + " User/Password lookup for Security Frameworks, and responds 200 if it passes BasicAuth "
- + "security, and 403 if it does not." }
- )
- private void basicAuth() {
- // This is a place holder for Documentation. The real BasicAuth API does not call Service.
- }
-
@ApiDoc(
method = POST,
path = "/authn/validate",
return Result.err(Status.ERR_Denied,"Bad Basic Auth");
}
+@ApiDoc(
+ method = GET,
+ path = "/authn/basicAuth",
+ params = {},
+ expectedCode = 200,
+ errorCodes = { 403 },
+ text = { "!!!! DEPRECATED without X509 Authentication STOP USING THIS API BY DECEMBER 2017, or use Certificates !!!!\n"
+ + "Use /authn/validate instead\n"
+ + "Note: Validate a Password using BasicAuth Base64 encoded Header. This HTTP/S call is intended as a fast"
+ + " User/Password lookup for Security Frameworks, and responds 200 if it passes BasicAuth "
+ + "security, and 403 if it does not." }
+ )
+ private void basicAuth() {
+ // This is a place holder for Documentation. The real BasicAuth API does not call Service.
+ }
+
/***********************************
* USER-ROLE
***********************************/
final UserRoleDAO.Data userRole = urr.value;
final ServiceValidator v = new ServiceValidator();
- if (v.user_role(userRole).err() ||
+ if (v.user_role(trans.user(),userRole).err() ||
v.user(trans.org(), userRole.user).err()) {
return Result.err(Status.ERR_BadData,v.errs());
}
private Result<NsDAO.Data> nsd;
@Override
public Result<?> mayChange() {
+ if(urr.value.role.startsWith(urr.value.user)) {
+ return Result.ok((NsDAO.Data)null);
+ }
if (nsd==null) {
RoleDAO.Data r = RoleDAO.Data.decode(userRole);
nsd = ques.mayUser(trans, trans.user(), r, Access.write);
return nsd;
}
});
- Result<NsDAO.Data> nsr = ques.deriveNs(trans, userRole.role);
- if (nsr.notOKorIsEmpty()) {
- return Result.err(nsr);
+
+ NsDAO.Data ndd;
+ if(userRole.role.startsWith(userRole.user)) {
+ userRole.ns=userRole.user;
+ userRole.rname="user";
+ ndd = null;
+ } else {
+ Result<NsDAO.Data> nsr = ques.deriveNs(trans, userRole.role);
+ if (nsr.notOK()) {
+ return Result.err(nsr);
+ }
+ ndd = nsr.value;
}
switch(fd.status) {
case OK:
Result<String> rfc = func.createFuture(trans, fd.value, userRole.user+'|'+userRole.ns + '.' + userRole.rname,
- userRole.user, nsr.value, FUTURE_OP.C);
+ userRole.user, ndd, FUTURE_OP.C);
if (rfc.isOK()) {
return Result.err(Status.ACC_Future, "UserRole [%s - %s.%s] is saved for future processing",
userRole.user,
return Result.ok(users);
}
- /***********************************
+/***********************************
* HISTORY
***********************************/
@Override
}
// May user see Namespace of Permission (since it's only one piece... we can't check for "is permission part of")
- Result<NsDAO.Data> rnd = ques.deriveNs(trans,type);
- if (rnd.notOK()) {
- return Result.err(rnd);
+ Result<List<HistoryDAO.Data>> resp;
+ if(type.startsWith(trans.user())) {
+ resp = ques.historyDAO().readBySubject(trans, type, "perm", yyyymm);
+ } else {
+ Result<NsDAO.Data> rnd = ques.deriveNs(trans,type);
+ if (rnd.notOK()) {
+ return Result.err(rnd);
+ }
+ rnd = ques.mayUser(trans, trans.user(), rnd.value, Access.read);
+ if (rnd.notOK()) {
+ return Result.err(rnd);
+ }
+ resp = ques.historyDAO().readBySubject(trans, type, "perm", yyyymm);
}
- rnd = ques.mayUser(trans, trans.user(), rnd.value, Access.read);
- if (rnd.notOK()) {
- return Result.err(rnd);
- }
- Result<List<HistoryDAO.Data>> resp = ques.historyDAO().readBySubject(trans, type, "perm", yyyymm);
if (resp.notOK()) {
return Result.err(resp);
}
@Override
public Result<HISTORY> getHistoryByNS(AuthzTrans trans, String ns, int[] yyyymm, final int sort) {
final Validator v = new ServiceValidator();
- if (v.nullOrBlank("NS",ns)
- .err()) {
+ if (v.nullOrBlank("NS",ns).err()) {
return Result.err(Status.ERR_BadData,v.errs());
}
return mapper.history(trans, resp.value,sort);
}
+ @Override
+ public Result<HISTORY> getHistoryBySubject(AuthzTrans trans, String subject, String target, int[] yyyymm, final int sort) {
+ NsDAO.Data ndd = new NsDAO.Data();
+ ndd.name = FQI.reverseDomain(subject);
+ Result<Data> rnd = ques.mayUser(trans, trans.user(), ndd, Access.read);
+ if (rnd.notOK()) {
+ return Result.err(rnd);
+ }
+
+ Result<List<HistoryDAO.Data>> resp = ques.historyDAO().readBySubject(trans, subject, target, yyyymm);
+ if (resp.notOK()) {
+ return Result.err(resp);
+ }
+ return mapper.history(trans, resp.value,sort);
+ }
+
/***********************************
* DELEGATE
***********************************/
* @param from
* @return
*/
- Result<Void> changeUserCred(AuthzTrans trans, REQUEST from);
+ Result<Void> resetUserCred(AuthzTrans trans, REQUEST from);
/**
*
*/
public Result<HISTORY> getHistoryByNS(AuthzTrans trans, String subj, int[] yyyymm, int sort);
+ /**
+ *
+ * @param trans
+ * @param target
+ * @param yyyymm
+ * @param sort
+ * @return
+ */
+ public Result<HISTORY> getHistoryBySubject(AuthzTrans trans, String subject, String target, int[] yyyymm, int sort);
+
/***********************************
* DELEGATE
***********************************/
*/
public void dbReset(AuthzTrans trans);
-
-
-
}
}
}
});
+
+ /**
+ * Get History by Subject
+ */
+ authzAPI.route(GET,"/authz/hist/subject/:type/:subject",API.HISTORY,new Code(facade,"Get History by Perm Type", true) {
+ @Override
+ public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {
+ int[] years;
+ int descend;
+ try {
+ years = getYears(req);
+ descend = decending(req);
+ } catch (Exception e) {
+ context.error(trans, resp, Result.err(Status.ERR_BadData, e.getMessage()));
+ return;
+ }
+
+ Result<Void> r = context.getHistoryBySubject(trans, resp, pathParam(req,":type"), pathParam(req,":subject"),years,descend);
+ switch(r.status) {
+ case OK:
+ resp.setStatus(HttpStatus.OK_200);
+ break;
+ default:
+ context.error(trans,resp,r);
+ }
+ }
+ });
}
// Check if Ascending
*/
public abstract Result<Void> getHistoryByUser(AuthzTrans trans, HttpServletResponse resp, String user, int[] yyyymm, final int sort);
- public abstract Result<Void> getHistoryByRole(AuthzTrans trans, HttpServletResponse resp, String subject, int[] yyyymm, final int sort);
+ public abstract Result<Void> getHistoryByRole(AuthzTrans trans, HttpServletResponse resp, String role, int[] yyyymm, final int sort);
- public abstract Result<Void> getHistoryByPerm(AuthzTrans trans, HttpServletResponse resp, String subject, int[] yyyymm, final int sort);
+ public abstract Result<Void> getHistoryByPerm(AuthzTrans trans, HttpServletResponse resp, String perm, int[] yyyymm, final int sort);
- public abstract Result<Void> getHistoryByNS(AuthzTrans trans, HttpServletResponse resp, String subject, int[] yyyymm, final int sort);
+ public abstract Result<Void> getHistoryByNS(AuthzTrans trans, HttpServletResponse resp, String ns, int[] yyyymm, final int sort);
- /*
+ public abstract Result<Void> getHistoryBySubject(AuthzTrans trans, HttpServletResponse resp, String type, String subject, int[] yyyymm, int sort);
+
+ /*
* Cache
*/
public abstract Result<Void> cacheClear(AuthzTrans trans, String pathParam);
import java.io.IOException;
import java.lang.reflect.Method;
+import java.util.ArrayList;
import java.util.Date;
+import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
if (result.variables==null) {
detail = new String[1];
} else {
- int l = result.variables.length;
- detail=new String[l+1];
- System.arraycopy(result.variables, 0, detail, 1, l);
+ List<String> dlist = new ArrayList<String>();
+ String os;
+ for(Object s : result.variables) {
+ if(s!=null && (os=s.toString()).length()>0) {
+ dlist.add(os);
+ }
+ }
+ detail = new String[dlist.size()];
+ dlist.toArray(detail);
}
//int httpstatus;
break;
case ERR_ChoiceNeeded:
msgId = "SVC1300";
- detail = new String[result.variables.length];
- for(int i=0; i<result.variables.length;++i) {
- detail[i]=result.variables[i].toString();
- }
response.setStatus(/*httpstatus=*/300);
break;
case ERR_Backend:
Question.logEncryptTrace(trans,data.asString());
}
- return service.changeUserCred(trans, data.asObject());
+ return service.resetUserCred(trans, data.asObject());
} catch (APIException e) {
trans.error().log(e,"Bad Input data");
return Result.err(Status.ERR_BadData, e.getLocalizedMessage());
public static final String GET_HISTORY_ROLE = "getHistoryByRole";
public static final String GET_HISTORY_PERM = "getHistoryByPerm";
public static final String GET_HISTORY_NS = "getHistoryByNS";
+ public static final String GET_HISTORY_SUBJECT = "getHistoryBySubject";
/* (non-Javadoc)
* @see com.att.authz.facade.AuthzFacade#getHistoryByUser(org.onap.aaf.auth.env.test.AuthzTrans, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
}
}
+ /* (non-Javadoc)
+ * @see com.att.authz.facade.AuthzFacade#getHistoryByUser(org.onap.aaf.auth.env.test.AuthzTrans, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ @Override
+ public Result<Void> getHistoryBySubject(AuthzTrans trans, HttpServletResponse resp, String subject, String target, int[] yyyymm, final int sort) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(GET_HISTORY_SUBJECT);
+ sb.append(' ');
+ sb.append(subject);
+ sb.append(" for ");
+ boolean first = true;
+ for (int i : yyyymm) {
+ if (first) {
+ first = false;
+ } else {
+ sb.append(',');
+ }
+ sb.append(i);
+ }
+ TimeTaken tt = trans.start(sb.toString(), Env.SUB|Env.ALWAYS);
+
+ try {
+ Result<HISTORY> rh = service.getHistoryBySubject(trans,subject,target,yyyymm,sort);
+ switch(rh.status) {
+ case OK:
+ RosettaData<HISTORY> data = historyDF.newData(trans).load(rh.value);
+ if (Question.willSpecialLog(trans, trans.user())) {
+ Question.logEncryptTrace(trans,data.asString());
+ }
+
+ data.to(resp.getOutputStream());
+ setContentType(resp,historyDF.getOutType());
+ return Result.ok();
+ default:
+ return Result.err(rh);
+ }
+ } catch (Exception e) {
+ trans.error().log(e,IN,GET_HISTORY_USER);
+ return Result.err(e);
+ } finally {
+ tt.done();
+ }
+ }
+
public final static String CACHE_CLEAR = "cacheClear ";
// public final static String CACHE_VALIDATE = "validateCache";
import org.onap.aaf.auth.dao.cass.CertDAO;
import org.onap.aaf.auth.dao.cass.CredDAO;
import org.onap.aaf.auth.dao.cass.DelegateDAO;
+import org.onap.aaf.auth.dao.cass.DelegateDAO.Data;
import org.onap.aaf.auth.dao.cass.FutureDAO;
import org.onap.aaf.auth.dao.cass.HistoryDAO;
import org.onap.aaf.auth.dao.cass.Namespace;
import org.onap.aaf.auth.dao.cass.RoleDAO;
import org.onap.aaf.auth.dao.cass.Status;
import org.onap.aaf.auth.dao.cass.UserRoleDAO;
-import org.onap.aaf.auth.dao.cass.DelegateDAO.Data;
import org.onap.aaf.auth.dao.hl.Question;
import org.onap.aaf.auth.dao.hl.Question.Access;
import org.onap.aaf.auth.env.AuthzTrans;
import org.onap.aaf.auth.rserv.Pair;
import org.onap.aaf.auth.service.MayChange;
import org.onap.aaf.cadi.aaf.marshal.CertsMarshal;
+import org.onap.aaf.cadi.util.Split;
import org.onap.aaf.cadi.util.Vars;
import org.onap.aaf.misc.env.Env;
import org.onap.aaf.misc.env.TimeTaken;
@Override
public Result<PermDAO.Data> perm(AuthzTrans trans, Request req) {
PermRequest from = (PermRequest)req;
- Result<NsSplit> nss = q.deriveNsSplit(trans, from.getType());
+ String type = from.getType();
+ if(type==null) {
+ return Result.err(Result.ERR_BadData, "Invalid Perm Type");
+ }
PermDAO.Data pd = new PermDAO.Data();
- if (nss.isOK()) {
- pd.ns=nss.value.ns;
- pd.type = nss.value.name;
- pd.instance = from.getInstance();
- pd.action = from.getAction();
- pd.description = from.getDescription();
- trans.checkpoint(pd.fullPerm(), Env.ALWAYS);
- return Result.ok(pd);
- } else {
- return Result.err(nss);
+ if(type.contains("@")) {
+ String[] split = Split.splitTrim(':', type);
+ pd.ns = split[0];
+ pd.type=split.length>1?split[1]:"";
+ pd.instance = from.getInstance();
+ pd.action = from.getAction();
+ pd.description = from.getDescription();
+ return Result.ok(pd);
+ } else {
+ Result<NsSplit> nss = q.deriveNsSplit(trans, from.getType());
+ if (nss.isOK()) {
+ pd.ns=nss.value.ns;
+ pd.type = nss.value.name;
+ pd.instance = from.getInstance();
+ pd.action = from.getAction();
+ pd.description = from.getDescription();
+ trans.checkpoint(pd.fullPerm(), Env.ALWAYS);
+ return Result.ok(pd);
+ } else {
+ return Result.err(nss);
+ }
}
}
if (pd==null) {
msg("Perm Data is null.");
} else {
- ns(pd.ns);
+ if(!pd.ns.contains("@")) {
+ ns(pd.ns);
+ }
permType(pd.type,pd.ns);
permInstance(pd.instance);
permAction(pd.action);
}
return this;
}
-
+
public ServiceValidator role(RoleDAO.Data pd) {
if (pd==null) {
msg("Role Data is null.");
return this;
}
+ public ServiceValidator user_role(String user, UserRoleDAO.Data urdd) {
+ role(user,urdd.role);
+ if(!urdd.role.startsWith(user)) {
+ nullOrBlank("UserRole.ns",urdd.ns);
+ nullOrBlank("UserRole.rname",urdd.rname);
+ }
+ return this;
+ }
+
+
public ServiceValidator user_role(UserRoleDAO.Data urdd) {
if (urdd==null) {
msg("UserRole is null");
#
. ./d.props
-${DOCKER:=docker} exec -it aaf-$1 bash -c "cd /opt/app/osaaf/logs && exec bash"
+${DOCKER:=docker} exec -it aaf-$1 bash -c "cd /opt/app && exec bash"
--- /dev/null
+#!/bin/bash
+#########
+# ============LICENSE_START====================================================
+# org.onap.aaf
+# ===========================================================================
+# Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+# ===========================================================================
+# 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.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END====================================================
+#
+# This is only called from HEAT, as it needs a single check and wait for Cassandra to be ready
+#
+cd ../auth-cass/docker
+. dinstall.sh $@
+cd -
+if [ "$1" = "publish" ]; then
+ shift
+fi
+. drun.sh
--env aaf_locator_container_ns=${NAMESPACE} \
--env aaf_locator_fqdn=${HOSTNAME} \
--env aaf_locator_public_fqdn=${HOSTNAME} \
+ --env aaf_deployed_version=${VERSION} \
--env LATITUDE=${LATITUDE} \
--env LONGITUDE=${LONGITUDE} \
--env CASSANDRA_CLUSTER=${CASSANDRA_CLUSTER} \
-. ../../docker/d.props
+. ../../docker/aaf.props
IMAGE=onap/aaf/aaf_agent:$VERSION
kubectl -n onap run -it --rm aaf-agent-$USER --image=$IMAGE --overrides='
# When using Docker Repo, add, and include trailing "/"
# repository: nexus3.onap.org:10003/
# repository: localhost:5000/
- version: 2.1.12-SNAPSHOT
+ version: 2.1.14-SNAPSHOT
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
appVersion: "1.0"
description: AAF Helm Chart
name: aaf
-version: 2.1.12-SNAPSHOT
+version: 2.1.14-SNAPSHOT
value: "{{.Values.services.aaf_locator_name}}"
- name: aaf_locator_name_helm
value: "{{.Values.services.aaf_locator_name_helm}}"
+ - name: aaf_deployed_version
+ value: "{{ .Values.image.version }}"
- name: CASSANDRA_CLUSTER
value: "{{.Values.services.cass.fqdn}}.{{.Values.services.ns}}"
# - name: CASSANDRA_USER
# Set from CAP Based PROPS, if necessary
aaf_env=${aaf_env:-"${AAF_ENV}"}
-aaf_release=${aaf_release:-"${VERSION}"}
+aaf_deployed_version=${aaf_deployed_version:-"${VERSION}"}
cadi_latitude=${cadi_latitude:-"${LATITUDE}"}
cadi_longitude=${cadi_longitude:-"${LONGITUDE}"}
cadi_x509_issuers=${cadi_x509_issuers:-"${CADI_X509_ISSUERS}"}
-aaf|aaf_env|DEV
-aaf|aaf_oauth2_introspect_url|https://AAF_LOCATE_URL/%CNS.%AAF_NS.introspect:2.1/introspect
-aaf|aaf_oauth2_token_url|https://AAF_LOCATE_URL/%CNS.%AAF_NS.token:2.1/token
-aaf|aaf_url|https://AAF_LOCATE_URL/%CNS.%AAF_NS.service:2.1
-aaf|cadi_protocols|TLSv1.1,TLSv1.2
-aaf|cadi_x509_issuers|CN=intermediateCA_1, OU=OSAAF, O=ONAP, C=US:CN=intermediateCA_7, OU=OSAAF, O=ONAP, C=US:CN=intermediateCA_9, OU=OSAAF, O=ONAP, C=US
-aaf|cm_url|https://AAF_LOCATE_URL/%CNS.%AAF_NS.cm:2.1
-aaf|fs_url|https://AAF_LOCATE_URL/%CNS.%AAF_NS.fs:2.1
-aaf|gui_url|https://AAF_LOCATE_URL/%CNS.%AAF_NS.gui:2.1
+aaf,aaf_cm_url,https://AAF_LOCATE_URL/%CNS.%AAF_NS.cm:2.1\r
+aaf,aaf_env,DEV\r
+aaf,aaf_fs_url,https://AAF_LOCATE_URL/%CNS.%AAF_NS.fs:2.1\r
+aaf,aaf_gui_url,https://AAF_LOCATE_URL/%CNS.%AAF_NS.gui:2.1\r
+aaf,aaf_locate_url,https://aaf.dev.att.com:8095\r
+aaf,aaf_oauth2_introspect_url,https://AAF_LOCATE_URL/%CNS.%AAF_NS.introspect:2.1/introspect\r
+aaf,aaf_oauth2_token_url,https://AAF_LOCATE_URL/%CNS.%AAF_NS.token:2.1/token\r
+aaf,aaf_oauth_url,https://AAF_LOCATE_URL/%CNS.%AAF_NS.oauth:2.1\r
+aaf,aaf_root_ns,com.att.aaf\r
+aaf,aaf_url,https://AAF_LOCATE_URL/%CNS.%AAF_NS.service:2.1\r
+aaf,cadi_protocols,"TLSv1.1,TLSv1.2"\r
+aaf,cadi_x509_issuers,"CN=intermediateCA_1, OU=OSAAF, O=ONAP, C=US:CN=intermediateCA_7, OU=OSAAF, O=ONAP, C=US:CN=intermediateCA_9, OU=OSAAF, O=ONAP, C=US"\r
* If you want a simple field comparison, it is faster without REGEX
*/
public boolean match(Permission p) {
+ if(p==null) {
+ return false;
+ }
String aafNS;
String aafType;
String aafInstance;
List<SecuritySetter<HttpURLConnection>> lss = loadSetters(access,si);
/////////
String directAAFURL = aaf_urls.get(Config.AAF_URL);
- if(directAAFURL!=null && !directAAFURL.contains("/locate/")) {
+ if(directAAFURL!=null && !directAAFURL.contains("/locate/") || !directAAFURL.contains("AAF_LOCATE_URL")) {
print(true,"Test Connections by non-located aaf_url");
Locator<URI> locator = new SingleEndpointLocator(directAAFURL);
connectTest(locator,new URI(directAAFURL));
public StringBuilder toMsg(StringBuilder sb, Error err) {
sb.append(err.getMessageId());
sb.append(' ');
- String[] vars = new String[err.getVariables().size()];
+ Object[] vars = new String[err.getVariables().size()];
err.getVariables().toArray(vars);
Vars.convert(sb, err.getText(),vars);
return sb;
}
+
+ public Error getError(Future<?> future) throws APIException {
+ return errDF.newData().in(TYPE.JSON).load(future.body()).asObject();
+ }
}
return "AAF Inaccessible";
case UNVALIDATED:
addUser(new User<AAFPermission>(user,bytes,con.timeout));
- return "User/Pass combo invalid for " + user;
+ return "user/pass combo invalid for " + user;
case DENIED:
return "AAF denies API for " + user;
default:
// Note: Either Carbon or Silicon based LifeForms ok
String authz = req.getHeader("Authorization");
+ String target = "invalid";
if (authz != null && authz.startsWith("Basic ")) {
if (warn&&!req.isSecure()) {
aaf.access.log(Level.WARN,"WARNING! BasicAuth has been used over an insecure channel");
Miss miss = missed(bp.getName(), bp.getCred());
if (miss!=null && !miss.mayContinue()) {
- return new BasicHttpTafResp(aaf.access,null,buildMsg(bp,req,
+ return new BasicHttpTafResp(aaf.access,bp.getName(),buildMsg(bp,req,
"User/Pass Retry limit exceeded"),
RESP.TRY_AUTHENTICATING,resp,aaf.getRealm(),true);
}
// Note: AddMiss checks for miss==null, and is part of logic
boolean rv= addMiss(bp.getName(),bp.getCred());
if (rv) {
- return new BasicHttpTafResp(aaf.access,null,buildMsg(bp,req,
+ return new BasicHttpTafResp(aaf.access,bp.getName(),buildMsg(bp,req,
"user/pass combo invalid via AAF from " + req.getRemoteAddr()),
RESP.TRY_AUTHENTICATING,resp,aaf.getRealm(),true);
} else {
- return new BasicHttpTafResp(aaf.access,null,buildMsg(bp,req,
+ return new BasicHttpTafResp(aaf.access,bp.getName(),buildMsg(bp,req,
"user/pass combo invalid via AAF from " + req.getRemoteAddr() + " - Retry limit exceeded"),
RESP.FAIL,resp,aaf.getRealm(),true);
}
} catch (IOException e) {
String msg = buildMsg(null,req,"Invalid Auth Token");
aaf.access.log(Level.WARN,msg,'(', e.getMessage(), ')');
- return new BasicHttpTafResp(aaf.access,null,msg, RESP.TRY_AUTHENTICATING, resp, aaf.getRealm(),true);
+ return new BasicHttpTafResp(aaf.access,target,msg, RESP.TRY_AUTHENTICATING, resp, aaf.getRealm(),true);
} catch (Exception e) {
String msg = buildMsg(null,req,"Authenticating Service unavailable");
try {
aaf.access.log(e1, "Error Invalidating Client");
}
aaf.access.log(Level.WARN,msg,'(', e.getMessage(), ')');
- return new BasicHttpTafResp(aaf.access,null,msg, RESP.FAIL, resp, aaf.getRealm(),false);
+ return new BasicHttpTafResp(aaf.access,target,msg, RESP.FAIL, resp, aaf.getRealm(),false);
}
}
- return new BasicHttpTafResp(aaf.access,null,"Requesting HTTP Basic Authorization",RESP.TRY_AUTHENTICATING,resp,aaf.getRealm(),false);
+ return new BasicHttpTafResp(aaf.access,target,"Requesting HTTP Basic Authorization",RESP.TRY_AUTHENTICATING,resp,aaf.getRealm(),false);
}
private String buildMsg(Principal pr, HttpServletRequest req, Object... msg) {
}
public static Locator<URI> create(final String name, final String version) throws LocatorException {
+ if(locatorCreator==null) {
+ throw new LocatorException("LocatorCreator is not set");
+ }
return locatorCreator.create(name, version);
}
@Override
public Item best() throws LocatorException {
if (!hasItems()) {
- throw new LocatorException("No Entries found for '" + aaf_locator_uri.toString() + "/locate/" + name + ':' + version + '\'');
+ throw new LocatorException("No Entries found for '" + aaf_locator_uri.toString() + '/' + name + ':' + version + '\'');
}
List<EP> lep = new ArrayList<>();
EP first = null;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.InetAddress;
+import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
import java.util.ArrayDeque;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Deque;
import java.util.GregorianCalendar;
import locate.v1_1.Configuration.Props;
public class Agent {
- private static final String HASHES = "################################################################";
+ private static final String AGENT_LOAD_URLS = "Agent:loadURLs";
+ private static final String HASHES = "################################################################";
private static final String PRINT = "print";
private static final String FILE = "file";
public static final String PKCS12 = "pkcs12";
aafsso.setLogDefault();
aafsso.setStdErrDefault();
- Map<String, String> aaf_urls = loadURLs(access);
- aafsso.addProp(Config.AAF_URL_CM, aaf_urls.get(Config.AAF_URL_CM));
+ /*urls=*/loadURLs(access);
aafsso.writeFiles();
}
String dot_le = access.getProperty(Config.AAF_LOCATOR_CONTAINER,null);
dot_le=dot_le==null?"":'.'+dot_le;
String version = access.getProperty(Config.AAF_API_VERSION,Config.AAF_DEFAULT_API_VERSION);
- for(String u : new String[] {"aaf","locate","oauth","cm","gui","fs","hello","token","introspect"}) {
- String proto = "fs".equals(u)?"http://":"https://";
- String lhost;
- if("locate".equals(u)) {
- lhost=rph.default_fqdn;
- } else {
- lhost=Config.AAF_LOCATE_URL_TAG;
- }
- String value = rph.replacements("Agent:loadURLs",
- proto + lhost + "/%CNS.%AAF_NS." + ("aaf".equals(u)?"service":u) + ':' + version,
- null,dot_le);
+ for(String u : new String[] {"locate","aaf","oauth","cm","gui","fs","hello","token","introspect"}) {
+ String tag;
+ String append=null;
switch(u) {
- case "aaf": rv.put(Config.AAF_URL, value); break;
- case "locate": rv.put(Config.getAAFLocateUrl(access), value); break;
- case "token": rv.put(Config.AAF_OAUTH2_TOKEN_URL, value); break;
- case "introspect": rv.put(Config.AAF_OAUTH2_INTROSPECT_URL, value); break;
- case "cm": rv.put(Config.AAF_URL_CM, value); break;
- case "gui": rv.put(Config.AAF_URL_GUI, value); break;
- case "fs": rv.put(Config.AAF_URL_FS, value); break;
- case "hello": rv.put(Config.AAF_URL_HELLO, value); break;
+ case "aaf": tag = Config.AAF_URL; break;
+ case "locate":tag = Config.AAF_LOCATE_URL; break;
+ case "oauth": tag = Config.AAF_URL_OAUTH; break;
+ case "token": tag = Config.AAF_OAUTH2_TOKEN_URL; append="/token"; break;
+ case "introspect": tag = Config.AAF_OAUTH2_INTROSPECT_URL; append="/introspect"; break;
+ case "cm": tag = Config.AAF_URL_CM; break;
+ case "gui": tag = Config.AAF_URL_GUI; break;
+ case "fs": tag = Config.AAF_URL_FS; break;
+ case "hello": tag = Config.AAF_URL_HELLO; break;
default:
- rv.put("aaf_url_" + u, value);
+ tag = "aaf_url_" + u;
+ }
+ String value;
+ if((value=access.getProperty(tag,null))==null) {
+ String proto = "fs".equals(u)?"http://":"https://";
+ String lhost;
+ if("locate".equals(u)) {
+ lhost=rph.default_fqdn;
+ } else {
+ lhost=Config.AAF_LOCATE_URL_TAG;
+ }
+ value = rph.replacements(AGENT_LOAD_URLS,
+ proto + lhost + "/%CNS.%AAF_NS." + ("aaf".equals(u)?"service":u) + ':' + version,
+ null,dot_le);
+ if(append!=null) {
+ value+=append;
+ }
+ } else {
+ value = rph.replacements(AGENT_LOAD_URLS, value,null,dot_le);
}
+ rv.put(tag, value);
};
aaf_urls = rv;
}
private static String fqi(Deque<String> cmds) {
if (cmds.size()<1) {
String alias = env.getProperty(Config.CADI_ALIAS);
+ if(alias==null) {
+ alias = env.getProperty(Config.AAF_APPID);
+ }
return alias!=null?alias:AAFSSO.cons.readLine("AppID: ");
}
return cmds.removeFirst();
app.add(Config.AAF_LOCATE_URL, Config.getAAFLocateUrl(propAccess));
app.add(Config.AAF_ENV,propAccess, "DEV");
- String release = propAccess.getProperty(Config.AAF_RELEASE);
+ String release = propAccess.getProperty(Config.AAF_DEPLOYED_VERSION);
+ if(release==null) {
+ release = System.getProperty(Config.AAF_DEPLOYED_VERSION,null);
+ }
if(release!=null) {
- app.add(Config.AAF_RELEASE, release);
+ app.add(Config.AAF_DEPLOYED_VERSION, release);
}
for(Entry<Object, Object> aaf_loc_prop : propAccess.getProperties().entrySet()) {
String key = aaf_loc_prop.getKey().toString();
} else {
aafcon = aafcon(propAccess);
if (aafcon!=null) { // get Properties from Remote AAF
- final String locator = getProperty(propAccess,aafcon.env,false,Config.AAF_LOCATE_URL,"AAF Locator URL: ");
-
- Future<Configuration> acf = aafcon.client(new SingleEndpointLocator(locator))
- .read("/configure/"+fqi+"/aaf", configDF);
- if (acf.get(TIMEOUT)) {
- for (Props props : acf.value.getProps()) {
- PropHolder ph = CRED_TAGS.contains(props.getTag())?cred:app;
- if(props.getTag().endsWith("_password")) {
- ph.addEnc(props.getTag(), props.getValue());
- } else {
- ph.add(props.getTag(), props.getValue());
- }
- }
- } else if (acf.code()==401){
- trans.error().log("Bad Password sent to AAF");
- } else if (acf.code()==404){
- trans.error().log("This version of AAF does not support remote Properties");
- } else {
- trans.error().log(errMsg.toMsg(acf));
+ for (Props props : aafProps(trans,aafcon,getProperty(propAccess,aafcon.env,false,Config.AAF_LOCATE_URL,"AAF Locator URL: "),fqi)) {
+ PropHolder ph = CRED_TAGS.contains(props.getTag())?cred:app;
+ if(props.getTag().endsWith("_password")) {
+ ph.addEnc(props.getTag(), props.getValue());
+ } else {
+ ph.add(props.getTag(), props.getValue());
+ }
}
+
}
}
}
}
}
+ public static List<Props> aafProps(Trans trans, AAFCon<?> aafcon, String locator, String fqi) throws CadiException, APIException, URISyntaxException {
+ Future<Configuration> acf = aafcon.client(new SingleEndpointLocator(locator))
+ .read("/configure/"+fqi+"/aaf", configDF);
+ if (acf.get(TIMEOUT)) {
+ return acf.value.getProps();
+ } else if (acf.code()==401){
+ trans.error().log("Bad Password sent to AAF");
+ } else if (acf.code()==404){
+ trans.error().log("This version of AAF does not support remote Properties");
+ } else {
+ trans.error().log(errMsg.toMsg(acf));
+ }
+ return new ArrayList<>();
+ }
private static void validate(final PropAccess pa) throws LocatorException, CadiException, APIException {
System.out.println("Validating Configuration...");
X509Certificate x509;
List<X509Certificate> chainList = new ArrayList<>();
Set<X509Certificate> caSet = new HashSet<>();
+ X509Certificate curr = null;
for (Certificate c : certColl) {
x509 = (X509Certificate)c;
// Is a Root (self-signed, anyway)
if (x509.getSubjectDN().equals(x509.getIssuerDN())) {
caSet.add(x509);
} else {
- chainList.add(x509);
+ // Expect Certs in Trust Chain Order.
+ if(curr==null) {
+ chainList.add(x509);
+ curr=x509;
+ } else {
+ // Only Add Cert next on the list
+ if(curr.getIssuerDN().equals(x509.getSubjectDN())) {
+ chainList.add(x509);
+ curr=x509;
+ }
+ }
}
}
-// chainList.addAll(caSet);
- //Collections.reverse(chainList);
// Properties, etc
// Add CADI Keyfile Entry to Properties
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
public class TokenClientFactory extends Persist<Token,TimedToken> {
private static TokenClientFactory instance;
+ private final Set<String> alts;
private Map<String,AAFConHttp> aafcons = new ConcurrentHashMap<>();
private SecurityInfoC<HttpURLConnection> hsi;
// Package on purpose
private TokenClientFactory(Access pa) throws APIException, GeneralSecurityException, IOException, CadiException {
super(pa, new RosettaEnv(pa.getProperties()),Token.class,"outgoing");
+
Map<String, String> aaf_urls = Agent.loadURLs(pa);
+ alts = new TreeSet<>();
+
if (access.getProperty(Config.AAF_OAUTH2_TOKEN_URL,null)==null) {
access.getProperties().put(Config.AAF_OAUTH2_TOKEN_URL, aaf_urls.get(Config.AAF_OAUTH2_TOKEN_URL)); // Default to AAF
}
+
if (access.getProperty(Config.AAF_OAUTH2_INTROSPECT_URL,null)==null) {
access.getProperties().put(Config.AAF_OAUTH2_INTROSPECT_URL, aaf_urls.get(Config.AAF_OAUTH2_INTROSPECT_URL)); // Default to AAF);
}
-
+
+ for(String tag : new String[] {Config.AAF_ALT_OAUTH2_TOKEN_URL, Config.AAF_ALT_OAUTH2_INTROSPECT_URL}) {
+ String value = access.getProperty(tag, null);
+ if(value!=null) {
+ alts.add(tag);
+ alts.add(value);
+ }
+ }
+
symm = Symm.encrypt.obtain();
hsi = SecurityInfoC.instance(access, HttpURLConnection.class);
}
}
}
char okind;
- if ( Config.AAF_OAUTH2_TOKEN_URL.equals(tagOrURL) ||
- Config.AAF_OAUTH2_INTROSPECT_URL.equals(tagOrURL) ||
- tagOrURL.equals(access.getProperty(Config.AAF_OAUTH2_TOKEN_URL, null)) ||
- tagOrURL.equals(access.getProperty(Config.AAF_OAUTH2_INTROSPECT_URL, null))
- ) {
- okind = Kind.AAF_OAUTH;
- } else {
- okind = Kind.OAUTH;
- }
+ if (alts.contains(tagOrURL)) {
+ okind = Kind.OAUTH;
+ } else {
+ okind = Kind.AAF_OAUTH;
+ }
TokenClient tci = new TokenClient(
okind,
this,
*/
public TafResp validate(Taf.LifeForm reading, HttpServletRequest req, HttpServletResponse resp) {
// See if Request implements BasicCred (aka CadiWrap or other), and if User/Pass has already been set separately
- final String user;
+ String user = "invalid";
String password=null;
byte[] cred=null;
if (req instanceof BasicCred) {
} else {
access.printf(Level.AUDIT,"Malformed BasicAuth entry ip=%s, entry=%s",req.getRemoteAddr(),
access.encrypt(temp));
- return new BasicHttpTafResp(access,null,"Malformed BasicAuth entry",RESP.FAIL,resp,realm,false);
+ return new BasicHttpTafResp(access,user,"Malformed BasicAuth entry",RESP.FAIL,resp,realm,false);
}
if (!rbac.validate(user,Type.PASSWORD,password.getBytes(),req)) {
- return new BasicHttpTafResp(access,null,buildMsg(null,req,"user/pass combo invalid for ",user,"from",req.getRemoteAddr()),
+ return new BasicHttpTafResp(access,user,buildMsg(null,req,"user/pass combo invalid for ",user,"from",req.getRemoteAddr()),
RESP.TRY_AUTHENTICATING,resp,realm,true);
}
} catch (IOException e) {
access.log(e, ERROR_GETTING_TOKEN_CLIENT);
- return new BasicHttpTafResp(access,null,ERROR_GETTING_TOKEN_CLIENT,RESP.FAIL,resp,realm,false);
+ return new BasicHttpTafResp(access,user,ERROR_GETTING_TOKEN_CLIENT,RESP.FAIL,resp,realm,false);
}
} else {
- return new BasicHttpTafResp(access,null,"Not a Basic Auth",RESP.TRY_ANOTHER_TAF,resp,realm,false);
+ return new BasicHttpTafResp(access,user,"Not a Basic Auth",RESP.TRY_ANOTHER_TAF,resp,realm,false);
}
}
Result<TimedToken> rtt = pclient.content.getToken('B',scope);
if (rtt.isOK()) {
if (rtt.value.expired()) {
- return new BasicHttpTafResp(access,null,"BasicAuth/OAuth Token: Token Expired",RESP.FAIL,resp,realm,true);
+ return new BasicHttpTafResp(access,user,"BasicAuth/OAuth Token: Token Expired",RESP.FAIL,resp,realm,true);
} else {
TimedToken tt = rtt.value;
Result<OAuth2Principal> prin = tkMgr.toPrincipal(tt.getAccessToken(), cred);
if (prin.isOK()) {
return new BasicHttpTafResp(access,prin.value,"BasicAuth/OAuth Token Authentication",RESP.IS_AUTHENTICATED,resp,realm,true);
} else {
- return new BasicHttpTafResp(access,null,"BasicAuth/OAuth Token: " + prin.code + ' ' + prin.error,RESP.FAIL,resp,realm,true);
+ return new BasicHttpTafResp(access,user,"BasicAuth/OAuth Token: " + prin.code + ' ' + prin.error,RESP.FAIL,resp,realm,true);
}
}
} else {
- return new BasicHttpTafResp(access,null,"BasicAuth/OAuth Token: " + rtt.code + ' ' + rtt.error,RESP.FAIL,resp,realm,true);
+ return new BasicHttpTafResp(access,user,"BasicAuth/OAuth Token: " + rtt.code + ' ' + rtt.error,RESP.FAIL,resp,realm,true);
}
} finally {
pclient.done();
}
} catch (APIException | CadiException | LocatorException | NoSuchAlgorithmException e) {
access.log(e, ERROR_GETTING_TOKEN_CLIENT);
- return new BasicHttpTafResp(access,null,ERROR_GETTING_TOKEN_CLIENT,RESP.TRY_ANOTHER_TAF,resp,realm,false);
+ return new BasicHttpTafResp(access,user,ERROR_GETTING_TOKEN_CLIENT,RESP.TRY_ANOTHER_TAF,resp,realm,false);
}
}
}
if(specificVersion!=null) {
String split[] = Split.splitTrim('.', specificVersion);
- locate.setPkg(split.length>3?Integer.parseInt(split[3]):0);
- locate.setPatch(split.length>2?Integer.parseInt(split[2]):0);
- locate.setMinor(split.length>1?Integer.parseInt(split[1]):0);
- locate.setMajor(split.length>0?Integer.parseInt(split[0]):0);
+ String deply[]= Split.splitTrim('.', access.getProperty(Config.AAF_DEPLOYED_VERSION, ""));
+ locate.setMajor(best(split,deply,0));
+ locate.setMinor(best(split,deply,1));
+ locate.setPatch(best(split,deply,2));
+ locate.setPkg(best(split,deply,3));
}
String protocol = access.getProperty(Config.AAF_LOCATOR_PROTOCOL + dot_le, defProtocol);
return me;
}
- private StringBuilder print(StringBuilder sb, List<MgmtEndpoint> lme) {
+ /*
+ * Find the best version between Actual Interface and Deployed version
+ */
+ private int best(String[] split, String[] deploy, int i) {
+ StringBuilder sb = new StringBuilder();
+ char c;
+ String s;
+ if(split.length>i) {
+ s=split[i];
+ for(int j=0;j<s.length();++j) {
+ if(Character.isDigit(c=s.charAt(j))) {
+ sb.append(c);
+ } else {
+ break;
+ }
+ }
+ }
+
+ if(sb.length()==0 && deploy.length>i) {
+ s=deploy[i];
+ for(int j=0;j<s.length();++j) {
+ if(Character.isDigit(c=s.charAt(j))) {
+ sb.append(c);
+ } else {
+ break;
+ }
+ }
+ }
+
+ return sb.length()==0?0:Integer.parseInt(sb.toString());
+ }
+
+ private StringBuilder print(StringBuilder sb, List<MgmtEndpoint> lme) {
int cnt = 0;
for(MgmtEndpoint m : lme) {
print(sb,cnt++,m);
out.append('.');
out.append(mep.getMinor());
out.append('.');
- out.append(mep.getPkg());
- out.append('.');
out.append(mep.getPatch());
+ out.append('.');
+ out.append(mep.getPkg());
out.append("\n\tPort: ");
out.append(mep.getPort());
out.append("\n\tProtocol: ");
out.setLongitude(mep.getLongitude());
out.setMajor(mep.getMajor());
out.setMinor(mep.getMinor());
- out.setPkg(mep.getPkg());
out.setPatch(mep.getPatch());
+ out.setPkg(mep.getPkg());
out.setPort(mep.getPort());
out.setProtocol(mep.getProtocol());
out.getSpecialPorts().addAll(mep.getSpecialPorts());
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import org.onap.aaf.cadi.Access.Level;
import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.LocatorException;
import org.onap.aaf.cadi.PropAccess;
import org.onap.aaf.cadi.Symm;
import org.onap.aaf.cadi.aaf.Defaults;
+import org.onap.aaf.cadi.aaf.v2_0.AAFCon;
+import org.onap.aaf.cadi.client.Future;
import org.onap.aaf.cadi.config.Config;
import org.onap.aaf.cadi.configure.ArtifactDir;
+import org.onap.aaf.cadi.locator.SingleEndpointLocator;
import org.onap.aaf.cadi.util.MyConsole;
import org.onap.aaf.cadi.util.SubStandardConsole;
import org.onap.aaf.cadi.util.TheConsole;
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.rosetta.env.RosettaDF;
+import org.onap.aaf.misc.rosetta.env.RosettaEnv;
+
+import locate.v1_1.Configuration;
+import locate.v1_1.Configuration.Props;
public class AAFSSO {
public static final MyConsole cons = TheConsole.implemented() ? new TheConsole() : new SubStandardConsole();
appID=null;
}
+ String aaf_container_ns = "";
if (appID!=null) {
- diskprops.setProperty(Config.AAF_APPID,appID);
if( access.getProperty(Config.AAF_APPPASS)==null) {
- char[] password = cons.readPassword("Password for %s: ", appID);
+ appID = user = cons.readLine("Deployer ID [%s]: ", user);
+ access.setProperty(Config.AAF_APPID,appID);
+ char[] password = cons.readPassword("Password for %s: ", user);
if(password.length>0) {
String app_pass = access.encrypt(new String(password));
access.setProperty(Config.AAF_APPPASS,app_pass);
diskprops.setProperty(Config.AAF_APPPASS,app_pass);
}
+ aaf_container_ns = cons.readLine("Container Namespace (blank if none)? [\"\"]: ", aaf_container_ns);
}
+ diskprops.setProperty(Config.AAF_APPID,appID);
}
String keystore=access.getProperty(Config.CADI_KEYSTORE);
err.append("-D" + Config.AAF_APPPASS + "=<passwd> ");
}
- String locateUrl = Config.getAAFLocateUrl(access);
- if (locateUrl==null) {
- locateUrl=AAFSSO.cons.readLine("AAF Locator URL=https://");
- if (locateUrl==null || locateUrl.length()==0) {
- err = new StringBuilder(Config.AAF_LOCATE_URL);
- err.append(" is required.");
- ok = false;
- return;
- } else {
- locateUrl="https://"+locateUrl;
- }
- access.setProperty(Config.AAF_LOCATE_URL, locateUrl);
- addProp(Config.AAF_LOCATE_URL, locateUrl);
- }
-
- final String apiVersion = access.getProperty(Config.AAF_API_VERSION, Config.AAF_DEFAULT_API_VERSION);
- final String aaf_root_ns = access.getProperty(Config.AAF_ROOT_NS);
- String locateRoot;
- if(aaf_root_ns==null) {
- locateRoot=Defaults.AAF_ROOT;
- } else {
- locateRoot = Defaults.AAF_LOCATE_CONST + "/%CNS." + aaf_root_ns;
- }
- if(access.getProperty(Config.AAF_URL)==null) {
-
- access.setProperty(Config.AAF_URL, locateRoot+".service:"+apiVersion);
- }
- if(access.getProperty(Config.AAF_URL_CM)==null) {
- access.setProperty(Config.AAF_URL_CM, locateRoot+".cm:"+apiVersion);
- }
String cadiLatitude = access.getProperty(Config.CADI_LATITUDE);
if (cadiLatitude==null) {
System.out.println("# If you do not know your Global Coordinates, we suggest bing.com/maps");
}
ok = err==null;
}
+ String locateUrl = Config.getAAFLocateUrl(access);
+ if (locateUrl==null) {
+ locateUrl=AAFSSO.cons.readLine("AAF Locator URL=https://");
+ if (locateUrl==null || locateUrl.length()==0) {
+ err = new StringBuilder(Config.AAF_LOCATE_URL);
+ err.append(" is required.");
+ ok = false;
+ return;
+ } else {
+ locateUrl="https://"+locateUrl;
+ }
+ access.setProperty(Config.AAF_LOCATE_URL, locateUrl);
+ addProp(Config.AAF_LOCATE_URL, locateUrl);
+ try {
+ if(access.getProperty(Config.AAF_URL)==null) {
+ access.setProperty(Config.AAF_URL, "https://AAF_LOCATE/AAF_NS.service:2.1");
+ }
+ AAFCon<?> aafCon = AAFCon.newInstance(access);
+ Future<Configuration> acf;
+ RosettaDF<Configuration> configDF = new RosettaEnv().newDataFactory(Configuration.class);
+ acf = aafCon.client(new SingleEndpointLocator(locateUrl))
+ .read("/configure/"+user+"/aaf", configDF);
+ if (acf.get(aafCon.connTimeout)) {
+ for(Props p : acf.value.getProps()) {
+ addProp(p.getTag(),p.getValue());
+ if(access.getProperty(p.getTag())==null) {
+ access.setProperty(p.getTag(), p.getValue());
+ }
+ }
+ } else {
+ access.log(Level.INFO,acf.body());
+ }
+ } catch (LocatorException | APIException | URISyntaxException e) {
+ access.log(e);
+ }
+ }
+
+ final String apiVersion = access.getProperty(Config.AAF_API_VERSION, Config.AAF_DEFAULT_API_VERSION);
+ final String aaf_root_ns = access.getProperty(Config.AAF_ROOT_NS);
+ String locateRoot;
+ if(aaf_root_ns==null) {
+ locateRoot=Defaults.AAF_ROOT;
+ } else {
+ locateRoot = Defaults.AAF_LOCATE_CONST + "/%CNS." + aaf_root_ns;
+ }
+ if(access.getProperty(Config.AAF_URL)==null) {
+ access.setProperty(Config.AAF_URL, locateRoot+".service:"+apiVersion);
+ }
+
writeFiles();
}
Future<String> futureObj = Mockito.mock(Future.class);
Mockito.doReturn(futureObj).when(rcliObj).read( "/authn/basicAuth","text/plain");
realm = authnObj.validate("test", "test","test");
- assertTrue(realm.contains("User/Pass combo invalid"));
+ assertTrue(realm.contains("user/pass combo invalid"));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
AFT_LATITUDE=32.780140
AFT_LONGITUDE=-96.800451
AFT_ENVIRONMENT=AFTUAT
-DEPLOYED_VERSION=2.0.MITHRIL
+aaf_deployed_version=2.0.MITHRIL
cadi_prop_files=/opt/app/aaf/common/com.att.aaf.props
#cadi_keystore=/Volumes/Data/src/authz/common/cadiaaf.jks
public class PropAccess implements Access {
// Sonar says cannot be static... it's ok. not too many PropAccesses created.
- private final SimpleDateFormat iso8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+ private final SimpleDateFormat iso8601 = newISO8601();
+
+ public static SimpleDateFormat newISO8601() {
+ return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+ }
public static final Level DEFAULT = Level.AUDIT;
init(nprops);
}
- protected void init(Properties p) {
+ protected synchronized void init(Properties p) {
// Make sure these two are set before any changes in Logging
name = "cadi";
level=DEFAULT.maskOf();
}
}
- protected StringBuilder buildMsg(Level level, Object[] elements) {
+ public StringBuilder buildMsg(Level level, Object[] elements) {
return buildMsg(name,iso8601,level,elements);
}
-
+
+ /*
+ * Need to pass in DateFormat per thread, because not marked as thread safe
+ */
public static StringBuilder buildMsg(final String name, final DateFormat sdf, Level level, Object[] elements) {
final StringBuilder sb;
int end = elements.length;
public static final String AAF_LOCATE_URL = "aaf_locate_url"; //URL for AAF locator
public static final String AAF_LOCATE_URL_TAG = "AAF_LOCATE_URL"; // Name of Above for use in Config Variables.
public static final String AAF_DEFAULT_API_VERSION = "2.1";
+ public static final String AAF_DEPLOYED_VERSION="aaf_deployed_version";
public static final String AAF_API_VERSION = "aaf_api_version";
public static final String AAF_URL = "aaf_url"; //URL for AAF... Use to trigger AAF configuration
public static final String AAF_LOCATOR_CLASS = "aaf_locator_class";
public static final String AAF_CERT_IDS = "aaf_cert_ids";
public static final String AAF_DEBUG_IDS = "aaf_debug_ids"; // comma delimited
public static final String AAF_DATA_DIR = "aaf_data_dir"; // AAF processes and Components only.
- public static final String AAF_RELEASE = "aaf_release";
+ public static final String AAF_URL_OAUTH = "aaf_url_oauth";
public static final String AAF_URL_GUI="aaf_url_gui";
public static final String AAF_URL_FS="aaf_url_fs";
public static final String AAF_URL_CM = "aaf_url_cm";
}
access.log(Level.INIT, sb);
- Locator<URI> locator = loadLocator(si, logProp(rph, Config.getAAFLocateUrl(access), null));
+ Locator<URI> locator = loadLocator(si, aafURL);
taf = new HttpEpiTaf(access,locator, tc, htarray); // ok to pass locator == null
String level = logProp(access, CADI_LOGLEVEL, null);
if (_url==null) {
access.log(Level.INIT,"No URL passed to 'loadLocator'. Disabled");
} else {
+ try {
+ Class<?> aalCls = Class.forName("org.onap.aaf.cadi.aaf.v2_0.AbsAAFLocator");
+ Method aalMth = aalCls.getMethod("create", String.class,String.class);
+ int colon = _url.lastIndexOf(':');
+ if(colon>=0) {
+ int slash = _url.indexOf('/',colon);
+ String version;
+ if(slash<0) {
+ version = _url.substring(colon+1);
+ } else {
+ version = _url.substring(colon+1,slash);
+ }
+ slash = _url.lastIndexOf('/',colon);
+ if(slash>=0) {
+ Object aal = aalMth.invoke(null/*static*/, _url.substring(slash+1, colon),version);
+ return (Locator<URI>)aal;
+ }
+ }
+ } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+ String msg;
+ char quote;
+ if(e.getCause()!=null) {
+ msg=e.getCause().getMessage();
+ quote='"';
+ } else {
+ msg = "-";
+ quote=' ';
+ }
+ access.printf(Level.DEBUG, "Configured AbsAAFLocator not found%c%s%cContinuing Locator creation ",quote,msg,quote);
+ }
// String url = _url.replace("/AAF_NS.", "/%C%CID%AAF_NS.");
// String root_ns = access.getProperty(Config.AAF_ROOT_NS, null);
String url;
Method meth = lcls.getMethod("create",Access.class,String.class);
locator = (Locator<URI>)meth.invoke(null,access,url);
} catch (Exception e) {
- access.log(Level.TRACE, "(Not fatal) Cannot load by create(String)", e);
+ access.log(Level.NONE, "(Not fatal) Cannot load by create(String)", e);
}
if (locator==null) {
URI locatorURI = new URI(url);
if(value.indexOf("%NS")>=0) {
str = getNS(dot_le);
if(str==null || str.isEmpty()) {
- value = value.replace("%NS"+'.', str);
+ value = value.replace("%NS"+'.', "");
+ } else {
+ value = value.replace("%NS", str);
}
- value = value.replace("%NS", str);
}
// aaf_root_ns
this.access = access;
// reuse DME2 Properties for convenience if specific Properties don't exist
- msgHelp = String.format(INITIALIZING_ERR_FMT,"Keystore", access.getProperty(Config.CADI_KEYSTORE, ""));
- initializeKeyManager();
-
- msgHelp = String.format(INITIALIZING_ERR_FMT,"Truststore", access.getProperty(Config.CADI_TRUSTSTORE, ""));
- initializeTrustManager();
-
String str = access.getProperty(Config.CADI_ALIAS, null);
if(str==null || str.isEmpty()) {
defaultAlias = null;
} else {
defaultClientAlias = str;
}
+
+ msgHelp = String.format(INITIALIZING_ERR_FMT,"Keystore", access.getProperty(Config.CADI_KEYSTORE, ""));
+ initializeKeyManager();
+ msgHelp = String.format(INITIALIZING_ERR_FMT,"Truststore", access.getProperty(Config.CADI_TRUSTSTORE, ""));
+ initializeTrustManager();
+
+
msgHelp = String.format(INITIALIZING_ERR_FMT,"Trustmasks", access.getProperty(Config.CADI_TRUST_MASKS, ""));
initializeTrustMasks();
}
}
}
+
+ StringBuilder sb = null;
for (KeyManager keyManager : keyManagerFactory.getKeyManagers()) {
if (keyManager instanceof X509KeyManager) {
- keyManagers.add((X509KeyManager)keyManager);
+ X509KeyManager xkm = (X509KeyManager)keyManager;
+ keyManagers.add(xkm);
+ if(defaultAlias!=null) {
+ sb=new StringBuilder("X509 Chain\n");
+ x509Info(sb,xkm.getCertificateChain(defaultAlias));
+ }
+ if(defaultClientAlias!=null && !defaultClientAlias.equals(defaultAlias)) {
+ if(sb==null) {
+ sb = new StringBuilder();
+ } else {
+ sb.append('\n');
+ }
+ sb.append("X509 Client Chain\n");
+ x509Info(sb,xkm.getCertificateChain(defaultAlias));
+ }
}
}
x509KeyManager = new X509KeyManager[keyManagers.size()];
keyManagers.toArray(x509KeyManager);
+
+ if(sb!=null) {
+ access.log(Level.INIT, sb);
+ }
+ }
+
+ private void x509Info(StringBuilder sb, X509Certificate[] chain) {
+ if(chain!=null) {
+ int i=0;
+ for(X509Certificate x : chain) {
+ sb.append(" ");
+ sb.append(i++);
+ sb.append(')');
+ sb.append("\n Subject: ");
+ sb.append(x.getSubjectDN());
+ sb.append("\n Issuer : ");
+ sb.append(x.getIssuerDN());
+ sb.append("\n Expires: ");
+ sb.append(x.getNotAfter());
+ sb.append('\n');
+ }
+ }
}
protected void initializeTrustManager() throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException, CadiException {
*
*/
public class CadiHTTPManip {
- private static final String ACCESS_CADI_CONTROL = ".access|cadi|control";
+ private static final String ACCESS_DENIED = "Access Denied";
+ private static final String NO_TAF_WILL_AUTHORIZE = "No TAF will authorize";
+ private static final String AUTHENTICATION_FAILURE = "Authentication Failure";
+ private static final String AUTHENTICATING_VIA_REDIRECTION = "Authenticating via redirection";
+ private static final String MSG_FMT = "user=%s,ip=%s:%d,msg=\"%s: %s\"";
+ private static final String AUTHENTICATED = "Authenticated";
+ private static final String ACCESS_CADI_CONTROL = ".access|cadi|control";
private static final String METH = "OPTIONS";
private static final String CADI = "/cadi/";
private static final String CADI_CACHE_PRINT = "/cadi/cache/print";
TafResp tresp = taf.validate(Taf.LifeForm.LFN, hreq, hresp);
switch(tresp.isAuthenticated()) {
case IS_AUTHENTICATED:
- access.printf(Level.INFO,"Authenticated: %s from %s:%d",
- tresp.desc(), hreq.getRemoteAddr(), hreq.getRemotePort());
+ access.printf(Level.DEBUG,MSG_FMT,tresp.getTarget(),hreq.getRemoteAddr(),
+ hreq.getRemotePort(),AUTHENTICATED,tresp.desc());
break;
case TRY_AUTHENTICATING:
switch (tresp.authenticate()) {
case IS_AUTHENTICATED:
- access.printf(Level.INFO,"Authenticated: %s from %s:%d",
- tresp.desc(), hreq.getRemoteAddr(), hreq.getRemotePort());
+ access.printf(Level.DEBUG,MSG_FMT,tresp.getTarget(),hreq.getRemoteAddr(),
+ hreq.getRemotePort(),AUTHENTICATED,tresp.desc());
break;
case HTTP_REDIRECT_INVOKED:
- access.log(Level.INFO,"Authenticating via redirection: ", tresp.desc());
+ access.printf(Level.DEBUG,MSG_FMT,tresp.getTarget(),hreq.getRemoteAddr(),
+ hreq.getRemotePort(),AUTHENTICATING_VIA_REDIRECTION,tresp.desc());
break;
case NO_FURTHER_PROCESSING:
- access.printf(Level.AUDIT,"Authentication Failure: %s from %s:%d"
- , tresp.desc(), hreq.getRemoteAddr(), hreq.getRemotePort());
+ access.printf(Level.AUDIT,MSG_FMT,tresp.getTarget(),hreq.getRemoteAddr(),
+ hreq.getRemotePort(),AUTHENTICATION_FAILURE,tresp.desc());
hresp.sendError(403, tresp.desc()); // Forbidden
break;
default:
- access.printf(Level.AUDIT,"No TAF will authorize for request from %s:%d"
- , hreq.getRemoteAddr(), hreq.getRemotePort());
+ access.printf(Level.AUDIT,MSG_FMT,tresp.getTarget(),hreq.getRemoteAddr(),
+ hreq.getRemotePort(),NO_TAF_WILL_AUTHORIZE,tresp.desc());
hresp.sendError(403, tresp.desc()); // Forbidden
}
break;
case NO_FURTHER_PROCESSING:
- access.printf(Level.AUDIT,"Authentication Failure: %s from %s:%d",
- tresp.desc(), hreq.getRemoteAddr(), hreq.getRemotePort());
- hresp.sendError(403, "Access Denied"); // FORBIDDEN
+ access.printf(Level.AUDIT,MSG_FMT, tresp.getTarget(),hreq.getRemoteAddr(),
+ hreq.getRemotePort(),NO_TAF_WILL_AUTHORIZE,tresp.desc());
+ hresp.sendError(403, ACCESS_DENIED); // FORBIDDEN
break;
default:
- access.printf(Level.AUDIT,"No TAF will authorize for request from %s:%d"
- , hreq.getRemoteAddr(), hreq.getRemotePort());
- hresp.sendError(403, "Access Denied"); // FORBIDDEN
+ access.printf(Level.AUDIT,MSG_FMT, tresp.getTarget(),hreq.getRemoteAddr(),
+ hreq.getRemotePort(),NO_TAF_WILL_AUTHORIZE,tresp.desc());
+ hresp.sendError(403, ACCESS_DENIED); // FORBIDDEN
}
+
return tresp;
}
}
return true;
}
-
+
public Lur getLur() {
return lur;
}
protected final Access access;
protected final String tafName;
+ // Note: Valid Resp is based on Principal being non-null
protected final TaggedPrincipal principal;
+ protected final String target;
protected final String desc;
private float timing;
this.access = access;
this.tafName = tafname;
this.principal = principal;
+ this.target = principal==null?"unknown":principal.getName();
+ this.desc = description;
+ }
+
+ /**
+ * AbsTafResp
+ *
+ * Set and hold
+ * Description (for logging)
+ * Principal (as created by derived class)
+ * Access (for access to underlying container, i.e. for Logging, auditing, ClassLoaders, etc)
+ *
+ * @param access
+ * @param tafname
+ * @param principal
+ * @param description
+ */
+ public AbsTafResp(Access access, String tafname, String target, String description) {
+ this.access = access;
+ this.tafName = tafname;
+ this.principal = null;
+ this.target = target;
this.desc = description;
}
return principal;
}
- /**
+ /* (non-Javadoc)
+ * @see org.onap.aaf.cadi.taf.TafResp#getTarget()
+ */
+ @Override
+ public String getTarget() {
+ return target;
+ }
+
+ /**
* getAccess()
*
* Get the Access object from the TAF, so that appropriate Logging, etc can be coordinated.
private final String loginPageURL;
private LoginPageTafResp(Access access, final HttpServletResponse resp, String loginPageURL) {
- super(access, "LoginPage", null, "Multiple Possible HTTP Logins available. Redirecting to Login Choice Page");
+ super(access, "LoginPage","unknown", "Multiple Possible HTTP Logins available. Redirecting to Login Choice Page");
httpResp = resp;
this.loginPageURL = loginPageURL;
}
return null;
}
- public Access getAccess() {
+ /* (non-Javadoc)
+ * @see org.onap.aaf.cadi.taf.TafResp#getTarget()
+ */
+ @Override
+ public String getTarget() {
+ return "unknown";
+ }
+
+ public Access getAccess() {
return Access.NULL;
}
return null;
}
- public Access getAccess() {
+ /* (non-Javadoc)
+ * @see org.onap.aaf.cadi.taf.TafResp#getTarget()
+ */
+ @Override
+ public String getTarget() {
+ return "punt";
+ }
+
+ public Access getAccess() {
return NullTafResp.singleton().getAccess();
}
* @return
*/
public TaggedPrincipal getPrincipal();
+
+ /** Target - when Authentication Fails, need to know what ID was being attempted
+ * @return
+ */
+ public String getTarget();
/**
* get the Access object which created this object, allowing the responder to appropriate Log, etc
return delegate.getPrincipal();
}
- @Override
+ /* (non-Javadoc)
+ * @see org.onap.aaf.cadi.taf.TafResp#getTarget()
+ */
+ @Override
+ public String getTarget() {
+ return delegate.getTarget();
+ }
+
+ @Override
public Access getAccess() {
return delegate.getAccess();
}
return principal;
}
- @Override
+ /* (non-Javadoc)
+ * @see org.onap.aaf.cadi.taf.TafResp#getTarget()
+ */
+ @Override
+ public String getTarget() {
+ return delegate.getTarget();
+ }
+
+ @Override
public Access getAccess() {
return delegate.getAccess();
}
return new BasicHttpTafResp(access,bp,bp.getName()+" authenticated by password",RESP.IS_AUTHENTICATED,resp,realm,false);
} else {
//TODO may need timed retries in a given time period
- return new BasicHttpTafResp(access,null,buildMsg(bp,req,"user/pass combo invalid for ",bc.getUser(),"from",req.getRemoteAddr()),
+ return new BasicHttpTafResp(access,bc.getUser(),buildMsg(bp,req,"user/pass combo invalid for ",bc.getUser(),"from",req.getRemoteAddr()),
RESP.TRY_AUTHENTICATING,resp,realm,true);
}
}
}
// Get User/Password from Authorization Header value
String authz = req.getHeader("Authorization");
+ String target="unknown";
+
if (authz != null && authz.startsWith("Basic ")) {
if (warn&&!req.isSecure()) {
access.log(Level.WARN,"WARNING! BasicAuth has been used over an insecure channel");
}
try {
CachedBasicPrincipal ba = new CachedBasicPrincipal(this,authz,realm,timeToLive);
+ target=ba.getName();
if (DenialOfServiceTaf.isDeniedID(ba.getName())!=null) {
return DenialOfServiceTaf.respDenyID(access,ba.getName());
}
return new BasicHttpTafResp(access,ba, ba.getName()+" authenticated by BasicAuth password",RESP.IS_AUTHENTICATED,resp,realm,false);
} else {
//TODO may need timed retries in a given time period
- return new BasicHttpTafResp(access,null,buildMsg(ba,req,"user/pass combo invalid"),
+ return new BasicHttpTafResp(access,target,buildMsg(ba,req,"user/pass combo invalid"),
RESP.TRY_AUTHENTICATING,resp,realm,true);
}
} catch (IOException e) {
String msg = buildMsg(null,req,"Failed HTTP Basic Authorization (", e.getMessage(), ')');
access.log(Level.INFO,msg);
- return new BasicHttpTafResp(access,null,msg, RESP.TRY_AUTHENTICATING, resp, realm,true);
+ return new BasicHttpTafResp(access,target,msg, RESP.TRY_AUTHENTICATING, resp, realm,true);
}
}
- return new BasicHttpTafResp(access,null,"Requesting HTTP Basic Authorization",RESP.TRY_AUTHENTICATING,resp,realm,false);
+ return new BasicHttpTafResp(access,target,"Requesting HTTP Basic Authorization",RESP.TRY_AUTHENTICATING,resp,realm,false);
}
protected String buildMsg(Principal pr, HttpServletRequest req, Object ... msg) {
this.wasFailed = wasFailed;
}
+ public BasicHttpTafResp(Access access, String target, String description, RESP status, HttpServletResponse resp, String realm, boolean wasFailed) {
+ super(access, tafName, target, description);
+ httpResp = resp;
+ this.realm = realm;
+ this.status = status;
+ this.wasFailed = wasFailed;
+ }
+
public RESP authenticate() throws IOException {
httpResp.setStatus(401); // Unauthorized
httpResp.setHeader("WWW-Authenticate", "Basic realm=\""+realm+'"');
// if Principal is found, check for "AS_USER" and whether this entity is trusted to declare
if (prin!=null) {
+ // Note: Tag for Certs is Fingerprint, but that takes computation... leaving off
return new X509HttpTafResp(
access,
prin,
private RESP ect; // Homage to Arethra Franklin
public DenialOfServiceTafResp(Access access, RESP resp, String description ) {
- super(access, tafName, null, description);
+ super(access, tafName, "dos", description);
ect = resp;
}
assertThat(tafResp.getAccess(), is(access));
assertThat(tafResp.isFailedAttempt(), is(false));
- tafResp = new AbsTafResp(null, JUNIT, null, null) {
+ tafResp = new AbsTafResp(null, JUNIT, "unknown", null) {
@Override public RESP authenticate() throws IOException {
return null;
}
assertThat(tafResp.isValid(), is(false));
assertThat(tafResp.isAuthenticated(), is(RESP.TRY_ANOTHER_TAF));
assertThat(tafResp.getPrincipal(), is(nullValue()));
+ assertThat(tafResp.getTarget(), is("unknown"));
assertThat(tafResp.getAccess(), is(nullValue()));
assertThat(tafResp.taf(), is(JUNIT));
assertThat(tafResp.isFailedAttempt(), is(false));
@Override public RESP isAuthenticated() { return RESP.TRY_ANOTHER_TAF; }
@Override public RESP authenticate() throws IOException { return null; }
@Override public TaggedPrincipal getPrincipal() { return null; }
+ @Override public String getTarget() {return "unknown";}
@Override public Access getAccess() { return null; }
@Override public boolean isFailedAttempt() { return false; }
@Override public float timing() { return 0; }
@Override public RESP isAuthenticated() { return RESP.TRY_AUTHENTICATING; }
@Override public RESP authenticate() throws IOException { return null; }
@Override public TaggedPrincipal getPrincipal() { return null; }
+ @Override public String getTarget() {return "unknown";}
@Override public Access getAccess() { return null; }
@Override public boolean isFailedAttempt() { return false; }
@Override public float timing() { return 0; }
--- /dev/null
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+
+Running AAF
+=========================
+
+The default methodology for running AAF for ONAP is to run as on of the ONAP OOM charts. This allows AAF to be starting in the right order, be available, etc for ONAP Components.
+
+AAF is very effective as Standalone Java processes, Docker or non OOM Helm Charts, because AAF is an infrastructure component used by ONAP. It is not an integral ONAP Component,
+which means that it can be run independently in a number way. From someone's home computer to the extreme Scale and Resilency requirements of Class A Enterprises.
+
+OOM
+---
+
+Please see OOM Documentation to run AAF with other ONAP Components
+
+Helm
+----
+
+Use git to pull down "authz" code set. Build if desired.
+
+ - Ensure Docker and K8s is install (Minikube is very useful for local machines, see internet)
+ - Ensure Helm is installed an configured (see internet)
+ - cd authz/auth/helm
+ - helm --namespace onap -n dublin install aaf
+ - Control with kubectl (see K8S/Minikub docs)
+
+ - A sample App that generates all its certificates and configurations automatically is available as "aaf-hello
+ - helm --namespace onap -n hello install aaf-hello
+
+Docker
+------
+
+Use git to pull down "authz" code set. See Build info for Docker.
+
+ - cd authz/auth/docker
+ - if you need Docker Container, cd ../cass/docker
+ - bash dinstall.sh
+ - (note: if you add the word "publish", cqlsh is available for your local apps at port 9042)
+
+ - bash dcqlsh.sh (puts you into CQLSH inside Docker)
+ - docker container exec -it aaf-cass bash -c "cqlsh -k authz --request-timeout=60"
+ - bash dbash.sh (short cut to get you a Shell in the "cass" container)
+
+ - all the d...sh scripts utilize short-cut names.
+ - "cass" is actually aaf-cass in Docker, "service" is actually aaf-service in Docker
+
+ - dbuild.sh (builds new Docker Containers, see Build)
+ - dclean.sh (cleans out Docker Containers, getting ready for a new build)
+ - drun.sh <blank|shortcut name> (Creates and Starts Container for all or one AAF components)
+ - dstop.sh <blank|shortcut name> (Stops Container for all or one AAF Components)
+ - dstart.sh <blank|shortcut name> (Use when container exists for all or one AAF Components)
+
.. http://creativecommons.org/licenses/by/4.0
.. Copyright © 2017 AT&T Intellectual Property. All rights reserved.
-
Release Notes
=============
-Version: 2.1.13 (Dublin, 3.1.0-ONAP)
+Version: 2.1.13 (Dublin, 4.0.0-ONAP)
---------------------------------------
:Release Date: 2019-06-06
- `AAF-785 <https://jira.onap.org/browse/AAF-785>`_ non STAGING version on master
- `AAF-822 <https://jira.onap.org/browse/AAF-822>`_ Startup issues with K8S, Certs
+**Usage Notes**
+ - AAF Core and SMS elements have consistently started from scratch. The one case where this didn't happen for SMS,
+ it was found that incompatible data was left in volume. Removal of old data for SMS (See SMS notes) should resolve
+ - On the same instance, one AAF Core component had a similar scenario. A simple bounce of aaf-locator resolved.
+ - Existing Cassandra
+ - For each release, AAF maintains the authz/auth/auth-cass/cass_init/init.cql which is used to setup Keyspaces from scratch
+ - Any changes are also done in small CQL files, you MIGHT need authz/auth/auth-cass/cass_init/init2_10.cql for Dublin
+
+
Version: 2.1.8 (Casablanca, 3.0.0-ONAP, Casablanca Maintenance Release)
--------------------------------------------------------------------------
- `CII Best Practices Passing Badge information for AAF <https://bestpractices.coreinfrastructure.org/en/projects/2303?criteria_level=0>`_
- `Project Vulnerability Review Table for AAF <https://wiki.onap.org/pages/viewpage.action?pageId=43385140>`_
+
+
*/\r
public String setAppender(String appender) throws IOException {\r
File f = new File(String.format(FIRST_FILE_FORMAT_STR, dir, root, appender));\r
+ File lock = new File(f.getAbsoluteFile()+".lock");\r
if(f.exists()) {\r
- int i = 0;\r
- while ((f = new File(String.format(FILE_FORMAT_STR, dir, root, appender, i))).exists()) {\r
- ++i;\r
- }\r
+ if(lock.exists()) {\r
+ int i = 0;\r
+ while ((f = new File(String.format(FILE_FORMAT_STR, dir, root, appender, i))).exists() &&\r
+ (lock = new File(f.getAbsoluteFile()+".lock")).exists()) {\r
+ ++i;\r
+ }\r
+ }\r
}\r
\r
try {\r
+ lock.createNewFile();\r
+ lock.deleteOnExit();\r
f.createNewFile();\r
} catch (IOException e) {\r
throw new IOException("Cannot create file '" + f.getCanonicalPath() + '\'', e);\r