001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.component.gae.login;
018
019 import java.io.OutputStreamWriter;
020 import java.io.PrintWriter;
021 import java.net.HttpURLConnection;
022 import java.net.URL;
023 import java.net.URLEncoder;
024 import java.nio.charset.Charset;
025
026 import com.google.gdata.client.GoogleAuthTokenFactory;
027 import com.google.gdata.util.AuthenticationException;
028
029 /**
030 * Implements the interactions with Google's authentication and authorization
031 * services. If the endpoint is configured to run in development mode the
032 * authentication and authorization services of the development server are used.
033 */
034 public class GLoginServiceImpl implements GLoginService {
035
036 /**
037 * Authenticates a user and stores the authentication token to
038 * {@link GLoginData#setAuthenticationToken(String)}. If the endpoint is
039 * configured to run in development mode this method simply returns without
040 * any further action.
041 */
042 public void authenticate(GLoginData data) throws AuthenticationException {
043 if (data.isDevMode()) {
044 return;
045 }
046 GoogleAuthTokenFactory factory =
047 new GoogleAuthTokenFactory("ah", data.getClientName(), null);
048 String token = factory.getAuthToken(
049 data.getUserName(),
050 data.getPassword(),
051 null, null, "ah", data.getClientName());
052 data.setAuthenticationToken(token);
053 }
054
055 /**
056 * Dispatches authorization to {@link #authorizeDev(GLoginData)} if the
057 * endpoint is configured to run in development mode, otherwise to
058 * {@link #authorizeStd(GLoginData)}.
059 */
060 public void authorize(GLoginData data) throws Exception {
061 if (data.isDevMode()) {
062 authorizeDev(data);
063 } else {
064 authorizeStd(data);
065 }
066 }
067
068 /**
069 * Authorizes access to a development server and stores the resulting
070 * authorization cookie to {@link GLoginData#setAuthorizationCookie(String)}
071 * . Authorization in development mode doesn't require an authentication
072 * token.
073 */
074 protected void authorizeDev(GLoginData data) throws Exception {
075 String homeLocation = String.format("http://%s:%d", data.getHostName(), data.getDevPort());
076 HttpURLConnection connection = createURLConnection(homeLocation + "/_ah/login", true);
077 connection.connect();
078 PrintWriter writer = new PrintWriter(
079 new OutputStreamWriter(connection.getOutputStream()));
080 writer.println(String.format("email=%s&isAdmin=%s&continue=%s",
081 URLEncoder.encode(data.getUserName(), Charset.defaultCharset().name()),
082 data.isDevAdmin() ? "on" : "off",
083 URLEncoder.encode(homeLocation, Charset.defaultCharset().name())));
084 writer.flush();
085 data.setAuthorizationCookie(connection.getHeaderField("Set-Cookie"));
086 connection.disconnect();
087 }
088
089 /**
090 * Authorizes access to a Google App Engine application and stores the
091 * resulting authorization cookie to
092 * {@link GLoginData#setAuthorizationCookie(String)}. This method requires
093 * an authentication token from
094 * {@link GLoginData#getAuthenticationToken()}.
095 */
096 protected void authorizeStd(GLoginData data) throws Exception {
097 String url = String.format("https://%s/_ah/login?auth=%s",
098 data.getHostName(), data.getAuthenticationToken());
099 HttpURLConnection connection = createURLConnection(url, false);
100 connection.connect();
101 data.setAuthorizationCookie(connection.getHeaderField("Set-Cookie"));
102 connection.disconnect();
103 }
104
105 private static HttpURLConnection createURLConnection(String url, boolean dev) throws Exception {
106 // TODO: support usage of proxy (via endpoint parameters or GLoginData object)
107 HttpURLConnection connection = (HttpURLConnection)new URL(url).openConnection();
108 connection.setInstanceFollowRedirects(false);
109 if (dev) {
110 connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
111 connection.setRequestMethod("POST");
112 connection.setDoOutput(true);
113 }
114 return connection;
115 }
116
117 }