From 2f682b5e3cfc3fc5f961b60129be7bc90e0d6a03 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Wed, 28 Dec 2016 22:38:21 +0300 Subject: juick-www: now on spring-webmvc --- .../java/com/juick/www/controllers/Settings.java | 287 +++++++++++++++++++++ 1 file changed, 287 insertions(+) create mode 100644 juick-www/src/main/java/com/juick/www/controllers/Settings.java (limited to 'juick-www/src/main/java/com/juick/www/controllers/Settings.java') diff --git a/juick-www/src/main/java/com/juick/www/controllers/Settings.java b/juick-www/src/main/java/com/juick/www/controllers/Settings.java new file mode 100644 index 00000000..63cf99e6 --- /dev/null +++ b/juick-www/src/main/java/com/juick/www/controllers/Settings.java @@ -0,0 +1,287 @@ +/* + * Juick + * Copyright (C) 2008-2013, Ugnich Anton + * + * 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.www.controllers; + +import com.juick.server.helpers.NotifyOpts; +import com.juick.server.helpers.UserInfo; +import com.juick.server.util.HttpBadRequestException; +import com.juick.server.util.HttpUtils; +import com.juick.service.*; +import com.juick.util.UserUtils; +import com.juick.www.WebApp; +import net.coobird.thumbnailator.Thumbnails; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.multipart.MultipartFile; + +import javax.inject.Inject; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.Session; +import javax.mail.Transport; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; +import javax.servlet.ServletException; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +/** + * + * @author Ugnich Anton + */ +@Controller +public class Settings { + private static final Logger logger = LoggerFactory.getLogger(Settings.class); + + @Inject + WebApp webApp; + @Inject + TagService tagService; + @Inject + UserService userService; + @Inject + CrosspostService crosspostService; + @Inject + SubscriptionService subscriptionService; + @Inject + EmailService emailService; + @Inject + TelegramService telegramService; + + @RequestMapping(value = "/settings", method = RequestMethod.GET) + protected String doGet(HttpServletRequest request, HttpServletResponse response, ModelMap model) throws IOException { + com.juick.User visitor = webApp.getVisitorUser(request, response); + if (visitor.getUid() == 0) { + response.sendRedirect("/login"); + } + List pages = Arrays.asList("main", "password", "about", "auth-email", "privacy"); + String page = request.getParameter("page"); + if (StringUtils.isEmpty(page) || !pages.contains(page)) { + page = "main"; + } + + model.addAttribute("title", "Настройки"); + model.addAttribute("visitor", visitor); + model.addAttribute("tags", tagService.getPopularTags()); + model.addAttribute("auths", userService.getAuthCodes(visitor)); + model.addAttribute("eopts", userService.getEmailOpts(visitor)); + model.addAttribute("ehash", userService.getEmailHash(visitor)); + model.addAttribute("emails", userService.getEmails(visitor)); + model.addAttribute("jids", userService.getAllJIDs(visitor)); + List hours = IntStream.rangeClosed(0, 23).boxed() + .map(i -> StringUtils.leftPad(String.format("%d", i), 2, "0")).collect(Collectors.toList()); + model.addAttribute("hours", hours); + model.addAttribute("fbstatus", crosspostService.getFbCrossPostStatus(visitor.getUid()).isCrosspostEnabled()); + model.addAttribute("twitter_name", crosspostService.getTwitterName(visitor.getUid())); + model.addAttribute("telegram_name", crosspostService.getTelegramName(visitor.getUid())); + model.addAttribute("notify_options", subscriptionService.getNotifyOptions(visitor)); + model.addAttribute("userinfo", userService.getUserInfo(visitor)); + if (page.equals("auth-email")) { + if (emailService.verifyAddressByCode(visitor.getUid(), request.getParameter("code"))) { + ; + model.addAttribute("result", "OK!"); + } else { + model.addAttribute("result", "Sorry, code unknown."); + } + } + return String.format("views/settings_%s", page); + } + + @RequestMapping(value = "/settings", method = RequestMethod.POST) + protected String doPost(HttpServletRequest request, HttpServletResponse response, + @RequestParam(required = false) MultipartFile avatar, + ModelMap model) + throws IOException, ServletException { + com.juick.User visitor = webApp.getVisitorUser(request, response); + if (visitor.getUid() == 0) { + throw new HttpBadRequestException(); + } + List pages = Arrays.asList("main", "password", "about", "email", "email-add", "email-del", + "email-subscr", "auth-email", "privacy", "jid-del", "twitter-del", "telegram-del", "facebook-disable", + "facebook-enable", "vk-del"); + String page = request.getParameter("page"); + if (StringUtils.isEmpty(page) || !pages.contains(page)) { + throw new HttpBadRequestException(); + } + String result = StringUtils.EMPTY; + switch (page) { + case "password": + if (userService.updatePassword(visitor, request.getParameter("password"))) { + result = "

Password has been changed.

"; + String hash = userService.getHashByUID(visitor.getUid()); + Cookie c = new Cookie("hash", hash); + c.setMaxAge(365 * 24 * 60 * 60); + response.addCookie(c); + } + break; + case "main": + NotifyOpts opts = new NotifyOpts(); + opts.setRepliesEnabled(StringUtils.isNotEmpty(request.getParameter("jnotify"))); + opts.setSubscriptionsEnabled(StringUtils.isNotEmpty(request.getParameter("subscr_notify"))); + opts.setRecommendationsEnabled(StringUtils.isNotEmpty(request.getParameter("recomm"))); + if (subscriptionService.setNotifyOptions(visitor, opts)) { + result = "

Notification options has been updated

"; + } + break; + case "about": + UserInfo info = new UserInfo(); + info.setFullName(request.getParameter("fullname")); + info.setCountry(request.getParameter("country")); + info.setUrl(request.getParameter("url")); + info.setDescription(request.getParameter("descr")); + String avatarTmpPath = HttpUtils.receiveMultiPartFile(avatar, webApp.getTmpDir()); + if (StringUtils.isNotEmpty(avatarTmpPath)) { + String originalExtension = FilenameUtils.getExtension(avatarTmpPath); + String originalName = String.format("%s.%s", visitor.getUid(), originalExtension); + String targetName = String.format("%s.png", visitor.getUid()); + Path ao = Paths.get(webApp.getImgDir(), "ao", originalName); + Path a = Paths.get(webApp.getImgDir(), "a", targetName); + Path as = Paths.get(webApp.getImgDir(), "as", targetName); + Files.move(Paths.get(webApp.getTmpDir(), avatarTmpPath), ao, StandardCopyOption.REPLACE_EXISTING); + Thumbnails.of(ao.toFile()).size(96, 96).toFile(a.toFile()); + Thumbnails.of(ao.toFile()).size(32, 32).toFile(as.toFile()); + } + if (userService.updateUserInfo(visitor, info)) { + result = String.format("

Your info is updated.

Back to blog.

", visitor.getName()); + } + break; + case "jid-del": + // FIXME: stop using ugnich-csv in parameters + String[] params = request.getParameter("delete").split(";", 2); + boolean res = false; + if (params[0].equals("xmpp")) { + res = userService.deleteJID(visitor.getUid(), params[1]); + } else if (params[0].equals("xmpp-unauth")) { + res = userService.unauthJID(visitor.getUid(), params[1]); + } + if (res) { + result = "

Deleted. Back.

"; + } else { + result = "

Error

"; + } + break; + case "email": + String newHash = userService.updateSecretEmail(visitor); + if (StringUtils.isNotEmpty(newHash)) { + result = String.format("

New secret email: %s@mail.juick.com

" + + "

Back.

", newHash); + } else { + throw new HttpBadRequestException(); + } + break; + case "email-add": + try { + emailService.verifyAddressByCode(visitor.getUid(), request.getParameter("account")); + } catch (EmptyResultDataAccessException e) { + String authCode = UserUtils.generateHash(8); + if (emailService.addVerificationCode(visitor.getUid(), request.getParameter("account"), authCode)) { + Session session = Session.getDefaultInstance(System.getProperties()); + try { + MimeMessage message = new MimeMessage(session); + message.setFrom(new InternetAddress("noreply@mail.juick.com")); + message.addRecipient(Message.RecipientType.TO, new InternetAddress(request.getParameter("account"))); + message.setSubject("Juick authorization link"); + message.setText(String.format("Follow link to attach this email to Juick account:\n" + + "http://juick.com/settings?page=auth-email&code=%s\n\n" + + "If you don't know, what this mean - just ignore this mail.\n", authCode)); + Transport.send(message); + result = "

Authorization link has been sent to your email. Follow it to proceed.

" + + "

Back

"; + + } catch (MessagingException ex) { + logger.error("mail exception", ex); + throw new HttpBadRequestException(); + } + } + } + break; + case "email-del": + if (emailService.deleteEmail(visitor.getUid(), request.getParameter("account"))) { + result = "

Deleted. Back.

"; + } else { + result = "

An error occured while deleting.

"; + } + break; + case "email-subscr": + if (emailService.setSubscriptionHour(visitor.getUid(), request.getParameter("account"), + request.getParameter("time"))) { + result = String.format("

Saved! Will send to %s at %s:00 GMT." + + "

Back

", request.getParameter("account"), + request.getParameter("time")); + } else { + result = "

Disabled.

Back

"; + } + break; + case "twitter-del": + crosspostService.deleteTwitterToken(visitor.getUid()); + for (Cookie cookie : request.getCookies()) { + if (cookie.getName().equals("request_token")) { + cookie.setMaxAge(0); + response.addCookie(cookie); + } + if (cookie.getName().equals("request_token_secret")) { + cookie.setMaxAge(0); + response.addCookie(cookie); + } + } + result = "

Back

"; + break; + case "telegram-del": + telegramService.deleteTelegramUser(visitor.getUid()); + result = "

Back

"; + break; + case "facebook-disable": + crosspostService.disableFBCrosspost(visitor.getUid()); + result = "

Back

"; + break; + case "facebook-enable": + crosspostService.enableFBCrosspost(visitor.getUid()); + result = "

Back

"; + break; + case "vk-del": + crosspostService.deleteVKUser(visitor.getUid()); + result = "

Back

"; + break; + default: + throw new HttpBadRequestException(); + } + + model.addAttribute("title", "Настройки"); + model.addAttribute("visitor", visitor); + model.addAttribute("result", result); + return "views/settings_result"; + } +} -- cgit v1.2.3