aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2017-01-17 11:57:50 +0300
committerGravatar Vitaly Takmazov2017-01-17 14:14:30 +0300
commit3890570bf190a63f8f34c47a7fd21e780a61b6b0 (patch)
tree94ee4a300ae032c3e01ba8bfc17ea462f0511578
parent965d46f8188378eea8acb99e8f6c448a26a1ee19 (diff)
juick-www: Facebook and VK login using scribejava
-rw-r--r--juick-www/src/main/java/com/juick/www/Utils.java12
-rw-r--r--juick-www/src/main/java/com/juick/www/controllers/FacebookLogin.java125
-rw-r--r--juick-www/src/main/java/com/juick/www/controllers/VKontakteLogin.java116
-rw-r--r--juick-www/src/main/java/com/juick/www/facebook/User.java (renamed from juick-www/src/main/java/com/juick/www/facebook/Graph.java)4
4 files changed, 134 insertions, 123 deletions
diff --git a/juick-www/src/main/java/com/juick/www/Utils.java b/juick-www/src/main/java/com/juick/www/Utils.java
index 37016ed2..d7b5597d 100644
--- a/juick-www/src/main/java/com/juick/www/Utils.java
+++ b/juick-www/src/main/java/com/juick/www/Utils.java
@@ -32,6 +32,7 @@ import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
+import java.util.Optional;
/**
*
@@ -108,4 +109,15 @@ public class Utils {
return null;
}
}
+ /**
+ * Returns the viewName to return for coming back to the sender url
+ *
+ * @param request Instance of {@link HttpServletRequest} or use an injected instance
+ * @return Optional with the view name. Recomended to use an alternativa url with
+ * {@link Optional#orElse(java.lang.Object)}
+ */
+ public static Optional<String> getPreviousPageByRequest(HttpServletRequest request)
+ {
+ return Optional.ofNullable(request.getHeader("Referer")).map(requestUrl -> "redirect:" + requestUrl);
+ }
}
diff --git a/juick-www/src/main/java/com/juick/www/controllers/FacebookLogin.java b/juick-www/src/main/java/com/juick/www/controllers/FacebookLogin.java
index cc11f99a..b1d275b6 100644
--- a/juick-www/src/main/java/com/juick/www/controllers/FacebookLogin.java
+++ b/juick-www/src/main/java/com/juick/www/controllers/FacebookLogin.java
@@ -19,27 +19,35 @@ package com.juick.www.controllers;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.scribejava.apis.FacebookApi;
+import com.github.scribejava.core.builder.ServiceBuilder;
+import com.github.scribejava.core.model.OAuth2AccessToken;
+import com.github.scribejava.core.model.OAuthRequest;
+import com.github.scribejava.core.model.Verb;
+import com.github.scribejava.core.oauth.OAuth20Service;
+import com.juick.server.util.HttpBadRequestException;
import com.juick.service.CrosspostService;
import com.juick.service.UserService;
import com.juick.www.Utils;
-import com.juick.www.facebook.Graph;
-import org.apache.commons.lang3.CharEncoding;
+import com.juick.www.facebook.User;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
import javax.inject.Inject;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
+import java.io.IOException;
import java.util.UUID;
+import java.util.concurrent.ExecutionException;
/**
*
@@ -54,6 +62,7 @@ public class FacebookLogin {
private final String FACEBOOK_SECRET;
private final String FACEBOOK_REDIRECT = "http://juick.com/_fblogin";
private final ObjectMapper mapper;
+ private ServiceBuilder serviceBuilder;
@Inject
CrosspostService crosspostService;
@@ -64,7 +73,7 @@ public class FacebookLogin {
public FacebookLogin(Environment env) {
FACEBOOK_APPID = env.getProperty("facebook_appid");
FACEBOOK_SECRET = env.getProperty("facebook_secret");
-
+ serviceBuilder = new ServiceBuilder();
mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
@@ -72,82 +81,70 @@ public class FacebookLogin {
}
@RequestMapping(value = "/_fblogin", method = RequestMethod.GET)
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
- String fbstate;
-
- String code = request.getParameter("code");
+ protected String doGet(HttpServletRequest request,
+ @RequestParam(required = false) String code,
+ @RequestParam(required = false) String state,
+ @CookieValue(required = false) String fbstate,
+ HttpServletResponse response) throws IOException, ExecutionException, InterruptedException {
if (StringUtils.isBlank(code)) {
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?scope=publish_stream&client_id=" + FACEBOOK_APPID + "&redirect_uri=" + URLEncoder.encode(FACEBOOK_REDIRECT, CharEncoding.UTF_8) + "&state=" + fbstate);
- return;
+ OAuth20Service facebookAuthService = serviceBuilder
+ .apiKey(FACEBOOK_APPID)
+ .apiSecret(FACEBOOK_SECRET)
+ .callback(FACEBOOK_REDIRECT)
+ .scope("publish_actions")
+ .state(fbstate)
+ .build(FacebookApi.instance());
+ return "redirect:" + facebookAuthService.getAuthorizationUrl();
}
- fbstate = Utils.getCookie(request, "fbstate");
- if (fbstate == null || fbstate.isEmpty() || !fbstate.equals(request.getParameter("state"))) {
- response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
- return;
+ if (StringUtils.isBlank(fbstate) || !fbstate.equals(state)) {
+ throw new HttpBadRequestException();
} 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, CharEncoding.UTF_8) + "&client_secret=" + FACEBOOK_SECRET + "&code=" + URLEncoder.encode(code, CharEncoding.UTF_8));
- if (token == null || token.isEmpty() || !token.startsWith("access_token=")) {
- logger.error("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()) {
+ OAuth20Service facebookService = serviceBuilder
+ .apiKey(FACEBOOK_APPID)
+ .apiSecret(FACEBOOK_SECRET)
+ .callback(FACEBOOK_REDIRECT)
+ .state(state)
+ .build(FacebookApi.instance());
+ OAuth2AccessToken token = facebookService.getAccessToken(code);
+ final OAuthRequest meRequest = new OAuthRequest(Verb.GET, "https://graph.facebook.com/v2.8/me?fields=id,name,link,verified");
+ facebookService.signRequest(token, meRequest);
+ String graph = facebookService.execute(meRequest).getBody();
+ if (StringUtils.isBlank(graph)) {
logger.error("FACEBOOK GRAPH ERROR");
- response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- return;
+ throw new HttpBadRequestException();
+ }
+ User fb = mapper.readValue(graph, User.class);
+ long fbID = NumberUtils.toLong(fb.getId(), 0);
+ if (fbID == 0 || StringUtils.isBlank(fb.getName()) || StringUtils.isBlank(fb.getLink())) {
+ throw new HttpBadRequestException();
}
- try {
- Graph fb = mapper.readValue(graph, Graph.class);
-
- long fbID = NumberUtils.toLong(fb.getId(), 0);
- if (fbID == 0 || StringUtils.isBlank(fb.getName()) || StringUtils.isBlank(fb.getLink())) {
- throw new Exception();
+ int uid = crosspostService.getUIDbyFBID(fbID);
+ if (uid > 0) {
+ if (!crosspostService.updateFacebookUser(fbID, token.getAccessToken(), fb.getName(), fb.getLink())) {
+ throw new HttpBadRequestException();
}
-
- int uid = crosspostService.getUIDbyFBID(fbID);
- if (uid > 0) {
- if (!crosspostService.updateFacebookUser(fbID, token, fb.getName(), fb.getLink())) {
- throw new Exception();
- }
- Cookie c = new Cookie("hash", userService.getHashByUID(uid));
- c.setMaxAge(50 * 24 * 60 * 60);
- response.addCookie(c);
- response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
- response.setHeader("Location", "/");
- } else if (fb.getVerified()) {
- String loginhash = UUID.randomUUID().toString();
- if (!crosspostService.createFacebookUser(fbID, loginhash, token, fb.getName(), fb.getLink())) {
- throw new Exception();
- }
- response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
- response.setHeader("Location", "/signup?type=fb&hash=" + loginhash);
- } else {
- throw new Exception();
+ Cookie c = new Cookie("hash", userService.getHashByUID(uid));
+ c.setMaxAge(50 * 24 * 60 * 60);
+ response.addCookie(c);
+ return Utils.getPreviousPageByRequest(request).orElse("/");
+ } else if (fb.getVerified()) {
+ String loginhash = UUID.randomUUID().toString();
+ if (!crosspostService.createFacebookUser(fbID, loginhash, token.getAccessToken(), fb.getName(), fb.getLink())) {
+ throw new HttpBadRequestException();
}
- } catch (Exception e) {
- logger.error("fb error", e);
- response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- return;
+ return "redirect:/signup?type=fb&hash=" + loginhash;
+ } else {
+ throw new HttpBadRequestException();
}
}
}
diff --git a/juick-www/src/main/java/com/juick/www/controllers/VKontakteLogin.java b/juick-www/src/main/java/com/juick/www/controllers/VKontakteLogin.java
index d860a7bc..6ecdfd4a 100644
--- a/juick-www/src/main/java/com/juick/www/controllers/VKontakteLogin.java
+++ b/juick-www/src/main/java/com/juick/www/controllers/VKontakteLogin.java
@@ -19,26 +19,34 @@ package com.juick.www.controllers;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.scribejava.apis.VkontakteApi;
+import com.github.scribejava.core.builder.ServiceBuilder;
+import com.github.scribejava.core.model.OAuth2AccessToken;
+import com.github.scribejava.core.model.OAuthRequest;
+import com.github.scribejava.core.model.Verb;
+import com.github.scribejava.core.oauth.OAuth20Service;
+import com.juick.server.util.HttpBadRequestException;
import com.juick.service.CrosspostService;
import com.juick.service.UserService;
import com.juick.www.Utils;
-import com.juick.www.vk.Token;
import com.juick.www.vk.UsersResponse;
-import org.apache.commons.lang3.CharEncoding;
import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
import javax.inject.Inject;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
-import java.net.URLEncoder;
import java.util.UUID;
+import java.util.concurrent.ExecutionException;
/**
* @author Ugnich Anton
@@ -46,8 +54,8 @@ import java.util.UUID;
@Controller
public class VKontakteLogin {
private static final Logger logger = LoggerFactory.getLogger(VKontakteLogin.class);
- private static final String VK_APPID = "3544101";
- private static final String VK_SECRET = "z2afNI8jA5lIpZ2jsTm1";
+ private final String VK_APPID;
+ private final String VK_SECRET;
private static final String VK_REDIRECT = "http://juick.com/_vklogin";
@Inject
@@ -55,7 +63,13 @@ public class VKontakteLogin {
@Inject
UserService userService;
- public VKontakteLogin() {
+ private ServiceBuilder serviceBuilder;
+
+ @Inject
+ public VKontakteLogin(Environment env) {
+ VK_APPID = env.getProperty("vk_appid");
+ VK_SECRET = env.getProperty("vk_secret");
+ serviceBuilder = new ServiceBuilder();
mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
@@ -65,66 +79,52 @@ public class VKontakteLogin {
private final ObjectMapper mapper;
@RequestMapping(value = "/_vklogin", method = RequestMethod.GET)
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
- String code = request.getParameter("code");
+ protected String doGet(HttpServletRequest request,
+ @RequestParam(required = false) String code,
+ HttpServletResponse response) throws IOException, ExecutionException, InterruptedException {
if (StringUtils.isBlank(code)) {
- response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
- response.setHeader("Location", "https://oauth.vk.com/authorize?client_id=" + VK_APPID + "&redirect_uri=" + URLEncoder.encode(VK_REDIRECT, CharEncoding.UTF_8) + "&scope=friends,wall,offline&response_type=code");
- return;
+ OAuth20Service vkAuthService = serviceBuilder
+ .apiKey(VK_APPID)
+ .apiSecret(VK_SECRET)
+ .scope("friends,wall,offline")
+ .callback(VK_REDIRECT)
+ .build(VkontakteApi.instance());
+ return "redirect:" + vkAuthService.getAuthorizationUrl();
}
+ OAuth20Service vkService = serviceBuilder
+ .apiKey(VK_APPID)
+ .apiSecret(VK_SECRET)
+ .build(VkontakteApi.instance());
+ OAuth2AccessToken token = vkService.getAccessToken(code);
- String tokenjson = Utils.fetchURL("https://oauth.vk.com/access_token?client_id=" + VK_APPID + "&redirect_uri=" + URLEncoder.encode(VK_REDIRECT, CharEncoding.UTF_8) + "&client_secret=" + VK_SECRET + "&code=" + URLEncoder.encode(code, CharEncoding.UTF_8));
- if (tokenjson == null || tokenjson.isEmpty()) {
- logger.error("VK TOKEN EMPTY");
- response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- return;
- }
- String token = null;
- long vkID = 0;
- Token json = mapper.readValue(tokenjson, Token.class);
- token = json.getAccessToken();
- vkID = json.getUserId();
- if (token == null || vkID == 0) {
- logger.error("VK TOKEN EMPTY: {}", tokenjson);
- response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- return;
- }
-
- String graph = Utils.fetchURL("https://api.vk.com/method/users.get?uids=" + vkID + "&fields=screen_name&access_token=" + token);
- if (graph == null || graph.isEmpty()) {
- logger.error("VK GRAPH ERROR");
- response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- return;
- }
+ OAuthRequest meRequest = new OAuthRequest(Verb.GET, "https://api.vk.com/method/users.get?fields=screen_name");
+ vkService.signRequest(token, meRequest);
+ String graph = vkService.execute(meRequest).getBody();
- try {
- com.juick.www.vk.User jsonUser = mapper.readValue(graph, UsersResponse.class).getUsers().get(0);
- String vkName = jsonUser.getFirstName() + " " + jsonUser.getLastName();
- String vkLink = jsonUser.getScreenName();
+ com.juick.www.vk.User jsonUser = mapper.readValue(graph, UsersResponse.class).getUsers().get(0);
+ String vkName = jsonUser.getFirstName() + " " + jsonUser.getLastName();
+ String vkLink = jsonUser.getScreenName();
- if (vkName == null || vkLink == null || vkName.isEmpty() || vkName.length() == 1 || vkLink.isEmpty()) {
- throw new Exception();
- }
+ if (vkName.length() == 1 || StringUtils.isBlank(vkLink)) {
+ logger.error("vk user error");
+ throw new HttpBadRequestException();
+ }
- int uid = crosspostService.getUIDbyVKID(vkID);
- if (uid > 0) {
- Cookie c = new Cookie("hash", userService.getHashByUID(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 (!crosspostService.createVKUser(vkID, loginhash, token, vkName, vkLink)) {
- throw new Exception();
- }
- response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
- response.setHeader("Location", "/signup?type=vk&hash=" + loginhash);
+ Long vkID = NumberUtils.toLong(jsonUser.getUid(), 0);
+ int uid = crosspostService.getUIDbyVKID(vkID);
+ if (uid > 0) {
+ Cookie c = new Cookie("hash", userService.getHashByUID(uid));
+ c.setMaxAge(50 * 24 * 60 * 60);
+ response.addCookie(c);
+ return Utils.getPreviousPageByRequest(request).orElse("/");
+ } else {
+ String loginhash = UUID.randomUUID().toString();
+ if (!crosspostService.createVKUser(vkID, loginhash, token.getAccessToken(), vkName, vkLink)) {
+ logger.error("create vk user error");
+ throw new HttpBadRequestException();
}
- } catch (Exception e) {
- logger.error("JSON ERROR", e);
- response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ return "redirect:/signup?type=vk&hash=" + loginhash;
}
}
}
diff --git a/juick-www/src/main/java/com/juick/www/facebook/Graph.java b/juick-www/src/main/java/com/juick/www/facebook/User.java
index f4c6ab2a..763e98d7 100644
--- a/juick-www/src/main/java/com/juick/www/facebook/Graph.java
+++ b/juick-www/src/main/java/com/juick/www/facebook/User.java
@@ -1,11 +1,13 @@
package com.juick.www.facebook;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Created by vitalyster on 28.11.2016.
*/
-public class Graph {
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class User {
private String id;
private String name;
private String link;