From 5146e43ab81143a4fab59b43d4a71fd3de0f6ac9 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Mon, 12 Dec 2016 14:28:34 +0300 Subject: juick-spring-www: settings templates and other WIP --- juick-spring-www/build.gradle | 2 + .../juick/www/controllers/SettingsController.java | 213 ++++++++++++++++++++- .../webapp/WEB-INF/templates/views/pm_inbox.html | 8 +- .../webapp/WEB-INF/templates/views/pm_sent.html | 8 +- .../WEB-INF/templates/views/settings_about.html | 10 +- .../templates/views/settings_auth-email.html | 2 +- .../WEB-INF/templates/views/settings_main.html | 104 +++++----- .../WEB-INF/templates/views/settings_password.html | 2 +- .../WEB-INF/templates/views/settings_result.html | 4 +- 9 files changed, 272 insertions(+), 81 deletions(-) (limited to 'juick-spring-www') diff --git a/juick-spring-www/build.gradle b/juick-spring-www/build.gradle index 56042c5a..c6da5edd 100644 --- a/juick-spring-www/build.gradle +++ b/juick-spring-www/build.gradle @@ -32,6 +32,8 @@ dependencies { compile "org.thymeleaf.extras:thymeleaf-extras-springsecurity4:3.0.1.RELEASE" compile "nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:2.1.2" + compile 'net.coobird:thumbnailator:0.4.8' + testCompile "junit:junit:${rootProject.junitVersion}" testCompile "org.hamcrest:hamcrest-all:${rootProject.hamcrestVersion}" testCompile "org.mockito:mockito-core:1.+" diff --git a/juick-spring-www/src/main/java/com/juick/www/controllers/SettingsController.java b/juick-spring-www/src/main/java/com/juick/www/controllers/SettingsController.java index ceccdbb7..d150d71e 100644 --- a/juick-spring-www/src/main/java/com/juick/www/controllers/SettingsController.java +++ b/juick-spring-www/src/main/java/com/juick/www/controllers/SettingsController.java @@ -1,18 +1,41 @@ package com.juick.www.controllers; import com.juick.User; +import com.juick.server.helpers.NotifyOpts; +import com.juick.server.helpers.UserInfo; +import com.juick.server.util.HttpBadRequestException; +import com.juick.server.util.HttpForbiddenException; +import com.juick.server.util.HttpUtils; import com.juick.service.*; import com.juick.util.UserUtils; +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.core.env.Environment; +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.servlet.ServletException; +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.http.Cookie; +import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.security.Principal; +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; @@ -23,6 +46,7 @@ import java.util.stream.IntStream; */ @Controller public class SettingsController { + private static final Logger logger = LoggerFactory.getLogger(SettingsController.class); @Inject UserService userService; @Inject @@ -33,13 +57,16 @@ public class SettingsController { SubscriptionService subscriptionService; @Inject EmailService emailService; + @Inject + TelegramService telegramService; + @Inject + Environment env; - @RequestMapping("settings") + @RequestMapping(value = "settings", method = RequestMethod.GET) public String showSettings( @RequestParam(required = false) String page, @RequestParam(required = false) String code, - ModelMap context - ) throws ServletException, IOException { + ModelMap context) { User visitor = UserUtils.getCurrentUser(); if (visitor.getUid() == 0) { return "redirect:/login"; @@ -71,4 +98,180 @@ public class SettingsController { } return String.format("views/settings_%s", page); } + @RequestMapping(value = "/settings", method = RequestMethod.POST) + protected String doPost( + HttpServletResponse response, + @RequestParam String page, + @RequestParam(required = false) String password, + @RequestParam(required = false) String jnotify, + @RequestParam(required = false) String subscr_notify, + @RequestParam(required = false) String recomm, + @RequestParam(required = false) String fullname, + @RequestParam(required = false) String country, + @RequestParam(required = false) String url, + @RequestParam(required = false) String descr, + @RequestParam(required = false) MultipartFile avatar, + @RequestParam(required = false) String account, + @RequestParam(required = false) String time, + ModelMap context) throws IOException { + User visitor = UserUtils.getCurrentUser(); + if (visitor.getUid() == 0) { + throw new HttpForbiddenException(); + } + 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"); + if (StringUtils.isEmpty(page) || !pages.contains(page)) { + throw new HttpBadRequestException(); + } + String result = ""; + switch (page) { + case "password": + if (userService.updatePassword(visitor, password)) { + result = "

Password has been changed.

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

Notification options has been updated

"; + } + break; + case "about": + UserInfo info = new UserInfo(); + info.setFullName(fullname); + info.setCountry(country); + info.setUrl(url); + info.setDescription(descr); + String imgPath = env.getProperty("img_path", "/var/www/juick.com/i/"); + String tmpDir = env.getProperty("upload_tmp_dir", + "/var/www/juick.com/i/tmp/"); + String avatarTmpPath = HttpUtils.receiveMultiPartFile(avatar, tmpDir); + 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(imgPath, "ao", originalName); + Path a = Paths.get(imgPath, "a", targetName); + Path as = Paths.get(imgPath, "as", targetName); + Files.move(Paths.get(tmpDir, 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); +// int res = -1; +// if (params[0].equals("xmpp")) { +// res = sql.update("DELETE FROM jids WHERE user_id=? AND jid=?", visitor.getUid(), params[1]); +// } else if (params[0].equals("xmpp-unauth")) { +// res = sql.update("DELETE FROM auth WHERE user_id=? AND protocol='xmpp' AND account=?", visitor.getUid(), params[1]); +// } +// if (res == 1) { +// 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(), account); + } catch (EmptyResultDataAccessException e) { + String authCode = UserUtils.generateHash(8); + if (emailService.addVerificationCode(visitor.getUid(), 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(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(), account)) { + result = "

Deleted. Back.

"; + } else { + result = "

An error occured while deleting.

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

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

Back

", account, time); + } else { + result = "

Disabled.

Back

"; + } + break; + case "twitter-del": + crosspostService.deleteTwitterToken(visitor.getUid()); + // FIXME: use spring-security +// 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(); + } + context.put("title", "Настройки"); + context.put("visitor", visitor); + context.put("result", result); + return "views/settings_result"; + } } diff --git a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/pm_inbox.html b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/pm_inbox.html index 7ab557f5..7de997b8 100644 --- a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/pm_inbox.html +++ b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/pm_inbox.html @@ -12,10 +12,10 @@
  • - @ugnich: + @ugnich:
    01.01.1970
    @@ -37,7 +37,7 @@ diff --git a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/pm_sent.html b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/pm_sent.html index f2c05ad3..8978ff67 100644 --- a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/pm_sent.html +++ b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/pm_sent.html @@ -20,10 +20,10 @@
  • - @ugnich: + @ugnich:
    01.01.1970
    @@ -35,7 +35,7 @@
    diff --git a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_about.html b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_about.html index b93a699e..6f8f61dd 100644 --- a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_about.html +++ b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_about.html @@ -10,12 +10,12 @@
    -

    Full name:

    -

    Country:

    -

    URL:
    +

    Full name:

    +

    Country:

    +

    URL:
    Please, start with "http://"

    About:
    -
    +
    Max. 255 symbols

    Avatar:
    Recommendations: PNG, 96x96, <50Kb. Also, JPG and GIF supported.

    @@ -24,7 +24,7 @@
    diff --git a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_auth-email.html b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_auth-email.html index d4788fd6..715d474d 100644 --- a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_auth-email.html +++ b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_auth-email.html @@ -13,7 +13,7 @@ diff --git a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_main.html b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_main.html index 42eff2e3..2db977f4 100644 --- a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_main.html +++ b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_main.html @@ -13,29 +13,27 @@
    Notification options -

    Reply notifications ("Message posted")

    -

    Subscriptions notifications ("@user subscribed...")

    -

    Posts recommendations ("Recommended by @user")

    +

    Reply notifications ("Message posted")

    +

    Subscriptions notifications ("@user subscribed...")

    +

    Posts recommendations ("Recommended by @user")

    Telegram - {% if telegram_name is not empty %} -
    -
    Telegram: {{ telegram_name }} — + +
    Telegram: telegram_name
    - {% else %} -

    To connect Telegram account: send any text message to @Juick_bot +

    + To connect Telegram account: send any text message to @Juick_bot

    - {% endif %}
    @@ -44,19 +42,17 @@

    Your accounts:

    - {% for jid in jids %} -
    - {% endfor %} - {% for auth in auths %} + +
    +
    + + th:value="|xmpp-unauth;${auth.getAccount()}|" th:text="${auth.getAccount()}">account — Confirm
    - {% endfor %} +

    - {% if jids is not empty %} -

    - {% endif %} +

    To add new jabber account: send any text message to juick@juick.com

    @@ -75,42 +71,37 @@

    Your accounts:

    - {% for email in emails %} -
    - {% endfor %} - {% if emails is empty %} - -

    - {% else %} -

    -

    - {% endif %} + +
    +
    +

    + -

    + +

    +

    +
    - {% if emails is not empty %} -
    +

    You can receive all your subscriptions by email:
    Sent to every day at

    - {% endif %}

     

    You can post to Juick via e-mail. Send your plain text messages to special secret e-mail. You can attach one photo or video file.

    -

    Secret email: {% if ehash is not empty %} {{ ehash }} {% else %}-{% endif %}

    +

    Secret email: SecretEmail@juick.com-

    @@ -119,48 +110,43 @@ Facebook - {% if fbstatus.isConnected() %} - {% if fbstatus.isCrosspostEnabled() %} -
    +
    Facebook: Enabled
    - {% else %} -
    +
    Facebook: Disabled
    - {% endif %} - {% else %} -

    Cross-posting to Facebook: Connect to Facebook

    - {% endif %} +

    Cross-posting to Facebook: + + Connect to Facebook + +

    Twitter - {% if twitter_name is not empty %} -
    -
    Twitter: {{ twitter_name }} — + +
    Twitter: @twitterName
    - {% else %} -

    Cross-posting to Twitter: Cross-posting to Twitter: Connect to Twitter

    - {% endif %}
    diff --git a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_password.html b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_password.html index 4c6e0d4d..d1e7e075 100644 --- a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_password.html +++ b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_password.html @@ -19,7 +19,7 @@ diff --git a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_result.html b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_result.html index ddde1baf..20cb097d 100644 --- a/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_result.html +++ b/juick-spring-www/src/main/webapp/WEB-INF/templates/views/settings_result.html @@ -8,10 +8,10 @@
    -

    Settings update status

    +

    Settings update status

    -- cgit v1.2.3