From e14d4612d313b7424b2163ba247843655c4dfca1 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Fri, 19 Jul 2024 13:25:06 +0300 Subject: Update premium status on login --- src/main/java/com/juick/PremiumManager.java | 43 ++++++++++++++++++++++ src/main/java/com/juick/config/AppConfig.java | 5 +++ .../java/com/juick/service/PatreonService.java | 33 +++++++++++++++++ src/main/java/com/juick/service/VKService.java | 10 +++-- .../com/juick/www/api/webhooks/PatreonWebhook.java | 24 +----------- 5 files changed, 88 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/juick/PremiumManager.java (limited to 'src/main/java/com') diff --git a/src/main/java/com/juick/PremiumManager.java b/src/main/java/com/juick/PremiumManager.java new file mode 100644 index 00000000..f1fd553e --- /dev/null +++ b/src/main/java/com/juick/PremiumManager.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2008-2024, 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; + +import com.juick.service.EmailService; +import com.juick.service.PatreonService; +import com.juick.service.VKService; +import com.juick.service.security.entities.JuickUser; +import jakarta.inject.Inject; +import org.springframework.context.ApplicationListener; +import org.springframework.security.authentication.event.AuthenticationSuccessEvent; + +public class PremiumManager implements ApplicationListener { + @Inject + VKService vkService; + @Inject + PatreonService patreonService; + @Inject + EmailService emailService; + @Override + public void onApplicationEvent(AuthenticationSuccessEvent event) { + var juickUser = (JuickUser)event.getAuthentication().getPrincipal(); + var isDon = vkService.updatePremiumStatus(juickUser.getUser().getUid()); + if (!isDon) { + patreonService.updateStatus(emailService.getEmails(juickUser.getUser().getUid(), false)); + } + } +} diff --git a/src/main/java/com/juick/config/AppConfig.java b/src/main/java/com/juick/config/AppConfig.java index 64ccfcf9..ad9825de 100644 --- a/src/main/java/com/juick/config/AppConfig.java +++ b/src/main/java/com/juick/config/AppConfig.java @@ -161,4 +161,9 @@ public class AppConfig { WatchdogService watchdogService() { return new SystemdWatchdogService(); } + + @Bean + PremiumManager premiumManager() { + return new PremiumManager(); + } } diff --git a/src/main/java/com/juick/service/PatreonService.java b/src/main/java/com/juick/service/PatreonService.java index 08a828db..8f21f389 100644 --- a/src/main/java/com/juick/service/PatreonService.java +++ b/src/main/java/com/juick/service/PatreonService.java @@ -20,6 +20,8 @@ package com.juick.service; import com.fasterxml.jackson.databind.ObjectMapper; import okhttp3.OkHttpClient; import okhttp3.Request; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -28,12 +30,17 @@ import org.springframework.web.util.UriComponentsBuilder; import jakarta.inject.Inject; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import java.util.stream.StreamSupport; @Component public class PatreonService { + private static final Logger logger = LoggerFactory.getLogger("Patreon"); + + @Inject + private UserService userService; @Inject private OkHttpClient httpClient; @Inject @@ -89,4 +96,30 @@ public class PatreonService { } return List.of(); } + + public void updateStatus(List updatedEmails) { + var campainsResponse = fetchCampaigns(); + List activeEmails = new ArrayList<>(); + campainsResponse.forEach(campaign -> { + var pledgesResponse = fetchPledges(campaign); + pledgesResponse.forEach(pledge -> { + logger.debug("Pledge email: {}", pledge); + activeEmails.add(pledge); + }); + }); + activeEmails.forEach(email -> { + var user = userService.getUserByEmail(email); + if (!user.isAnonymous()) { + userService.setPremium(user.getUid(), true); + } + }); + updatedEmails.stream().filter(email -> !activeEmails.contains(email)) + .forEach(deleted -> { + var user = userService.getUserByEmail(deleted); + if (!user.isAnonymous() && user.isPremium()) { + logger.debug("User is not a patron anymore: {}", deleted); + userService.setPremium(user.getUid(), false); + } + }); + } } diff --git a/src/main/java/com/juick/service/VKService.java b/src/main/java/com/juick/service/VKService.java index 19fa5b58..b9b2483f 100644 --- a/src/main/java/com/juick/service/VKService.java +++ b/src/main/java/com/juick/service/VKService.java @@ -56,7 +56,7 @@ public class VKService { .build(VkontakteApi.instance())); } - public void updatePremiumStatus(Integer userId) { + public boolean updatePremiumStatus(Integer userId) { var vkUser = userService.getVkTokens(userId); if (vkUser != null) { OAuth2AccessToken token = new OAuth2AccessToken(vkUser.getRight()); @@ -65,12 +65,13 @@ public class VKService { getVkAuthService().signRequest(token, donRequest); try (Response vkResponse = getVkAuthService().execute(donRequest)) { if (vkResponse.isSuccessful()) { - logger.info(vkResponse.getBody()); + logger.debug(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); + logger.debug("{} is Don: {}", vkUser.getLeft(), isDon); userService.setPremium(userId, isDon); + return isDon; } else { // token is expired or does not have "groups" permissions userService.updateVkToken(userId, ""); @@ -80,8 +81,9 @@ public class VKService { logger.error("Don request error", e); } } else { - logger.warn("User is not connected to VK: {}", userId); + logger.debug("User is not connected to VK: {}", userId); } + return false; } public OAuth20Service getVkAuthService() { diff --git a/src/main/java/com/juick/www/api/webhooks/PatreonWebhook.java b/src/main/java/com/juick/www/api/webhooks/PatreonWebhook.java index d8467ff0..c05585ac 100644 --- a/src/main/java/com/juick/www/api/webhooks/PatreonWebhook.java +++ b/src/main/java/com/juick/www/api/webhooks/PatreonWebhook.java @@ -67,28 +67,6 @@ public class PatreonWebhook { var updatedEmails = StreamSupport.stream(json.get("included").spliterator(), false) .filter(node -> node.get("type").textValue().equals("user")) .map(node -> node.get("attributes").get("email").textValue()).toList(); - var campainsResponse = patreonService.fetchCampaigns(); - List activeEmails = new ArrayList<>(); - campainsResponse.forEach(campaign -> { - var pledgesResponse = patreonService.fetchPledges(campaign); - pledgesResponse.forEach(pledge -> { - logger.info("Pledge email: {}", pledge); - activeEmails.add(pledge); - }); - }); - activeEmails.forEach(email -> { - var user = userService.getUserByEmail(email); - if (!user.isAnonymous()) { - userService.setPremium(user.getUid(), true); - } - }); - updatedEmails.stream().filter(email -> !activeEmails.contains(email)) - .forEach(deleted -> { - var user = userService.getUserByEmail(deleted); - if (!user.isAnonymous()) { - logger.info("User is not a patron anymore: {}", deleted); - userService.setPremium(user.getUid(), false); - } - }); + patreonService.updateStatus(updatedEmails); } } -- cgit v1.2.3