From 6c3663df82c7e29febc0aebd51717184df7da09c Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Wed, 11 Jan 2023 06:57:36 +0300 Subject: Social login refactoring: set cookie after login --- src/main/java/com/juick/TelegramBotManager.java | 20 ++++++++------------ .../java/com/juick/service/TelegramService.java | 2 -- .../com/juick/service/TelegramServiceImpl.java | 10 ---------- src/main/java/com/juick/service/UserService.java | 2 ++ .../java/com/juick/service/UserServiceImpl.java | 16 ++++++++++++++++ .../java/com/juick/www/controllers/SignUp.java | 17 ++++++++++++++--- .../com/juick/www/controllers/SocialLogin.java | 22 ++++++++++++++++------ 7 files changed, 56 insertions(+), 33 deletions(-) diff --git a/src/main/java/com/juick/TelegramBotManager.java b/src/main/java/com/juick/TelegramBotManager.java index b68658ae..b92704a0 100644 --- a/src/main/java/com/juick/TelegramBotManager.java +++ b/src/main/java/com/juick/TelegramBotManager.java @@ -136,7 +136,7 @@ public class TelegramBotManager implements NotificationListener { logger.error("error parsing telegram update: {}", update); return; } - User user_from = userService.getUserByUID(telegramService.getUser(message.chat().id())).orElse(AnonymousUser.INSTANCE); + User user_from = userService.getUserByTelegramId(message.chat().id()).orElse(AnonymousUser.INSTANCE); logger.info("Found juick user {}", user_from.getUid()); Optional> originalMessageData = messagesService.findMessageByProperty("durovId", String.valueOf(message.messageId())); @@ -157,7 +157,7 @@ public class TelegramBotManager implements NotificationListener { telegramNotify(message.chat().id(), "Error updating message", new com.juick.model.Message()); } } else { - User user_from = userService.getUserByUID(telegramService.getUser(message.chat().id())).orElse(AnonymousUser.INSTANCE); + User user_from = userService.getUserByTelegramId(message.chat().id()).orElse(AnonymousUser.INSTANCE); logger.info("Found juick user {}", user_from.getUid()); String username = message.from().username(); @@ -355,7 +355,7 @@ public class TelegramBotManager implements NotificationListener { } private void processTelegramResponse(Long chatId, SendResponse response, com.juick.model.Message source) { - int userId = telegramService.getUser(chatId); + var user = userService.getUserByTelegramId(chatId).orElse(AnonymousUser.INSTANCE); if (!response.isOk()) { if (response.errorCode() == 403) { // remove from anonymous users @@ -365,11 +365,9 @@ public class TelegramBotManager implements NotificationListener { logger.info("deleted {} chat", d); } ); - if (userId > 0) { - User userToDelete = userService.getUserByUID(userId) - .orElseThrow(IllegalStateException::new); - boolean status = telegramService.deleteTelegramUser(userToDelete.getUid()); - logger.info("deleting telegram id of @{} : {}", userToDelete.getName(), status); + if (!user.isAnonymous()) { + boolean status = telegramService.deleteTelegramUser(user.getUid()); + logger.info("deleting telegram id of @{} : {}", user.getName(), status); } } else { logger.warn("error response, isOk: {}, errorCode: {}, description: {}", @@ -377,9 +375,7 @@ public class TelegramBotManager implements NotificationListener { } } else { if (MessageUtils.isReply(source)) { - messagesService.setLastReadComment(userService.getUserByUID(userId) - .orElseThrow(IllegalStateException::new), source.getMid(), source.getRid()); - User user = userService.getUserByUID(userId).orElseThrow(IllegalStateException::new); + messagesService.setLastReadComment(user, source.getMid(), source.getRid()); userService.updateLastSeen(user); applicationEventPublisher.publishEvent( new SystemEvent(this, SystemActivity.read(user, source))); @@ -453,7 +449,7 @@ public class TelegramBotManager implements NotificationListener { users.forEach(c -> telegramNotify(c, msg, jmsg)); // anonymous - chats.stream().filter(u -> telegramService.getUser(u) == 0).forEach(c -> telegramNotify(c, msg, jmsg)); + chats.stream().filter(u -> userService.getUserByTelegramId(u).isPresent()).forEach(c -> telegramNotify(c, msg, jmsg)); } } diff --git a/src/main/java/com/juick/service/TelegramService.java b/src/main/java/com/juick/service/TelegramService.java index 4acf4cbe..16ba531d 100644 --- a/src/main/java/com/juick/service/TelegramService.java +++ b/src/main/java/com/juick/service/TelegramService.java @@ -30,8 +30,6 @@ public interface TelegramService { List getAnonymous(); - int getUser(long tgId); - boolean createTelegramUser(long tgID, String tgName); boolean deleteTelegramUser(Integer uid); diff --git a/src/main/java/com/juick/service/TelegramServiceImpl.java b/src/main/java/com/juick/service/TelegramServiceImpl.java index 12142e7a..7b893b6b 100644 --- a/src/main/java/com/juick/service/TelegramServiceImpl.java +++ b/src/main/java/com/juick/service/TelegramServiceImpl.java @@ -45,16 +45,6 @@ public class TelegramServiceImpl extends BaseJdbcService implements TelegramServ return getJdbcTemplate().queryForList("SELECT tg_id FROM telegram WHERE user_id IS NULL", Long.class); } - @Transactional(readOnly = true) - @Override - public int getUser(final long tgId) { - List list = getJdbcTemplate().queryForList( - "SELECT id FROM users INNER JOIN telegram " + - "ON telegram.user_id = users.id WHERE telegram.tg_id=?", Integer.class, tgId); - - return list.isEmpty() ? 0 : list.get(0); - } - @Transactional @Override public boolean createTelegramUser(final long tgID, final String tgName) { diff --git a/src/main/java/com/juick/service/UserService.java b/src/main/java/com/juick/service/UserService.java index 8fe8bc1f..8d7f7e02 100644 --- a/src/main/java/com/juick/service/UserService.java +++ b/src/main/java/com/juick/service/UserService.java @@ -180,6 +180,8 @@ public interface UserService { String getTelegramNameByHash(String hash); + Optional getUserByTelegramId(final Long id); + @CacheEvict(value = "users_by_name", allEntries = true) boolean setFacebookUser(String hash, int uid); diff --git a/src/main/java/com/juick/service/UserServiceImpl.java b/src/main/java/com/juick/service/UserServiceImpl.java index ab947bac..69ca7569 100644 --- a/src/main/java/com/juick/service/UserServiceImpl.java +++ b/src/main/java/com/juick/service/UserServiceImpl.java @@ -783,6 +783,22 @@ public class UserServiceImpl extends BaseJdbcService implements UserService { return list.isEmpty() ? StringUtils.EMPTY : list.get(0); } + @Override + @Transactional(readOnly = true) + public Optional getUserByTelegramId(Long id) { + List list = getJdbcTemplate().query( + """ + SELECT DISTINCT u.id, u.nick, u.passw, u.banned, u.last_seen, + COALESCE(f.fb_id, vk.vk_id, t.tg_id, e.user_id, 0) AS verified + FROM users u LEFT JOIN facebook f ON f.user_id = u.id + LEFT JOIN vk ON u.id = vk.user_id LEFT JOIN telegram t ON u.id = t.user_id + LEFT JOIN emails e ON e.user_id = u.id + WHERE t.tg_id = ?""", + new UserMapper(), id + ); + + return list.isEmpty() ? Optional.empty() : Optional.of(list.get(0)); + } @Transactional(readOnly = true) @Override diff --git a/src/main/java/com/juick/www/controllers/SignUp.java b/src/main/java/com/juick/www/controllers/SignUp.java index 8318dabd..955b3b92 100644 --- a/src/main/java/com/juick/www/controllers/SignUp.java +++ b/src/main/java/com/juick/www/controllers/SignUp.java @@ -24,8 +24,13 @@ import com.juick.www.WebApp; import com.juick.service.EmailService; import com.juick.service.UserService; import com.juick.service.security.entities.JuickUser; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.security.authentication.RememberMeAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.RememberMeServices; +import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.GetMapping; @@ -48,6 +53,8 @@ public class SignUp { private EmailService emailService; @Inject private WebApp webApp; + @Inject + private RememberMeServices rememberMeServices; @GetMapping("/signup") @@ -91,6 +98,8 @@ public class SignUp { @PostMapping("/signup") protected String doPost( + HttpServletRequest request, + HttpServletResponse response, @ModelAttribute User visitor, @RequestParam String type, @RequestParam String hash, @@ -180,9 +189,11 @@ public class SignUp { } if (visitor.isAnonymous()) { - UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = - new UsernamePasswordAuthenticationToken(new JuickUser(current), password, JuickUser.USER_AUTHORITY); - SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); + var authentication = new RememberMeAuthenticationToken( + ((AbstractRememberMeServices) rememberMeServices).getKey(), + new JuickUser(current), JuickUser.USER_AUTHORITY); + SecurityContextHolder.getContext().setAuthentication(authentication); + rememberMeServices.loginSuccess(request, response, authentication); } return "redirect:/"; } diff --git a/src/main/java/com/juick/www/controllers/SocialLogin.java b/src/main/java/com/juick/www/controllers/SocialLogin.java index 3d8e7027..66747df2 100644 --- a/src/main/java/com/juick/www/controllers/SocialLogin.java +++ b/src/main/java/com/juick/www/controllers/SocialLogin.java @@ -27,6 +27,7 @@ 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.security.entities.JuickUser; import com.juick.util.HttpBadRequestException; import jakarta.annotation.PostConstruct; @@ -44,6 +45,10 @@ 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.security.authentication.RememberMeAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.RememberMeServices; +import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import org.springframework.web.util.UriComponentsBuilder; @@ -102,6 +107,8 @@ public class SocialLogin { private TelegramService telegramService; @Inject private AppleClientSecretGenerator clientSecretGenerator; + @Inject + private RememberMeServices rememberMeServices; @PostConstruct public void init() { @@ -292,7 +299,8 @@ public class SocialLogin { @GetMapping("/_tglogin") public String doDurovLogin(@RequestParam Map params, - @RequestHeader(value = "referer", required = false) String referer, HttpServletResponse response) { + @RequestHeader(value = "referer", required = false) String referer, + HttpServletRequest request, HttpServletResponse response) { String dataCheckString = params.entrySet().stream().filter(p -> !p.getKey().equals("hash")) .sorted(Map.Entry.comparingByKey()).map(p -> p.getKey() + "=" + p.getValue()) .collect(Collectors.joining("\n")); @@ -301,11 +309,13 @@ public class SocialLogin { String resultString = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, secretKey).hmacHex(dataCheckString); if (hash.equals(resultString)) { long tgUser = Long.parseLong(params.get("id")); - int uid = telegramService.getUser(tgUser); - if (uid > 0) { - Cookie c = new Cookie("hash", userService.getHashByUID(uid)); - c.setMaxAge(50 * 24 * 60 * 60); - response.addCookie(c); + var user = userService.getUserByTelegramId(tgUser); + if (user.isPresent()) { + var authentication = new RememberMeAuthenticationToken( + ((AbstractRememberMeServices) rememberMeServices).getKey(), + new JuickUser(user.get()), JuickUser.USER_AUTHORITY); + SecurityContextHolder.getContext().setAuthentication(authentication); + rememberMeServices.loginSuccess(request, response, authentication); return "redirect:" + Optional.ofNullable(referer).orElse(StringUtils.EMPTY); } else { String username = StringUtils.defaultString(params.get("username"), params.get("first_name")); -- cgit v1.2.3