001 package com.khubla.pragmatach.plugin.google; 002 003 import java.util.ArrayList; 004 import java.util.List; 005 006 import net.sf.json.JSONObject; 007 import net.sf.json.JSONSerializer; 008 009 import org.apache.http.HttpEntity; 010 import org.apache.http.HttpResponse; 011 import org.apache.http.NameValuePair; 012 import org.apache.http.client.HttpClient; 013 import org.apache.http.client.entity.UrlEncodedFormEntity; 014 import org.apache.http.client.methods.HttpGet; 015 import org.apache.http.client.methods.HttpPost; 016 import org.apache.http.impl.client.BasicResponseHandler; 017 import org.apache.http.impl.client.DefaultHttpClient; 018 import org.apache.http.message.BasicNameValuePair; 019 import org.apache.http.protocol.HTTP; 020 import org.apache.http.util.EntityUtils; 021 022 import com.khubla.pragmatach.framework.api.PragmatachException; 023 import com.khubla.pragmatach.framework.api.Response; 024 import com.khubla.pragmatach.framework.application.Application; 025 import com.khubla.pragmatach.plugin.freemarker.FreemarkerController; 026 027 /** 028 * @author tome 029 * <p> 030 * https://developers.google.com/accounts/docs/OAuth2WebServer 031 * </p> 032 */ 033 public class GoogleLoginController extends FreemarkerController { 034 /** 035 * code 036 */ 037 private String code; 038 /** 039 * state 040 */ 041 private String state; 042 /** 043 * google client ID 044 */ 045 private String clientid; 046 /** 047 * google client secret 048 */ 049 private String clientsecret; 050 /** 051 * redirect URL 052 */ 053 private final String redirectURL; 054 /** 055 * access token 056 */ 057 private String accessToken; 058 /** 059 * scopes to ask for 060 */ 061 private static final String[] SCOPES = { "https://www.googleapis.com/auth/userinfo.profile", "https://www.googleapis.com/auth/userinfo.email" }; 062 /** 063 * Google user id 064 */ 065 private String id; 066 /** 067 * Google user name 068 */ 069 private String name; 070 /** 071 * Google user given name 072 */ 073 private String given_name; 074 /** 075 * Google user family name 076 */ 077 private String family_name; 078 /** 079 * Google email 080 */ 081 private String email; 082 083 /** 084 * ctor 085 */ 086 public GoogleLoginController(String redirectURL) throws PragmatachException { 087 this.redirectURL = redirectURL; 088 clientid = Application.getConfiguration().getParameter("google.clientid"); 089 clientsecret = Application.getConfiguration().getParameter("google.clientsecret"); 090 } 091 092 public Response doLogin() throws PragmatachException { 093 final String sessionID = getRequest().getSession().getId(); 094 if (sessionID != getRequest().getSession().getId()) { 095 throw new PragmatachException("CSRF Exception"); 096 } 097 accessToken = getGoogleAccessToken(code); 098 getUserInfo(accessToken); 099 return super.render(); 100 } 101 102 public String getAccessToken() { 103 return accessToken; 104 } 105 106 public String getClientid() { 107 return clientid; 108 } 109 110 public String getClientsecret() { 111 return clientsecret; 112 } 113 114 public String getCode() { 115 return code; 116 } 117 118 public String getEmail() { 119 return email; 120 } 121 122 public String getFamily_name() { 123 return family_name; 124 } 125 126 public String getGiven_name() { 127 return given_name; 128 } 129 130 /** 131 * request a token from the Google code 132 */ 133 @SuppressWarnings("deprecation") 134 private String getGoogleAccessToken(String googleCode) throws PragmatachException { 135 final String token = null; 136 if ((googleCode != null) && !"".equals(googleCode)) { 137 final String redirectUrl = getApplicationURL() + "/plugins/google/dologin"; 138 final String newUrl = "https://accounts.google.com/o/oauth2/token?client_id=" + clientid + "&redirect_uri=" + redirectUrl + "&client_secret=" + clientsecret + "&code=" + googleCode; 139 final HttpClient httpclient = new DefaultHttpClient(); 140 try { 141 final HttpPost httppost = new HttpPost(newUrl); 142 final List<NameValuePair> nvps = new ArrayList<NameValuePair>(); 143 nvps.add(new BasicNameValuePair("code", code)); 144 nvps.add(new BasicNameValuePair("client_id", clientid)); 145 nvps.add(new BasicNameValuePair("client_secret", clientsecret)); 146 nvps.add(new BasicNameValuePair("redirect_uri", redirectUrl)); 147 nvps.add(new BasicNameValuePair("grant_type", "authorization_code")); 148 httppost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8)); 149 final HttpResponse httpResponse = httpclient.execute(httppost); 150 if (httpResponse.getStatusLine().getStatusCode() == 200) { 151 final HttpEntity httpEntity = httpResponse.getEntity(); 152 final String jsonBody = EntityUtils.toString(httpEntity); 153 final JSONObject jsonObject = (JSONObject) JSONSerializer.toJSON(jsonBody); 154 final String access_token = jsonObject.getString("access_token"); 155 jsonObject.getString("expires_in"); 156 jsonObject.getString("token_type"); 157 return access_token; 158 } else { 159 System.out.println(httpResponse.getStatusLine().getReasonPhrase()); 160 } 161 } catch (final Exception e) { 162 throw new PragmatachException("Exception in getGoogleAccessToken", e); 163 } finally { 164 httpclient.getConnectionManager().shutdown(); 165 } 166 } 167 return token; 168 } 169 170 /** 171 * get the auth URL to POST to 172 */ 173 public String getGoogleAuthURL() { 174 final String sessionId = getRequest().getSession().getId(); 175 final String redirectUrl = getApplicationURL() + "/plugins/google/dologin"; 176 final String returnValue = "https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=" + clientid + "&redirect_uri=" + redirectUrl + "&state=" + sessionId + "&scope=" 177 + getScopes(); 178 return returnValue; 179 } 180 181 public String getId() { 182 return id; 183 } 184 185 public String getName() { 186 return name; 187 } 188 189 public String getRedirectURL() { 190 return redirectURL; 191 } 192 193 private String getScopes() { 194 String ret = ""; 195 for (final String s : SCOPES) { 196 ret += s + " "; 197 } 198 return ret; 199 } 200 201 public String getState() { 202 return state; 203 } 204 205 /** 206 * get the user info 207 */ 208 private void getUserInfo(String accessToken) throws PragmatachException { 209 HttpClient httpclient = new DefaultHttpClient(); 210 try { 211 final String newUrl = "https://www.googleapis.com/oauth2/v1/userinfo?access_token=" + accessToken; 212 httpclient = new DefaultHttpClient(); 213 final HttpGet httpget = new HttpGet(newUrl); 214 final BasicResponseHandler responseHandler = new BasicResponseHandler(); 215 final String responseBody = httpclient.execute(httpget, responseHandler); 216 final JSONObject json = (JSONObject) JSONSerializer.toJSON(responseBody); 217 id = json.getString("id"); 218 name = json.getString("name"); 219 given_name = json.getString("given_name"); 220 family_name = json.getString("family_name"); 221 email = json.getString("email"); 222 } catch (final Exception e) { 223 throw new PragmatachException("Exception in getUserInfo", e); 224 } finally { 225 httpclient.getConnectionManager().shutdown(); 226 } 227 } 228 229 public void setAccessToken(String accessToken) { 230 this.accessToken = accessToken; 231 } 232 233 public void setClientid(String clientid) { 234 this.clientid = clientid; 235 } 236 237 public void setClientsecret(String clientsecret) { 238 this.clientsecret = clientsecret; 239 } 240 241 public void setCode(String code) { 242 this.code = code; 243 } 244 245 public void setEmail(String email) { 246 this.email = email; 247 } 248 249 public void setFamily_name(String family_name) { 250 this.family_name = family_name; 251 } 252 253 public void setGiven_name(String given_name) { 254 this.given_name = given_name; 255 } 256 257 public void setId(String id) { 258 this.id = id; 259 } 260 261 public void setName(String name) { 262 this.name = name; 263 } 264 265 public void setState(String state) { 266 this.state = state; 267 } 268 }