/**************************************************************************************** * Copyright 2012 IBM Corp. * * * * 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. * ****************************************************************************************/ package com.ibm.sbt.security.authentication.oauth.consumer; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import javax.servlet.http.HttpServletRequest; import org.apache.http.HttpStatus; import com.ibm.commons.runtime.Context; import com.ibm.commons.runtime.util.UrlUtil; import com.ibm.commons.util.PathUtil; import com.ibm.commons.util.StringUtil; import com.ibm.sbt.core.configuration.Configuration; import com.ibm.sbt.security.authentication.oauth.OAuthException; import com.ibm.sbt.security.authentication.oauth.consumer.servlet.OACallback; import com.ibm.sbt.service.util.ServiceUtil; public abstract class OAuthHandler { private boolean showOAuthFlow; private String version; private String serverUrl; private String userId; /** * Do all steps in the OAuth flow before the Authorization step. * * @throws Exception */ abstract public void doPreAuthorizationFlow() throws Exception; /** * Do all steps in the OAuth flow after the Authorization step. * * @throws Exception */ abstract public void doPostAuthorizationFlow() throws Exception; /** * Gets the Server Authorization Endpoint URL * * @return */ abstract public String getAuthorizationURL(); /** * Returns the OAuth header string for each API request. * * @return */ abstract public String createAuthorizationHeader(); abstract public String getAccessToken(); abstract public boolean isInitialized(); abstract public String getAuthType(); public void setCallBackUrl(HttpServletRequest request) { }; /** * OAuth data is passed to other applications (e.g. API Explorer) to convey OAuth info that has already * been collected from the user, so that the other application does not have to collect it again * ("poor man's" SSO). */ public String createAuthData() { StringBuilder authData = new StringBuilder(1024); authData.append(createAuthorizationHeader()); authData.append(",").append(Configuration.SERVER_URL).append("=").append(this.getServerUrl()); authData.append(",").append(Configuration.AUTH_TYPE).append("=").append(this.getAuthType()); return authData.toString(); } public String buildErrorMessage(int responseCode, String responseBody) { String errorDetail = null; if (responseCode == HttpStatus.SC_NOT_IMPLEMENTED) { errorDetail = "Response Code: Not implemented (501), Msg: " + responseBody; } else if (responseCode == HttpStatus.SC_UNAUTHORIZED) { errorDetail = "Response Code: Unauthorized (401), Msg: " + responseBody; } else if (responseCode == HttpStatus.SC_BAD_REQUEST) { errorDetail = "Response Code: Bad Request (400), Msg: " + responseBody; } else if (responseCode == HttpStatus.SC_INTERNAL_SERVER_ERROR) { errorDetail = "Response Code: Internal Server error (500), Msg: " + responseBody; } else { errorDetail = "Response Code (" + responseCode + "), Msg: " + responseBody; } return errorDetail; } public boolean isShowOAuthFlow() { return showOAuthFlow; } public void setShowOAuthFlow(boolean showOAuthFlow) { this.showOAuthFlow = showOAuthFlow; } public String getServerUrl() { return serverUrl; } public void setServerUrl(String serverUrl) { this.serverUrl = serverUrl; } public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } /** * Looks for a token name and returns it's value. * * @param input * @param tokenName * @return */ public static String getTokenValue(String input, String tokenName) { if (input.startsWith("{")) { input = input.substring(1, input.length()); } if (input.endsWith("}")) { input = input.substring(0, input.length() - 1); } String splitterkey = input.contains("&") ? "&" : ","; // Connections and Smartcloud have different // response types String altTokenName = "\"" + tokenName + "\""; String[] tokens = input.split(splitterkey); String tokenValue = null; for (String token : tokens) { if (token.startsWith(tokenName + "=")) { tokenValue = token.substring(tokenName.length() + 1); break; } else if (token.startsWith(altTokenName + ":")) { tokenValue = token.substring(altTokenName.length() + 1); tokenValue.substring(0, tokenValue.length()); break; } } if (null != tokenValue && !tokenValue.equals("")) { if (tokenValue.startsWith("\"")) { tokenValue = tokenValue.substring(1, tokenValue.length()); } if (tokenValue.endsWith("\"")) { tokenValue = tokenValue.substring(0, tokenValue.length() - 1); } } return tokenValue; } public static String percentEncode(String str) { String encodedStr = null; if (!StringUtil.isEmpty(str)) { try { encodedStr = URLEncoder.encode(str, Configuration.ENCODING).replace("+", "%20") .replace("*", "%2A").replace("%7E", "~"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e.getMessage()); } } return encodedStr; } public static String convertToSafeHtml(String sourceText) { // escape HTML by escaping the < character if (sourceText == null) { return null; } return sourceText.replaceAll("<", "<"); } public String getApplicationPage(Context context) throws OAuthException { // We just return to the same page Object _req = context.getHttpRequest(); if (_req instanceof HttpServletRequest) { HttpServletRequest request = (HttpServletRequest) _req; String url = UrlUtil.getRequestUrl(request); return url; } return null; } public String getCallbackUrl(Context context) throws OAuthException { Object _req = context.getHttpRequest(); if (_req instanceof HttpServletRequest) { HttpServletRequest request = (HttpServletRequest) _req; String proxyBaseUrl = PathUtil.concat(ServiceUtil.getProxyUrl(request), OACallback.URL_PATH, '/'); return proxyBaseUrl; } return null; } public void setUserId(String userId) { this.userId = userId; } public String getUserId() { if (this.userId != null) { return this.userId; } Context context = Context.getUnchecked(); return (context == null) ? null : context.getCurrentUserId(); } }