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 }