diff options
author | Vitaly Takmazov | 2023-06-20 07:10:16 +0300 |
---|---|---|
committer | Vitaly Takmazov | 2023-06-21 01:02:41 +0300 |
commit | 10dcb7324fac83c0190ff4a842360a035449f278 (patch) | |
tree | 95b90305ff7e7cdb3fd298878353ed702a0754a1 /src/main/java/com/juick/service | |
parent | 314db08815ae98bff02a7489cddf861cd01f2629 (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.java | 5 | ||||
-rw-r--r-- | src/main/java/com/juick/service/UserServiceImpl.java | 13 | ||||
-rw-r--r-- | src/main/java/com/juick/service/VKService.java | 94 |
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; + } +} |