aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/juick/service
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2023-06-20 07:10:16 +0300
committerGravatar Vitaly Takmazov2023-06-21 01:02:41 +0300
commit10dcb7324fac83c0190ff4a842360a035449f278 (patch)
tree95b90305ff7e7cdb3fd298878353ed702a0754a1 /src/main/java/com/juick/service
parent314db08815ae98bff02a7489cddf861cd01f2629 (diff)
VK: read premium status using Callback API
Diffstat (limited to 'src/main/java/com/juick/service')
-rw-r--r--src/main/java/com/juick/service/UserService.java5
-rw-r--r--src/main/java/com/juick/service/UserServiceImpl.java13
-rw-r--r--src/main/java/com/juick/service/VKService.java94
3 files changed, 104 insertions, 8 deletions
diff --git a/src/main/java/com/juick/service/UserService.java b/src/main/java/com/juick/service/UserService.java
index fe5ce23f..4acc5b6a 100644
--- a/src/main/java/com/juick/service/UserService.java
+++ b/src/main/java/com/juick/service/UserService.java
@@ -25,12 +25,14 @@ import com.juick.model.ExternalToken;
import com.juick.util.UsernameTakenException;
import jakarta.annotation.Nonnull;
+import jakarta.annotation.Nullable;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
/**
@@ -151,7 +153,8 @@ public interface UserService {
String getTelegramName(int uid);
- List<Pair<String, String>> getVkTokens(List<Integer> uids);
+ @Nullable
+ Pair<String, String> getVkTokens(int uid);
void deleteVKUser(Integer uid);
diff --git a/src/main/java/com/juick/service/UserServiceImpl.java b/src/main/java/com/juick/service/UserServiceImpl.java
index c586886b..d19af067 100644
--- a/src/main/java/com/juick/service/UserServiceImpl.java
+++ b/src/main/java/com/juick/service/UserServiceImpl.java
@@ -741,14 +741,13 @@ public class UserServiceImpl extends BaseJdbcService implements UserService {
@Transactional(readOnly = true)
@Override
- public List<Pair<String, String>> getVkTokens(List<Integer> uids) {
- return getNamedParameterJdbcTemplate().query(
- """
- SELECT vk_id, access_token FROM vk WHERE crosspost = 1 AND access_token <> ''"""
- + (uids.isEmpty() ? "" : " AND user_id IN (:uids)"),
+ public Pair<String, String> getVkTokens(int uid) {
+ var result = getNamedParameterJdbcTemplate().query(
+ "SELECT vk_id, access_token FROM vk WHERE user_id=:uid AND crosspost = 1 AND access_token <> ''",
new MapSqlParameterSource()
- .addValue("uids", uids),
+ .addValue("uid", uid),
(rs, num) -> Pair.of(rs.getString(1), rs.getString(2)));
+ return result.isEmpty() ? null : result.get(0);
}
@Transactional
@@ -885,7 +884,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService {
@Transactional(readOnly = true)
@Override
public boolean canDeleteTelegramUser(User user) {
- return getEmails(user).size() > 0 || getFbCrossPostStatus(user.getUid()).isConnected() || !getVkTokens(List.of(user.getUid())).isEmpty();
+ return getEmails(user).size() > 0 || getFbCrossPostStatus(user.getUid()).isConnected() || getVkTokens(user.getUid()) != null;
}
private static class TokenMapper implements RowMapper<ExternalToken> {
diff --git a/src/main/java/com/juick/service/VKService.java b/src/main/java/com/juick/service/VKService.java
new file mode 100644
index 00000000..14d7e3e9
--- /dev/null
+++ b/src/main/java/com/juick/service/VKService.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2008-2023, 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 <http://www.gnu.org/licenses/>.
+ */
+
+package com.juick.service;
+
+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.Response;
+import com.github.scribejava.core.model.Verb;
+import com.github.scribejava.core.oauth.OAuth20Service;
+import jakarta.annotation.PostConstruct;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.inject.Inject;
+
+@Service
+public class VKService {
+ private static final Logger logger = LoggerFactory.getLogger("VK");
+ @Value("${vk_appid:appid}")
+ private String VK_APPID;
+ @Value("${vk_secret:secret}")
+ private String VK_SECRET;
+ private static final String VK_REDIRECT = "https://juick.com/_vklogin";
+ @Inject
+ private ObjectMapper jsonMapper;
+ @Inject
+ private UserService userService;
+ private OAuth20Service vkAuthService;
+
+ @PostConstruct
+ public void init() {
+ ServiceBuilder vkBuilder = new ServiceBuilder(VK_APPID);
+ setVkAuthService(vkBuilder.apiSecret(VK_SECRET)
+ .defaultScope("friends,wall,offline,groups")
+ .callback(VK_REDIRECT)
+ .build(VkontakteApi.instance()));
+ }
+
+ public void updatePremiumStatus(Integer userId) {
+ var vkUser = userService.getVkTokens(userId);
+ if (vkUser != null) {
+ OAuth2AccessToken token = new OAuth2AccessToken(vkUser.getRight());
+ OAuthRequest donRequest = new OAuthRequest(Verb.GET,
+ "https://api.vk.com/method/donut.isDon?owner_id=-67669480&v=5.131");
+ getVkAuthService().signRequest(token, donRequest);
+ try (Response vkResponse = getVkAuthService().execute(donRequest)) {
+ if (vkResponse.isSuccessful()) {
+ logger.info(vkResponse.getBody());
+ var response = jsonMapper.readTree(vkResponse.getBody());
+ if (response.has("response")) {
+ var isDon = response.get("response").intValue() > 0;
+ logger.info("{} is Don: {}", vkUser.getLeft(), isDon);
+ userService.setPremium(userId, isDon);
+ } else {
+ // token is expired or does not have "groups" permissions
+ userService.updateVkToken(userId, "");
+ }
+ }
+ } catch (Exception e) {
+ logger.error("Don request error", e);
+ }
+ } else {
+ logger.warn("User is not connected to VK: {}", userId);
+ }
+ }
+
+ public OAuth20Service getVkAuthService() {
+ return vkAuthService;
+ }
+
+ public void setVkAuthService(OAuth20Service vkAuthService) {
+ this.vkAuthService = vkAuthService;
+ }
+}