/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.security.oauth1; import org.eclipse.che.api.core.BadRequestException; import org.eclipse.che.api.core.rest.Service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.inject.Inject; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import java.net.URI; import java.net.URL; import java.util.List; import java.util.Map; import static java.lang.String.format; import static org.eclipse.che.commons.lang.UrlUtils.getParameter; import static org.eclipse.che.commons.lang.UrlUtils.getQueryParametersFromState; import static org.eclipse.che.commons.lang.UrlUtils.getRequestUrl; import static org.eclipse.che.commons.lang.UrlUtils.getState; /** * RESTful wrapper for OAuth 1.0. * * @author Kevin Pollet * @author Igor Vinokur */ @Path("oauth/1.0") public class OAuthAuthenticationService extends Service { private static final Logger LOG = LoggerFactory.getLogger(OAuthAuthenticationService.class); private final static String UNSUPPORTED_OAUTH_PROVIDER_ERROR = "Unsupported OAuth provider: %s"; @Inject protected OAuthAuthenticatorProvider providers; @GET @Path("authenticate") public Response authenticate(@QueryParam("oauth_provider") String providerName, @QueryParam("request_method") String requestMethod, @QueryParam("signature_method") String signatureMethod, @QueryParam("redirect_after_login") String redirectAfterLogin) throws OAuthAuthenticationException, BadRequestException { requiredNotNull(providerName, "Provider name"); requiredNotNull(redirectAfterLogin, "Redirect after login"); final OAuthAuthenticator oauth = getAuthenticator(providerName); final String authUrl = oauth.getAuthenticateUrl(getRequestUrl(uriInfo), requestMethod, signatureMethod); return Response.temporaryRedirect(URI.create(authUrl)).build(); } @GET @Path("callback") public Response callback() throws OAuthAuthenticationException, BadRequestException { final URL requestUrl = getRequestUrl(uriInfo); final Map<String, List<String>> parameters = getQueryParametersFromState(getState(requestUrl)); final String providerName = getParameter(parameters, "oauth_provider"); final String redirectAfterLogin = getParameter(parameters, "redirect_after_login"); getAuthenticator(providerName).callback(requestUrl); return Response.temporaryRedirect(URI.create(redirectAfterLogin)).build(); } @GET @Path("signature") public String signature(@QueryParam("oauth_provider") String providerName, @QueryParam("user_id") String userId, @QueryParam("request_url") String requestUrl, @QueryParam("request_method") String requestMethod) throws OAuthAuthenticationException, BadRequestException { requiredNotNull(providerName, "Provider name"); requiredNotNull(userId, "User Id"); requiredNotNull(requestUrl, "Request url"); requiredNotNull(requestMethod, "Request method"); return getAuthenticator(providerName).computeAuthorizationHeader(userId, requestMethod, requestUrl); } private OAuthAuthenticator getAuthenticator(String oauthProviderName) throws BadRequestException { OAuthAuthenticator oauth = providers.getAuthenticator(oauthProviderName); if (oauth == null) { LOG.warn(format(UNSUPPORTED_OAUTH_PROVIDER_ERROR, oauthProviderName)); throw new BadRequestException(format(UNSUPPORTED_OAUTH_PROVIDER_ERROR, oauthProviderName)); } return oauth; } /** * Checks object reference is not {@code null} * * @param object * object reference to check * @param subject * used as subject of exception message "{subject} required" * @throws BadRequestException * when object reference is {@code null} */ private void requiredNotNull(Object object, String subject) throws BadRequestException { if (object == null) { throw new BadRequestException(subject + " required"); } } }