/* * 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; } } }