2 * ============LICENSE_START====================================================
4 * ===========================================================================
5 * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6 * ===========================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END====================================================
22 package org.onap.aaf.cadi.filter;
24 import java.io.IOException;
25 import java.text.ParseException;
26 import java.text.SimpleDateFormat;
27 import java.util.Date;
28 import java.util.List;
30 import java.util.TreeMap;
32 import org.onap.aaf.cadi.Access;
33 import org.onap.aaf.cadi.Access.Level;
34 import org.onap.aaf.cadi.CadiException;
35 import org.onap.aaf.cadi.Symm;
36 import org.onap.aaf.cadi.util.CSV;
37 import org.onap.aaf.cadi.util.CSV.Visitor;
38 import org.onap.aaf.cadi.util.Holder;
41 * This Filter is designed to help MIGRATE users from systems that don't match the FQI style.
43 * Style 1, where just the ID is translated, i.e. OLD => new@something.onap.org, that is acceptable
44 * longer term, because it does not store Creds locally. The passwords are in appropriate systems, but
45 * it's still painful operationally, though it does ease migration.
47 * Style 3, however, which is Direct match of Authorization Header to replacement, is only there
48 * because some passwords are simply not acceptable for AAF, (too easy, for instance), and it is
49 * not feasible to break Organization Password rules for a Migration. Therefore, this method
50 * should not considered something that is in any way a permanent
54 * It goes without saying that any file with the password conversion should be protected by "400", etc.
56 * @author Instrumental (Jonathan)
59 public class MapBathConverter {
60 private static final String BASIC = "Basic ";
61 private final Map<String,String> map;
64 * Create with colon separated name value pairs
65 * Enter the entire "Basic dXNlcjpwYXNz" "Authorization" header, where "dXNlcjpwYXNz" is
66 * base64 encoded, which can be created with "cadi" tool (in jar)
68 * The replacement should also be an exact replacement of what you want. Recognize that
69 * this should be TEMPORARY as you are storing credentials outside the users control.
73 * @throws CadiException
75 public MapBathConverter(final Access access, final CSV csv) throws IOException, CadiException {
76 map = new TreeMap<>();
77 final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
78 final Date now = new Date();
79 csv.visit(new Visitor() {
81 public void visit(List<String> row) throws CadiException {
83 throw new CadiException("CSV file " + csv + " must have at least 2 Basic Auth columns and an Expiration Date(YYYY-MM-DD) in each row");
86 Date date = sdf.parse(row.get(2));
87 String oldID = row.get(0);
88 String newID = row.get(1);
90 if(!oldID.startsWith(BASIC) && newID.startsWith(BASIC)) {
91 throw new CadiException("CSV file " + csv + ": Uncredentialed ID " + idFromBasic(oldID,null) +
92 " may not transfer to credentialed ID " + idFromBasic(newID,null));
95 access.printf(Level.INIT, "ID Conversion from %s to %s enabled",
96 idFromBasic(oldID,null),
97 idFromBasic(newID,null));
100 access.printf(Level.INIT, "ID Conversion from %s to %s has expired.",
101 idFromBasic(oldID,null),
102 idFromBasic(newID,null));
104 } catch (ParseException e) {
105 throw new CadiException("Cannot Parse Date: " + row.get(2));
106 } catch (IOException e) {
107 throw new CadiException(e);
113 private static String idFromBasic(String bath, Holder<String> hpass) throws IOException, CadiException {
114 if(bath.startsWith(BASIC)) {
115 String cred = Symm.base64noSplit.decode(bath.substring(6));
116 int colon = cred.indexOf(':');
118 throw new CadiException("Invalid Authentication Credential for " + cred);
121 hpass.set(cred.substring(colon+1));
123 return cred.substring(0, colon);
130 * use to instantiate entries
134 public Map<String,String> map() {
138 public String convert(Access access, final String bath) {
139 String rv = map.get(bath);
143 Holder<String> hpass=null;
145 if(bath.startsWith(BASIC)) {
146 cred = idFromBasic(bath,(hpass=new Holder<String>(null)));
155 // Nothing here, just return original
158 if(rv.startsWith(BASIC)) {
159 tcred = idFromBasic(rv,null);
163 rv = BASIC + Symm.base64noSplit.encode(rv+':'+hpass.get());
167 access.printf(Level.AUDIT, "ID %s converted to %s",cred,tcred);
170 } catch (IOException | CadiException e) {
171 access.log(e,"Invalid Authorization");
173 return rv==null?bath:rv;