From: Instrumental Date: Fri, 31 May 2019 15:02:47 +0000 (-0500) Subject: Update DNSLocator code and use X-Git-Tag: 2.1.15~36 X-Git-Url: https://gerrit.onap.org/r/gitweb?p=aaf%2Fauthz.git;a=commitdiff_plain;h=98adb75e5e627d28ecdf659f4c8ed640ce53ed5e Update DNSLocator code and use Issue-ID: AAF-838 Change-Id: Ieaf112365e40237b6f252371d2d2f95e9bc47f89 Signed-off-by: Instrumental --- diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/CredDAO.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/CredDAO.java index 9c57d200..868f9ac2 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/CredDAO.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/CredDAO.java @@ -53,6 +53,7 @@ public class CredDAO extends CassDAOImpl { public static final String TABLE = "cred"; public static final int CACHE_SEG = 0x40; // yields segment 0x0-0x3F public static final int RAW = -1; + public static final int FQI = 0; public static final int BASIC_AUTH = 1; public static final int BASIC_AUTH_SHA256 = 2; public static final int CERT_SHA256_RSA =200; @@ -225,8 +226,12 @@ public class CredDAO extends CassDAOImpl { @Override public Result create(AuthzTrans trans, Data data) { if(data.tag == null) { - long l = srand.nextLong(); - data.tag = Long.toHexString(l); + if(data.type==0) { + data.tag="PlaceHolder"; + } else { + long l = srand.nextLong(); + data.tag = Long.toHexString(l); + } } return super.create(trans, data); } diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java index bd0c8355..2c98a9bc 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java @@ -920,6 +920,9 @@ public class Question { tt.done(); } + } else if (cred.type==CredDAO.FQI) { + cred.cred = null; + return Result.ok(cred); } return Result.err(Status.ERR_Security,"invalid/unreadable credential"); } diff --git a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/ns/List.java b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/ns/List.java index 3dae0fa5..42306c85 100644 --- a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/ns/List.java +++ b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/ns/List.java @@ -163,8 +163,9 @@ public class List extends BaseCmd { type = 9999; } switch(type) { + case 0: return "NoCrd"; case 1: return "U/P"; - case 2: return "U/P2"; + case 2: return "U/P2"; case 10: return "Cert"; case 200: return "x509"; default: diff --git a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/ID.java b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/ID.java new file mode 100644 index 00000000..12035a16 --- /dev/null +++ b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/ID.java @@ -0,0 +1,125 @@ +/** + * ============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.cmd.user; + +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.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; + +public class ID 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"}; + public ID(User parent) { + super(parent,"fqi", + new Param(optionsToString(options),true), + new Param("id",true) + ); + } + + @Override + public int _exec(int _idx, final String ... args) throws CadiException, APIException, LocatorException { + int idx = _idx; + String key = args[idx++]; + final int option = whichOption(options,key); + + final CredRequest cr = new CredRequest(); + cr.setId(args[idx++]); + cr.setType(0); + if (args.length>idx) + cr.setEntry(args[idx]); + + // Set Start/End commands + setStartEnd(cr); + Integer ret = same(new Retryable() { + @Override + public Integer code(Rcli client) throws CadiException, APIException { + Future fp=null; + String verb =null; + switch(option) { + case 0: + fp = client.create( + CRED_PATH, + getDF(CredRequest.class), + cr + ); + verb = "Added ID ["; + break; + case 1: + setQueryParamsOn(client); + fp = client.delete(CRED_PATH, + getDF(CredRequest.class), + cr + ); + verb = "Deleted ID ["; + break; + default: + break; + } + if (fp==null) { + return null; // get by Sonar check. + } + if (fp.get(AAFcli.timeout())) { + pw().print(verb); + pw().print(cr.getId()); + pw().println(']'); + } else if (fp.code()==202) { + pw().println("ID Action Accepted, but requires Approvals before actualizing"); + } else if (fp.code()==406 && option==1) { + pw().println("You cannot delete this ID"); + } else { + pw().println(ATTEMPT_FAILED_SPECIFICS_WITHELD); + } + return fp.code(); + } + }); + if (ret==null)ret = -1; + return ret; + } + + @Override + public void detailedHelp(int _indent, StringBuilder sb) { + int indent = _indent; + detailLine(sb,indent,"Add or Delete Fully Qualified Identity: An ID attached to the Namespace"); + indent+=2; + detailLine(sb,indent,"fqi - the ID to create/delete within AAF"); + sb.append('\n'); + detailLine(sb,indent,"This usage has NO Credential, and serves only to allow IDs to be attached"); + detailLine(sb,indent,"to Roles before credentials such as Certificates are established."); + detailLine(sb,indent,"The Domain can be related to any Namespace you have access to *"); + detailLine(sb,indent,"The Domain is in reverse order of Namespace, i.e. "); + detailLine(sb,indent+2,"NS of com.att.myapp can create user of XY1234@myapp.att.com"); + indent-=2; + api(sb,indent,HttpMethods.POST,"authn/cred",CredRequest.class,true); + api(sb,indent,HttpMethods.DELETE,"authn/cred",CredRequest.class,false); + api(sb,indent,HttpMethods.PUT,"authn/cred",CredRequest.class,false); + } +} diff --git a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/User.java b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/User.java index 26e35bec..746f9c22 100644 --- a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/User.java +++ b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/User.java @@ -29,6 +29,7 @@ public class User extends BaseCmd { public User(AAFcli aafcli) throws APIException { super(aafcli,"user"); cmds.add(new Role(this)); + cmds.add(new ID(this)); cmds.add(new Cred(this)); cmds.add(new Delg(this)); cmds.add(new List(this)); diff --git a/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/AAF_GUI.java b/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/AAF_GUI.java index 359cb28b..f8aeb11b 100644 --- a/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/AAF_GUI.java +++ b/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/AAF_GUI.java @@ -131,7 +131,8 @@ public class AAF_GUI extends AbsService implements State rcred = mapper.cred(trans, from, true); if (rcred.isOKhasData()) { - byte[] rawCred = rcred.value.cred.array(); rcred = ques.userCredSetup(trans, rcred.value); final ServiceValidator v = new ServiceValidator(); @@ -2333,7 +2332,9 @@ public class AuthzCassServiceImpl 0) { - return Result.err(Status.ERR_BadData,ok); - } - } else { - to.type=0; - } - if (passwd != null) { - to.cred = ByteBuffer.wrap(passwd.getBytes()); - to.type = CredDAO.RAW; + to.type = from.getType(); + if(to.type!=null && to.type==CredDAO.FQI) { + to.cred = null; } else { - to.type = 0; - } - + String passwd = from.getPassword(); + if (requiresPass) { + String ok = trans.org().isValidPassword(trans, to.id,passwd); + if (ok.length()>0) { + return Result.err(Status.ERR_BadData,ok); + } + } else { + to.type=0; + } + if (passwd != null) { + to.cred = ByteBuffer.wrap(passwd.getBytes()); + to.type = CredDAO.RAW; + } else { + to.type = CredDAO.FQI; + } + } + // Note: Ensure requested EndDate created will match Organization Password Rules // P.S. Do not apply TempPassword rule here. Do that when you know you are doing a Create/Reset (see Service) to.expires = getExpires(trans.org(),Expiration.Password,base,from.getId()); diff --git a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/validation/ServiceValidator.java b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/validation/ServiceValidator.java index 128fdcd1..adff4612 100644 --- a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/validation/ServiceValidator.java +++ b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/validation/ServiceValidator.java @@ -162,6 +162,7 @@ public class ServiceValidator extends Validator { } else { switch(cd.type) { case CredDAO.BASIC_AUTH_SHA256: + case CredDAO.FQI: // ok break; default: diff --git a/auth/helm/aaf/values.yaml b/auth/helm/aaf/values.yaml index 4ae0777e..fae26290 100644 --- a/auth/helm/aaf/values.yaml +++ b/auth/helm/aaf/values.yaml @@ -114,7 +114,7 @@ image: # When using Docker Repo, add, and include trailing "/" # repository: nexus3.onap.org:10003/ # repository: localhost:5000/ - version: 2.1.14 + version: 2.1.14-SNAPSHOT resources: {} # We usually recommend not to specify default resources and to leave this as a conscious diff --git a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFSingleLocator.java b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFSingleLocator.java index 93ab4ab8..80e9f190 100644 --- a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFSingleLocator.java +++ b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFSingleLocator.java @@ -23,6 +23,7 @@ package org.onap.aaf.cadi.aaf.v2_0; import java.net.URI; import java.net.URISyntaxException; +import org.onap.aaf.cadi.Access; import org.onap.aaf.cadi.Locator; import org.onap.aaf.cadi.LocatorException; @@ -89,4 +90,8 @@ public class AAFSingleLocator implements Locator { private class SingleItem implements Item { } + + public static AAFSingleLocator create(Access access, String url) throws URISyntaxException { + return new AAFSingleLocator(url); + } } diff --git a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AbsAAFLocator.java b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AbsAAFLocator.java index 2405962c..ac8168b9 100644 --- a/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AbsAAFLocator.java +++ b/cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AbsAAFLocator.java @@ -74,7 +74,12 @@ public abstract class AbsAAFLocator implements Locator } try { aaf_locator_host = rph.replacements(getClass().getSimpleName(),"https://"+Config.AAF_LOCATE_URL_TAG,null,null); - aaf_locator_uri = new URI(aaf_locator_host); + if(aaf_locator_host.endsWith("/locate")) { + aaf_locator_uri = new URI(aaf_locator_host); + } else { + aaf_locator_uri = new URI(aaf_locator_host+"/locate"); + } + access.printf(Level.INFO, "AbsAAFLocator AAF URI is %s",aaf_locator_uri); } catch (URISyntaxException e) { throw new LocatorException(e); diff --git a/cadi/client/src/main/java/org/onap/aaf/cadi/http/HMangr.java b/cadi/client/src/main/java/org/onap/aaf/cadi/http/HMangr.java index 1e5c5211..ae562cb2 100644 --- a/cadi/client/src/main/java/org/onap/aaf/cadi/http/HMangr.java +++ b/cadi/client/src/main/java/org/onap/aaf/cadi/http/HMangr.java @@ -162,14 +162,21 @@ public class HMangr { return same(ss,retryable); } public RET all(SecuritySetter ss, Retryable retryable) throws LocatorException, CadiException, APIException { - return oneOf(ss,retryable,true,null); + return call(ss,retryable,true,null); } public RET all(SecuritySetter ss, Retryable retryable,boolean notify) throws LocatorException, CadiException, APIException { - return oneOf(ss,retryable,notify,null); + return call(ss,retryable,notify,null); } + public RET allExcept(SecuritySetter ss, Retryable retryable,boolean notify, String selfHost) throws LocatorException, CadiException, APIException { + return call(ss,retryable,notify,selfHost); + } + public RET oneOf(SecuritySetter ss, Retryable retryable,boolean notify,String host) throws LocatorException, CadiException, APIException { + return call(ss,retryable,notify,host); + } + private RET call(SecuritySetter ss, Retryable retryable,boolean notify,String host) throws LocatorException, CadiException, APIException { RET ret = null; // make sure we have all current references: loc.refresh(); diff --git a/cadi/client/src/main/java/org/onap/aaf/cadi/locator/DNSLocator.java b/cadi/client/src/main/java/org/onap/aaf/cadi/locator/DNSLocator.java index 8357129f..b7c0b02c 100644 --- a/cadi/client/src/main/java/org/onap/aaf/cadi/locator/DNSLocator.java +++ b/cadi/client/src/main/java/org/onap/aaf/cadi/locator/DNSLocator.java @@ -60,23 +60,27 @@ public class DNSLocator implements Locator { if (aaf_locate==null) { throw new LocatorException("Null passed into DNSLocator constructor"); } - int start, port; + int start, defPort; if (aaf_locate.startsWith("https:")) { - protocol = "https:"; - start = 9; // https:// - port = 443; + protocol = "https"; + start = 8; // https:// + defPort = 443; } else if (aaf_locate.startsWith("http:")) { - protocol = "http:"; - start = 8; // http:// - port = 80; + protocol = "http"; + start = 7; // http:// + defPort = 80; } else { throw new LocatorException("DNSLocator accepts only https or http protocols. (requested URL " + aaf_locate + ')'); } - - parsePorts(aaf_locate.substring(start), port); + host = parseHostAndPorts(aaf_locate, start, defPort); + refresh(); } - @Override + public static DNSLocator create(Access access, String url) throws LocatorException { + return new DNSLocator(access, url); + } + + @Override public URI get(Item item) throws LocatorException { return hosts[((DLItem)item).cnt].uri; } @@ -159,10 +163,11 @@ public class DNSLocator implements Locator { return false; } - private void parsePorts(String aaf_locate, int defaultPort) throws LocatorException { + private String parseHostAndPorts(String aaf_locate, int _start, int defaultPort) throws LocatorException { int slash, start; - int colon = aaf_locate.indexOf(':'); + int colon = aaf_locate.indexOf(':',_start); if (colon > 0) { + host = aaf_locate.substring(_start,colon); start = colon + 1; int left = aaf_locate.indexOf('[', start); if (left > 0) { @@ -195,8 +200,12 @@ public class DNSLocator implements Locator { } } } else { + slash = aaf_locate.indexOf('/', _start); + host = slash<_start?aaf_locate.substring(_start):aaf_locate.substring(_start,slash); startPort = endPort = defaultPort; - } + } + + return host; } private class Host { @@ -206,9 +215,13 @@ public class DNSLocator implements Locator { public Host(InetAddress inetAddress, int port, String suffix) throws URISyntaxException { ia = inetAddress; - uri = new URI(protocol,null,inetAddress.getHostAddress(),port,suffix,null,null); + uri = new URI(protocol,null,inetAddress.getCanonicalHostName(),port,suffix,null,null); status = Status.UNTRIED; } + + public String toString() { + return uri.toString() + " - " + status.name(); + } } private class DLItem implements Item { diff --git a/cadi/client/src/test/java/org/onap/aaf/cadi/http/test/JU_HMangr.java b/cadi/client/src/test/java/org/onap/aaf/cadi/http/test/JU_HMangr.java index 9d87d699..d1744253 100644 --- a/cadi/client/src/test/java/org/onap/aaf/cadi/http/test/JU_HMangr.java +++ b/cadi/client/src/test/java/org/onap/aaf/cadi/http/test/JU_HMangr.java @@ -21,8 +21,14 @@ package org.onap.aaf.cadi.http.test; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.when; import java.io.ByteArrayOutputStream; import java.io.PrintStream; @@ -34,10 +40,10 @@ import java.net.URISyntaxException; import javax.net.ssl.SSLHandshakeException; -import static org.hamcrest.CoreMatchers.*; - -import org.junit.*; -import org.mockito.*; +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.CadiException; import org.onap.aaf.cadi.Locator; @@ -49,6 +55,8 @@ import org.onap.aaf.cadi.client.Retryable; import org.onap.aaf.cadi.http.HMangr; import org.onap.aaf.misc.env.APIException; +import junit.framework.Assert; + public class JU_HMangr { @Mock Locator locMock; @@ -173,9 +181,14 @@ public class JU_HMangr { @Test public void allTest() throws LocatorException, CadiException, APIException { HManagerStub hman = new HManagerStub(access, locMock); + assertThat(hman.best(ssMock, retryableMock), is(nullValue())); - assertThat(hman.all(ssMock, retryableMock), is(nullValue())); - assertThat(hman.all(ssMock, retryableMock, true), is(nullValue())); + try { + hman.all(ssMock, retryableMock, true); + Assert.fail("Should have thrown LocatorException"); + } catch (LocatorException e) { + assertEquals(e.getLocalizedMessage(),"No available clients to call"); + } } @Test diff --git a/cadi/client/src/test/java/org/onap/aaf/cadi/locator/test/JU_DNSLocator.java b/cadi/client/src/test/java/org/onap/aaf/cadi/locator/test/JU_DNSLocator.java index 9b5bbafe..dfc7142a 100644 --- a/cadi/client/src/test/java/org/onap/aaf/cadi/locator/test/JU_DNSLocator.java +++ b/cadi/client/src/test/java/org/onap/aaf/cadi/locator/test/JU_DNSLocator.java @@ -53,9 +53,9 @@ public class JU_DNSLocator { item = dl.best(); uri = dl.get(item); - assertThat(uri.toString(), is("https://127.0.0.1:8100")); + assertThat(uri.toString(), is("https://localhost:8100")); item = dl.best(); - assertThat(uri.toString(), is("https://127.0.0.1:8100")); + assertThat(uri.toString(), is("https://localhost:8100")); assertThat(dl.hasItems(), is(true)); for (item = dl.first(); item != null; item = dl.next(item)) { diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/config/Config.java b/cadi/core/src/main/java/org/onap/aaf/cadi/config/Config.java index 8cb1045b..52bb53ef 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/config/Config.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/config/Config.java @@ -221,6 +221,7 @@ public class Config { 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"; + public static final String AAF_URL_CM_DEF = "https://AAF_LOCATE_URL/AAF_NS.cm:"+AAF_DEFAULT_API_VERSION; public static final String AAF_URL_HELLO = "aaf_url_hello"; public static final String CM_TRUSTED_CAS = "cm_trusted_cas"; @@ -856,18 +857,24 @@ public class Config { } 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_DEF); + 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",String.class); - locator = (Locator)meth.invoke(null,url); + Method meth = lcls.getMethod("create",Access.class,String.class); + locator = (Locator)meth.invoke(null,access,url); } catch (Exception e) { - access.log(Level.DEBUG, "(Not fatal) Cannot load by create(String)", e); + access.log(Level.TRACE, "(Not fatal) Cannot load by create(String)", e); } if (locator==null) { URI locatorURI = new URI(url);