X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=cadi%2Fcore%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Faaf%2Fcadi%2Ffilter%2FMapBathConverter.java;fp=cadi%2Fcore%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Faaf%2Fcadi%2Ffilter%2FMapBathConverter.java;h=7a138e97099fe973a56cfa60440c6f2da184631c;hb=7e5ccdd25e377cfa2dd5850ac3c2c1428c40b078;hp=0000000000000000000000000000000000000000;hpb=bdaf445e08978aadeca4232030fdbf6d39797dc8;p=aaf%2Fauthz.git diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/filter/MapBathConverter.java b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/MapBathConverter.java new file mode 100644 index 00000000..7a138e97 --- /dev/null +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/filter/MapBathConverter.java @@ -0,0 +1,170 @@ +/** + * ============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.filter; + +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import javax.xml.ws.Holder; + +import org.onap.aaf.cadi.Access; +import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.Symm; +import org.onap.aaf.cadi.util.CSV; +import org.onap.aaf.cadi.util.CSV.Visitor; + +/** + * This Filter is designed to help MIGRATE users from systems that don't match the FQI style. + * + * Style 1, where just the ID is translated, i.e. OLD => new@something.onap.org, that is acceptable + * longer term, because it does not store Creds locally. The passwords are in appropriate systems, but + * it's still painful operationally, though it does ease migration. + * + * Style 3, however, which is Direct match of Authorization Header to replacement, is only there + * because some passwords are simply not acceptable for AAF, (too easy, for instance), and it is + * not feasible to break Organization Password rules for a Migration. Therefore, this method + * should not considered something that is in any way a permanent + * + + * + * It goes without saying that any file with the password conversion should be protected by "400", etc. + * + * @author Instrumental (Jonathan) + * + */ +public class MapBathConverter { + private static final String BASIC = "Basic "; + private final Map map; + + /** + * Create with colon separated name value pairs + * Enter the entire "Basic dXNlcjpwYXNz" "Authorization" header, where "dXNlcjpwYXNz" is + * base64 encoded, which can be created with "cadi" tool (in jar) + * + * The replacement should also be an exact replacement of what you want. Recognize that + * this should be TEMPORARY as you are storing credentials outside the users control. + * + * @param value + * @throws IOException + * @throws CadiException + */ + public MapBathConverter(final Access access, final CSV csv) throws IOException, CadiException { + map = new TreeMap<>(); + final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + final Date now = new Date(); + csv.visit(new Visitor() { + @Override + public void visit(List row) throws CadiException { + if(row.size()<3) { + throw new CadiException("CSV file " + csv + " must have at least 2 Basic Auth columns and an Expiration Date(YYYYMMDD) in each row"); + } + try { + Date date = sdf.parse(row.get(2)); + String oldID = row.get(0); + String newID = row.get(1); + if(date.after(now)) { + if(!oldID.startsWith(BASIC) && newID.startsWith(BASIC)) { + throw new CadiException("CSV file " + csv + ": Uncredentialed ID " + idFromBasic(oldID,null) + + " may not transfer to credentialed ID " + idFromBasic(newID,null)); + } else { + map.put(oldID,newID); + access.printf(Level.INIT, "ID Conversion from %s to %s enabled", + idFromBasic(oldID,null), + idFromBasic(newID,null)); + } + } else { + access.printf(Level.INIT, "ID Conversion from %s to %s has expired.", + idFromBasic(oldID,null), + idFromBasic(newID,null)); + } + } catch (ParseException e) { + throw new CadiException("Cannot Parse Date: " + row.get(2)); + } catch (IOException e) { + throw new CadiException(e); + } + } + }); + } + + private static String idFromBasic(String bath, Holder hpass) throws IOException, CadiException { + if(bath.startsWith(BASIC)) { + String cred = Symm.base64noSplit.decode(bath.substring(6)); + int colon = cred.indexOf(':'); + if(colon<0) { + throw new CadiException("Invalid Authentication Credential for " + cred); + } + if(hpass!=null) { + hpass.value = cred.substring(colon+1); + } + return cred.substring(0, colon); + } else { + return bath; + } + } + + /** + * use to instantiate entries + * + * @return + */ + public Map map() { + return map; + } + + public String convert(Access access, final String bath) { + String rv = map.get(bath); + String cred=null; + Holder hpass=null; + try { + if(rv==null || !rv.startsWith(BASIC)) { + if(bath.startsWith(BASIC)) { + cred = idFromBasic(bath,(hpass=new Holder())); + } + } + + if(cred!=null) { + if(rv==null) { + rv = map.get(cred); + } + // for SAFETY REASONS, we WILL NOT allow a non validated cred to + // pass a password from file. Should be caught from Instation, but... + if(rv!=null) { + if(rv.startsWith(BASIC)) { + return bath; + } else { + rv = BASIC + Symm.base64noSplit.encode(rv+':'+hpass.value); + } + } + } + } catch (IOException | CadiException e) { + access.log(e,"Invalid Authorization"); + } + + return rv; + } +}