aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/juick/www
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2023-07-19 23:50:14 +0300
committerGravatar Vitaly Takmazov2023-07-19 23:59:40 +0300
commitc576c003716851863c832b5e0dacb9186516f167 (patch)
tree420c517806d28db3c8f448eacbc3d61f01106629 /src/main/java/com/juick/www
parent128753a9bd11e09940d58d97c67db59a15251b71 (diff)
Migrate to Twitter API 2.0
Diffstat (limited to 'src/main/java/com/juick/www')
-rw-r--r--src/main/java/com/juick/www/controllers/Site.java1
-rw-r--r--src/main/java/com/juick/www/controllers/SocialLogin.java89
2 files changed, 43 insertions, 47 deletions
diff --git a/src/main/java/com/juick/www/controllers/Site.java b/src/main/java/com/juick/www/controllers/Site.java
index 8b35593c..47438900 100644
--- a/src/main/java/com/juick/www/controllers/Site.java
+++ b/src/main/java/com/juick/www/controllers/Site.java
@@ -95,6 +95,7 @@ public class Site {
tagService.getUserTagStats(user.getUid()).stream()
.sorted((e1, e2) -> Integer.compare(e2.getUsageCount(), e1.getUsageCount())).limit(20)
.map(t -> t.getTag().getName()).toList());
+ model.addAttribute("twitter1", userService.isTwitter1User(user));
}
@GetMapping("/login")
diff --git a/src/main/java/com/juick/www/controllers/SocialLogin.java b/src/main/java/com/juick/www/controllers/SocialLogin.java
index 0cac26c5..bae9deb2 100644
--- a/src/main/java/com/juick/www/controllers/SocialLogin.java
+++ b/src/main/java/com/juick/www/controllers/SocialLogin.java
@@ -16,18 +16,19 @@
*/
package com.juick.www.controllers;
+import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.scribejava.apis.*;
import com.github.scribejava.core.builder.ServiceBuilder;
import com.github.scribejava.core.model.*;
+import com.github.scribejava.core.oauth.AccessTokenRequestParams;
+import com.github.scribejava.core.oauth.AuthorizationUrlBuilder;
import com.github.scribejava.core.oauth.OAuth10aService;
import com.github.scribejava.core.oauth.OAuth20Service;
+import com.github.scribejava.core.pkce.PKCEService;
import com.juick.model.ext.facebook.User;
import com.juick.model.ext.vk.UsersResponse;
-import com.juick.service.EmailService;
-import com.juick.service.TelegramService;
-import com.juick.service.UserService;
-import com.juick.service.VKService;
+import com.juick.service.*;
import com.juick.service.security.entities.JuickUser;
import com.juick.util.HttpBadRequestException;
@@ -82,17 +83,16 @@ public class SocialLogin {
private String FACEBOOK_SECRET;
@Value("${ap_base_uri:http://localhost:8080/}")
private String baseUri;
- private static final String TWITTER_VERIFY_URL = "https://api.twitter.com/1.1/account/verify_credentials.json";
+ private static final String TWITTER_VERIFY_URL = "https://api.twitter.com/2/users/me";
@Inject
private ObjectMapper jsonMapper;
private ServiceBuilder twitterBuilder;
private OAuth20Service facebookAuthService, appleSignInService;
@Inject
private VKService vkService;
- @Value("${twitter_consumer_key:appid}")
- private String twitterConsumerKey;
- @Value("${twitter_consumer_secret:secret}")
- private String twitterConsumerSecret;
+ @Inject
+ private TwitterService twitterService;
+
@Value("${telegram_token:secret}")
private String telegramToken;
@Value("${apple_app_id:appid}")
@@ -108,10 +108,11 @@ public class SocialLogin {
@Inject
private RememberMeServices rememberMeServices;
+ private AuthorizationUrlBuilder authorizationUrlBuilder;
+
@PostConstruct
public void init() {
ServiceBuilder facebookBuilder = new ServiceBuilder(FACEBOOK_APPID);
- twitterBuilder = new ServiceBuilder(twitterConsumerKey);
UriComponentsBuilder redirectBuilder = UriComponentsBuilder.fromUriString(baseUri);
String facebookRedirectUri = redirectBuilder.replacePath("/_fblogin").build().toUriString();
@@ -189,47 +190,41 @@ public class SocialLogin {
}
@GetMapping("/_twitter")
- protected void doTwitterLogin(com.juick.model.User user, 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();
- }
- }
- OAuth10aService oAuthService = twitterBuilder.apiSecret(twitterConsumerSecret)
- .callback("https://juick.com/_twitter").build(TwitterApi.instance());
+ protected String doTwitterLogin(@RequestParam(required = false) String code,
+ @RequestParam(required = false) String state,
+ com.juick.model.User user,
+ HttpServletRequest request)
+ throws IOException, ExecutionException, InterruptedException {
- 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);
+ if (StringUtils.isBlank(code)) {
+ state = UUID.randomUUID().toString();
+ authorizationUrlBuilder = twitterService.getTwitterAuthService().createAuthorizationUrlBuilder()
+ .state(state)
+ .initPKCE();
+ return "redirect:" + authorizationUrlBuilder.build();
} 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.model.ext.twitter.User twitterUser = jsonMapper.readValue(
- oAuthService.execute(oAuthRequest).getBody(), com.juick.model.ext.twitter.User.class);
- if (userService.linkTwitterAccount(user, accessToken.getToken(), accessToken.getTokenSecret(),
- twitterUser.screenName())) {
- response.setStatus(HttpServletResponse.SC_FOUND);
- response.setHeader("Location", "http://juick.com/settings");
+ var token = twitterService.getTwitterAuthService().getAccessToken(AccessTokenRequestParams.create(code)
+ .pkceCodeVerifier(authorizationUrlBuilder.getPkce().getCodeVerifier()));
+ var me = new OAuthRequest(Verb.GET, TWITTER_VERIFY_URL);
+ twitterService.getTwitterAuthService().signRequest(token, me);
+ try (var response = twitterService.getTwitterAuthService().execute(me)) {
+ if (response.isSuccessful()) {
+ logger.info("Twitter response: {}", response.getBody());
+ JsonNode json = jsonMapper.readTree(response.getBody());
+ var screenName = json.get("data").get("username").asText();
+ if (userService.linkTwitterAccount(user, token.getAccessToken(), token.getRefreshToken(),
+ screenName)) {
+ return "redirect:https://juick.com/settings";
+ } else {
+ throw new HttpBadRequestException();
+ }
} else {
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ logger.warn("Twitter error {}: {}", response.getCode(), response.getBody());
+ throw new HttpBadRequestException();
}
+ } catch (Exception e) {
+ logger.error("Twitter error", e);
+ throw new HttpBadRequestException();
}
}
}