+
+ List<Priori<Lur>> lurs = new ArrayList<>();
+
+ /////////////////////////////////////////////////////
+ // Configure a Local Property Based RBAC/LUR
+ /////////////////////////////////////////////////////
+ try {
+ String users = access.getProperty(USERS,null);
+ String groups = access.getProperty(GROUPS,null);
+
+ if (groups!=null || users!=null) {
+ LocalLur ll = new LocalLur(access, users, groups); // note b64==null is ok.. just means no encryption.
+ lurs.add(new Priori<Lur>(ll,10));
+
+ String writeto = access.getProperty(WRITE_TO,null);
+ if (writeto!=null) {
+ String msg = UsersDump.updateUsers(writeto, ll);
+ if (msg!=null) {
+ access.log(Level.INIT,"ERROR! Error Updating ",writeto,"with roles and users:",msg);
+ }
+ }
+ }
+ } catch (IOException e) {
+ throw new CadiException(e);
+ }
+
+ /////////////////////////////////////////////////////
+ // Configure the OAuth Lur (if any)
+ /////////////////////////////////////////////////////
+ String tokenUrl = logProp(rph,AAF_OAUTH2_TOKEN_URL, null);
+ String introspectUrl = logProp(rph,AAF_OAUTH2_INTROSPECT_URL, null);
+ if (tokenUrl!=null && introspectUrl !=null) {
+ try {
+ Class<?> olurCls = loadClass(access, CADI_OLUR_CLASS_DEF);
+ if (olurCls!=null) {
+ Constructor<?> olurCnst = olurCls.getConstructor(PropAccess.class,String.class,String.class);
+ Lur olur = (Lur)olurCnst.newInstance(access,tokenUrl,introspectUrl);
+ lurs.add(new Priori<Lur>(olur,20));
+ access.log(Level.INIT, "OAuth2 LUR enabled");
+ } else {
+ access.log(Level.INIT,"AAF/OAuth LUR plugin is not available.");
+ }
+ } catch (NoSuchMethodException| SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+ String msg = e.getMessage();
+ if (msg==null && e.getCause()!=null) {
+ msg = e.getCause().getMessage();
+ }
+ access.log(Level.INIT,"AAF/OAuth LUR is not instantiated.",msg,e);
+ }
+ } else {
+ access.log(Level.INIT, "OAuth2 Lur disabled");
+ }
+
+ if (con!=null) { // try to reutilize connector
+ lurs.add(new Priori<Lur>(con.newLur(),30));
+ } else {
+ /////////////////////////////////////////////////////
+ // Configure the AAF Lur (if any)
+ /////////////////////////////////////////////////////
+ String aafURL = logProp(rph,AAF_URL,null); // Trigger Property
+ String aafEnv = access.getProperty(AAF_ENV,null);
+ if (aafEnv == null && aafURL!=null && access instanceof PropAccess) { // set AAF_ENV from AAF_URL
+ int ec = aafURL.indexOf("envContext=");
+ if (ec>0) {
+ ec += 11; // length of envContext=
+ int slash = aafURL.indexOf('/', ec);
+ if (slash>0) {
+ aafEnv = aafURL.substring(ec, slash);
+ ((PropAccess)access).setProperty(AAF_ENV, aafEnv);
+ access.printf(Level.INIT, "Setting aafEnv to %s from aaf_url value",aafEnv);
+ }
+ }
+ }
+
+ // Don't configure AAF if it is using DirectAccess
+ if (!hasDirect("DirectAAFLur",additionalTafLurs)) {
+ if (aafURL==null) {
+ access.log(Level.INIT,"No AAF LUR properties, AAF will not be loaded");
+ } else {// There's an AAF_URL... try to configure an AAF
+ String aafLurClassStr = logProp(access,AAF_LUR_CLASS,AAF_V2_0_AAF_LUR_PERM);
+ ////////////AAF Lur 2.0 /////////////
+ if (aafLurClassStr!=null && aafLurClassStr.startsWith(AAF_V2_0)) {
+ try {
+ Object aafcon = loadAAFConnector(si, aafURL);
+ if (aafcon==null) {
+ access.log(Level.INIT,"AAF LUR class,",aafLurClassStr,"cannot be constructed without valid AAFCon object.");
+ } else {
+ Class<?> aafAbsAAFCon = loadClass(access, AAF_V2_0_AAFCON);
+ if (aafAbsAAFCon!=null) {
+ Method mNewLur = aafAbsAAFCon.getMethod("newLur");
+ Object aaflur = mNewLur.invoke(aafcon);
+
+ if (aaflur==null) {
+ access.log(Level.INIT,"ERROR! AAF LUR Failed construction. NOT Configured");
+ } else {
+ access.log(Level.INIT,"AAF LUR Configured to ",aafURL);
+ lurs.add(new Priori<Lur>((Lur)aaflur,40));
+ String debugIDs = logProp(access,Config.AAF_DEBUG_IDS, null);
+ if (debugIDs !=null && aaflur instanceof CachingLur) {
+ ((CachingLur<?>)aaflur).setDebug(debugIDs);
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ access.log(e,"AAF LUR class,",aafLurClassStr,"could not be constructed with given Constructors.");
+ }
+ }
+ }
+ }
+ }
+
+ /////////////////////////////////////////////////////
+ // Any Additional passed in Constructor
+ /////////////////////////////////////////////////////
+ if (additionalTafLurs!=null) {
+ int i=0;
+ for (Object additional : additionalTafLurs) {
+ if (additional instanceof Lur) {
+ lurs.add(new Priori<Lur>((Lur)additional,50+i++));
+ access.log(Level.INIT, additional);
+ }
+ }
+ }
+
+ /////////////////////////////////////////////////////
+ // Additional LURs by Plugin
+ /////////////////////////////////////////////////////
+ Priori.add(access, CADI_ADD_LURS, lurs);
+
+ /////////////////////////////////////////////////////
+ // Return a Lur based on how many there are...
+ /////////////////////////////////////////////////////
+ switch(lurs.size()) {
+ case 0:
+ access.log(Level.INIT,"WARNING! No CADI LURs configured");
+ // Return a NULL Lur that does nothing.
+ return new NullLur();
+ case 1:
+ return lurs.get(0).t; // Only one, just return it, save processing
+ default:
+ // Multiple Lurs, use EpiLUR to handle
+ Collections.sort(lurs);
+ Lur[] la = new Lur[lurs.size()];
+ int i=-1;
+ StringBuilder sb = new StringBuilder("Lurs processed in this order:\n");
+ for(Priori<Lur> pht : lurs) {
+ la[++i] = pht.t;
+ sb.append(" ");
+ sb.append(pht.t.getClass().getName());
+ sb.append('(');
+ sb.append(pht.priority);
+ sb.append(")\n");
+ }
+ access.log(Level.INIT, sb);
+ return new EpiLur(la);
+ }
+ }
+
+ private static boolean hasDirect(String simpleClassName, Object[] additionalTafLurs) {
+ if (additionalTafLurs!=null) {
+ for (Object tf : additionalTafLurs) {
+ if (tf.getClass().getSimpleName().equals(simpleClassName)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public static Object loadAAFConnector(SecurityInfoC<HttpURLConnection> si, String aafURL) {
+ Access access = si.access;
+ Object aafcon = null;
+ Class<?> aafConClass = null;
+
+ try {
+ if (aafURL!=null) {
+ String aafConnector = access.getProperty(AAF_CONNECTOR_CLASS, AAF_V2_0_AAF_CON_HTTP);
+ if (AAF_V2_0_AAF_CON_HTTP.equals(aafConnector)) {
+ aafConClass = loadClass(access, AAF_V2_0_AAF_CON_HTTP);
+ if (aafConClass != null) {
+ for (Constructor<?> c : aafConClass.getConstructors()) {
+ List<Object> lo = new ArrayList<>();
+ for (Class<?> pc : c.getParameterTypes()) {
+ if (pc.equals(Access.class)) {
+ lo.add(access);
+ } else if (pc.equals(Locator.class)) {
+ lo.add(loadLocator(si, aafURL));
+ }
+ }
+ if (c.getParameterTypes().length != lo.size()) {
+ continue; // back to another Constructor
+ } else {
+ aafcon = c.newInstance(lo.toArray());
+ }
+ break;
+ }
+ }
+ }
+ if (aafcon != null) {
+ String mechid = logProp(access, Config.AAF_APPID, null);
+ String pass = access.getProperty(Config.AAF_APPPASS, null);
+ if (mechid != null && pass != null) {
+ try {
+ Method basicAuth = aafConClass.getMethod("basicAuth", String.class, String.class);
+ basicAuth.invoke(aafcon, mechid, pass);
+ } catch (NoSuchMethodException nsme) {
+ access.log(Level.NONE, nsme);
+ // it's ok, don't use
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ access.log(e, "AAF Connector could not be constructed with given Constructors.");
+ }
+
+ return aafcon;
+ }
+
+ public static Class<?> loadClass(Access access, String className) {
+ Class<?> cls=null;
+ try {
+ cls = access.classLoader().loadClass(className);
+ } catch (ClassNotFoundException cnfe) {
+ access.log(Level.NONE, cnfe);
+ try {
+ cls = access.getClass().getClassLoader().loadClass(className);
+ } catch (ClassNotFoundException cnfe2) {
+ access.log(Level.NONE, cnfe2);
+ // just return null
+ }
+ }
+ return cls;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Locator<URI> loadLocator(SecurityInfoC<HttpURLConnection> si, final String _url) throws LocatorException {
+ Access access = si.access;
+ Locator<URI> locator = 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;
+ RegistrationPropHolder rph;
+ try {
+ rph = new RegistrationPropHolder(access, 0);
+ url = rph.replacements("Config.loadLocator",_url, null, null);
+ access.printf(Level.INFO, "loadLocator URL is %s",url);
+ } catch (UnknownHostException | CadiException e1) {
+ throw new LocatorException(e1);
+ }
+
+ String aaf_locator_class;
+ if(_url.equals(url) && !url.contains("/locate/")) {
+ aaf_locator_class = "org.onap.aaf.cadi.locator.DNSLocator";
+ } else {
+ aaf_locator_class = AAF_LOCATOR_CLASS_DEF;
+ }
+ try {
+ Class<?> lcls = loadClass(access,aaf_locator_class);
+ if (lcls==null) {
+ throw new CadiException("Need to include aaf-cadi-aaf jar for AAFLocator");
+ }
+ // First check for preloaded
+ try {
+ Method meth = lcls.getMethod("create",Access.class,String.class);
+ locator = (Locator<URI>)meth.invoke(null,access,url);
+ } catch (Exception e) {
+ access.log(Level.NONE, "(Not fatal) Cannot load by create(String)", e);
+ }
+ if (locator==null) {
+ URI locatorURI = new URI(url);
+ FixURIinfo fui = new FixURIinfo(locatorURI);
+ Constructor<?> cnst = lcls.getConstructor(SecurityInfoC.class,URI.class);
+ locator = (Locator<URI>)cnst.newInstance(new Object[] {si,locatorURI});
+ int port = fui.getPort();
+ String portS = port<0?"":(":"+port);
+
+ access.log(Level.INFO, "AAFLocator enabled using " + locatorURI.getScheme() +"://"+fui.getHost() + portS);
+ } else {
+ access.log(Level.INFO, "AAFLocator enabled using preloaded " + locator.getClass().getSimpleName());
+ }
+ } catch (InvocationTargetException e) {
+ if (e.getTargetException() instanceof LocatorException) {
+ throw (LocatorException)e.getTargetException();
+ }
+ access.log(Level.INIT,e.getTargetException().getMessage(),"AAFLocator for",url,"could not be created.",e);
+ } catch (Exception e) {
+ access.log(Level.INIT,"AAFLocator for",url,"could not be created.",e);
+ }
+ }
+ return locator;
+ }
+
+ // Set by CSP, or is hostname.
+ public static String getDefaultRealm() {
+ return defaultRealm;
+ }
+
+ public static String getAAFLocateUrl(Access access) {
+ String rv = null;
+ String cont = access.getProperty(AAF_LOCATOR_CONTAINER,null);
+ if(cont!=null) {
+ rv = access.getProperty(AAF_LOCATE_URL + '.' +cont, null);
+ }
+ if(rv==null) {
+ rv = access.getProperty(AAF_LOCATE_URL, null);
+ }
+ return rv;
+ }
+
+ private static class Priori<T> implements Comparable<Priori<T>> {
+ public final T t;
+ public final int priority;
+
+ public Priori(final T t, final int priority) {
+ this.t = t;
+ this.priority = priority;
+ }
+
+ @Override
+ public int compareTo(Priori<T> o) {
+ if(priority==o.priority) {
+ return 0;
+ } else if(priority<o.priority) {
+ return -1;
+ } else {
+ return 1;