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 javax.xml.ws.Holder;
34 import org.onap.aaf.cadi.Access;
35 import org.onap.aaf.cadi.Access.Level;
36 import org.onap.aaf.cadi.CadiException;
37 import org.onap.aaf.cadi.Symm;
38 import org.onap.aaf.cadi.util.CSV;
39 import org.onap.aaf.cadi.util.CSV.Visitor;
42 * This Filter is designed to help MIGRATE users from systems that don't match the FQI style.
44 * Style 1, where just the ID is translated, i.e. OLD => new@something.onap.org, that is acceptable
45 * longer term, because it does not store Creds locally. The passwords are in appropriate systems, but
46 * it's still painful operationally, though it does ease migration.
48 * Style 3, however, which is Direct match of Authorization Header to replacement, is only there
49 * because some passwords are simply not acceptable for AAF, (too easy, for instance), and it is
50 * not feasible to break Organization Password rules for a Migration. Therefore, this method
51 * should not considered something that is in any way a permanent
55 * It goes without saying that any file with the password conversion should be protected by "400", etc.
57 * @author Instrumental (Jonathan)
60 public class MapBathConverter {
61 private static final String BASIC = "Basic ";
62 private final Map<String,String> map;
65 * Create with colon separated name value pairs
66 * Enter the entire "Basic dXNlcjpwYXNz" "Authorization" header, where "dXNlcjpwYXNz" is
67 * base64 encoded, which can be created with "cadi" tool (in jar)
69 * The replacement should also be an exact replacement of what you want. Recognize that
70 * this should be TEMPORARY as you are storing credentials outside the users control.
74 * @throws CadiException
76 public MapBathConverter(final Access access, final CSV csv) throws IOException, CadiException {
77 map = new TreeMap<>();
78 final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
79 final Date now = new Date();
80 csv.visit(new Visitor() {
82 public void visit(List<String> row) throws CadiException {
84 throw new CadiException("CSV file " + csv + " must have at least 2 Basic Auth columns and an Expiration Date(YYYY-MM-DD) in each row");
87 Date date = sdf.parse(row.get(2));
88 String oldID = row.get(0);
89 String newID = row.get(1);
91 if(!oldID.startsWith(BASIC) && newID.startsWith(BASIC)) {
92 throw new CadiException("CSV file " + csv + ": Uncredentialed ID " + idFromBasic(oldID,null) +
93 " may not transfer to credentialed ID " + idFromBasic(newID,null));
96 access.printf(Level.INIT, "ID Conversion from %s to %s enabled",
97 idFromBasic(oldID,null),
98 idFromBasic(newID,null));
101 access.printf(Level.INIT, "ID Conversion from %s to %s has expired.",
102 idFromBasic(oldID,null),
103 idFromBasic(newID,null));
105 } catch (ParseException e) {
106 throw new CadiException("Cannot Parse Date: " + row.get(2));
107 } catch (IOException e) {
108 throw new CadiException(e);
114 private static String idFromBasic(String bath, Holder<String> hpass) throws IOException, CadiException {
115 if(bath.startsWith(BASIC)) {
116 String cred = Symm.base64noSplit.decode(bath.substring(6));
117 int colon = cred.indexOf(':');
119 throw new CadiException("Invalid Authentication Credential for " + cred);
122 hpass.value = cred.substring(colon+1);
124 return cred.substring(0, colon);
131 * use to instantiate entries
135 public Map<String,String> map() {
139 public String convert(Access access, final String bath) {
140 String rv = map.get(bath);
144 Holder<String> hpass=null;
146 if(bath.startsWith(BASIC)) {
147 cred = idFromBasic(bath,(hpass=new Holder<String>()));
156 // Nothing here, just return original
159 if(rv.startsWith(BASIC)) {
160 tcred = idFromBasic(rv,null);
164 rv = BASIC + Symm.base64noSplit.encode(rv+':'+hpass.value);
168 access.printf(Level.AUDIT, "ID %s converted to %s",cred,tcred);
171 } catch (IOException | CadiException e) {
172 access.log(e,"Invalid Authorization");
174 return rv==null?bath:rv;