aboutsummaryrefslogtreecommitdiff
path: root/src/java/com/juick/http/www/FacebookLogin.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/java/com/juick/http/www/FacebookLogin.java')
-rw-r--r--src/java/com/juick/http/www/FacebookLogin.java162
1 files changed, 162 insertions, 0 deletions
diff --git a/src/java/com/juick/http/www/FacebookLogin.java b/src/java/com/juick/http/www/FacebookLogin.java
new file mode 100644
index 00000000..8933075b
--- /dev/null
+++ b/src/java/com/juick/http/www/FacebookLogin.java
@@ -0,0 +1,162 @@
+/*
+ * Juick
+ * Copyright (C) 2008-2013, Ugnich Anton
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.juick.http.www;
+
+import com.juick.server.UserQueries;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.UUID;
+import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.json.JSONObject;
+
+/**
+ *
+ * @author Ugnich Anton
+ */
+public class FacebookLogin {
+
+ private static final String FACEBOOK_APPID = "130568668304";
+ private static final String FACEBOOK_SECRET = "95813bfb6ab8f473410c50d4f971649e";
+ private static final String FACEBOOK_REDIRECT = "http://juick.com/_fblogin";
+
+ protected void doGet(Connection sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ String fbstate;
+
+ String code = request.getParameter("code");
+ if (code == null || code.equals("")) {
+ fbstate = UUID.randomUUID().toString();
+
+ Cookie c = new Cookie("fbstate", fbstate);
+ response.addCookie(c);
+
+ response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
+ response.setHeader("Location", "https://www.facebook.com/dialog/oauth?client_id=" + FACEBOOK_APPID + "&redirect_uri=" + URLEncoder.encode(FACEBOOK_REDIRECT, "utf-8") + "&state=" + fbstate);
+ return;
+ }
+
+ fbstate = Utils.getCookie(request, "fbstate");
+ if (fbstate == null || fbstate.isEmpty() || !fbstate.equals(request.getParameter("state"))) {
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ } else {
+ Cookie c = new Cookie("fbstate", "-");
+ c.setMaxAge(0);
+ response.addCookie(c);
+ }
+
+ String token = Utils.fetchURL("https://graph.facebook.com/oauth/access_token?client_id=" + FACEBOOK_APPID + "&redirect_uri=" + URLEncoder.encode(FACEBOOK_REDIRECT, "utf-8") + "&client_secret=" + FACEBOOK_SECRET + "&code=" + URLEncoder.encode(code, "utf-8"));
+ if (token == null || token.isEmpty() || !token.startsWith("access_token=")) {
+ System.err.println("FACEBOOK TOKEN ERROR: " + token);
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ return;
+ }
+ token = token.substring(13); // access_token=...
+ int tokenamp = token.indexOf('&'); // &expires=
+ if (tokenamp > 0) {
+ token = token.substring(0, tokenamp);
+ }
+
+ String graph = Utils.fetchURL("https://graph.facebook.com/me?access_token=" + token);
+ if (graph == null || graph.isEmpty()) {
+ System.err.println("FACEBOOK GRAPH ERROR");
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ try {
+ JSONObject json = new JSONObject(graph);
+ String fbIDStr = json.getString("id");
+ String fbName = json.getString("name");
+ String fbLink = json.getString("link");
+
+ long fbID = 0;
+ if (fbIDStr != null && !fbIDStr.isEmpty()) {
+ fbID = Long.parseLong(fbIDStr);
+ }
+
+ if (fbID == 0 || fbName == null || fbLink == null || fbName.isEmpty() || fbLink.isEmpty()) {
+ throw new Exception();
+ }
+
+ int uid = getUIDbyFBID(sql, fbID);
+ if (uid > 0) {
+ Cookie c = new Cookie("hash", UserQueries.getHashByUID(sql, uid));
+ c.setMaxAge(50 * 24 * 60 * 60);
+ response.addCookie(c);
+ response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
+ response.setHeader("Location", "/");
+ } else {
+ String loginhash = UUID.randomUUID().toString();
+ if (!insertDB(sql, fbID, loginhash, token, fbName, fbLink)) {
+ throw new Exception();
+ }
+ response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
+ response.setHeader("Location", "/signup?type=fb&hash=" + loginhash);
+ }
+ } catch (Exception e) {
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ return;
+ }
+ }
+
+ private int getUIDbyFBID(Connection sql, long fbID) {
+ int uid = 0;
+ PreparedStatement stmt = null;
+ ResultSet rs = null;
+ try {
+ stmt = sql.prepareStatement("SELECT user_id FROM facebook WHERE fb_id=? AND user_id IS NOT NULL");
+ stmt.setLong(1, fbID);
+ rs = stmt.executeQuery();
+ if (rs.first()) {
+ uid = rs.getInt(1);
+ }
+ } catch (SQLException e) {
+ System.err.println(e);
+ } finally {
+ Utils.finishSQL(rs, stmt);
+ }
+ return uid;
+ }
+
+ private boolean insertDB(Connection sql, long fbID, String loginhash, String token, String fbName, String fbLink) {
+ boolean ret = false;
+ PreparedStatement stmt = null;
+ try {
+ stmt = sql.prepareStatement("INSERT INTO facebook(fb_id,loginhash,access_token,fb_name,fb_link) VALUES (?,?,?,?,?)");
+ stmt.setLong(1, fbID);
+ stmt.setString(2, loginhash);
+ stmt.setString(3, token);
+ stmt.setString(4, fbName);
+ stmt.setString(5, fbLink);
+ stmt.executeUpdate();
+ ret = true;
+ } catch (SQLException e) {
+ System.err.println(e);
+ } finally {
+ Utils.finishSQL(null, stmt);
+ }
+ return ret;
+ }
+}