summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Gathman <jonathan.gathman@att.com>2018-05-16 21:17:51 +0000
committerGerrit Code Review <gerrit@onap.org>2018-05-16 21:17:51 +0000
commit0978e42055b2039648dd2c9c8b70d77d86670e83 (patch)
tree87aaf8ecdf177b316f2534c198c0ca1181e4e0ff
parentf129d3fde1205cffe9680959f365b618b1a3f85a (diff)
parent799f1236dceea6234561f39f73a317f8d93d71e6 (diff)
Merge "Improve coverage of cadi-core"
-rw-r--r--cadi/core/src/main/java/org/onap/aaf/cadi/taf/HttpEpiTaf.java117
-rw-r--r--cadi/core/src/main/java/org/onap/aaf/cadi/taf/LoginPageTafResp.java58
-rw-r--r--cadi/core/src/test/java/org/onap/aaf/cadi/taf/test/JU_HttpEpiTaf.java145
-rw-r--r--cadi/core/src/test/java/org/onap/aaf/cadi/taf/test/JU_LoginPageTafResp.java101
4 files changed, 345 insertions, 76 deletions
diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/HttpEpiTaf.java b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/HttpEpiTaf.java
index cc283973..5cd6323d 100644
--- a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/HttpEpiTaf.java
+++ b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/HttpEpiTaf.java
@@ -7,9 +7,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -40,9 +40,9 @@ import org.onap.aaf.cadi.TrustChecker;
/**
* HttpEpiTaf
- *
+ *
* An extension of the basic "EpiTAF" concept, check known HTTP Related TAFs for valid credentials
- *
+ *
* @author Jonathan
*
*/
@@ -51,10 +51,10 @@ public class HttpEpiTaf implements HttpTaf {
private Access access;
private Locator<URI> locator;
private TrustChecker trustChecker;
-
+
/**
* HttpEpiTaf constructor
- *
+ *
* Construct the HttpEpiTaf from variable Http specific TAF parameters
* @param tafs
@@ -65,52 +65,52 @@ public class HttpEpiTaf implements HttpTaf {
this.access = access;
this.locator = locator;
this.trustChecker = tc;
- // Establish what Header Property to look for UserChain/Trust Props
-// trustChainProp = access.getProperty(Config.CADI_TRUST_PROP, Config.CADI_TRUST_PROP_DEFAULT);
+ // Establish what Header Property to look for UserChain/Trust Props
- if(tafs.length==0) throw new CadiException("Need at least one HttpTaf implementation in constructor");
+ if (tafs.length == 0) {
+ throw new CadiException("Need at least one HttpTaf implementation in constructor");
+ }
}
/**
* validate
- *
- * Respond with the first Http specific TAF to authenticate user based on variable info
+ *
+ * Respond with the first Http specific TAF to authenticate user based on variable info
* and "LifeForm" (is it a human behind a browser, or a server utilizing HTTP Protocol).
- *
+ *
* If there is no HttpTAF that can authenticate, respond with the first TAF that suggests it can
* establish an Authentication conversation (TRY_AUTHENTICATING) (Examples include a redirect to CSP
- * Servers for CSP Cookie, or BasicAuth 401 response, suggesting User/Password for given Realm
+ * Servers for CSP Cookie, or BasicAuth 401 response, suggesting User/Password for given Realm
* submission
- *
+ *
* If no TAF declares either, respond with NullTafResp (which denies all questions)
*/
public TafResp validate(LifeForm reading, HttpServletRequest req, HttpServletResponse resp) {
// Given a LifeForm Neutral, for HTTP, we need to discover true Life-Form Readings
- if(reading==LifeForm.LFN) {
+ if (reading == LifeForm.LFN) {
reading = tricorderScan(req);
}
- TafResp tresp=null, firstTry = null;
+ TafResp tresp = null;
+ TafResp firstTry = null;
List<Redirectable> redirectables = null;
- List<TafResp> trlog = access.willLog(Level.DEBUG)?new ArrayList<TafResp>():null;
+ List<TafResp> log = (access.willLog(Level.DEBUG)) ? new ArrayList<TafResp>() : null;
try {
- for(HttpTaf taf : tafs) {
+ for (HttpTaf taf : tafs) {
tresp = taf.validate(reading, req, resp);
- if(trlog!=null) {
- trlog.add(tresp);
- }
+ addToLog(log, tresp);
switch(tresp.isAuthenticated()) {
case TRY_ANOTHER_TAF:
break; // and loop
case TRY_AUTHENTICATING:
- if(tresp instanceof Redirectable) {
- if(redirectables==null) {
- redirectables = new ArrayList<Redirectable>();
+ if (tresp instanceof Redirectable) {
+ if (redirectables == null) {
+ redirectables = new ArrayList<>();
}
redirectables.add((Redirectable)tresp);
- } else if(firstTry==null) {
+ } else if (firstTry == null) {
firstTry = tresp;
}
- break;
+ break;
case IS_AUTHENTICATED:
tresp = trustChecker.mayTrust(tresp, req);
return tresp;
@@ -118,46 +118,42 @@ public class HttpEpiTaf implements HttpTaf {
return tresp;
}
}
- } finally {
- if(trlog!=null) {
- for( TafResp tr : trlog) {
- access.log(Level.DEBUG, tr.desc());
- }
- }
+ } finally {
+ printLog(log);
}
-
- // If No TAFs configured, at this point. It is safer at this point to be "not validated",
+
+ // If No TAFs configured, at this point. It is safer at this point to be "not validated",
// rather than "let it go"
// Note: if exists, there will always be more than 0 entries, according to above code
- if(redirectables==null) {
- return firstTry!=null?firstTry:NullTafResp.singleton();
+ if (redirectables == null) {
+ return (firstTry != null) ? firstTry : NullTafResp.singleton();
}
-
+
// If there is one Tryable entry then return it
- if(redirectables.size()>1) {
- return LoginPageTafResp.create(access,locator,resp,redirectables);
+ if (redirectables.size() > 1) {
+ return LoginPageTafResp.create(access, locator, resp, redirectables);
} else {
return redirectables.get(0);
}
}
-
+
public boolean revalidate(Principal prin) throws Exception {
return false;
}
/*
* Since this is internal, we use a little Star Trek humor to indicate looking in the HTTP Request to see if we can determine what kind
- * of "LifeForm" reading we can determine, i.e. is there a Human (CarbonBasedLifeForm) behind a browser, or is it mechanical
+ * of "LifeForm" reading we can determine, i.e. is there a Human (CarbonBasedLifeForm) behind a browser, or is it mechanical
* id (SiliconBasedLifeForm)? This makes a difference in some Authentication, i.e CSP, which doesn't work well for SBLFs
*/
private LifeForm tricorderScan(HttpServletRequest req) {
// For simplicity's sake, we'll say Humans use FQDNs, not IPs.
-
+
// Current guess that only Browsers bother to set "Agent" codes that identify the kind of browser they are.
// If mechanical frameworks are found that populate this, then more advanced analysis may be required
// Jonathan 1/22/2013
String agent = req.getHeader("User-Agent");
- if(agent!=null && agent.startsWith("Mozilla")) { // covers I.E./Firefox/Safari/probably any other "advanced" Browser see http://en.wikipedia.org/wiki/User_agent
+ if (agent != null && agent.startsWith("Mozilla")) { // covers I.E./Firefox/Safari/probably any other "advanced" Browser see http://en.wikipedia.org/wiki/User_agent
return LifeForm.CBLF;
}
return LifeForm.SBLF; // notably skips "curl","wget", (which is desired behavior. We don't want to try CSP, etc on these)
@@ -165,17 +161,36 @@ public class HttpEpiTaf implements HttpTaf {
public Resp revalidate(CachedPrincipal prin, Object state) {
Resp resp;
- for(HttpTaf taf : tafs) {
- resp = taf.revalidate(prin,state);
- switch(resp) {
- case NOT_MINE:
- break;
- default:
- return resp;
+ for (HttpTaf taf : tafs) {
+ resp = taf.revalidate(prin, state);
+ if (resp != Resp.NOT_MINE) {
+ return resp;
}
+// switch(resp) {
+// case NOT_MINE:
+// break;
+// default:
+// return resp;
+// }
}
return Resp.NOT_MINE;
}
+
+ private void addToLog(List<TafResp> log, TafResp tresp) {
+ if (log == null) {
+ return;
+ }
+ log.add(tresp);
+ }
+
+ private void printLog(List<TafResp> log) {
+ if (log == null) {
+ return;
+ }
+ for (TafResp tresp : log) {
+ access.log(Level.DEBUG, tresp.desc());
+ }
+ }
/**
* List HttpTafs with their "toString" representations... primarily useful for Debugging in an IDE
@@ -183,7 +198,7 @@ public class HttpEpiTaf implements HttpTaf {
*/
public String toString() {
StringBuilder sb = new StringBuilder();
- for(HttpTaf ht : tafs) {
+ for (HttpTaf ht : tafs) {
sb.append(ht.toString());
sb.append(". ");
}
diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/LoginPageTafResp.java b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/LoginPageTafResp.java
index 9c9cbc22..3f80170e 100644
--- a/cadi/core/src/main/java/org/onap/aaf/cadi/taf/LoginPageTafResp.java
+++ b/cadi/core/src/main/java/org/onap/aaf/cadi/taf/LoginPageTafResp.java
@@ -53,34 +53,42 @@ public class LoginPageTafResp extends AbsTafResp {
return RESP.TRY_AUTHENTICATING;
}
- public static TafResp create(Access access, Locator<URI> locator, final HttpServletResponse resp, List<Redirectable> redir) {
- if(locator!=null) {
- try {
- Item item = locator.best();
- URI uri = locator.get(item);
- if(uri!=null) {
- StringBuilder sb = new StringBuilder(uri.toString());
- String query = uri.getQuery();
- boolean first = query==null || query.length()==0;
- int count=0;
- for(Redirectable t : redir) {
- if(first) {
- sb.append('?');
- first=false;
- }
- else sb.append('&');
- sb.append(t.get());
- ++count;
- }
- if(count>0)return new LoginPageTafResp(access, resp, sb.toString());
+ public static TafResp create(Access access, Locator<URI> locator, final HttpServletResponse resp, List<Redirectable> redirectables) {
+ if (locator == null) {
+ if (!redirectables.isEmpty()) {
+ access.log(Level.DEBUG,"LoginPage Locator is not configured. Taking first Redirectable Taf");
+ return redirectables.get(0);
+ }
+ return NullTafResp.singleton();
+ }
+
+ try {
+ Item item = locator.best();
+ URI uri = locator.get(item);
+ if (uri == null) {
+ return NullTafResp.singleton();
+ }
+
+ StringBuilder sb = new StringBuilder(uri.toString());
+ String query = uri.getQuery();
+ boolean first = ((query == null) || (query.length() == 0));
+ for (Redirectable redir : redirectables) {
+ if (first) {
+ sb.append('?');
+ first = false;
+ }
+ else {
+ sb.append('&');
}
- } catch (Exception e) {
- access.log(e, "Error deriving Login Page location");
+ sb.append(redir.get());
}
- } else if(!redir.isEmpty()) {
- access.log(Level.DEBUG,"LoginPage Locator is not configured. Taking first Redirectable Taf");
- return redir.get(0);
+ if (!redirectables.isEmpty()) {
+ return new LoginPageTafResp(access, resp, sb.toString());
+ }
+ } catch (Exception e) {
+ access.log(e, "Error deriving Login Page location");
}
+
return NullTafResp.singleton();
}
}
diff --git a/cadi/core/src/test/java/org/onap/aaf/cadi/taf/test/JU_HttpEpiTaf.java b/cadi/core/src/test/java/org/onap/aaf/cadi/taf/test/JU_HttpEpiTaf.java
new file mode 100644
index 00000000..93a20474
--- /dev/null
+++ b/cadi/core/src/test/java/org/onap/aaf/cadi/taf/test/JU_HttpEpiTaf.java
@@ -0,0 +1,145 @@
+/**
+ * ============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.cadi.taf.test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.onap.aaf.cadi.Access.Level;
+import org.onap.aaf.cadi.CachedPrincipal.Resp;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.Locator;
+import org.onap.aaf.cadi.PropAccess;
+import org.onap.aaf.cadi.Taf.LifeForm;
+import org.onap.aaf.cadi.TrustChecker;
+import org.onap.aaf.cadi.taf.HttpEpiTaf;
+import org.onap.aaf.cadi.taf.HttpTaf;
+import org.onap.aaf.cadi.taf.NullTaf;
+import org.onap.aaf.cadi.taf.Redirectable;
+import org.onap.aaf.cadi.taf.TafResp;
+import org.onap.aaf.cadi.taf.TafResp.RESP;
+
+public class JU_HttpEpiTaf {
+
+ private PropAccess access;
+
+ @Mock private Locator<URI> locMock;
+ @Mock private TrustChecker trustCheckerMock;
+ @Mock private HttpServletRequest reqMock;
+ @Mock private HttpServletResponse respMock;
+ @Mock private HttpTaf tafMock;
+ @Mock private TafResp trespMock;
+ @Mock private Redirectable redirMock;
+
+ @Before
+ public void setup() throws URISyntaxException {
+ MockitoAnnotations.initMocks(this);
+
+ access = new PropAccess(new PrintStream(new ByteArrayOutputStream()), new String[0]);
+ }
+
+ @Test
+ public void test() throws Exception {
+ HttpEpiTaf taf;
+ try {
+ taf = new HttpEpiTaf(access, locMock, trustCheckerMock);
+ fail("Should've thrown an exception");
+ } catch (CadiException e) {
+ assertThat(e.getMessage(), is("Need at least one HttpTaf implementation in constructor"));
+ }
+
+ taf = new HttpEpiTaf(access, locMock, trustCheckerMock, new NullTaf());
+ taf.validate(LifeForm.CBLF, reqMock, respMock);
+
+ // Coverage of tricorderScan
+ taf.validate(LifeForm.LFN, reqMock, respMock);
+ when(reqMock.getHeader("User-Agent")).thenReturn("Non-mozilla-header");
+ taf.validate(LifeForm.LFN, reqMock, respMock);
+ when(reqMock.getHeader("User-Agent")).thenReturn("Mozilla-header");
+ taf.validate(LifeForm.LFN, reqMock, respMock);
+
+ access.setLogLevel(Level.DEBUG);
+ taf.validate(LifeForm.CBLF, reqMock, respMock);
+
+ when(tafMock.validate(LifeForm.CBLF, reqMock, respMock)).thenReturn(trespMock);
+ when(trespMock.isAuthenticated()).thenReturn(RESP.TRY_ANOTHER_TAF);
+ taf = new HttpEpiTaf(access, locMock, trustCheckerMock, tafMock);
+ taf.validate(LifeForm.CBLF, reqMock, respMock);
+
+ when(trespMock.isAuthenticated()).thenReturn(RESP.IS_AUTHENTICATED);
+ taf.validate(LifeForm.CBLF, reqMock, respMock);
+
+ when(trespMock.isAuthenticated()).thenReturn(RESP.TRY_AUTHENTICATING);
+ taf.validate(LifeForm.CBLF, reqMock, respMock);
+
+ taf = new HttpEpiTaf(access, locMock, trustCheckerMock, tafMock, tafMock);
+ taf.validate(LifeForm.CBLF, reqMock, respMock);
+
+ when(tafMock.validate(LifeForm.CBLF, reqMock, respMock)).thenReturn(redirMock);
+ when(redirMock.isAuthenticated()).thenReturn(RESP.TRY_AUTHENTICATING);
+ taf.validate(LifeForm.CBLF, reqMock, respMock);
+
+ taf = new HttpEpiTaf(access, locMock, trustCheckerMock, tafMock, tafMock);
+ taf.validate(LifeForm.CBLF, reqMock, respMock);
+
+ taf = new HttpEpiTaf(access, locMock, trustCheckerMock, tafMock);
+ taf.validate(LifeForm.CBLF, reqMock, respMock);
+
+ taf = new HttpEpiTaf(access, locMock, null, tafMock);
+ when(redirMock.isAuthenticated()).thenReturn(RESP.IS_AUTHENTICATED);
+ try {
+ taf.validate(LifeForm.CBLF, reqMock, respMock);
+ fail("Should've thrown an exception");
+ } catch (Exception e) {
+ }
+
+ assertThat(taf.revalidate(null), is(false));
+ assertThat(taf.revalidate(null), is(false));
+
+ when(tafMock.revalidate(null, null)).thenReturn(Resp.NOT_MINE);
+ assertThat(taf.revalidate(null, null), is(Resp.NOT_MINE));
+ when(tafMock.revalidate(null, null)).thenReturn(Resp.REVALIDATED);
+ assertThat(taf.revalidate(null, null), is(Resp.REVALIDATED));
+
+ when(tafMock.revalidate(null, null)).thenReturn(Resp.NOT_MINE).thenReturn(Resp.NOT_MINE).thenReturn(Resp.REVALIDATED);
+ taf = new HttpEpiTaf(access, locMock, trustCheckerMock, tafMock, tafMock, tafMock);
+ assertThat(taf.revalidate(null, null), is(Resp.REVALIDATED));
+
+ taf.toString();
+
+ }
+
+}
diff --git a/cadi/core/src/test/java/org/onap/aaf/cadi/taf/test/JU_LoginPageTafResp.java b/cadi/core/src/test/java/org/onap/aaf/cadi/taf/test/JU_LoginPageTafResp.java
new file mode 100644
index 00000000..3124bbd4
--- /dev/null
+++ b/cadi/core/src/test/java/org/onap/aaf/cadi/taf/test/JU_LoginPageTafResp.java
@@ -0,0 +1,101 @@
+/**
+ * ============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.cadi.taf.test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.onap.aaf.cadi.Access;
+import org.onap.aaf.cadi.Locator;
+import org.onap.aaf.cadi.Locator.Item;
+import org.onap.aaf.cadi.LocatorException;
+import org.onap.aaf.cadi.PropAccess;
+import org.onap.aaf.cadi.taf.LoginPageTafResp;
+import org.onap.aaf.cadi.taf.Redirectable;
+import org.onap.aaf.cadi.taf.TafResp;
+import org.onap.aaf.cadi.taf.TafResp.RESP;
+
+public class JU_LoginPageTafResp {
+
+ private static final String uriString = "example.com";
+
+ private URI uri;
+ private Access access;
+ private List<Redirectable> redirectables;
+
+ @Mock private HttpServletResponse respMock;
+ @Mock private Locator<URI> locatorMock;
+ @Mock private Redirectable redirMock;
+
+ @Before
+ public void setup() throws URISyntaxException {
+ MockitoAnnotations.initMocks(this);
+
+ access = new PropAccess(new PrintStream(new ByteArrayOutputStream()), new String[0]);
+
+ redirectables = new ArrayList<>();
+ uri = new URI(uriString);
+ }
+
+ @Test
+ public void test() throws LocatorException, IOException {
+ TafResp resp;
+ resp = LoginPageTafResp.create(access, null, respMock, redirectables);
+ assertThat(resp.desc(), is("All Authentication denied"));
+
+ redirectables.add(redirMock);
+ redirectables.add(redirMock);
+ resp = LoginPageTafResp.create(access, null, respMock, redirectables);
+ assertThat((Redirectable)resp, is(redirMock));
+
+ resp = LoginPageTafResp.create(access, locatorMock, respMock, redirectables);
+ assertThat(resp.desc(), is("All Authentication denied"));
+
+ when(locatorMock.get((Item)any())).thenReturn(uri);
+ resp = LoginPageTafResp.create(access, locatorMock, respMock, redirectables);
+ assertThat(resp.desc(), is("Multiple Possible HTTP Logins available. Redirecting to Login Choice Page"));
+ assertThat(resp.authenticate(), is(RESP.HTTP_REDIRECT_INVOKED));
+ assertThat(resp.isAuthenticated(), is(RESP.TRY_AUTHENTICATING));
+
+ redirectables = new ArrayList<>();
+ resp = LoginPageTafResp.create(access, locatorMock, respMock, redirectables);
+ assertThat(resp.desc(), is("All Authentication denied"));
+
+ }
+
+}