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;
@Override
public Result<Data> 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);
}
tt.done();
}
+ } else if (cred.type==CredDAO.FQI) {
+ cred.cred = null;
+ return Result.ok(cred);
}
return Result.err(Status.ERR_Security,"invalid/unreadable credential");
}
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:
--- /dev/null
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.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<Integer>() {
+ @Override
+ public Integer code(Rcli<?> client) throws CadiException, APIException {
+ Future<CredRequest> 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);
+ }
+}
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));
deployedVersion = access.getProperty(Config.AAF_RELEASE, "N/A:2.x");
// Certificate Manager
- cmCon = new AAFConHttp(env.access(),Config.AAF_URL_CM);
+ String aaf_url_cm = env.getProperty(Config.AAF_URL_CM,Config.AAF_URL_CM_DEF);
+ cmCon = new AAFConHttp(env.access(),aaf_url_cm);
artifactsDF = env.newDataFactory(Artifacts.class);
certInfoDF = env.newDataFactory(CertInfo.class);
try {
Result<CredDAO.Data> 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();
// Note: ASPR specifies character differences, but we don't actually store the
// password to validate char differences.
- rb = ques.userCredCheck(trans, curr, rawCred);
+// byte[] rawCred = rcred.value.type==CredDAO.RAW?null:;
+
+ rb = ques.userCredCheck(trans, curr, rcred.value.cred.array());
if (rb.notOK()) {
return Result.err(rb);
} else if (rb.value){
CredDAO.Data to = new CredDAO.Data();
to.id=from.getId();
to.ns = Question.domain2ns(to.id);
- 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;
+ 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());
} else {
switch(cd.type) {
case CredDAO.BASIC_AUTH_SHA256:
+ case CredDAO.FQI:
// ok
break;
default:
# 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
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;
private class SingleItem implements Item {
}
+
+ public static AAFSingleLocator create(Access access, String url) throws URISyntaxException {
+ return new AAFSingleLocator(url);
+ }
}
}
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);
return same(ss,retryable);
}
public<RET> RET all(SecuritySetter<HttpURLConnection> ss, Retryable<RET> retryable) throws LocatorException, CadiException, APIException {
- return oneOf(ss,retryable,true,null);
+ return call(ss,retryable,true,null);
}
public<RET> RET all(SecuritySetter<HttpURLConnection> ss, Retryable<RET> retryable,boolean notify) throws LocatorException, CadiException, APIException {
- return oneOf(ss,retryable,notify,null);
+ return call(ss,retryable,notify,null);
}
+ public <RET> RET allExcept(SecuritySetter<HttpURLConnection> ss, Retryable<RET> retryable,boolean notify, String selfHost) throws LocatorException, CadiException, APIException {
+ return call(ss,retryable,notify,selfHost);
+ }
+
public<RET> RET oneOf(SecuritySetter<HttpURLConnection> ss, Retryable<RET> retryable,boolean notify,String host) throws LocatorException, CadiException, APIException {
+ return call(ss,retryable,notify,host);
+ }
+ private<RET> RET call(SecuritySetter<HttpURLConnection> ss, Retryable<RET> retryable,boolean notify,String host) throws LocatorException, CadiException, APIException {
RET ret = null;
// make sure we have all current references:
loc.refresh();
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;
}
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) {
}
}
} 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 {
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 {
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;
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;
import org.onap.aaf.cadi.http.HMangr;
import org.onap.aaf.misc.env.APIException;
+import junit.framework.Assert;
+
public class JU_HMangr {
@Mock Locator<URI> locMock;
@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
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)) {
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";
} 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<URI>)meth.invoke(null,url);
+ Method meth = lcls.getMethod("create",Access.class,String.class);
+ locator = (Locator<URI>)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);