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.oauth;
24 import java.io.IOException;
25 import java.nio.file.Path;
26 import java.security.GeneralSecurityException;
27 import java.security.Principal;
28 import java.util.HashMap;
30 import java.util.concurrent.ConcurrentHashMap;
32 import org.onap.aaf.cadi.CadiException;
33 import org.onap.aaf.cadi.LocatorException;
34 import org.onap.aaf.cadi.PropAccess;
35 import org.onap.aaf.cadi.Access.Level;
36 import org.onap.aaf.cadi.client.Result;
37 import org.onap.aaf.cadi.config.Config;
38 import org.onap.aaf.cadi.persist.Persist;
39 import org.onap.aaf.misc.env.APIException;
40 import org.onap.aaf.misc.rosetta.env.RosettaDF;
41 import org.onap.aaf.misc.rosetta.env.RosettaEnv;
43 import aaf.v2_0.Perms;
44 import aafoauth.v2_0.Introspect;
46 public class TokenMgr extends Persist<Introspect, TokenPerm> {
47 protected static Map<String,TokenPerm> tpmap = new ConcurrentHashMap<>();
48 protected static Map<String,TokenMgr> tmmap = new HashMap<>(); // synchronized in getInstance
49 protected static Map<String,String> currentToken = new HashMap<>(); // synchronized in getTP
50 public static RosettaDF<Perms> permsDF;
51 public static RosettaDF<Introspect> introspectDF;
53 private final TokenPermLoader tpLoader;
55 private TokenMgr(PropAccess access, String tokenURL, String introspectURL) throws APIException, CadiException {
56 super(access,new RosettaEnv(access.getProperties()),Introspect.class,"introspect");
57 synchronized(access) {
59 permsDF = env.newDataFactory(Perms.class);
60 introspectDF = env.newDataFactory(Introspect.class);
63 if ("dbToken".equals(tokenURL) && "dbIntrospect".equals(introspectURL)) {
64 tpLoader = new TokenPermLoader() { // null Loader
66 public Result<TokenPerm> load(String accessToken, byte[] cred)
67 throws APIException, CadiException, LocatorException {
68 return Result.err(404, "DBLoader");
72 RemoteTokenPermLoader rtpl = new RemoteTokenPermLoader(tokenURL, introspectURL); // default is remote
73 String i = access.getProperty(Config.AAF_APPID,null);
74 String p = access.getProperty(Config.AAF_APPPASS, null);
75 if (i==null || p==null) {
76 throw new CadiException(Config.AAF_APPID + " and " + Config.AAF_APPPASS + " must be set to initialize TokenMgr");
78 rtpl.introCL.client_creds(i,p);
83 private TokenMgr(PropAccess access, TokenPermLoader tpl) throws APIException, CadiException {
84 super(access,new RosettaEnv(access.getProperties()),Introspect.class,"incoming");
85 synchronized(access) {
87 permsDF = env.newDataFactory(Perms.class);
88 introspectDF = env.newDataFactory(Introspect.class);
94 public static synchronized TokenMgr getInstance(final PropAccess access, final String tokenURL, final String introspectURL) throws APIException, CadiException {
96 TokenMgr tm = tmmap.get(key=tokenURL+'/'+introspectURL);
98 tmmap.put(key, tm=new TokenMgr(access,tokenURL,introspectURL));
103 public Result<OAuth2Principal> toPrincipal(final String accessToken, final byte[] hash) throws APIException, CadiException, LocatorException {
104 Result<TokenPerm> tp = get(accessToken, hash, new Loader<TokenPerm>() {
106 public Result<TokenPerm> load(String key) throws APIException, CadiException, LocatorException {
108 return tpLoader.load(accessToken,hash);
109 } catch (APIException | LocatorException e) {
110 throw new CadiException(e);
115 return Result.ok(200, new OAuth2Principal(tp.value,hash));
117 return Result.err(tp);
121 public Result<TokenPerm> get(final String accessToken, final byte[] hash) throws APIException, CadiException, LocatorException {
122 return get(accessToken,hash,new Loader<TokenPerm>() {
124 public Result<TokenPerm> load(String key) throws APIException, CadiException, LocatorException {
125 return tpLoader.load(key,hash);
129 // return tpLoader.load(accessToken,hash);
132 public interface TokenPermLoader{
133 public Result<TokenPerm> load(final String accessToken, final byte[] cred) throws APIException, CadiException, LocatorException;
136 private class RemoteTokenPermLoader implements TokenPermLoader {
137 private TokenClientFactory tcf;
138 private TokenClient tokenCL, introCL;
140 public RemoteTokenPermLoader(final String tokenURL, final String introspectURL) throws APIException, CadiException {
142 tcf = TokenClientFactory.instance(access);
143 int timeout = Integer.parseInt(access.getProperty(Config.AAF_CONN_TIMEOUT, Config.AAF_CONN_TIMEOUT_DEF));
144 tokenCL = tcf.newClient(tokenURL,
146 if (introspectURL.equals(tokenURL)) {
149 introCL = tcf.newClient(introspectURL,
153 } catch (GeneralSecurityException | IOException | NumberFormatException | LocatorException e) {
154 throw new CadiException(e);
158 public Result<TokenPerm> load(final String accessToken, final byte[] cred) throws APIException, CadiException, LocatorException {
159 long start = System.currentTimeMillis();
161 Result<Introspect> ri = introCL.introspect(accessToken);
163 return Result.ok(ri.code, new TokenPerm(TokenMgr.this,permsDF,ri.value,cred,getPath(accessToken)));
165 return Result.err(ri);
168 access.printf(Level.INFO, "Token loaded in %d ms",System.currentTimeMillis()-start);
173 public void clear(Principal p, StringBuilder report) {
174 TokenPerm tp = tpmap.remove(p.getName());
176 report.append("Nothing to clear");
178 report.append("Cleared ");
179 report.append(p.getName());
184 protected TokenPerm newCacheable(Introspect i, long expires, byte[] hash, Path path) throws APIException {
185 // Note: Introspect drives the Expiration... ignoring expires.
186 return new TokenPerm(this,permsDF,i,hash,path);
189 public TokenPerm putIntrospect(Introspect intro, byte[] cred) throws APIException {
190 return newCacheable(intro, intro.getExp(), cred, getPath(intro.getAccessToken()));