diff options
Diffstat (limited to 'auth')
8 files changed, 327 insertions, 240 deletions
diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/FutureDAO.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/FutureDAO.java index 7831815f..72c0e98b 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/FutureDAO.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/FutureDAO.java @@ -90,9 +90,9 @@ public class FutureDAO extends CassDAOImpl<AuthzTrans,FutureDAO.Data> { data.memo = row.getString(2); data.start = row.getTimestamp(3); data.expires = row.getTimestamp(4); - data.construct = row.getBytes(5); - data.target_key = row.getString(6); - data.target_date = row.getTimestamp(7); + data.target_key = row.getString(5); + data.target_date = row.getTimestamp(6); + data.construct = row.getBytes(7); return data; } @@ -109,9 +109,9 @@ public class FutureDAO extends CassDAOImpl<AuthzTrans,FutureDAO.Data> { obj[++idx] = data.memo; obj[++idx] = data.start; obj[++idx] = data.expires; - obj[++idx] = data.construct; obj[++idx] = data.target_key; obj[++idx] = data.target_date; + obj[++idx] = data.construct; } } diff --git a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/AAFcli.java b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/AAFcli.java index edbe2068..8fcea294 100644 --- a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/AAFcli.java +++ b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/AAFcli.java @@ -94,6 +94,10 @@ public class AAFcli { this(access,new AuthzEnv(access.getProperties()),wtr,hman, si,ss); } + public AuthzEnv env() { + return env; + } + public AAFcli(Access access, AuthzEnv env, Writer wtr, HMangr hman, SecurityInfoC<HttpURLConnection> si, SecuritySetter<HttpURLConnection> ss) throws APIException { this.env = env; this.access = access; @@ -328,7 +332,7 @@ public class AAFcli { Thread.sleep((long)(delay+globalDelay)); } } catch (Exception e) { - if (expect.contains(-1)) { + if (expect.contains(-1)) { pw.println(e.getMessage()); ret = -1; } else { diff --git a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/Cred.java b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/Cred.java index d41f0cf3..a1cb3e7a 100644 --- a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/Cred.java +++ b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/Cred.java @@ -21,30 +21,37 @@ package org.onap.aaf.auth.cmd.user; +import java.util.List; + 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.aaf.client.ErrMessage; 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; +import aaf.v2_0.Error; public class Cred 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","reset","extend"/*,"clean"*/}; - public Cred(User parent) { + private ErrMessage em; +// private RosettaDF<Error> errDF; + public Cred(User parent) throws APIException { super(parent,"cred", new Param(optionsToString(options),true), new Param("id",true), new Param("password (! D|E)",false), new Param("entry# (if multi)",false) ); + em = new ErrMessage(aafcli.env()); } @Override @@ -59,8 +66,9 @@ public class Cred extends Cmd { if (idx>=args.length) throw new CadiException("Password Required"); cr.setPassword(args[idx++]); } - if (args.length>idx) + if (args.length>idx) { cr.setEntry(args[idx]); + } // Set Start/End commands setStartEnd(cr); @@ -114,6 +122,19 @@ public class Cred extends Cmd { pw().println(']'); } else if (fp.code()==202) { pw().println("Credential Action Accepted, but requires Approvals before actualizing"); + } else if (fp.code()==300) { + Error err = em.getError(fp); + String text = err.getText(); + List<String> vars = err.getVariables(); + + // IMPORTANT! We do this backward, because it is looking for string + // %1 or %13. If we replace %1 first, that messes up %13 + for(int i=vars.size()-1;i>0;--i) { + text = text.replace("%"+(i+1), (i<10?" ":"") + i+") " + vars.get(i)); + } + + text = text.replace("%1",vars.get(0)); + pw().println(text); } else if (fp.code()==406 && option==1) { pw().println("You cannot delete this Credential"); } else { diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/server/AbsServiceStarter.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/server/AbsServiceStarter.java index f5831139..11ba6562 100644 --- a/auth/auth-core/src/main/java/org/onap/aaf/auth/server/AbsServiceStarter.java +++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/server/AbsServiceStarter.java @@ -128,6 +128,7 @@ public abstract class AbsServiceStarter<ENV extends RosettaEnv, TRANS extends Tr _start(service); } catch (Exception e) { e.printStackTrace(); + shutdown(); } } diff --git a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java index 8fc2ad52..37ca509a 100644 --- a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java +++ b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java @@ -73,6 +73,7 @@ import org.onap.aaf.auth.dao.hl.Function.OP_STATUS; import org.onap.aaf.auth.dao.hl.Question; import org.onap.aaf.auth.dao.hl.Question.Access; import org.onap.aaf.auth.env.AuthzTrans; +import org.onap.aaf.auth.env.AuthzTrans.REQD_TYPE; import org.onap.aaf.auth.layer.Result; import org.onap.aaf.auth.org.Executor; import org.onap.aaf.auth.org.Organization; @@ -85,6 +86,7 @@ import org.onap.aaf.auth.service.mapper.Mapper; import org.onap.aaf.auth.service.mapper.Mapper.API; import org.onap.aaf.auth.service.validation.ServiceValidator; import org.onap.aaf.auth.validation.Validator; +import org.onap.aaf.cadi.aaf.Defaults; import org.onap.aaf.cadi.principal.BasicPrincipal; import org.onap.aaf.cadi.util.FQI; import org.onap.aaf.misc.env.Env; @@ -113,7 +115,8 @@ import aaf.v2_0.CredRequest; public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> implements AuthzService <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> { - private Mapper <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> mapper; + private static final String TWO_SPACE = " "; + private Mapper <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> mapper; @Override public Mapper <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> mapper() {return mapper;} @@ -1988,6 +1991,9 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE public Result<?> mayChange() { if (nsd==null) { nsd = ques.mayUser(trans, trans.user(), rpd.value, Access.write); + if(nsd.notOK()) { + trans.requested(REQD_TYPE.future,true); + } } return nsd; } @@ -1997,32 +2003,32 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE return Result.err(nsr); } switch(fd.status) { - case OK: - Result<String> rfc = func.createFuture(trans,fd.value, - rpd.value.fullPerm(), - trans.user(), - nsr.value.get(0), - FUTURE_OP.G); - if (rfc.isOK()) { - return Result.err(Status.ACC_Future, "Perm [%s.%s|%s|%s] is saved for future processing", - rpd.value.ns, - rpd.value.type, - rpd.value.instance, - rpd.value.action); - } else { - return Result.err(rfc); - } - case Status.ACC_Now: - Result<Void> rv = null; - if (createPerm!=null) {// has been validated for creating - rv = func.createPerm(trans, createPerm, false); - } - if (rv==null || rv.isOK()) { - rv = func.addPermToRole(trans, rrd.value, rpd.value, false); - } - return rv; - default: - return Result.err(fd); + case OK: + Result<String> rfc = func.createFuture(trans,fd.value, + rpd.value.fullPerm(), + trans.user(), + nsr.value.get(0), + FUTURE_OP.G); + if (rfc.isOK()) { + return Result.err(Status.ACC_Future, "Perm [%s.%s|%s|%s] is saved for future processing", + rpd.value.ns, + rpd.value.type, + rpd.value.instance, + rpd.value.action); + } else { + return Result.err(rfc); + } + case Status.ACC_Now: + Result<Void> rv = null; + if (createPerm!=null) {// has been validated for creating + rv = func.createPerm(trans, createPerm, false); + } + if (rv==null || rv.isOK()) { + rv = func.addPermToRole(trans, rrd.value, rpd.value, false); + } + return rv; + default: + return Result.err(fd); } } @@ -2300,13 +2306,17 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE } private class MayChangeCred implements MayChange { - - private Result<NsDAO.Data> nsd; + private static final String EXTEND = "extend"; + private static final String RESET = "reset"; + private static final String DELETE = "delete"; + private Result<NsDAO.Data> nsd; private AuthzTrans trans; private CredDAO.Data cred; - public MayChangeCred(AuthzTrans trans, CredDAO.Data cred) { + private String action; + public MayChangeCred(AuthzTrans trans, CredDAO.Data cred, String action) { this.trans = trans; this.cred = cred; + this.action = action; } @Override @@ -2317,17 +2327,38 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE } // Get the Namespace if (nsd.isOK()) { - String user[] = Split.split('.',trans.user()); - if (user.length>2) { - String company = user[user.length-1] + '.' + user[user.length-2]; - if (ques.isGranted(trans, trans.user(), ROOT_NS,"password",company,"reset")) { - return Result.ok(); - } - } + String ns = nsd.value.name; + String user = trans.user(); + String company; + String temp[] = Split.split('.',ns); + switch(temp.length) { + case 0: + company = Defaults.AAF_NS; + break; + case 1: + company = temp[0]; + break; + default: + company = temp[0] + '.' + temp[1]; + } + switch(action) { + case DELETE: + if(ques.isOwner(trans, user,ns) || + ques.isAdmin(trans, user,ns) || + ques.isGranted(trans, user, ROOT_NS,"password",company,DELETE)) { + return Result.ok(); + } + break; + case RESET: + case EXTEND: + if (ques.isGranted(trans, trans.user(), ROOT_NS,"password",company,action)) { + return Result.ok(); + } + break; + } } - return Result.err(Status.ERR_Denied,"%s is not allowed to change %s in %s",trans.user(),cred.id,cred.ns); + return Result.err(Status.ERR_Denied,"%s is not allowed to %s %s in %s",trans.user(),action,cred.id,cred.ns); } - } private final long DAY_IN_MILLIS = 24*3600*1000L; @@ -2626,7 +2657,7 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE } ) @Override - public Result<Void> changeUserCred(final AuthzTrans trans, REQUEST from) { + public Result<Void> resetUserCred(final AuthzTrans trans, REQUEST from) { final String cmdDescription = "Update User Credential"; TimeTaken tt = trans.start(cmdDescription, Env.SUB); try { @@ -2644,13 +2675,15 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE return Result.err(Status.ERR_UserNotFound, "Credential does not exist"); } - MayChange mc = new MayChangeCred(trans, rcred.value); + MayChange mc = new MayChangeCred(trans, rcred.value,MayChangeCred.RESET); Result<?> rmc = mc.mayChange(); if (rmc.notOK()) { return Result.err(rmc); } - Result<Integer> ri = selectEntryIfMultiple((CredRequest)from, rlcd.value); + List<CredDAO.Data> lcdd = filterList(rlcd.value,CredDAO.BASIC_AUTH, CredDAO.BASIC_AUTH_SHA256); + + Result<Integer> ri = selectEntryIfMultiple((CredRequest)from, lcdd, MayChangeCred.RESET); if (ri.notOK()) { return Result.err(ri); } @@ -2733,27 +2766,6 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE } } - /* - * Codify the way to get Either Choice Needed or actual Integer from Credit Request - */ - private Result<Integer> selectEntryIfMultiple(final CredRequest cr, List<CredDAO.Data> lcd) { - int entry = 0; - if (lcd.size() > 1) { - String inputOption = cr.getEntry(); - if (inputOption == null) { - String message = selectCredFromList(lcd, false); - Object[] variables = buildVariables(lcd); - return Result.err(Status.ERR_ChoiceNeeded, message, variables); - } else { - entry = Integer.parseInt(inputOption) - 1; - } - if (entry < 0 || entry >= lcd.size()) { - return Result.err(Status.ERR_BadData, "User chose invalid credential selection"); - } - } - return Result.ok(entry); - } - @ApiDoc( method = PUT, path = "/authn/cred/:days", @@ -2795,14 +2807,18 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE if (rlcd.notOKorIsEmpty()) { return Result.err(Status.ERR_UserNotFound, "Credential does not exist"); } + + // Only Passwords can be extended + List<CredDAO.Data> lcdd = filterList(rlcd.value,CredDAO.BASIC_AUTH, CredDAO.BASIC_AUTH_SHA256); //Need to do the "Pick Entry" mechanism - Result<Integer> ri = selectEntryIfMultiple((CredRequest)from, rlcd.value); + // Note, this sorts + Result<Integer> ri = selectEntryIfMultiple((CredRequest)from, lcdd, "extend"); if (ri.notOK()) { return Result.err(ri); } - CredDAO.Data found = rlcd.value.get(ri.value); + CredDAO.Data found = lcdd.get(ri.value); CredDAO.Data cd = cred.value; // Copy over the cred cd.id = found.id; @@ -2824,29 +2840,204 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE } } - private String[] buildVariables(List<CredDAO.Data> value) { + @ApiDoc( + method = DELETE, + path = "/authn/cred", + params = {}, + expectedCode = 200, + errorCodes = {300,403,404,406}, + text = { "Delete a Credential. If multiple credentials exist for this", + "ID, you will need to specify which entry you are deleting in the", + "CredRequest object." + } + ) + @Override + public Result<Void> deleteUserCred(AuthzTrans trans, REQUEST from) { + final Result<CredDAO.Data> cred = mapper.cred(trans, from, false); + final Validator v = new ServiceValidator(); + if (v.nullOrBlank("cred", cred.value.id).err()) { + return Result.err(Status.ERR_BadData,v.errs()); + } + + MayChange mc = new MayChangeCred(trans,cred.value,MayChangeCred.DELETE); + Result<?> rmc = mc.mayChange(); + if (rmc.notOK()) { + return Result.err(rmc); + } + + Result<List<CredDAO.Data>> rlcd = ques.credDAO().readID(trans, cred.value.id); + if (rlcd.notOKorIsEmpty()) { + // Empty Creds should have no user_roles. + Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO().readByUser(trans, cred.value.id); + if (rlurd.isOK()) { + for (UserRoleDAO.Data data : rlurd.value) { + ques.userRoleDAO().delete(trans, data, false); + } + } + return Result.err(Status.ERR_UserNotFound, "Credential does not exist"); + } + boolean isLastCred = rlcd.value.size()==1; + + + int entry = 0; + if (!trans.requested(force)) { + if (rlcd.value.size() > 1) { + CredRequest cr = (CredRequest)from; + String inputOption = cr.getEntry(); + if (inputOption == null) { + List<CredDAO.Data> list = filterList(rlcd.value,CredDAO.BASIC_AUTH,CredDAO.BASIC_AUTH_SHA256,CredDAO.CERT_SHA256_RSA); + String message = selectCredFromList(list, MayChangeCred.DELETE); + Object[] variables = buildVariables(list); + return Result.err(Status.ERR_ChoiceNeeded, message, variables); + } else { + try { + if (inputOption.length()>5) { // should be a date + Date d = Chrono.xmlDatatypeFactory.newXMLGregorianCalendar(inputOption).toGregorianCalendar().getTime(); + entry = 0; + for (CredDAO.Data cd : rlcd.value) { + if (cd.type.equals(cr.getType()) && cd.expires.equals(d)) { + break; + } + ++entry; + } + } else { + entry = Integer.parseInt(inputOption) - 1; + } + } catch (NullPointerException e) { + return Result.err(Status.ERR_BadData, "Invalid Date Format for Entry"); + } catch (NumberFormatException e) { + return Result.err(Status.ERR_BadData, "User chose invalid credential selection"); + } + } + isLastCred = (entry==-1)?true:false; + } else { + isLastCred = true; + } + if (entry < -1 || entry >= rlcd.value.size()) { + return Result.err(Status.ERR_BadData, "User chose invalid credential selection"); + } + } + + Result<FutureDAO.Data> fd = mapper.future(trans,CredDAO.TABLE,from,cred.value,false, + () -> "Delete Credential [" + + cred.value.id + + ']', + mc); + + Result<List<NsDAO.Data>> nsr = ques.nsDAO().read(trans, cred.value.ns); + if (nsr.notOKorIsEmpty()) { + return Result.err(nsr); + } + + switch(fd.status) { + case OK: + Result<String> rfc = func.createFuture(trans, fd.value, cred.value.id, + trans.user(), nsr.value.get(0), FUTURE_OP.D); + + if (rfc.isOK()) { + return Result.err(Status.ACC_Future, "Credential Delete [%s] is saved for future processing",cred.value.id); + } else { + return Result.err(rfc); + } + case Status.ACC_Now: + Result<?>udr = null; + if (!trans.requested(force)) { + if (entry<0 || entry >= rlcd.value.size()) { + return Result.err(Status.ERR_BadData,"Invalid Choice [" + entry + "] chosen for Delete [%s] is saved for future processing",cred.value.id); + } + udr = ques.credDAO().delete(trans, rlcd.value.get(entry),false); + } else { + for (CredDAO.Data curr : rlcd.value) { + udr = ques.credDAO().delete(trans, curr, false); + if (udr.notOK()) { + return Result.err(udr); + } + } + } + if (isLastCred) { + Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO().readByUser(trans, cred.value.id); + if (rlurd.isOK()) { + for (UserRoleDAO.Data data : rlurd.value) { + ques.userRoleDAO().delete(trans, data, false); + } + } + } + if (udr==null) { + return Result.err(Result.ERR_NotFound,"No User Data found"); + } + if (udr.isOK()) { + return Result.ok(); + } + return Result.err(udr); + default: + return Result.err(fd); + } + + } + + /* + * Codify the way to get Either Choice Needed or actual Integer from Credit Request + */ + private Result<Integer> selectEntryIfMultiple(final CredRequest cr, List<CredDAO.Data> lcd, String action) { + int entry = 0; + if (lcd.size() > 1) { + String inputOption = cr.getEntry(); + if (inputOption == null) { + String message = selectCredFromList(lcd, action); + Object[] variables = buildVariables(lcd); + return Result.err(Status.ERR_ChoiceNeeded, message, variables); + } else { + entry = Integer.parseInt(inputOption) - 1; + } + if (entry < 0 || entry >= lcd.size()) { + return Result.err(Status.ERR_BadData, "User chose invalid credential selection"); + } + } + return Result.ok(entry); + } + + private List<CredDAO.Data> filterList(List<CredDAO.Data> orig, Integer ... types) { + List<CredDAO.Data> rv = new ArrayList<>(); + for(CredDAO.Data cdd : orig) { + if(cdd!=null) { + for(int t : types) { + if(t==cdd.type) { + rv.add(cdd); + } + } + } + } + return rv; + } + + private String[] buildVariables(List<CredDAO.Data> value) { // ensure credentials are sorted so we can fully automate Cred regression test - Collections.sort(value, (cred1, cred2) -> cred1.expires.compareTo(cred2.expires)); + Collections.sort(value, (cred1, cred2) -> + cred1.type==cred2.type?cred2.expires.compareTo(cred1.expires): + cred1.type<cred2.type?-1:1); String [] vars = new String[value.size()+1]; vars[0]="Choice"; + CredDAO.Data cdd; for (int i = 0; i < value.size(); i++) { - vars[i+1] = value.get(i).id + " " + value.get(i).type - + " |" + value.get(i).expires; + cdd = value.get(i); + vars[i+1] = cdd.id + TWO_SPACE + cdd.type + TWO_SPACE + (cdd.type<10?TWO_SPACE:"")+ cdd.expires + TWO_SPACE + cdd.tag; } return vars; } - private String selectCredFromList(List<CredDAO.Data> value, boolean isDelete) { + private String selectCredFromList(List<CredDAO.Data> value, String action) { StringBuilder errMessage = new StringBuilder(); - String userPrompt = isDelete?"Select which cred to delete (set force=true to delete all):":"Select which cred to update:"; + String userPrompt = MayChangeCred.DELETE.equals(action)? + "Select which cred to delete (set force=true to delete all):": + "Select which cred to " + action + ':'; int numSpaces = value.get(0).id.length() - "Id".length(); errMessage.append(userPrompt + '\n'); - errMessage.append(" Id"); + errMessage.append(" ID"); for (int i = 0; i < numSpaces; i++) { errMessage.append(' '); } - errMessage.append(" Type Expires" + '\n'); + errMessage.append(" Type Expires Tag " + '\n'); for (int i=0;i<value.size();++i) { errMessage.append(" %s\n"); } @@ -2856,140 +3047,6 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE } - @ApiDoc( - method = DELETE, - path = "/authn/cred", - params = {}, - expectedCode = 200, - errorCodes = {300,403,404,406}, - text = { "Delete a Credential. If multiple credentials exist for this", - "ID, you will need to specify which entry you are deleting in the", - "CredRequest object." - } - ) - @Override - public Result<Void> deleteUserCred(AuthzTrans trans, REQUEST from) { - final Result<CredDAO.Data> cred = mapper.cred(trans, from, false); - final Validator v = new ServiceValidator(); - if (v.nullOrBlank("cred", cred.value.id).err()) { - return Result.err(Status.ERR_BadData,v.errs()); - } - - Result<List<CredDAO.Data>> rlcd = ques.credDAO().readID(trans, cred.value.id); - if (rlcd.notOKorIsEmpty()) { - // Empty Creds should have no user_roles. - Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO().readByUser(trans, cred.value.id); - if (rlurd.isOK()) { - for (UserRoleDAO.Data data : rlurd.value) { - ques.userRoleDAO().delete(trans, data, false); - } - } - return Result.err(Status.ERR_UserNotFound, "Credential does not exist"); - } - boolean isLastCred = rlcd.value.size()==1; - - MayChange mc = new MayChangeCred(trans,cred.value); - Result<?> rmc = mc.mayChange(); - if (rmc.notOK()) { - return Result.err(rmc); - } - - int entry = 0; - if (!trans.requested(force)) { - if (rlcd.value.size() > 1) { - CredRequest cr = (CredRequest)from; - String inputOption = cr.getEntry(); - if (inputOption == null) { - String message = selectCredFromList(rlcd.value, true); - Object[] variables = buildVariables(rlcd.value); - return Result.err(Status.ERR_ChoiceNeeded, message, variables); - } else { - try { - if (inputOption.length()>5) { // should be a date - Date d = Chrono.xmlDatatypeFactory.newXMLGregorianCalendar(inputOption).toGregorianCalendar().getTime(); - entry = 0; - for (CredDAO.Data cd : rlcd.value) { - if (cd.type.equals(cr.getType()) && cd.expires.equals(d)) { - break; - } - ++entry; - } - } else { - entry = Integer.parseInt(inputOption) - 1; - } - } catch (NullPointerException e) { - return Result.err(Status.ERR_BadData, "Invalid Date Format for Entry"); - } catch (NumberFormatException e) { - return Result.err(Status.ERR_BadData, "User chose invalid credential selection"); - } - } - isLastCred = (entry==-1)?true:false; - } else { - isLastCred = true; - } - if (entry < -1 || entry >= rlcd.value.size()) { - return Result.err(Status.ERR_BadData, "User chose invalid credential selection"); - } - } - - Result<FutureDAO.Data> fd = mapper.future(trans,CredDAO.TABLE,from,cred.value,false, - () -> "Delete Credential [" + - cred.value.id + - ']', - mc); - - Result<List<NsDAO.Data>> nsr = ques.nsDAO().read(trans, cred.value.ns); - if (nsr.notOKorIsEmpty()) { - return Result.err(nsr); - } - - switch(fd.status) { - case OK: - Result<String> rfc = func.createFuture(trans, fd.value, cred.value.id, - trans.user(), nsr.value.get(0), FUTURE_OP.D); - - if (rfc.isOK()) { - return Result.err(Status.ACC_Future, "Credential Delete [%s] is saved for future processing",cred.value.id); - } else { - return Result.err(rfc); - } - case Status.ACC_Now: - Result<?>udr = null; - if (!trans.requested(force)) { - if (entry<0 || entry >= rlcd.value.size()) { - return Result.err(Status.ERR_BadData,"Invalid Choice [" + entry + "] chosen for Delete [%s] is saved for future processing",cred.value.id); - } - udr = ques.credDAO().delete(trans, rlcd.value.get(entry),false); - } else { - for (CredDAO.Data curr : rlcd.value) { - udr = ques.credDAO().delete(trans, curr, false); - if (udr.notOK()) { - return Result.err(udr); - } - } - } - if (isLastCred) { - Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO().readByUser(trans, cred.value.id); - if (rlurd.isOK()) { - for (UserRoleDAO.Data data : rlurd.value) { - ques.userRoleDAO().delete(trans, data, false); - } - } - } - if (udr==null) { - return Result.err(Result.ERR_NotFound,"No User Data found"); - } - if (udr.isOK()) { - return Result.ok(); - } - return Result.err(udr); - default: - return Result.err(fd); - } - - } - - @Override public Result<Date> doesCredentialMatch(AuthzTrans trans, REQUEST credReq) { TimeTaken tt = trans.start("Does Credential Match", Env.SUB); @@ -3015,22 +3072,6 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE } @ApiDoc( - method = GET, - path = "/authn/basicAuth", - params = {}, - expectedCode = 200, - errorCodes = { 403 }, - text = { "!!!! DEPRECATED without X509 Authentication STOP USING THIS API BY DECEMBER 2017, or use Certificates !!!!\n" - + "Use /authn/validate instead\n" - + "Note: Validate a Password using BasicAuth Base64 encoded Header. This HTTP/S call is intended as a fast" - + " User/Password lookup for Security Frameworks, and responds 200 if it passes BasicAuth " - + "security, and 403 if it does not." } - ) - private void basicAuth() { - // This is a place holder for Documentation. The real BasicAuth API does not call Service. - } - - @ApiDoc( method = POST, path = "/authn/validate", params = {}, @@ -3060,6 +3101,22 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE return Result.err(Status.ERR_Denied,"Bad Basic Auth"); } +@ApiDoc( + method = GET, + path = "/authn/basicAuth", + params = {}, + expectedCode = 200, + errorCodes = { 403 }, + text = { "!!!! DEPRECATED without X509 Authentication STOP USING THIS API BY DECEMBER 2017, or use Certificates !!!!\n" + + "Use /authn/validate instead\n" + + "Note: Validate a Password using BasicAuth Base64 encoded Header. This HTTP/S call is intended as a fast" + + " User/Password lookup for Security Frameworks, and responds 200 if it passes BasicAuth " + + "security, and 403 if it does not." } + ) + private void basicAuth() { + // This is a place holder for Documentation. The real BasicAuth API does not call Service. + } + /*********************************** * USER-ROLE ***********************************/ diff --git a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzService.java b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzService.java index 61dbbd95..80d317f0 100644 --- a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzService.java +++ b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzService.java @@ -447,7 +447,7 @@ public interface AuthzService<NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERT * @param from * @return */ - Result<Void> changeUserCred(AuthzTrans trans, REQUEST from); + Result<Void> resetUserCred(AuthzTrans trans, REQUEST from); /** * diff --git a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/facade/AuthzFacadeImpl.java b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/facade/AuthzFacadeImpl.java index 253f91da..e85e52ec 100644 --- a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/facade/AuthzFacadeImpl.java +++ b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/facade/AuthzFacadeImpl.java @@ -44,7 +44,9 @@ import static org.onap.aaf.auth.layer.Result.OK; import java.io.IOException; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.Date; +import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -172,9 +174,15 @@ public abstract class AuthzFacadeImpl<NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE if (result.variables==null) { detail = new String[1]; } else { - int l = result.variables.length; - detail=new String[l+1]; - System.arraycopy(result.variables, 0, detail, 1, l); + List<String> dlist = new ArrayList<String>(); + String os; + for(Object s : result.variables) { + if(s!=null && (os=s.toString()).length()>0) { + dlist.add(os); + } + } + detail = new String[dlist.size()]; + dlist.toArray(detail); } //int httpstatus; @@ -280,10 +288,6 @@ public abstract class AuthzFacadeImpl<NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE break; case ERR_ChoiceNeeded: msgId = "SVC1300"; - detail = new String[result.variables.length]; - for(int i=0; i<result.variables.length;++i) { - detail[i]=result.variables[i].toString(); - } response.setStatus(/*httpstatus=*/300); break; case ERR_Backend: @@ -1623,7 +1627,7 @@ public abstract class AuthzFacadeImpl<NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE Question.logEncryptTrace(trans,data.asString()); } - return service.changeUserCred(trans, data.asObject()); + return service.resetUserCred(trans, data.asObject()); } catch (APIException e) { trans.error().log(e,"Bad Input data"); return Result.err(Status.ERR_BadData, e.getLocalizedMessage()); diff --git a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/mapper/Mapper_2_0.java b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/mapper/Mapper_2_0.java index 7a5d0c18..44ad7fcb 100644 --- a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/mapper/Mapper_2_0.java +++ b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/mapper/Mapper_2_0.java @@ -38,6 +38,7 @@ import org.onap.aaf.auth.dao.cass.ApprovalDAO; import org.onap.aaf.auth.dao.cass.CertDAO; import org.onap.aaf.auth.dao.cass.CredDAO; import org.onap.aaf.auth.dao.cass.DelegateDAO; +import org.onap.aaf.auth.dao.cass.DelegateDAO.Data; import org.onap.aaf.auth.dao.cass.FutureDAO; import org.onap.aaf.auth.dao.cass.HistoryDAO; import org.onap.aaf.auth.dao.cass.Namespace; @@ -47,7 +48,6 @@ import org.onap.aaf.auth.dao.cass.PermDAO; import org.onap.aaf.auth.dao.cass.RoleDAO; import org.onap.aaf.auth.dao.cass.Status; import org.onap.aaf.auth.dao.cass.UserRoleDAO; -import org.onap.aaf.auth.dao.cass.DelegateDAO.Data; import org.onap.aaf.auth.dao.hl.Question; import org.onap.aaf.auth.dao.hl.Question.Access; import org.onap.aaf.auth.env.AuthzTrans; |