/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.shindig.gadgets.oauth; import org.apache.shindig.gadgets.AuthType; import org.apache.shindig.gadgets.GadgetException; import org.apache.shindig.gadgets.spec.RequestAuthenticationInfo; import com.google.common.collect.Maps; import java.util.Map; import javax.servlet.http.HttpServletRequest; /** * Arguments to an OAuth fetch sent by the client. */ public class OAuthArguments { private static final String SERVICE_PARAM = "OAUTH_SERVICE_NAME"; private static final String TOKEN_PARAM = "OAUTH_TOKEN_NAME"; private static final String REQUEST_TOKEN_PARAM = "OAUTH_REQUEST_TOKEN"; private static final String REQUEST_TOKEN_SECRET_PARAM = "OAUTH_REQUEST_TOKEN_SECRET"; private static final String USE_TOKEN_PARAM = "OAUTH_USE_TOKEN"; private static final String CLIENT_STATE_PARAM = "oauthState"; private static final String BYPASS_SPEC_CACHE_PARAM = "bypassSpecCache"; private static final String SIGN_OWNER_PARAM = "signOwner"; private static final String SIGN_VIEWER_PARAM = "signViewer"; /** * Should the OAuth access token be used? */ public static enum UseToken { /** Do not use the OAuth access token */ NEVER, /** Use the access token if it exists already, but don't prompt for permission */ IF_AVAILABLE, /** Use the access token if it exists, and prompt if it doesn't */ ALWAYS, } /** Should we attempt to use an access token for the request */ private UseToken useToken = UseToken.ALWAYS; /** OAuth service nickname. Signed fetch uses the empty string */ private String serviceName = ""; /** OAuth token nickname. Signed fetch uses the empty string */ private String tokenName = ""; /** Request token the client wants us to use, may be null */ private String requestToken = null; /** Token secret that goes with the request token */ private String requestTokenSecret = null; /** Encrypted state blob stored on the client */ private String origClientState = null; /** Whether we should bypass the gadget spec cache */ private boolean bypassSpecCache = false; /** Include information about the owner? */ private boolean signOwner = false; /** Include information about the viewer? */ private boolean signViewer = false; /** * Parse OAuthArguments from parameters to the makeRequest servlet. * * @param auth authentication type for the request * @param request servlet request * @throws GadgetException if any parameters are invalid. */ public OAuthArguments(AuthType auth, HttpServletRequest request) throws GadgetException { useToken = parseUseToken(auth, getRequestParam(request, USE_TOKEN_PARAM, "")); serviceName = getRequestParam(request, SERVICE_PARAM, ""); tokenName = getRequestParam(request, TOKEN_PARAM, ""); requestToken = getRequestParam(request, REQUEST_TOKEN_PARAM, null); requestTokenSecret = getRequestParam(request, REQUEST_TOKEN_SECRET_PARAM, null); origClientState = getRequestParam(request, CLIENT_STATE_PARAM, null); bypassSpecCache = "1".equals(getRequestParam(request, BYPASS_SPEC_CACHE_PARAM, null)); signOwner = Boolean.parseBoolean(getRequestParam(request, SIGN_OWNER_PARAM, "true")); signViewer = Boolean.parseBoolean(getRequestParam(request, SIGN_VIEWER_PARAM, "true")); } public OAuthArguments(RequestAuthenticationInfo info) throws GadgetException { Map<String, String> attrs = Maps.newTreeMap(String.CASE_INSENSITIVE_ORDER); attrs.putAll(info.getAttributes()); useToken = parseUseToken(info.getAuthType(), getAuthInfoParam(attrs, USE_TOKEN_PARAM, "")); serviceName = getAuthInfoParam(attrs, SERVICE_PARAM, ""); tokenName = getAuthInfoParam(attrs, TOKEN_PARAM, ""); requestToken = getAuthInfoParam(attrs, REQUEST_TOKEN_PARAM, null); requestTokenSecret = getAuthInfoParam(attrs, REQUEST_TOKEN_SECRET_PARAM, null); origClientState = null; bypassSpecCache = false; signOwner = info.isSignOwner(); signViewer = info.isSignViewer(); } /** * @return the named attribute from the Preload tag attributes, or default if the attribute is * not present. */ private static String getAuthInfoParam(Map<String, String> attrs, String name, String def) { String val = attrs.get(name); if (val == null) { val = def; } return val; } /** * @return the named parameter from the request, or default if the named parameter is not present. */ private static String getRequestParam(HttpServletRequest request, String name, String def) { String val = request.getParameter(name); if (val == null) { val = def; } return val; } /** * Figure out what the client wants us to do with the OAuth access token. */ private static UseToken parseUseToken(AuthType auth, String useTokenStr) throws GadgetException { if (useTokenStr.length() == 0) { if (auth == AuthType.SIGNED) { // signed fetch defaults to not using the token return UseToken.NEVER; } else { // OAuth defaults to always using it. return UseToken.ALWAYS; } } useTokenStr = useTokenStr.toLowerCase(); if ("always".equals(useTokenStr)) { return UseToken.ALWAYS; } if ("if_available".equals(useTokenStr)) { return UseToken.IF_AVAILABLE; } if ("never".equals(useTokenStr)) { return UseToken.NEVER; } throw new GadgetException(GadgetException.Code.INVALID_PARAMETER, "Unknown use token value " + useTokenStr); } /** * Create an OAuthArguments object with all default values. The details can be filled in later * using the setters. * * Be careful using this in anything except test code. If you find yourself wanting to use this * method in real code, consider writing a new constructor instead. */ public OAuthArguments() { } /** * Copy constructor. */ public OAuthArguments(OAuthArguments orig) { useToken = orig.useToken; serviceName = orig.serviceName; tokenName = orig.tokenName; requestToken = orig.requestToken; requestTokenSecret = orig.requestTokenSecret; origClientState = orig.origClientState; bypassSpecCache = orig.bypassSpecCache; signOwner = orig.signOwner; signViewer = orig.signViewer; } public boolean mustUseToken() { return (useToken == UseToken.ALWAYS); } public boolean mayUseToken() { return (useToken == UseToken.IF_AVAILABLE || useToken == UseToken.ALWAYS); } public UseToken getUseToken() { return useToken; } public void setUseToken(UseToken useToken) { this.useToken = useToken; } public String getServiceName() { return serviceName; } public void setServiceName(String serviceName) { this.serviceName = serviceName; } public String getTokenName() { return tokenName; } public void setTokenName(String tokenName) { this.tokenName = tokenName; } public String getRequestToken() { return requestToken; } public void setRequestToken(String requestToken) { this.requestToken = requestToken; } public String getRequestTokenSecret() { return requestTokenSecret; } public void setRequestTokenSecret(String requestTokenSecret) { this.requestTokenSecret = requestTokenSecret; } public String getOrigClientState() { return origClientState; } public void setOrigClientState(String origClientState) { this.origClientState = origClientState; } public boolean getBypassSpecCache() { return bypassSpecCache; } public void setBypassSpecCache(boolean bypassSpecCache) { this.bypassSpecCache = bypassSpecCache; } public boolean getSignOwner() { return signOwner; } public void setSignOwner(boolean signOwner) { this.signOwner = signOwner; } public boolean getSignViewer() { return signViewer; } public void setSignViewer(boolean signViewer) { this.signViewer = signViewer; } }