From bc28b399695f1f99f8ee58cb4f0f0e4bd7d52508 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Thu, 15 Feb 2018 13:17:36 +0300 Subject: www: merge social login methods --- .../com/juick/www/controllers/FacebookLogin.java | 155 ----------- .../com/juick/www/controllers/SocialLogin.java | 282 +++++++++++++++++++++ .../com/juick/www/controllers/TwitterAuth.java | 118 --------- .../com/juick/www/controllers/VKontakteLogin.java | 139 ---------- 4 files changed, 282 insertions(+), 412 deletions(-) delete mode 100644 juick-www/src/main/java/com/juick/www/controllers/FacebookLogin.java create mode 100644 juick-www/src/main/java/com/juick/www/controllers/SocialLogin.java delete mode 100644 juick-www/src/main/java/com/juick/www/controllers/TwitterAuth.java delete mode 100644 juick-www/src/main/java/com/juick/www/controllers/VKontakteLogin.java (limited to 'juick-www/src/main') 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 deleted file mode 100644 index 6e8d6864..00000000 --- a/juick-www/src/main/java/com/juick/www/controllers/FacebookLogin.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 2008-2017, Juick - * - * 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 . - */ -package com.juick.www.controllers; - -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.EmailService; -import com.juick.service.UserService; -import com.juick.www.Utils; -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.beans.factory.annotation.Value; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.CookieValue; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; - -import javax.annotation.PostConstruct; -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.util.UUID; -import java.util.concurrent.ExecutionException; - -/** - * - * @author Ugnich Anton - */ -@Controller -public class FacebookLogin { - - private static final Logger logger = LoggerFactory.getLogger(FacebookLogin.class); - - @Value("${facebook_appid}") - private String FACEBOOK_APPID; - @Value("${facebook_secret}") - private String FACEBOOK_SECRET; - private final String FACEBOOK_REDIRECT = "http://juick.com/_fblogin"; - @Inject - private ObjectMapper jsonMapper; - private ServiceBuilder serviceBuilder; - - @Inject - private CrosspostService crosspostService; - @Inject - private UserService userService; - @Inject - private EmailService emailService; - - @PostConstruct - public void init() { - serviceBuilder = new ServiceBuilder(FACEBOOK_APPID); - } - - @GetMapping("/_fblogin") - 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); - OAuth20Service facebookAuthService = serviceBuilder - .apiSecret(FACEBOOK_SECRET) - .callback(FACEBOOK_REDIRECT) - .scope("email") - .state(fbstate) - .build(FacebookApi.instance()); - return "redirect:" + facebookAuthService.getAuthorizationUrl(); - } - - if (StringUtils.isBlank(fbstate) || !fbstate.equals(state)) { - throw new HttpBadRequestException(); - } else { - Cookie c = new Cookie("fbstate", "-"); - c.setMaxAge(0); - response.addCookie(c); - } - 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.10/me?fields=id,name,link,verified,email"); - facebookService.signRequest(token, meRequest); - String graph = facebookService.execute(meRequest).getBody(); - if (StringUtils.isBlank(graph)) { - logger.error("FACEBOOK GRAPH ERROR"); - throw new HttpBadRequestException(); - } - User fb = jsonMapper.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(); - } - - int uid = crosspostService.getUIDbyFBID(fbID); - if (uid > 0) { - if (!crosspostService.updateFacebookUser(fbID, token.getAccessToken(), fb.getName(), fb.getLink())) { - throw new HttpBadRequestException(); - } - Cookie c = new Cookie("hash", userService.getHashByUID(uid)); - c.setMaxAge(50 * 24 * 60 * 60); - response.addCookie(c); - return Utils.getPreviousPageByRequest(request).orElse("redirect:/"); - } else if (fb.getVerified()) { - String loginhash = UUID.randomUUID().toString(); - if (!crosspostService.createFacebookUser(fbID, loginhash, token.getAccessToken(), fb.getName(), fb.getLink())) { - if (StringUtils.isNotEmpty(fb.getEmail())) { - logger.info("found {} for facebook user {}", fb.getEmail(), fb.getLink()); - Integer userId = crosspostService.getUIDbyFBID(fbID); - if (!emailService.getEmails(userId, false).contains(fb.getEmail())) { - emailService.addEmail(userId, fb.getEmail()); - } - } - logger.info("email not found for facebook user {}", fb.getLink()); - throw new HttpBadRequestException(); - } - return "redirect:/signup?type=fb&hash=" + loginhash; - } else { - throw new HttpBadRequestException(); - } - } -} diff --git a/juick-www/src/main/java/com/juick/www/controllers/SocialLogin.java b/juick-www/src/main/java/com/juick/www/controllers/SocialLogin.java new file mode 100644 index 00000000..4a502637 --- /dev/null +++ b/juick-www/src/main/java/com/juick/www/controllers/SocialLogin.java @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2008-2017, Juick + * + * 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 . + */ +package com.juick.www.controllers; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.scribejava.apis.FacebookApi; +import com.github.scribejava.apis.TwitterApi; +import com.github.scribejava.apis.VkontakteApi; +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.core.model.*; +import com.github.scribejava.core.oauth.OAuth10aService; +import com.github.scribejava.core.oauth.OAuth20Service; +import com.juick.server.util.HttpBadRequestException; +import com.juick.server.util.UserUtils; +import com.juick.service.CrosspostService; +import com.juick.service.EmailService; +import com.juick.service.UserService; +import com.juick.www.Utils; +import com.juick.www.facebook.User; +import com.juick.www.vk.UsersResponse; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import javax.annotation.PostConstruct; +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.util.UUID; +import java.util.concurrent.ExecutionException; + +/** + * + * @author Ugnich Anton + */ +@Controller +public class SocialLogin { + + private static final Logger logger = LoggerFactory.getLogger(SocialLogin.class); + + @Value("${facebook_appid}") + private String FACEBOOK_APPID; + @Value("${facebook_secret}") + private String FACEBOOK_SECRET; + private static final String FACEBOOK_REDIRECT = "http://juick.com/_fblogin"; + private static final String VK_REDIRECT = "http://juick.com/_vklogin"; + private static final String TWITTER_VERIFY_URL = "https://api.twitter.com/1.1/account/verify_credentials.json"; + @Inject + private ObjectMapper jsonMapper; + private ServiceBuilder facebookBuilder, twitterBuilder, vkBuilder; + + @Value("${twitter_consumer_key}") + private String twitterConsumerKey; + @Value("${twitter_consumer_secret}") + private String twitterConsumerSecret; + @Value("${vk_appid}") + private String VK_APPID; + @Value("${vk_secret}") + private String VK_SECRET; + + @Inject + private CrosspostService crosspostService; + @Inject + private UserService userService; + @Inject + private EmailService emailService; + + @PostConstruct + public void init() { + facebookBuilder = new ServiceBuilder(FACEBOOK_APPID); + twitterBuilder = new ServiceBuilder(twitterConsumerKey); + vkBuilder = new ServiceBuilder(VK_APPID); + } + + @GetMapping("/_fblogin") + protected String doFacebookLogin(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); + OAuth20Service facebookAuthService = facebookBuilder + .apiSecret(FACEBOOK_SECRET) + .callback(FACEBOOK_REDIRECT) + .scope("email") + .state(fbstate) + .build(FacebookApi.instance()); + return "redirect:" + facebookAuthService.getAuthorizationUrl(); + } + + if (StringUtils.isBlank(fbstate) || !fbstate.equals(state)) { + throw new HttpBadRequestException(); + } else { + Cookie c = new Cookie("fbstate", "-"); + c.setMaxAge(0); + response.addCookie(c); + } + OAuth20Service facebookService = facebookBuilder + .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.10/me?fields=id,name,link,verified,email"); + facebookService.signRequest(token, meRequest); + String graph = facebookService.execute(meRequest).getBody(); + if (StringUtils.isBlank(graph)) { + logger.error("FACEBOOK GRAPH ERROR"); + throw new HttpBadRequestException(); + } + User fb = jsonMapper.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(); + } + + int uid = crosspostService.getUIDbyFBID(fbID); + if (uid > 0) { + if (!crosspostService.updateFacebookUser(fbID, token.getAccessToken(), fb.getName(), fb.getLink())) { + throw new HttpBadRequestException(); + } + Cookie c = new Cookie("hash", userService.getHashByUID(uid)); + c.setMaxAge(50 * 24 * 60 * 60); + response.addCookie(c); + return Utils.getPreviousPageByRequest(request).orElse("redirect:/"); + } else if (fb.getVerified()) { + String loginhash = UUID.randomUUID().toString(); + if (!crosspostService.createFacebookUser(fbID, loginhash, token.getAccessToken(), fb.getName(), fb.getLink())) { + if (StringUtils.isNotEmpty(fb.getEmail())) { + logger.info("found {} for facebook user {}", fb.getEmail(), fb.getLink()); + Integer userId = crosspostService.getUIDbyFBID(fbID); + if (!emailService.getEmails(userId, false).contains(fb.getEmail())) { + emailService.addEmail(userId, fb.getEmail()); + } + } + logger.info("email not found for facebook user {}", fb.getLink()); + throw new HttpBadRequestException(); + } + return "redirect:/signup?type=fb&hash=" + loginhash; + } else { + throw new HttpBadRequestException(); + } + } + @GetMapping("/_twitter") + protected void doTwitterLogin(HttpServletRequest request, HttpServletResponse response) + throws IOException, ExecutionException, InterruptedException { + String hash = StringUtils.EMPTY, request_token = StringUtils.EMPTY, request_token_secret = StringUtils.EMPTY; + String verifier = request.getParameter("oauth_verifier"); + Cookie[] cookies = request.getCookies(); + for (Cookie cookie : cookies) { + if (cookie.getName().equals("hash")) { + hash = cookie.getValue(); + } + if (cookie.getName().equals("request_token")) { + request_token = cookie.getValue(); + } + if (cookie.getName().equals("request_token_secret")) { + request_token_secret = cookie.getValue(); + } + } + com.juick.User user = UserUtils.getCurrentUser(); + OAuth10aService oAuthService = twitterBuilder + .apiSecret(twitterConsumerSecret) + .callback("http://juick.com/_twitter") + .build(TwitterApi.instance()); + + if (request_token.isEmpty() && request_token_secret.isEmpty() + && (verifier == null || verifier.isEmpty())) { + OAuth1RequestToken requestToken = oAuthService.getRequestToken(); + String authUrl = oAuthService.getAuthorizationUrl(requestToken); + response.addCookie(new Cookie("request_token", requestToken.getToken())); + response.addCookie(new Cookie("request_token_secret", requestToken.getTokenSecret())); + response.setStatus(HttpServletResponse.SC_FOUND); + response.setHeader("Location", authUrl); + } else { + if (verifier != null && verifier.length() > 0) { + OAuth1RequestToken requestToken = new OAuth1RequestToken(request_token, request_token_secret); + OAuth1AccessToken accessToken = oAuthService.getAccessToken(requestToken, verifier); + OAuthRequest oAuthRequest = new OAuthRequest(Verb.GET, TWITTER_VERIFY_URL); + oAuthService.signRequest(accessToken, oAuthRequest); + com.juick.www.twitter.User twitterUser = jsonMapper.readValue(oAuthService.execute(oAuthRequest).getBody(), + com.juick.www.twitter.User.class); + if (userService.linkTwitterAccount(user, accessToken.getToken(), accessToken.getTokenSecret(), + twitterUser.getScreenName())) { + response.setStatus(HttpServletResponse.SC_FOUND); + response.setHeader("Location", "http://juick.com/settings"); + } else { + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + } + } + } + @GetMapping("/_vklogin") + protected String doVKLogin(HttpServletRequest request, + @RequestParam(required = false) String code, + @RequestParam(required = false) String state, + @CookieValue(required = false) String vkstate, + HttpServletResponse response) throws IOException, ExecutionException, InterruptedException { + if (StringUtils.isBlank(code)) { + vkstate = UUID.randomUUID().toString(); + Cookie c = new Cookie("vkstate", vkstate); + response.addCookie(c); + OAuth20Service vkAuthService = vkBuilder + .apiSecret(VK_SECRET) + .scope("friends,wall,offline") + .state(vkstate) + .callback(VK_REDIRECT) + .build(VkontakteApi.instance()); + return "redirect:" + vkAuthService.getAuthorizationUrl(); + } + + if (StringUtils.isBlank(vkstate) || !vkstate.equals(state)) { + throw new HttpBadRequestException(); + } else { + Cookie c = new Cookie("vkstate", "-"); + c.setMaxAge(0); + response.addCookie(c); + } + + OAuth20Service vkService = vkBuilder + .apiKey(VK_APPID) + .apiSecret(VK_SECRET) + .build(VkontakteApi.instance()); + OAuth2AccessToken token = vkService.getAccessToken(code); + + 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(); + + com.juick.www.vk.User jsonUser = jsonMapper.readValue(graph, UsersResponse.class).getUsers().get(0); + String vkName = jsonUser.getFirstName() + " " + jsonUser.getLastName(); + String vkLink = jsonUser.getScreenName(); + + if (vkName.length() == 1 || StringUtils.isBlank(vkLink)) { + logger.error("vk user error"); + throw new HttpBadRequestException(); + } + + 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("redirect:/"); + } else { + String loginhash = UUID.randomUUID().toString(); + if (!crosspostService.createVKUser(vkID, loginhash, token.getAccessToken(), vkName, vkLink)) { + logger.error("create vk user error"); + throw new HttpBadRequestException(); + } + return "redirect:/signup?type=vk&hash=" + loginhash; + } + } +} diff --git a/juick-www/src/main/java/com/juick/www/controllers/TwitterAuth.java b/juick-www/src/main/java/com/juick/www/controllers/TwitterAuth.java deleted file mode 100644 index 43252495..00000000 --- a/juick-www/src/main/java/com/juick/www/controllers/TwitterAuth.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2008-2017, Juick - * - * 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 . - */ - -package com.juick.www.controllers; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.scribejava.apis.TwitterApi; -import com.github.scribejava.core.builder.ServiceBuilder; -import com.github.scribejava.core.model.OAuth1AccessToken; -import com.github.scribejava.core.model.OAuth1RequestToken; -import com.github.scribejava.core.model.OAuthRequest; -import com.github.scribejava.core.model.Verb; -import com.github.scribejava.core.oauth.OAuth10aService; -import com.juick.server.util.UserUtils; -import com.juick.service.UserService; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; - -import javax.annotation.PostConstruct; -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.util.concurrent.ExecutionException; - -/** - * Created by vt on 01.12.2015. - */ -@Controller -public class TwitterAuth { - - private final static String VERIFY_URL = "https://api.twitter.com/1.1/account/verify_credentials.json"; - - @Value("${twitter_consumer_key}") - private String consumerKey; - @Value("${twitter_consumer_secret}") - private String consumerSecret; - - @Inject - private ObjectMapper jsonMapper; - - @Inject - private UserService userService; - - private ServiceBuilder serviceBuilder; - - @PostConstruct - public void init() { - serviceBuilder = new ServiceBuilder(consumerKey); - } - - @GetMapping("/_twitter") - protected void doGet(HttpServletRequest request, HttpServletResponse response) - throws IOException, ExecutionException, InterruptedException { - String hash = StringUtils.EMPTY, request_token = StringUtils.EMPTY, request_token_secret = StringUtils.EMPTY; - String verifier = request.getParameter("oauth_verifier"); - Cookie[] cookies = request.getCookies(); - for (Cookie cookie : cookies) { - if (cookie.getName().equals("hash")) { - hash = cookie.getValue(); - } - if (cookie.getName().equals("request_token")) { - request_token = cookie.getValue(); - } - if (cookie.getName().equals("request_token_secret")) { - request_token_secret = cookie.getValue(); - } - } - com.juick.User user = UserUtils.getCurrentUser(); - OAuth10aService oAuthService = serviceBuilder - .apiSecret(consumerSecret) - .callback("http://juick.com/_twitter") - .build(TwitterApi.instance()); - - if (request_token.isEmpty() && request_token_secret.isEmpty() - && (verifier == null || verifier.isEmpty())) { - OAuth1RequestToken requestToken = oAuthService.getRequestToken(); - String authUrl = oAuthService.getAuthorizationUrl(requestToken); - response.addCookie(new Cookie("request_token", requestToken.getToken())); - response.addCookie(new Cookie("request_token_secret", requestToken.getTokenSecret())); - response.setStatus(HttpServletResponse.SC_FOUND); - response.setHeader("Location", authUrl); - } else { - if (verifier != null && verifier.length() > 0) { - OAuth1RequestToken requestToken = new OAuth1RequestToken(request_token, request_token_secret); - OAuth1AccessToken accessToken = oAuthService.getAccessToken(requestToken, verifier); - OAuthRequest oAuthRequest = new OAuthRequest(Verb.GET, VERIFY_URL); - oAuthService.signRequest(accessToken, oAuthRequest); - com.juick.www.twitter.User twitterUser = jsonMapper.readValue(oAuthService.execute(oAuthRequest).getBody(), - com.juick.www.twitter.User.class); - if (userService.linkTwitterAccount(user, accessToken.getToken(), accessToken.getTokenSecret(), - twitterUser.getScreenName())) { - response.setStatus(HttpServletResponse.SC_FOUND); - response.setHeader("Location", "http://juick.com/settings"); - } else { - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } - } - } - } -} 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 deleted file mode 100644 index 382c3194..00000000 --- a/juick-www/src/main/java/com/juick/www/controllers/VKontakteLogin.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2008-2017, Juick - * - * 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 . - */ -package com.juick.www.controllers; - -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.UsersResponse; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.math.NumberUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.CookieValue; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; - -import javax.annotation.PostConstruct; -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.util.UUID; -import java.util.concurrent.ExecutionException; - -/** - * @author Ugnich Anton - */ -@Controller -public class VKontakteLogin { - private static final Logger logger = LoggerFactory.getLogger(VKontakteLogin.class); - @Value("${vk_appid}") - private String VK_APPID; - @Value("${vk_secret}") - private String VK_SECRET; - private static final String VK_REDIRECT = "http://juick.com/_vklogin"; - - @Inject - private CrosspostService crosspostService; - @Inject - private UserService userService; - - private ServiceBuilder serviceBuilder; - - @PostConstruct - public void init() { - serviceBuilder = new ServiceBuilder(VK_APPID); - } - - @Inject - private ObjectMapper jsonMapper; - - @GetMapping("/_vklogin") - protected String doGet(HttpServletRequest request, - @RequestParam(required = false) String code, - @RequestParam(required = false) String state, - @CookieValue(required = false) String vkstate, - HttpServletResponse response) throws IOException, ExecutionException, InterruptedException { - if (StringUtils.isBlank(code)) { - vkstate = UUID.randomUUID().toString(); - Cookie c = new Cookie("vkstate", vkstate); - response.addCookie(c); - OAuth20Service vkAuthService = serviceBuilder - .apiSecret(VK_SECRET) - .scope("friends,wall,offline") - .state(vkstate) - .callback(VK_REDIRECT) - .build(VkontakteApi.instance()); - return "redirect:" + vkAuthService.getAuthorizationUrl(); - } - - if (StringUtils.isBlank(vkstate) || !vkstate.equals(state)) { - throw new HttpBadRequestException(); - } else { - Cookie c = new Cookie("vkstate", "-"); - c.setMaxAge(0); - response.addCookie(c); - } - - OAuth20Service vkService = serviceBuilder - .apiKey(VK_APPID) - .apiSecret(VK_SECRET) - .build(VkontakteApi.instance()); - OAuth2AccessToken token = vkService.getAccessToken(code); - - 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(); - - com.juick.www.vk.User jsonUser = jsonMapper.readValue(graph, UsersResponse.class).getUsers().get(0); - String vkName = jsonUser.getFirstName() + " " + jsonUser.getLastName(); - String vkLink = jsonUser.getScreenName(); - - if (vkName.length() == 1 || StringUtils.isBlank(vkLink)) { - logger.error("vk user error"); - throw new HttpBadRequestException(); - } - - 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("redirect:/"); - } else { - String loginhash = UUID.randomUUID().toString(); - if (!crosspostService.createVKUser(vkID, loginhash, token.getAccessToken(), vkName, vkLink)) { - logger.error("create vk user error"); - throw new HttpBadRequestException(); - } - return "redirect:/signup?type=vk&hash=" + loginhash; - } - } -} -- cgit v1.2.3