summaryrefslogtreecommitdiffstats
path: root/aaf/src/src/main/java/com/att/cadi/aaf/v2_0
diff options
context:
space:
mode:
Diffstat (limited to 'aaf/src/src/main/java/com/att/cadi/aaf/v2_0')
-rw-r--r--aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFAuthn.java197
-rw-r--r--aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFCon.java279
-rw-r--r--aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFConDME2.java158
-rw-r--r--aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFConHttp.java148
-rw-r--r--aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFLurPerm.java199
-rw-r--r--aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFTaf.java199
-rw-r--r--aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFTrustChecker.java91
-rw-r--r--aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AbsAAFLur.java275
8 files changed, 1546 insertions, 0 deletions
diff --git a/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFAuthn.java b/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFAuthn.java
new file mode 100644
index 0000000..0c72dcd
--- /dev/null
+++ b/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFAuthn.java
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aai
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * Copyright © 2017 Amdocs
+ * * ===========================================================================
+ * * 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====================================================
+ * *
+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * *
+ ******************************************************************************/
+package com.att.cadi.aaf.v2_0;
+
+import com.att.aft.dme2.api.DME2Exception;
+import com.att.cadi.AbsUserCache;
+import com.att.cadi.CachedPrincipal;
+import com.att.cadi.GetCred;
+import com.att.cadi.Hash;
+import com.att.cadi.User;
+import com.att.cadi.aaf.AAFPermission;
+import com.att.cadi.client.Future;
+import com.att.cadi.client.Rcli;
+import com.att.cadi.config.Config;
+import com.att.cadi.lur.ConfigPrincipal;
+import com.att.inno.env.APIException;
+
+public class AAFAuthn<CLIENT> extends AbsUserCache<AAFPermission> {
+ private AAFCon<CLIENT> con;
+ private String realm;
+
+ /**
+ * Configure with Standard AAF properties, Stand alone
+ * @param con
+ * @throws Exception
+ */
+ // Package on purpose
+ AAFAuthn(AAFCon<CLIENT> con) throws Exception {
+ super(con.access,con.cleanInterval,con.highCount,con.usageRefreshTriggerCount);
+ this.con = con;
+
+ try {
+ setRealm();
+ } catch (APIException e) {
+ if(e.getCause() instanceof DME2Exception) {
+ // Can't contact AAF, assume default
+ realm=con.access.getProperty(Config.AAF_DEFAULT_REALM, Config.getDefaultRealm());
+ }
+ }
+ }
+
+ /**
+ * Configure with Standard AAF properties, but share the Cache (with AAF Lur)
+ * @param con
+ * @throws Exception
+ */
+ // Package on purpose
+ AAFAuthn(AAFCon<CLIENT> con, AbsUserCache<AAFPermission> cache) throws Exception {
+ super(cache);
+ this.con = con;
+ try {
+ setRealm();
+ } catch (Exception e) {
+ if(e.getCause() instanceof DME2Exception) {
+ access.log(e);
+ // Can't contact AAF, assume default
+ realm=con.access.getProperty(Config.AAF_DEFAULT_REALM, Config.getDefaultRealm());
+ }
+ }
+ }
+
+ private void setRealm() throws Exception {
+ // Make a call without security set to get the 401 response, which
+ // includes the Realm of the server
+ // This also checks on Connectivity early on.
+ Future<String> fp = con.client(AAFCon.AAF_VERSION).read("/authn/basicAuth", "text/plain");
+ if(fp.get(con.timeout)) {
+ throw new Exception("Do not preset Basic Auth Information for AAFAuthn");
+ } else {
+ if(fp.code()==401) {
+ realm = fp.header("WWW-Authenticate");
+ if(realm!=null && realm.startsWith("Basic realm=\"")) {
+ realm = realm.substring(13, realm.length()-1);
+ } else {
+ realm = "unknown.com";
+ }
+ }
+ }
+ }
+
+ /**
+ * Return Native Realm of AAF Instance.
+ *
+ * @return
+ */
+ public String getRealm() {
+ return realm;
+ }
+
+ /**
+ * Returns null if ok, or an Error String;
+ *
+ * @param user
+ * @param password
+ * @return
+ * @throws Exception
+ */
+ public String validate(String user, String password) throws Exception {
+ User<AAFPermission> usr = getUser(user);
+ if(password.startsWith("enc:???")) {
+ password = access.decrypt(password, true);
+ }
+
+ byte[] bytes = password.getBytes();
+ if(usr != null && usr.principal != null && usr.principal.getName().equals(user)
+ && usr.principal instanceof GetCred) {
+
+ if(Hash.isEqual(((GetCred)usr.principal).getCred(),bytes)) {
+ return null;
+ } else {
+ remove(usr);
+ usr = null;
+ }
+ }
+
+ AAFCachedPrincipal cp = new AAFCachedPrincipal(this,con.app, user, bytes, con.cleanInterval);
+ // Since I've relocated the Validation piece in the Principal, just revalidate, then do Switch
+ // Statement
+ switch(cp.revalidate()) {
+ case REVALIDATED:
+ if(usr!=null) {
+ usr.principal = cp;
+ } else {
+ addUser(new User<AAFPermission>(cp,con.timeout));
+ }
+ return null;
+ case INACCESSIBLE:
+ return "AAF Inaccessible";
+ case UNVALIDATED:
+ return "User/Pass combo invalid";
+ default:
+ return "AAFAuthn doesn't handle this Principal";
+ }
+ }
+
+ private class AAFCachedPrincipal extends ConfigPrincipal implements CachedPrincipal {
+ private long expires,timeToLive;
+
+ public AAFCachedPrincipal(AAFAuthn<?> aaf, String app, String name, byte[] pass, int timeToLive) {
+ super(name,pass);
+ this.timeToLive = timeToLive;
+ expires = timeToLive + System.currentTimeMillis();
+ }
+
+ public Resp revalidate() {
+ try {
+ Miss missed = missed(getName());
+ if(missed==null || missed.mayContinue(getCred())) {
+ Rcli<CLIENT> client = con.client(AAFCon.AAF_VERSION).forUser(con.basicAuth(getName(), new String(getCred())));
+ Future<String> fp = client.read(
+ "/authn/basicAuth",
+ "text/plain"
+ );
+ if(fp.get(con.timeout)) {
+ expires = System.currentTimeMillis() + timeToLive;
+ addUser(new User<AAFPermission>(this, expires));
+ return Resp.REVALIDATED;
+ } else {
+ addMiss(getName(), getCred());
+ return Resp.UNVALIDATED;
+ }
+ } else {
+ return Resp.UNVALIDATED;
+ }
+ } catch (Exception e) {
+ con.access.log(e);
+ return Resp.INACCESSIBLE;
+ }
+ }
+
+ public long expires() {
+ return expires;
+ }
+ };
+
+}
diff --git a/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFCon.java b/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFCon.java
new file mode 100644
index 0000000..c58dd9a
--- /dev/null
+++ b/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFCon.java
@@ -0,0 +1,279 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aai
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * Copyright © 2017 Amdocs
+ * * ===========================================================================
+ * * 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====================================================
+ * *
+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * *
+ ******************************************************************************/
+package com.att.cadi.aaf.v2_0;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.Principal;
+
+import com.att.cadi.AbsUserCache;
+import com.att.cadi.Access;
+import com.att.cadi.CadiException;
+import com.att.cadi.CadiWrap;
+import com.att.cadi.Connector;
+import com.att.cadi.LocatorException;
+import com.att.cadi.Lur;
+import com.att.cadi.SecuritySetter;
+import com.att.cadi.aaf.AAFPermission;
+import com.att.cadi.aaf.marshal.CertsMarshal;
+import com.att.cadi.client.Rcli;
+import com.att.cadi.client.Retryable;
+import com.att.cadi.config.Config;
+import com.att.cadi.config.SecurityInfo;
+import com.att.cadi.lur.EpiLur;
+import com.att.cadi.principal.BasicPrincipal;
+import com.att.inno.env.APIException;
+import com.att.inno.env.util.Split;
+import com.att.rosetta.env.RosettaDF;
+import com.att.rosetta.env.RosettaEnv;
+
+import aaf.v2_0.Certs;
+import aaf.v2_0.Perms;
+import aaf.v2_0.Users;
+
+public abstract class AAFCon<CLIENT> implements Connector {
+ public static final String AAF_VERSION = "2.0";
+
+ final public Access access;
+ // Package access
+ final public int timeout, cleanInterval, connTimeout;
+ final public int highCount, userExpires, usageRefreshTriggerCount;
+ private Rcli<CLIENT> client = null;
+ final public RosettaDF<Perms> permsDF;
+ final public RosettaDF<Certs> certsDF;
+ final public RosettaDF<Users> usersDF;
+ private String realm;
+ public final String app;
+ protected SecuritySetter<CLIENT> ss;
+ protected SecurityInfo<CLIENT> si;
+ protected final URI initURI;
+
+ public Rcli<CLIENT> client(String apiVersion) throws CadiException {
+ if(client==null) {
+ client = rclient(initURI,ss);
+ client.apiVersion(apiVersion)
+ .readTimeout(connTimeout);
+ }
+ return client;
+ }
+
+ protected AAFCon(Access access, String tag, SecurityInfo<CLIENT> si) throws CadiException{
+ try {
+ this.access = access;
+ this.si = si;
+ this.ss = si.defSS;
+ if(ss==null) {
+ String mechid = access.getProperty(Config.AAF_MECHID, null);
+ String encpass = access.getProperty(Config.AAF_MECHPASS, null);
+ if(encpass==null) {
+ String alias = access.getProperty(Config.CADI_ALIAS, mechid);
+ if(alias==null) {
+ throw new CadiException(Config.CADI_ALIAS + " or " + Config.AAF_MECHID + " required.");
+ }
+ si.defSS=ss = x509Alias(alias);
+ } else {
+ if(mechid!=null && encpass !=null) {
+ si.defSS=ss=basicAuth(mechid, encpass);
+ } else {
+ si.defSS=ss=new SecuritySetter<CLIENT>() {
+
+ @Override
+ public String getID() {
+ return "";
+ }
+
+ @Override
+ public void setSecurity(CLIENT client) throws CadiException {
+ throw new CadiException("AAFCon has not been initialized with Credentials (SecuritySetter)");
+ }
+ };
+ }
+ }
+ }
+
+ timeout = Integer.parseInt(access.getProperty(Config.AAF_READ_TIMEOUT, Config.AAF_READ_TIMEOUT_DEF));
+ cleanInterval = Integer.parseInt(access.getProperty(Config.AAF_CLEAN_INTERVAL, Config.AAF_CLEAN_INTERVAL_DEF));
+ highCount = Integer.parseInt(access.getProperty(Config.AAF_HIGH_COUNT, Config.AAF_HIGH_COUNT_DEF).trim());
+ connTimeout = Integer.parseInt(access.getProperty(Config.AAF_CONN_TIMEOUT, Config.AAF_CONN_TIMEOUT_DEF).trim());
+ userExpires = Integer.parseInt(access.getProperty(Config.AAF_USER_EXPIRES, Config.AAF_USER_EXPIRES_DEF).trim());
+ usageRefreshTriggerCount = Integer.parseInt(access.getProperty(Config.AAF_USER_EXPIRES, Config.AAF_USER_EXPIRES_DEF).trim())-1; // zero based
+
+
+ initURI = new URI(access.getProperty(tag,null));
+ if(initURI==null) {
+ throw new CadiException(tag + " property is required.");
+ }
+
+ app=reverseDomain(ss.getID());
+ realm="openecomp.org";
+
+ RosettaEnv env = new RosettaEnv();
+ permsDF = env.newDataFactory(Perms.class);
+ usersDF = env.newDataFactory(Users.class);
+ certsDF = env.newDataFactory(Certs.class);
+ certsDF.rootMarshal(new CertsMarshal()); // Speedier Marshaling
+ } catch (APIException|URISyntaxException e) {
+ throw new CadiException("AAFCon cannot be configured",e);
+ }
+ }
+
+ /**
+ * Return the backing AAFCon, if there is a Lur Setup that is AAF.
+ *
+ * If there is no AAFLur setup, it will return "null"
+ * @param servletRequest
+ * @return
+ */
+ public static final AAFCon<?> obtain(Object servletRequest) {
+ if(servletRequest instanceof CadiWrap) {
+ Lur lur = ((CadiWrap)servletRequest).getLur();
+ if(lur != null) {
+ if(lur instanceof EpiLur) {
+ AbsAAFLur<?> aal = (AbsAAFLur<?>) ((EpiLur)lur).subLur(AbsAAFLur.class);
+ if(aal!=null) {
+ return aal.aaf;
+ }
+ } else {
+ if(lur instanceof AbsAAFLur) {
+ return ((AbsAAFLur<?>)lur).aaf;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ public AAFAuthn<CLIENT> newAuthn() throws APIException {
+ try {
+ return new AAFAuthn<CLIENT>(this);
+ } catch (APIException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new APIException(e);
+ }
+ }
+
+ public AAFAuthn<CLIENT> newAuthn(AbsUserCache<AAFPermission> c) throws APIException {
+ try {
+ return new AAFAuthn<CLIENT>(this,c);
+ } catch (APIException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new APIException(e);
+ }
+ }
+
+ public AAFLurPerm newLur() throws CadiException {
+ try {
+ return new AAFLurPerm(this);
+ } catch (CadiException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new CadiException(e);
+ }
+ }
+
+ public AAFLurPerm newLur(AbsUserCache<AAFPermission> c) throws APIException {
+ try {
+ return new AAFLurPerm(this,c);
+ } catch (APIException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new APIException(e);
+ }
+ }
+
+ /**
+ * Take a Fully Qualified User, and get a Namespace from it.
+ * @param user
+ * @return
+ */
+ public static String reverseDomain(String user) {
+ StringBuilder sb = null;
+ String[] split = Split.split('.',user);
+ int at;
+ for(int i=split.length-1;i>=0;--i) {
+ if(sb == null) {
+ sb = new StringBuilder();
+ } else {
+ sb.append('.');
+ }
+
+ if((at = split[i].indexOf('@'))>0) {
+ sb.append(split[i].subSequence(at+1, split[i].length()));
+ } else {
+ sb.append(split[i]);
+ }
+ }
+
+ return sb==null?"":sb.toString();
+ }
+
+ protected abstract Rcli<CLIENT> rclient(URI uri, SecuritySetter<CLIENT> ss) throws CadiException;
+
+ public abstract<RET> RET best(Retryable<RET> retryable) throws LocatorException, CadiException, APIException;
+
+
+ public abstract SecuritySetter<CLIENT> basicAuth(String user, String password) throws CadiException;
+
+ public abstract SecuritySetter<CLIENT> transferSS(Principal principal) throws CadiException;
+
+ public abstract SecuritySetter<CLIENT> basicAuthSS(BasicPrincipal principal) throws CadiException;
+
+ public abstract SecuritySetter<CLIENT> x509Alias(String alias) throws APIException, CadiException;
+
+
+ public String getRealm() {
+ return realm;
+
+ }
+
+ public SecuritySetter<CLIENT> set(SecuritySetter<CLIENT> ss) {
+ this.ss = ss;
+ if(client!=null) {
+ client.setSecuritySetter(ss);
+ }
+ return ss;
+ }
+
+ public SecurityInfo<CLIENT> securityInfo() {
+ return si;
+ }
+
+ public String defID() {
+ if(ss!=null) {
+ return ss.getID();
+ }
+ return "unknown";
+ }
+
+ public void invalidate() throws CadiException {
+ if(client!=null) {
+ client.invalidate();
+ }
+ client = null;
+ }
+
+
+}
diff --git a/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFConDME2.java b/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFConDME2.java
new file mode 100644
index 0000000..07bc390
--- /dev/null
+++ b/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFConDME2.java
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aai
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * Copyright © 2017 Amdocs
+ * * ===========================================================================
+ * * 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====================================================
+ * *
+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * *
+ ******************************************************************************/
+package com.att.cadi.aaf.v2_0;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.URI;
+import java.security.GeneralSecurityException;
+import java.security.Principal;
+import java.util.Properties;
+
+import com.att.aft.dme2.api.DME2Client;
+import com.att.aft.dme2.api.DME2Exception;
+import com.att.aft.dme2.api.DME2Manager;
+import com.att.cadi.Access;
+import com.att.cadi.CadiException;
+import com.att.cadi.LocatorException;
+import com.att.cadi.SecuritySetter;
+import com.att.cadi.client.Rcli;
+import com.att.cadi.client.Retryable;
+import com.att.cadi.config.Config;
+import com.att.cadi.config.SecurityInfo;
+import com.att.cadi.dme2.DME2BasicAuth;
+import com.att.cadi.dme2.DME2TransferSS;
+import com.att.cadi.dme2.DME2x509SS;
+import com.att.cadi.dme2.DRcli;
+import com.att.cadi.principal.BasicPrincipal;
+import com.att.inno.env.APIException;
+
+public class AAFConDME2 extends AAFCon<DME2Client>{
+ private DME2Manager manager;
+
+ public AAFConDME2(Access access) throws CadiException, GeneralSecurityException, IOException{
+ super(access,Config.AAF_URL,new SecurityInfo<DME2Client> (access));
+ manager = newManager(access);
+ }
+
+ public AAFConDME2(Access access, String url) throws CadiException, GeneralSecurityException, IOException{
+ super(access,url,new SecurityInfo<DME2Client> (access));
+ manager = newManager(access);
+ }
+
+ public AAFConDME2(Access access, SecurityInfo<DME2Client> si) throws CadiException {
+ super(access,Config.AAF_URL,si);
+ manager = newManager(access);
+ }
+
+ public AAFConDME2(Access access, String url, SecurityInfo<DME2Client> si) throws CadiException {
+ super(access,url,si);
+ manager = newManager(access);
+ }
+
+ private DME2Manager newManager(Access access) throws CadiException {
+ Properties props = new Properties();
+ Config.cadiToDME2(access, props);
+ try {
+ return new DME2Manager("AAFCon",props);
+ } catch (DME2Exception e) {
+ throw new CadiException(e);
+ }
+ }
+
+
+ /* (non-Javadoc)
+ * @see com.att.cadi.aaf.v2_0.AAFCon#basicAuth(java.lang.String, java.lang.String)
+ */
+ @Override
+ public SecuritySetter<DME2Client> basicAuth(String user, String password) throws CadiException {
+ if(password.startsWith("enc:???")) {
+ try {
+ password = access.decrypt(password, true);
+ } catch (IOException e) {
+ throw new CadiException("Error Decrypting Password",e);
+ }
+ }
+
+ try {
+ return set(new DME2BasicAuth(user,password,si));
+ } catch (IOException e) {
+ throw new CadiException("Error setting up DME2BasicAuth",e);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.att.cadi.aaf.v2_0.AAFCon#rclient(java.net.URI, com.att.cadi.SecuritySetter)
+ */
+ @Override
+ protected Rcli<DME2Client> rclient(URI uri, SecuritySetter<DME2Client> ss) {
+ DRcli dc = new DRcli(uri, ss);
+ dc.setManager(manager);
+ return dc;
+ }
+
+ @Override
+ public SecuritySetter<DME2Client> transferSS(Principal principal) throws CadiException {
+ try {
+ return principal==null?ss:new DME2TransferSS(principal, app);
+ } catch (IOException e) {
+ throw new CadiException("Error creating DME2TransferSS",e);
+ }
+ }
+
+ @Override
+ public SecuritySetter<DME2Client> basicAuthSS(BasicPrincipal principal) throws CadiException {
+ try {
+ return new DME2BasicAuth(principal,si);
+ } catch (IOException e) {
+ throw new CadiException("Error creating DME2BasicAuth",e);
+ }
+
+ }
+
+ @Override
+ public SecuritySetter<DME2Client> x509Alias(String alias) throws CadiException {
+ try {
+ return new DME2x509SS(alias,si);
+ } catch (Exception e) {
+ throw new CadiException("Error creating DME2x509SS",e);
+ }
+ }
+
+ @Override
+ public <RET> RET best(Retryable<RET> retryable) throws LocatorException, CadiException, APIException {
+ // NOTE: DME2 had Retry Logic embedded lower.
+ try {
+ return (retryable.code(rclient(initURI,ss)));
+ } catch (ConnectException e) {
+ // DME2 should catch
+ try {
+ manager.refresh();
+ } catch (Exception e1) {
+ throw new CadiException(e1);
+ }
+ throw new CadiException(e);
+ }
+ }
+}
diff --git a/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFConHttp.java b/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFConHttp.java
new file mode 100644
index 0000000..ffe1331
--- /dev/null
+++ b/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFConHttp.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aai
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * Copyright © 2017 Amdocs
+ * * ===========================================================================
+ * * 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====================================================
+ * *
+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * *
+ ******************************************************************************/
+package com.att.cadi.aaf.v2_0;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URI;
+import java.security.GeneralSecurityException;
+import java.security.Principal;
+
+import com.att.cadi.Access;
+import com.att.cadi.CadiException;
+import com.att.cadi.Locator;
+import com.att.cadi.LocatorException;
+import com.att.cadi.SecuritySetter;
+import com.att.cadi.client.AbsTransferSS;
+import com.att.cadi.client.Rcli;
+import com.att.cadi.client.Retryable;
+import com.att.cadi.config.Config;
+import com.att.cadi.config.SecurityInfo;
+import com.att.cadi.http.HBasicAuthSS;
+import com.att.cadi.http.HMangr;
+import com.att.cadi.http.HRcli;
+import com.att.cadi.http.HTransferSS;
+import com.att.cadi.http.HX509SS;
+import com.att.cadi.principal.BasicPrincipal;
+import com.att.inno.env.APIException;
+
+public class AAFConHttp extends AAFCon<HttpURLConnection> {
+ private final HMangr hman;
+
+ public AAFConHttp(Access access) throws CadiException, GeneralSecurityException, IOException {
+ super(access,Config.AAF_URL,new SecurityInfo<HttpURLConnection>(access));
+ hman = new HMangr(access,Config.loadLocator(access, access.getProperty(Config.AAF_URL,null)));
+ }
+
+ public AAFConHttp(Access access, String tag) throws CadiException, GeneralSecurityException, IOException {
+ super(access,tag,new SecurityInfo<HttpURLConnection>(access));
+ hman = new HMangr(access,Config.loadLocator(access, access.getProperty(tag,null)));
+ }
+
+ public AAFConHttp(Access access, String urlTag, SecurityInfo<HttpURLConnection> si) throws CadiException {
+ super(access,urlTag,si);
+ hman = new HMangr(access,Config.loadLocator(access, access.getProperty(urlTag,null)));
+ }
+
+ public AAFConHttp(Access access, Locator locator) throws CadiException, GeneralSecurityException, IOException {
+ super(access,Config.AAF_URL,new SecurityInfo<HttpURLConnection>(access));
+ hman = new HMangr(access,locator);
+ }
+
+ public AAFConHttp(Access access, Locator locator, SecurityInfo<HttpURLConnection> si) throws CadiException {
+ super(access,Config.AAF_URL,si);
+ hman = new HMangr(access,locator);
+ }
+
+ public AAFConHttp(Access access, Locator locator, SecurityInfo<HttpURLConnection> si, String tag) throws CadiException {
+ super(access,tag,si);
+ hman = new HMangr(access, locator);
+ }
+
+ /* (non-Javadoc)
+ * @see com.att.cadi.aaf.v2_0.AAFCon#basicAuth(java.lang.String, java.lang.String)
+ */
+ @Override
+ public SecuritySetter<HttpURLConnection> basicAuth(String user, String password) throws CadiException {
+ if(password.startsWith("enc:???")) {
+ try {
+ password = access.decrypt(password, true);
+ } catch (IOException e) {
+ throw new CadiException("Error decrypting password",e);
+ }
+ }
+ try {
+ return set(new HBasicAuthSS(user,password,si));
+ } catch (IOException e) {
+ throw new CadiException("Error creating HBasicAuthSS",e);
+ }
+ }
+
+ public SecuritySetter<HttpURLConnection> x509Alias(String alias) throws APIException, CadiException {
+ try {
+ return set(new HX509SS(alias,si));
+ } catch (Exception e) {
+ throw new CadiException("Error creating X509SS",e);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.att.cadi.aaf.v2_0.AAFCon#rclient(java.net.URI, com.att.cadi.SecuritySetter)
+ */
+ @Override
+ protected Rcli<HttpURLConnection> rclient(URI ignoredURI, SecuritySetter<HttpURLConnection> ss) throws CadiException {
+ try {
+ return new HRcli(hman, hman.loc.best() ,ss);
+ } catch (Exception e) {
+ throw new CadiException(e);
+ }
+ }
+
+ @Override
+ public AbsTransferSS<HttpURLConnection> transferSS(Principal principal) throws CadiException {
+ return new HTransferSS(principal, app,si);
+ }
+
+ /* (non-Javadoc)
+ * @see com.att.cadi.aaf.v2_0.AAFCon#basicAuthSS(java.security.Principal)
+ */
+ @Override
+ public SecuritySetter<HttpURLConnection> basicAuthSS(BasicPrincipal principal) throws CadiException {
+ try {
+ return new HBasicAuthSS(principal,si);
+ } catch (IOException e) {
+ throw new CadiException("Error creating HBasicAuthSS",e);
+ }
+ }
+
+ public HMangr hman() {
+ return hman;
+ }
+
+ @Override
+ public <RET> RET best(Retryable<RET> retryable) throws LocatorException, CadiException, APIException {
+ return hman.best(ss, (Retryable<RET>)retryable);
+ }
+
+}
diff --git a/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFLurPerm.java b/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFLurPerm.java
new file mode 100644
index 0000000..c1c25c2
--- /dev/null
+++ b/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFLurPerm.java
@@ -0,0 +1,199 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aai
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * Copyright © 2017 Amdocs
+ * * ===========================================================================
+ * * 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====================================================
+ * *
+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * *
+ ******************************************************************************/
+package com.att.cadi.aaf.v2_0;
+
+import java.net.ConnectException;
+import java.net.URISyntaxException;
+import java.security.Principal;
+import java.util.Map;
+
+import com.att.aft.dme2.api.DME2Exception;
+import com.att.cadi.AbsUserCache;
+import com.att.cadi.Access;
+import com.att.cadi.Access.Level;
+import com.att.cadi.CachedPrincipal.Resp;
+import com.att.cadi.CadiException;
+import com.att.cadi.Permission;
+import com.att.cadi.User;
+import com.att.cadi.aaf.AAFPermission;
+import com.att.cadi.client.Future;
+import com.att.cadi.client.Rcli;
+import com.att.cadi.client.Retryable;
+import com.att.inno.env.APIException;
+
+import aaf.v2_0.Perm;
+import aaf.v2_0.Perms;
+
+/**
+ * Use AAF Service as Permission Service.
+ *
+ * This Lur goes after AAF Permissions, which are elements of Roles, not the Roles themselves.
+ *
+ * If you want a simple Role Lur, use AAFRoleLur
+ *
+ *
+ */
+public class AAFLurPerm extends AbsAAFLur<AAFPermission> {
+ /**
+ * Need to be able to transmutate a Principal into either ATTUID or MechID, which are the only ones accepted at this
+ * point by AAF. There is no "domain", aka, no "@att.com" in "ab1234@att.com".
+ *
+ * The only thing that matters here for AAF is that we don't waste calls with IDs that obviously aren't valid.
+ * Thus, we validate that the ID portion follows the rules before we waste time accessing AAF remotely
+ * @throws APIException
+ * @throws URISyntaxException
+ * @throws DME2Exception
+ */
+ // Package on purpose
+ AAFLurPerm(AAFCon<?> con) throws CadiException, DME2Exception, URISyntaxException, APIException {
+ super(con);
+ }
+
+ // Package on purpose
+ AAFLurPerm(AAFCon<?> con, AbsUserCache<AAFPermission> auc) throws DME2Exception, URISyntaxException, APIException {
+ super(con,auc);
+ }
+
+ protected User<AAFPermission> loadUser(Principal p) {
+ // Note: The rules for AAF is that it only stores permissions for ATTUID and MechIDs, which don't
+ // have domains. We are going to make the Transitive Class (see this.transmutative) to convert
+ Principal principal = transmutate.mutate(p);
+ if(principal==null)return null; // if not a valid Transmutated credential, don't bother calling...
+ return loadUser(p, p.getName());
+ }
+
+ protected User<AAFPermission> loadUser(String name) {
+ return loadUser((Principal)null, name);
+ }
+
+ private User<AAFPermission> loadUser(final Principal prin, final String name) {
+
+ //TODO Create a dynamic way to declare domains supported.
+ final long start = System.nanoTime();
+ final boolean[] success = new boolean[]{false};
+
+// new Exception("loadUser").printStackTrace();
+ try {
+ return aaf.best(new Retryable<User<AAFPermission>>() {
+ @Override
+ public User<AAFPermission> code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+ Future<Perms> fp = client.read("/authz/perms/user/"+name,aaf.permsDF);
+
+ // In the meantime, lookup User, create if necessary
+ User<AAFPermission> user = getUser(name);
+ Principal p;
+ if(prin == null) {
+ p = new Principal() {// Create a holder for lookups
+ private String n = name;
+ public String getName() {
+ return n;
+ }
+ };
+ } else {
+ p = prin;
+ }
+
+ if(user==null) {
+ addUser(user = new User<AAFPermission>(p,aaf.userExpires)); // no password
+ }
+
+ // OK, done all we can, now get content
+ if(fp.get(aaf.timeout)) {
+ success[0]=true;
+ Map<String, Permission> newMap = user.newMap();
+ for(Perm perm : fp.value.getPerm()) {
+ user.add(newMap,new AAFPermission(perm.getType(),perm.getInstance(),perm.getAction()));
+ aaf.access.log(Level.DEBUG, name,"has '",perm.getType(),'|',perm.getInstance(),'|',perm.getAction(),'\'');
+ }
+ user.setMap(newMap);
+ user.renewPerm();
+ } else {
+ int code;
+ switch(code=fp.code()) {
+ case 401:
+ aaf.access.log(Access.Level.ERROR, code, "Unauthorized to make AAF calls");
+ break;
+ default:
+ aaf.access.log(Access.Level.ERROR, code, fp.body());
+ }
+ }
+
+ return user;
+ }
+ });
+ } catch (Exception e) {
+ aaf.access.log(e,"Calling","/authz/perms/user/"+name);
+ return null;
+ } finally {
+ float time = (System.nanoTime()-start)/1000000f;
+ aaf.access.log(Level.AUDIT, success[0]?"Loaded":"Load Failure",name,"from AAF in",time,"ms");
+ }
+ }
+
+ public Resp reload(User<AAFPermission> user) {
+ final String name = user.principal.getName();
+ long start = System.nanoTime();
+ boolean success = false;
+ try {
+ Future<Perms> fp = aaf.client(AAFCon.AAF_VERSION).read(
+ "/authz/perms/user/"+name,
+ aaf.permsDF
+ );
+
+ // OK, done all we can, now get content
+ if(fp.get(aaf.timeout)) {
+ success = true;
+ Map<String,Permission> newMap = user.newMap();
+ for(Perm perm : fp.value.getPerm()) {
+ user.add(newMap, new AAFPermission(perm.getType(),perm.getInstance(),perm.getAction()));
+ aaf.access.log(Level.DEBUG, name,"has",perm.getType(),perm.getInstance(),perm.getAction());
+ }
+ user.renewPerm();
+ return Resp.REVALIDATED;
+ } else {
+ int code;
+ switch(code=fp.code()) {
+ case 401:
+ aaf.access.log(Access.Level.ERROR, code, "Unauthorized to make AAF calls");
+ break;
+ default:
+ aaf.access.log(Access.Level.ERROR, code, fp.body());
+ }
+ return Resp.UNVALIDATED;
+ }
+ } catch (Exception e) {
+ aaf.access.log(e,"Calling","/authz/perms/user/"+name);
+ return Resp.INACCESSIBLE;
+ } finally {
+ float time = (System.nanoTime()-start)/1000000f;
+ aaf.access.log(Level.AUDIT, success?"Reloaded":"Reload Failure",name,"from AAF in",time,"ms");
+ }
+ }
+
+ @Override
+ protected boolean isCorrectPermType(Permission pond) {
+ return pond instanceof AAFPermission;
+ }
+
+}
diff --git a/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFTaf.java b/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFTaf.java
new file mode 100644
index 0000000..a36c11a
--- /dev/null
+++ b/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFTaf.java
@@ -0,0 +1,199 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aai
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * Copyright © 2017 Amdocs
+ * * ===========================================================================
+ * * 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====================================================
+ * *
+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * *
+ ******************************************************************************/
+package com.att.cadi.aaf.v2_0;
+
+import java.io.IOException;
+import java.security.Principal;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.att.cadi.AbsUserCache;
+import com.att.cadi.Access.Level;
+import com.att.cadi.CachedPrincipal;
+import com.att.cadi.CachedPrincipal.Resp;
+import com.att.cadi.GetCred;
+import com.att.cadi.Hash;
+import com.att.cadi.Taf.LifeForm;
+import com.att.cadi.User;
+import com.att.cadi.aaf.AAFPermission;
+import com.att.cadi.client.Future;
+import com.att.cadi.client.Rcli;
+import com.att.cadi.principal.BasicPrincipal;
+import com.att.cadi.principal.CachedBasicPrincipal;
+import com.att.cadi.taf.HttpTaf;
+import com.att.cadi.taf.TafResp;
+import com.att.cadi.taf.TafResp.RESP;
+import com.att.cadi.taf.basic.BasicHttpTafResp;
+
+public class AAFTaf<CLIENT> extends AbsUserCache<AAFPermission> implements HttpTaf {
+// private static final String INVALID_AUTH_TOKEN = "Invalid Auth Token";
+// private static final String AUTHENTICATING_SERVICE_UNAVAILABLE = "Authenticating Service unavailable";
+ private AAFCon<CLIENT> aaf;
+ private boolean warn;
+
+ public AAFTaf(AAFCon<CLIENT> con, boolean turnOnWarning) {
+ super(con.access,con.cleanInterval,con.highCount, con.usageRefreshTriggerCount);
+ aaf = con;
+ warn = turnOnWarning;
+ }
+
+ public AAFTaf(AAFCon<CLIENT> con, boolean turnOnWarning, AbsUserCache<AAFPermission> other) {
+ super(other);
+ aaf = con;
+ warn = turnOnWarning;
+ }
+
+ public TafResp validate(LifeForm reading, HttpServletRequest req, HttpServletResponse resp) {
+ //TODO Do we allow just anybody to validate?
+
+ // Note: Either Carbon or Silicon based LifeForms ok
+ String auth = req.getHeader("Authorization");
+
+ System.out.println("value of auth ------1------- ++++++++++++++++++++++++++++++++++++++++++" +auth);
+
+ if(auth == null) {
+ return new BasicHttpTafResp(aaf.access,null,"Requesting HTTP Basic Authorization",RESP.TRY_AUTHENTICATING,resp,aaf.getRealm(),false);
+ } else {
+ if(warn&&!req.isSecure())aaf.access.log(Level.WARN,"WARNING! BasicAuth has been used over an insecure channel");
+
+ try {
+ CachedBasicPrincipal bp = new CachedBasicPrincipal(this,auth,aaf.getRealm(),aaf.cleanInterval);
+ System.out.println(" value of aaf.getRealm --------2--------- +++++++++++++++++++++++++++++++++++++++++++++" +aaf.getRealm() );
+ //System.out.println(" value of bp +++++++++++++++++++++++++++++++++++++++++++" +bp.toString());
+ System.out.println(" value of bp.getName() -------3----- +++++++++++++++++++++++++++++++++++++++++++" +bp.getName().toString());
+ System.out.println(" value of bp.getCred() -------4----- +++++++++++++++++++++++++++++++++++++++++++" +bp.getCred().toString());
+
+ // First try Cache
+ User<AAFPermission> usr = getUser(bp);
+
+ // System.out.println(" value of usr -------5-------++++++++++++++++++++++++++++++++++++++++++" +usr.toString());
+
+ if(usr != null && usr.principal != null) {
+ if(usr.principal instanceof GetCred) {
+ if(Hash.isEqual(bp.getCred(),((GetCred)usr.principal).getCred())) {
+
+ return new BasicHttpTafResp(aaf.access,bp,bp.getName()+" authenticated by cached AAF password",RESP.IS_AUTHENTICATED,resp,aaf.getRealm(),false);
+ }
+ }
+ }
+
+ Miss miss = missed(bp.getName());
+ System.out.println(" value of miss before if loop ---------6----- +++++++++++++++++++++++++++++++++++++" +miss );
+ if(miss!=null && !miss.mayContinue(bp.getCred())) {
+
+ System.out.println(" In if(miss!=null && !miss.mayContinue(bp.getCred())) -------7--------+++++++++++++++++++++++++++++++++++++++++++++");
+
+ return new BasicHttpTafResp(aaf.access,null,buildMsg(bp,req,
+ "User/Pass Retry limit exceeded"),
+ RESP.FAIL,resp,aaf.getRealm(),true);
+ }
+
+ Rcli<CLIENT> userAAF = aaf.client(AAFCon.AAF_VERSION).forUser(aaf.basicAuthSS(bp));
+
+ //System.out.println("value of userAAF ------8---- +++++++++++++++++++++++" +userAAF);
+ //System.out.println("value of userAAF +++++++++++++++++++++++" +userAAF.);
+ Future<String> fp = userAAF.read("/authn/basicAuth", "text/plain");
+
+ //System.out.println("value of fp --------9------ +++++++++++++++++++++++" +fp.toString());
+
+ if(fp.get(aaf.timeout)) {
+ System.out.println("In fp.get check -----10----- +++++++++++++");
+ if(usr!=null)usr.principal = bp;
+
+ else addUser(new User<AAFPermission>(bp,aaf.cleanInterval));
+ return new BasicHttpTafResp(aaf.access,bp,bp.getName()+" authenticated by AAF password",RESP.IS_AUTHENTICATED,resp,aaf.getRealm(),false);
+ } else {
+ // Note: AddMiss checks for miss==null, and is part of logic
+
+ System.out.println(" In the else part --------11--------++++++++++++++ ");
+
+ boolean rv= addMiss(bp.getName(),bp.getCred());
+ System.out.println(" value of bp.getName() and bp.getCred() before if check ----12--- ++++++++++++!!!!!!!!!!!++++++++++" +bp.getName() +"and " +bp.getCred());
+
+ if(rv) {
+ System.out.println("In if(rv) check -----13----- +++++++++++++");
+ return new BasicHttpTafResp(aaf.access,null,buildMsg(bp,req,
+ "User/Pass combo invalid via AAF"),
+ RESP.TRY_AUTHENTICATING,resp,aaf.getRealm(),true);
+ } else {
+ System.out.println("In if(rv) else check -----14----- +++++++++++++");
+ return new BasicHttpTafResp(aaf.access,null,buildMsg(bp,req,
+ "User/Pass combo invalid via AAF - Retry limit exceeded"),
+ RESP.FAIL,resp,aaf.getRealm(),true);
+ }
+ }
+ } catch (IOException e) {
+ String msg = buildMsg(null,req,"Invalid Auth Token");
+ System.out.println("In IOException catch block -----15----- +++++++++++++");
+ e.getStackTrace();
+ e.printStackTrace();
+ aaf.access.log(Level.INFO,msg,'(', e.getMessage(), ')');
+ return new BasicHttpTafResp(aaf.access,null,msg, RESP.TRY_AUTHENTICATING, resp, aaf.getRealm(),true);
+ } catch (Exception e) {
+ String msg = buildMsg(null,req,"Authenticating Service unavailable");
+ System.out.println("In Exception catch block -----16----- +++++++++++++");
+ e.getStackTrace();
+ e.printStackTrace();
+ aaf.access.log(Level.INFO,msg,'(', e.getMessage(), ')');
+ return new BasicHttpTafResp(aaf.access,null,msg, RESP.FAIL, resp, aaf.getRealm(),false);
+ }
+ }
+ }
+
+ private String buildMsg(Principal pr, HttpServletRequest req, Object ... msg) {
+ StringBuilder sb = new StringBuilder();
+ for(Object s : msg) {
+ sb.append(s.toString());
+ }
+ if(pr!=null) {
+ sb.append(" for ");
+ sb.append(pr.getName());
+ }
+ sb.append(" from ");
+ sb.append(req.getRemoteAddr());
+ sb.append(':');
+ sb.append(req.getRemotePort());
+ return sb.toString();
+ }
+
+
+
+ public Resp revalidate(CachedPrincipal prin) {
+ // !!!! TEST THIS.. Things may not be revalidated, if not BasicPrincipal
+ if(prin instanceof BasicPrincipal) {
+ Future<String> fp;
+ try {
+ Rcli<CLIENT> userAAF = aaf.client(AAFCon.AAF_VERSION).forUser(aaf.transferSS(prin));
+ fp = userAAF.read("/authn/basicAuth", "text/plain");
+ return fp.get(aaf.timeout)?Resp.REVALIDATED:Resp.UNVALIDATED;
+ } catch (Exception e) {
+ aaf.access.log(e, "Cannot Revalidate",prin.getName());
+ return Resp.INACCESSIBLE;
+ }
+ }
+ return Resp.NOT_MINE;
+ }
+
+}
diff --git a/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFTrustChecker.java b/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFTrustChecker.java
new file mode 100644
index 0000000..cc1e16c
--- /dev/null
+++ b/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AAFTrustChecker.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aai
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * Copyright © 2017 Amdocs
+ * * ===========================================================================
+ * * 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====================================================
+ * *
+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * *
+ ******************************************************************************/
+package com.att.cadi.aaf.v2_0;
+
+import javax.servlet.http.HttpServletRequest ;
+
+import com.att.cadi.Lur;
+import com.att.cadi.TrustChecker;
+import com.att.cadi.aaf.AAFPermission;
+import com.att.cadi.principal.TrustPrincipal;
+import com.att.cadi.taf.TafResp;
+import com.att.cadi.taf.TrustNotTafResp;
+import com.att.cadi.taf.TrustTafResp;
+import com.att.inno.env.util.Split;
+
+public class AAFTrustChecker implements TrustChecker {
+ private final String tag,type,instance,action;
+ private Lur lur;
+
+ /**
+ *
+ * Instance will be replaced by Identity
+ * @param lur
+ *
+ * @param tag
+ * @param perm
+ */
+ public AAFTrustChecker(final String tag, final String perm) {
+ this.tag = tag;
+ String[] split = Split.split('|', perm);
+ this.type = split[0];
+ this.instance = split[1];
+ this.action = split[2];
+ }
+
+ /* (non-Javadoc)
+ * @see com.att.cadi.TrustChecker#setLur(com.att.cadi.Lur)
+ */
+ @Override
+ public void setLur(Lur lur) {
+ this.lur = lur;
+ }
+
+ @Override
+ public TafResp mayTrust(TafResp tresp, HttpServletRequest req) {
+ String user_info = req.getHeader(tag);
+ if(user_info !=null ) {
+ String[] info = Split.split(',', user_info);
+ if(info.length>0) {
+ String[] flds = Split.split(':',info[0]);
+ if(flds.length>3 && "AS".equals(flds[3])) { // is it set for "AS"
+ if(!tresp.getPrincipal().getName().equals(flds[0])) { // We do trust ourselves, if a trust entry is made with self
+ if(lur.fish(tresp.getPrincipal(), new AAFPermission(type,instance,action))) {
+ return new TrustTafResp(tresp,
+ new TrustPrincipal(tresp.getPrincipal(), flds[0]),
+ " " + flds[0] + " validated using " + flds[2] + " by " + flds[1] + ','
+ );
+ } else {
+ return new TrustNotTafResp(tresp, " " + tresp.getPrincipal().getName() +
+ " requested identity change to " + flds[0] + ", but does not have Authorization");
+ }
+ }
+ }
+ }
+ }
+
+ return tresp;
+ }
+
+}
diff --git a/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AbsAAFLur.java b/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AbsAAFLur.java
new file mode 100644
index 0000000..0e831b9
--- /dev/null
+++ b/aaf/src/src/main/java/com/att/cadi/aaf/v2_0/AbsAAFLur.java
@@ -0,0 +1,275 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aai
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * Copyright © 2017 Amdocs
+ * * ===========================================================================
+ * * 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====================================================
+ * *
+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * *
+ ******************************************************************************/
+package com.att.cadi.aaf.v2_0;
+
+import java.net.URISyntaxException;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import com.att.aft.dme2.api.DME2Exception;
+import com.att.cadi.AbsUserCache;
+import com.att.cadi.Access.Level;
+import com.att.cadi.CachingLur;
+import com.att.cadi.Permission;
+import com.att.cadi.StrLur;
+import com.att.cadi.Transmutate;
+import com.att.cadi.User;
+import com.att.cadi.config.Config;
+import com.att.cadi.aaf.AAFPermission;
+import com.att.cadi.aaf.AAFTransmutate;
+import com.att.inno.env.APIException;
+import com.att.inno.env.util.Split;
+
+public abstract class AbsAAFLur<PERM extends Permission> extends AbsUserCache<PERM> implements StrLur, CachingLur<PERM> {
+ protected static final byte[] BLANK_PASSWORD = new byte[0];
+ protected static final Transmutate<Principal> transmutate = new AAFTransmutate();
+ private String[] debug = null;
+ public AAFCon<?> aaf;
+ private String[] supports;
+
+ public AbsAAFLur(AAFCon<?> con) throws DME2Exception, URISyntaxException, APIException {
+ super(con.access, con.cleanInterval, con.highCount, con.usageRefreshTriggerCount);
+ aaf = con;
+ setLur(this);
+ supports = con.access.getProperty(Config.AAF_DOMAIN_SUPPORT, Config.AAF_DOMAIN_SUPPORT_DEF).split("\\s*:\\s*");
+ }
+
+ public AbsAAFLur(AAFCon<?> con, AbsUserCache<PERM> auc) throws DME2Exception, URISyntaxException, APIException {
+ super(auc);
+ aaf = con;
+ setLur(this);
+ supports = con.access.getProperty(Config.AAF_DOMAIN_SUPPORT, Config.AAF_DOMAIN_SUPPORT_DEF).split("\\s*:\\s*");
+ }
+
+ @Override
+ public void setDebug(String ids) {
+ this.debug = ids==null?null:Split.split(',', ids);
+ }
+
+ protected abstract User<PERM> loadUser(Principal bait);
+ protected abstract User<PERM> loadUser(String name);
+ public final boolean supports(String userName) {
+ if(userName!=null) {
+ for(String s : supports) {
+ if(userName.endsWith(s))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected abstract boolean isCorrectPermType(Permission pond);
+
+ // This is where you build AAF CLient Code. Answer the question "Is principal "bait" in the "pond"
+ public boolean fish(Principal bait, Permission pond) {
+ return fish(bait.getName(), pond);
+ }
+
+ public void fishAll(Principal bait, List<Permission> perms) {
+ fishAll(bait.getName(),perms);
+ }
+
+ // This is where you build AAF CLient Code. Answer the question "Is principal "bait" in the "pond"
+ public boolean fish(String bait, Permission pond) {
+ if(isDebug(bait)) {
+ boolean rv = false;
+ StringBuilder sb = new StringBuilder("Log for ");
+ sb.append(bait);
+ if(supports(bait)) {
+ User<PERM> user = getUser(bait);
+ if(user==null) {
+ sb.append("\n\tUser is not in Cache");
+ } else {
+ if(user.noPerms())sb.append("\n\tUser has no Perms");
+ if(user.permExpired()) {
+ sb.append("\n\tUser's perm expired [");
+ sb.append(new Date(user.permExpires()));
+ sb.append(']');
+ } else {
+ sb.append("\n\tUser's perm expires [");
+ sb.append(new Date(user.permExpires()));
+ sb.append(']');
+ }
+ }
+ if(user==null || (user.noPerms() && user.permExpired())) {
+ user = loadUser(bait);
+ sb.append("\n\tloadUser called");
+ }
+ if(user==null) {
+ sb.append("\n\tUser was not Loaded");
+ } else if(user.contains(pond)) {
+ sb.append("\n\tUser contains ");
+ sb.append(pond.getKey());
+ rv = true;
+ } else {
+ sb.append("\n\tUser does not contain ");
+ sb.append(pond.getKey());
+ List<Permission> perms = new ArrayList<Permission>();
+ user.copyPermsTo(perms);
+ for(Permission p : perms) {
+ sb.append("\n\t\t");
+ sb.append(p.getKey());
+ }
+ }
+ } else {
+ sb.append("AAF Lur does not support [");
+ sb.append(bait);
+ sb.append("]");
+ }
+ aaf.access.log(Level.INFO, sb);
+ return rv;
+ } else {
+ if(supports(bait)) {
+ User<PERM> user = getUser(bait);
+ if(user==null || (user.noPerms() && user.permExpired())) {
+ user = loadUser(bait);
+ }
+ return user==null?false:user.contains(pond);
+ }
+ return false;
+ }
+ }
+
+ public void fishAll(String bait, List<Permission> perms) {
+ if(isDebug(bait)) {
+ StringBuilder sb = new StringBuilder("Log for ");
+ sb.append(bait);
+ if(supports(bait)) {
+ User<PERM> user = getUser(bait);
+ if(user==null) {
+ sb.append("\n\tUser is not in Cache");
+ } else {
+ if(user.noPerms())sb.append("\n\tUser has no Perms");
+ if(user.permExpired()) {
+ sb.append("\n\tUser's perm expired [");
+ sb.append(new Date(user.permExpires()));
+ sb.append(']');
+ } else {
+ sb.append("\n\tUser's perm expires [");
+ sb.append(new Date(user.permExpires()));
+ sb.append(']');
+ }
+ }
+ if(user==null || (user.noPerms() && user.permExpired())) {
+ user = loadUser(bait);
+ sb.append("\n\tloadUser called");
+ }
+ if(user==null) {
+ sb.append("\n\tUser was not Loaded");
+ } else {
+ sb.append("\n\tCopying Perms ");
+ user.copyPermsTo(perms);
+ for(Permission p : perms) {
+ sb.append("\n\t\t");
+ sb.append(p.getKey());
+ }
+ }
+ } else {
+ sb.append("AAF Lur does not support [");
+ sb.append(bait);
+ sb.append("]");
+ }
+ aaf.access.log(Level.INFO, sb);
+ } else {
+ if(supports(bait)) {
+ User<PERM> user = getUser(bait);
+ if(user==null || (user.noPerms() && user.permExpired())) user = loadUser(bait);
+ if(user!=null) {
+ user.copyPermsTo(perms);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void remove(String user) {
+ super.remove(user);
+ }
+
+ private boolean isDebug(String bait) {
+ if(debug!=null) {
+ if(debug.length==1 && "all".equals(debug[0]))return true;
+ for(String s : debug) {
+ if(s.equals(bait))return true;
+ }
+ }
+ return false;
+ }
+ /**
+ * This special case minimizes loops, avoids multiple Set hits, and calls all the appropriate Actions found.
+ *
+ * @param bait
+ * @param obj
+ * @param type
+ * @param instance
+ * @param actions
+ */
+ public<A> void fishOneOf(String bait, A obj, String type, String instance, List<Action<A>> actions) {
+ User<PERM> user = getUser(bait);
+ if(user==null || (user.noPerms() && user.permExpired()))user = loadUser(bait);
+// return user==null?false:user.contains(pond);
+ if(user!=null) {
+ ReuseAAFPermission perm = new ReuseAAFPermission(type,instance);
+ for(Action<A> action : actions) {
+ perm.setAction(action.getName());
+ if(user.contains(perm)) {
+ if(action.exec(obj))return;
+ }
+ }
+ }
+ }
+
+ public static interface Action<A> {
+ public String getName();
+ /**
+ * Return false to continue, True to end now
+ * @return
+ */
+ public boolean exec(A a);
+ }
+
+ private class ReuseAAFPermission extends AAFPermission {
+ public ReuseAAFPermission(String type, String instance) {
+ super(type,instance,null);
+ }
+
+ public void setAction(String s) {
+ action = s;
+ }
+
+ /**
+ * This function understands that AAF Keys are hierarchical, :A:B:C,
+ * Cassandra follows a similar method, so we'll short circuit and do it more efficiently when there isn't a first hit
+ * @return
+ */
+// public boolean setParentInstance() {
+// int i = instance.lastIndexOf(':');
+// if(i<0) return false;
+// instance = instance.substring(0, i);
+// return true;
+// }
+ }
+}