diff options
Diffstat (limited to 'src/main/java/com/juick/www')
30 files changed, 158 insertions, 565 deletions
diff --git a/src/main/java/com/juick/www/VisitorArgumentResolver.java b/src/main/java/com/juick/www/VisitorArgumentResolver.java index a092581a..6b85c0cd 100644 --- a/src/main/java/com/juick/www/VisitorArgumentResolver.java +++ b/src/main/java/com/juick/www/VisitorArgumentResolver.java @@ -29,7 +29,7 @@ import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; -import javax.inject.Inject; +import jakarta.inject.Inject; public class VisitorArgumentResolver implements HandlerMethodArgumentResolver { private final UserService userService; diff --git a/src/main/java/com/juick/www/WebApp.java b/src/main/java/com/juick/www/WebApp.java index cf9570aa..e8c562c5 100644 --- a/src/main/java/com/juick/www/WebApp.java +++ b/src/main/java/com/juick/www/WebApp.java @@ -26,7 +26,7 @@ import org.springframework.stereotype.Component; import org.springframework.web.servlet.resource.ResourceUrlProvider; import org.springframework.web.util.UriComponentsBuilder; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.util.ArrayList; import java.util.Arrays; import java.util.List; diff --git a/src/main/java/com/juick/www/ad/SapeService.java b/src/main/java/com/juick/www/ad/SapeService.java index 97ab882b..ca823974 100644 --- a/src/main/java/com/juick/www/ad/SapeService.java +++ b/src/main/java/com/juick/www/ad/SapeService.java @@ -31,7 +31,7 @@ import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import org.springframework.web.util.UriComponents; import ru.sape.Sape; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.net.URI; @ControllerAdvice(assignableTypes = Site.class) diff --git a/src/main/java/com/juick/www/api/ApiSocialLogin.java b/src/main/java/com/juick/www/api/ApiSocialLogin.java deleted file mode 100644 index c8758d59..00000000 --- a/src/main/java/com/juick/www/api/ApiSocialLogin.java +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (C) 2008-2020, 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.www.api; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.scribejava.apis.AppleClientSecretGenerator; -import com.github.scribejava.apis.AppleSignInApi; -import com.github.scribejava.apis.FacebookApi; -import com.github.scribejava.apis.GoogleTokenVerifier; -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.Verb; -import com.github.scribejava.core.oauth.OAuth20Service; -import com.juick.model.AuthResponse; -import com.juick.model.ext.facebook.User; -import com.juick.model.ext.vk.UsersResponse; -import com.juick.service.EmailService; -import com.juick.service.UserService; -import com.juick.util.HttpBadRequestException; -import com.juick.util.HttpForbiddenException; - -import org.apache.commons.lang3.RandomStringUtils; -import org.apache.commons.lang3.StringUtils; -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.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.util.UriComponentsBuilder; - -import jakarta.annotation.PostConstruct; -import javax.inject.Inject; -import java.io.IOException; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.ExecutionException; - -/** - * - * @author Ugnich Anton - */ -@Controller -public class ApiSocialLogin { - - private static final Logger logger = LoggerFactory.getLogger(ApiSocialLogin.class); - - @Value("${facebook_appid:appid}") - private String FACEBOOK_APPID; - @Value("${facebook_secret:secret}") - private String FACEBOOK_SECRET; - private static final String FACEBOOK_REDIRECT = "https://api.juick.com/_fblogin"; - private static final String VK_REDIRECT = "https://api.juick.com/_vklogin"; - @Inject - private ObjectMapper jsonMapper; - private OAuth20Service facebookAuthService, vkAuthService, appleSignInService; - - @Value("${twitter_consumer_key:appid}") - private String twitterConsumerKey; - @Value("${twitter_consumer_secret:secret}") - private String twitterConsumerSecret; - @Value("${vk_appid:appid}") - private String VK_APPID; - @Value("${vk_secret:secret}") - private String VK_SECRET; - @Value("${google_client_id:}") - private String googleClientId; - @Value("${apple_app_id:appid}") - private String appleApplicationId; - @Value("${ap_base_uri:http://localhost:8080/}") - private String baseUri; - - @Inject - private UserService userService; - @Inject - private EmailService emailService; - @Inject - private AppleClientSecretGenerator clientSecretGenerator; - @Inject - private Users users; - - @PostConstruct - public void init() { - ServiceBuilder facebookBuilder = new ServiceBuilder(FACEBOOK_APPID); - ServiceBuilder vkBuilder = new ServiceBuilder(VK_APPID); - facebookAuthService = facebookBuilder - .apiSecret(FACEBOOK_SECRET) - .callback(FACEBOOK_REDIRECT) - .defaultScope("email") - .build(FacebookApi.instance()); - vkAuthService = vkBuilder - .apiSecret(VK_SECRET) - .defaultScope("friends,wall,offline,groups") - .callback(VK_REDIRECT) - .build(VkontakteApi.instance()); - ServiceBuilder appleSignInBuilder = new ServiceBuilder(appleApplicationId); - UriComponentsBuilder redirectBuilder = UriComponentsBuilder.fromUriString(baseUri); - String appleSignInRedirectUri = redirectBuilder.replacePath("/api/_applelogin").build().toUriString(); - appleSignInService = appleSignInBuilder - .callback(appleSignInRedirectUri) - .defaultScope("email") - .build(new AppleSignInApi(clientSecretGenerator, appleApplicationId)); - } - - @GetMapping("/api/_fblogin") - protected String doFacebookLogin(@RequestParam(required = false) String code, - @RequestParam(required = false) String state) throws IOException, ExecutionException, InterruptedException { - if (StringUtils.isBlank(code)) { - String fbstate = UUID.randomUUID().toString(); - userService.addFacebookState(fbstate, state); - return "redirect:" + facebookAuthService.getAuthorizationUrl(fbstate); - } - - String redirectUrl = userService.verifyFacebookState(state); - - if (StringUtils.isEmpty(redirectUrl)) { - logger.error("state is missing"); - throw new HttpBadRequestException(); - } - OAuth2AccessToken token = facebookAuthService.getAccessToken(code); - final OAuthRequest meRequest = new OAuthRequest(Verb.GET, "https://graph.facebook.com/me?fields=id,name,email"); - facebookAuthService.signRequest(token, meRequest); - String graph = facebookAuthService.execute(meRequest).getBody(); - if (StringUtils.isBlank(graph)) { - logger.error("FACEBOOK GRAPH ERROR"); - throw new HttpBadRequestException(); - } - User fb = jsonMapper.readValue(graph, User.class); - long fbID = NumberUtils.toLong(fb.id(), 0); - if (fbID == 0 || StringUtils.isBlank(fb.name())) { - logger.error("Missing required fields, id: {}, name: {}", fbID, fb.name()); - throw new HttpBadRequestException(); - } - - Optional<com.juick.model.User> existingFacebookUser = userService.getUserByFacebookId(fbID); - if (existingFacebookUser.isPresent()) { - if (!userService.updateFacebookUser(fbID, token.getAccessToken(), fb.name())) { - logger.error("error updating facebook user, id: {}, token: {}", fbID, token.getAccessToken()); - throw new HttpBadRequestException(); - } - if (StringUtils.isNotEmpty(fb.email())) { - logger.info("found {} for facebook user {}", fb.email(), fb.name()); - Integer userId = existingFacebookUser.get().getUid(); - if (!emailService.getEmails(userId, false).contains(fb.email())) { - emailService.addEmail(userId, fb.email()); - } - } - UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(redirectUrl); - uriComponentsBuilder.queryParam("hash", userService.getHashByUID(existingFacebookUser.get().getUid())); - uriComponentsBuilder.queryParam("retpath", redirectUrl); - return "redirect:" + uriComponentsBuilder.build().toUriString(); - } else { - if (!userService.createFacebookUser(fbID, state, token.getAccessToken(), fb.name())) { - throw new HttpBadRequestException(); - } - return "redirect:/signup?type=fb&hash=" + state; - } - } - @GetMapping("/api/_vklogin") - protected String doVKLogin(@RequestParam(required = false) String code, - @RequestParam String state) throws IOException, ExecutionException, InterruptedException { - if (StringUtils.isBlank(code)) { - String vkstate = UUID.randomUUID().toString(); - userService.addVKState(vkstate, state); - return "redirect:" + vkAuthService.getAuthorizationUrl(vkstate); - } - - String redirectUrl = userService.verifyVKState(state); - if (StringUtils.isBlank(redirectUrl)) { - logger.error("state is missing"); - throw new HttpBadRequestException(); - } - OAuth2AccessToken token = vkAuthService.getAccessToken(code); - - OAuthRequest meRequest = new OAuthRequest(Verb.GET, "https://api.vk.com/method/users.get?fields=screen_name&v=5.131"); - vkAuthService.signRequest(token, meRequest); - String graph = vkAuthService.execute(meRequest).getBody(); - - com.juick.model.ext.vk.User jsonUser = jsonMapper.readValue(graph, UsersResponse.class).users().get(0); - String vkName = jsonUser.firstName() + " " + jsonUser.lastName(); - String vkLink = jsonUser.screenName(); - - if (vkName.length() == 1 || StringUtils.isBlank(vkLink)) { - logger.error("vk user error"); - throw new HttpBadRequestException(); - } - - long vkID = NumberUtils.toLong(jsonUser.id(), 0); - int uid = userService.getUIDbyVKID(vkID); - if (uid > 0) { - UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(redirectUrl); - uriComponentsBuilder.queryParam("hash", userService.getHashByUID(uid)); - uriComponentsBuilder.queryParam("retpath", redirectUrl); - return "redirect:" + uriComponentsBuilder.build().toUriString(); - } else { - String loginhash = UUID.randomUUID().toString(); - if (!userService.createVKUser(vkID, loginhash, token.getAccessToken(), vkName, vkLink)) { - logger.error("create vk user error"); - throw new HttpBadRequestException(); - } - return "redirect:/signup?type=vk&hash=" + loginhash; - } - } - @ResponseBody - @PostMapping("/api/_google") - public AuthResponse googleSignIn(@RequestParam(name = "idToken") String idTokenString) { - logger.info("Token: {}", idTokenString); - logger.info("Client: {}", googleClientId); - Optional<String> verifiedEmail = GoogleTokenVerifier.validateToken(googleClientId, idTokenString); - if (verifiedEmail.isPresent()) { - String email = verifiedEmail.get(); - com.juick.model.User visitor = userService.getUserByEmail(email); - if (visitor.isAnonymous()) { - String verificationCode = RandomStringUtils.randomAlphanumeric(8).toUpperCase(); - emailService.addVerificationCode(null, email, verificationCode); - return new AuthResponse(null, email, verificationCode); - } else { - return new AuthResponse(users.getMe(visitor), null, null); - } - } - throw new HttpForbiddenException(); - } - @ResponseBody - @PostMapping("/api/signup") - public com.juick.model.User signupWithEmail(String username, String password, String verificationCode) { - if (username.length() < 2 || username.length() > 16 || !username.matches("^[a-zA-Z0-9\\-]+$") - || password.length() < 6 || password.length() > 32) { - throw new HttpBadRequestException(); - } - - String verifiedEmail = emailService.getEmailByAuthCode(verificationCode); - if (StringUtils.isNotEmpty(verifiedEmail)) { - com.juick.model.User newUser = userService.createUser(username, password).orElseThrow(HttpBadRequestException::new); - emailService.addEmail(newUser.getUid(), verifiedEmail); - emailService.deleteAuthCode(verificationCode); - return newUser; - } else { - throw new HttpForbiddenException(); - } - } - @GetMapping("/api/_applelogin") - public String doAppleLogin(@RequestParam(required = false) String code, @RequestParam String state) { - if (StringUtils.isBlank(code)) { - String astate = UUID.randomUUID().toString(); - userService.addVKState(astate, state); - return "redirect:" + appleSignInService.getAuthorizationUrl(astate); - } - throw new HttpBadRequestException(); - } - @PostMapping("/api/_applelogin") - public String doVerifyAppleResponse(@RequestParam Map<String, String> body) throws InterruptedException, ExecutionException, IOException { - OAuth2AccessToken token = appleSignInService.getAccessToken(body.get("code")); - var jsonNode = jsonMapper.readTree(token.getRawResponse()); - var idToken = jsonNode.get("id_token").textValue(); - logger.info("Token: {}", idToken); - AppleSignInApi api = (AppleSignInApi) appleSignInService.getApi(); - var email = api.validateToken(idToken); - - if (email.isPresent()) { - com.juick.model.User user = userService.getUserByEmail(email.get()); - if (!user.isAnonymous()) { - String redirectUrl = userService.verifyVKState(body.get("state")); - if (StringUtils.isBlank(redirectUrl)) { - logger.error("state is missing"); - throw new HttpBadRequestException(); - } - UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(redirectUrl); - uriComponentsBuilder.queryParam("hash", userService.getHashByUID(user.getUid())); - uriComponentsBuilder.queryParam("retpath", redirectUrl); - return "redirect:" + uriComponentsBuilder.build().toUriString(); - } else { - String verificationCode = RandomStringUtils.randomAlphanumeric(8).toUpperCase(); - emailService.addVerificationCode(null, email.get(), verificationCode); - return "redirect:/signup?type=email&hash=" + verificationCode; - } - } - throw new HttpBadRequestException(); - } -} diff --git a/src/main/java/com/juick/www/api/Mastodon.java b/src/main/java/com/juick/www/api/Mastodon.java index 190ee5ef..ca3687e7 100644 --- a/src/main/java/com/juick/www/api/Mastodon.java +++ b/src/main/java/com/juick/www/api/Mastodon.java @@ -49,7 +49,7 @@ import org.springframework.security.oauth2.server.authorization.settings.ClientS import org.springframework.security.oauth2.server.authorization.settings.TokenSettings; import org.springframework.web.bind.annotation.*; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.net.URI; import java.time.Duration; import java.time.Instant; @@ -164,7 +164,7 @@ public class Mastodon { ) { } - @GetMapping({"/api/v1/instance", "/api/v2/instance"}) + @GetMapping("/api/v1/instance") public Instance getInstance() { return new Instance(domain, "Microblogging service", "Juick", "2.x","support@juick.com"); } diff --git a/src/main/java/com/juick/www/api/Messages.java b/src/main/java/com/juick/www/api/Messages.java index 969bef4f..ecea513b 100644 --- a/src/main/java/com/juick/www/api/Messages.java +++ b/src/main/java/com/juick/www/api/Messages.java @@ -39,7 +39,7 @@ import org.springframework.http.MediaType; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.io.IOException; import java.util.*; diff --git a/src/main/java/com/juick/www/api/Notifications.java b/src/main/java/com/juick/www/api/Notifications.java index c1ee74ab..f8f8dc14 100644 --- a/src/main/java/com/juick/www/api/Notifications.java +++ b/src/main/java/com/juick/www/api/Notifications.java @@ -28,7 +28,7 @@ import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.util.Collections; import java.util.List; import java.util.stream.Stream; diff --git a/src/main/java/com/juick/www/api/PM.java b/src/main/java/com/juick/www/api/PM.java index 5f0988c1..64f9bd82 100644 --- a/src/main/java/com/juick/www/api/PM.java +++ b/src/main/java/com/juick/www/api/PM.java @@ -34,7 +34,7 @@ import org.springframework.context.ApplicationEventPublisher; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.util.Collections; import java.util.List; diff --git a/src/main/java/com/juick/www/api/Post.java b/src/main/java/com/juick/www/api/Post.java index 4f1c2cad..57c23703 100644 --- a/src/main/java/com/juick/www/api/Post.java +++ b/src/main/java/com/juick/www/api/Post.java @@ -22,7 +22,7 @@ import java.net.URL; import java.util.List; import java.util.Optional; -import javax.inject.Inject; +import jakarta.inject.Inject; import com.juick.www.api.activity.helpers.ProfileUriBuilder; import io.swagger.v3.oas.annotations.Parameter; @@ -48,7 +48,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationEventPublisher; import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -74,38 +76,36 @@ public class Post { @RequestMapping(value = "/api/post", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(value = HttpStatus.OK) - public CommandResult doPostMessage( + public ResponseEntity<?> doPostMessage( @Parameter(hidden = true) User visitor, @RequestParam(required = false, defaultValue = StringUtils.EMPTY) String body, @RequestParam(required = false) String img, @RequestParam(required = false) MultipartFile attach) throws Exception { body = body.replace("\r", StringUtils.EMPTY); - - URI attachmentFName = HttpUtils.receiveMultiPartFile(attach, storageService.getTemporaryDirectory()); - - if (StringUtils.isBlank(attachmentFName.toString()) && img != null && img.length() > 10) { - URI juickUri = URI.create(img); - if (juickUri.getScheme().equals("juick")) { - attachmentFName = juickUri; - } else { - try { + try { + URI attachmentFName = HttpUtils.receiveMultiPartFile(attach, storageService.getTemporaryDirectory()); + if (StringUtils.isBlank(attachmentFName.toString()) && img != null && img.length() > 10) { + URI juickUri = URI.create(img); + if (juickUri.getScheme().equals("juick")) { + attachmentFName = juickUri; + } else { URL imgUrl = new URL(img); attachmentFName = HttpUtils.downloadImage(imgUrl, storageService.getTemporaryDirectory()); - } catch (Exception e) { - logger.error("DOWNLOAD ERROR", e); - throw new HttpBadRequestException(); } } + if (StringUtils.isBlank(body) && StringUtils.isBlank(attachmentFName.toString())) { + // Should be there for compatibility + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(CommandResult.fromString("Empty message")); + } + return ResponseEntity.ok(commandsManager.processCommand(visitor, body, attachmentFName)); + } catch (Exception e) { + logger.error("DOWNLOAD ERROR", e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(CommandResult.fromString(e.getMessage())); } - if (StringUtils.isBlank(body) && StringUtils.isBlank(attachmentFName.toString())) { - // Should be there for compatibility - throw new HttpBadRequestException(); - } - return commandsManager.processCommand(visitor, body, attachmentFName); } @RequestMapping(value = "/api/comment", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) - public CommandResult doPostComment( + public ResponseEntity<?> doPostComment( @Parameter(hidden = true) User visitor, @RequestParam(defaultValue = "0") int mid, @RequestParam(defaultValue = "0") int rid, @@ -114,11 +114,11 @@ public class Post { @RequestParam(required = false) MultipartFile attach) throws Exception { if (mid == 0) { - throw new HttpBadRequestException(); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(CommandResult.fromString("Invalid mid")); } Optional<Message> message = messagesService.getMessage(mid); if (message.isEmpty()) { - throw new HttpNotFoundException(); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(CommandResult.fromString("Message not found")); } Message msg = message.get(); @@ -127,7 +127,7 @@ public class Post { if (rid > 0) { reply = messagesService.getReply(mid, rid); if (reply == null) { - throw new HttpNotFoundException(); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(CommandResult.fromString("Reply not found")); } } @@ -135,25 +135,23 @@ public class Post { || userService.isInBL(visitor.getUid(), msg.getUser().getUid()) || (reply != null && userService.isInBL(visitor.getUid(), reply.getUser().getUid()))) { // TODO: validator - throw new HttpForbiddenException(); + return ResponseEntity.status(HttpStatus.FORBIDDEN).body(CommandResult.fromString("Forbidden")); } - - URI attachmentFName = HttpUtils.receiveMultiPartFile(attach, storageService.getTemporaryDirectory()); - - if (StringUtils.isBlank(attachmentFName.toString()) && img != null && img.length() > 10) { - try { + try { + URI attachmentFName = HttpUtils.receiveMultiPartFile(attach, storageService.getTemporaryDirectory()); + if (StringUtils.isBlank(attachmentFName.toString()) && img != null && img.length() > 10) { attachmentFName = HttpUtils.downloadImage(new URL(img), storageService.getTemporaryDirectory()); - } catch (Exception e) { - logger.error("DOWNLOAD ERROR", e); - throw new HttpBadRequestException(); } + if (StringUtils.isBlank(body) && StringUtils.isBlank(attachmentFName.toString())) { + // Should be there for compatibility + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(CommandResult.fromString("Empty message")); + } + return ResponseEntity.ok(commandsManager.processCommand(visitor, String.format("#%d/%d %s", mid, rid, body), + attachmentFName)); + } catch (Exception e) { + logger.error("DOWNLOAD ERROR", e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(CommandResult.fromString(e.getMessage())); } - if (StringUtils.isBlank(body) && StringUtils.isBlank(attachmentFName.toString())) { - // Should be there for compatibility - throw new HttpBadRequestException(); - } - return commandsManager.processCommand(visitor, String.format("#%d/%d %s", mid, rid, body), - attachmentFName); } @PostMapping("/api/like") diff --git a/src/main/java/com/juick/www/api/Service.java b/src/main/java/com/juick/www/api/Service.java index 41fdcfbf..ed6699d2 100644 --- a/src/main/java/com/juick/www/api/Service.java +++ b/src/main/java/com/juick/www/api/Service.java @@ -37,6 +37,7 @@ import jakarta.mail.internet.AddressException; import jakarta.mail.internet.InternetAddress; import jakarta.mail.internet.MimeMessage; +import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomStringUtils; @@ -53,7 +54,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.context.request.async.AsyncRequestTimeoutException; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; @@ -221,7 +222,8 @@ public class Service { } @GetMapping("/api/events") - public SseEmitter handle(@Parameter(hidden = true) User visitor) { + public SseEmitter handle(@Parameter(hidden = true) User visitor, HttpServletResponse response) { + response.addHeader("X-Accel-Buffering", "no"); logger.info("{} connected", visitor.getName()); if (!visitor.isAnonymous()) { userService.updateLastSeen(visitor); diff --git a/src/main/java/com/juick/www/api/SystemActivity.java b/src/main/java/com/juick/www/api/SystemActivity.java index a75ef3b6..33d4e1d3 100644 --- a/src/main/java/com/juick/www/api/SystemActivity.java +++ b/src/main/java/com/juick/www/api/SystemActivity.java @@ -23,7 +23,7 @@ import com.juick.model.User; import java.util.Collections; import java.util.List; -import javax.annotation.Nonnull; +import jakarta.annotation.Nonnull; public class SystemActivity { private SystemActivity(ActivityType type) { diff --git a/src/main/java/com/juick/www/api/Tags.java b/src/main/java/com/juick/www/api/Tags.java index 5bb25af6..b89918a6 100644 --- a/src/main/java/com/juick/www/api/Tags.java +++ b/src/main/java/com/juick/www/api/Tags.java @@ -24,7 +24,7 @@ import io.swagger.v3.oas.annotations.Parameter; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.util.List; /** diff --git a/src/main/java/com/juick/www/api/Users.java b/src/main/java/com/juick/www/api/Users.java index 34382f8e..923d00b9 100644 --- a/src/main/java/com/juick/www/api/Users.java +++ b/src/main/java/com/juick/www/api/Users.java @@ -23,7 +23,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import javax.inject.Inject; +import jakarta.inject.Inject; import com.juick.model.AnonymousUser; import com.juick.model.ApplicationStatus; diff --git a/src/main/java/com/juick/www/api/activity/Profile.java b/src/main/java/com/juick/www/api/activity/Profile.java index 101c59f9..e5bd04ac 100644 --- a/src/main/java/com/juick/www/api/activity/Profile.java +++ b/src/main/java/com/juick/www/api/activity/Profile.java @@ -52,7 +52,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.io.InputStream; import java.net.URI; import java.nio.charset.StandardCharsets; diff --git a/src/main/java/com/juick/www/api/hostmeta/HostMeta.java b/src/main/java/com/juick/www/api/hostmeta/HostMeta.java deleted file mode 100644 index c6f1dce6..00000000 --- a/src/main/java/com/juick/www/api/hostmeta/HostMeta.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2008-2020, 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.www.api.hostmeta; - -import com.cliqset.xrd.Link; -import com.cliqset.xrd.XRD; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -import java.util.Collections; - -import static com.cliqset.xrd.XRDConstants.XRD_MEDIA_TYPE; - -@RestController -public class HostMeta { - @Value("${ap_base_uri:http://localhost:8080/}") - private String baseUri; - @GetMapping(value = "/.well-known/host-meta", produces = { XRD_MEDIA_TYPE, MediaType.APPLICATION_XML_VALUE }) - public XRD hostMetaResponse() { - Link webfinger = new Link(); - webfinger.setTemplate(String.format("%swebfinger?resource={uri}", baseUri)); - XRD xrd = new XRD(); - xrd.setLinks(Collections.singletonList(webfinger)); - return xrd; - } -} diff --git a/src/main/java/com/juick/www/api/webfinger/Resource.java b/src/main/java/com/juick/www/api/webfinger/Resource.java index 4b2bc388..3f04097c 100644 --- a/src/main/java/com/juick/www/api/webfinger/Resource.java +++ b/src/main/java/com/juick/www/api/webfinger/Resource.java @@ -17,53 +17,6 @@ package com.juick.www.api.webfinger; -import com.juick.model.User; -import com.juick.www.api.webfinger.model.Account; -import com.juick.www.api.webfinger.model.Link; -import com.juick.util.HttpNotFoundException; -import com.juick.service.UserService; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.util.UriComponentsBuilder; -import rocks.xmpp.addr.Jid; - -import javax.inject.Inject; -import java.util.List; - -import static com.juick.www.api.activity.model.Context.ACTIVITY_MEDIA_TYPE; - -@RestController public class Resource { public static final String MEDIA_TYPE = "application/jrd+json"; - @Inject - private UserService userService; - @Value("${web_domain:localhost}") - private String domain; - @Value("${ap_base_uri:http://localhost:8080/}") - private String baseUri; - - @GetMapping(value = "/.well-known/webfinger", produces = { - Resource.MEDIA_TYPE, MediaType.APPLICATION_JSON_VALUE }) - public Account getWebResource(@RequestParam String resource) { - if (resource.startsWith("acct:")) { - try { - Jid account = Jid.of(resource.substring(5)); - if (account.getDomain().equals(domain)) { - User user = userService.getUserByName(account.getLocal()); - if (!user.isAnonymous()) { - UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(baseUri); - builder.path(String.format("/u/%s", user.getName())); - Link blog = new Link("self", ACTIVITY_MEDIA_TYPE, builder.toUriString()); - return new Account(resource, List.of(blog)); - } - } - } catch (NullPointerException | IllegalArgumentException e) { - throw new HttpNotFoundException(); - } - } - throw new HttpNotFoundException(); - } } 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 99999838..c05585ac 100644 --- a/src/main/java/com/juick/www/api/webhooks/PatreonWebhook.java +++ b/src/main/java/com/juick/www/api/webhooks/PatreonWebhook.java @@ -32,7 +32,7 @@ import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -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<String> 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); } } diff --git a/src/main/java/com/juick/www/api/webhooks/TelegramWebhook.java b/src/main/java/com/juick/www/api/webhooks/TelegramWebhook.java index 76b38168..4636e9f6 100644 --- a/src/main/java/com/juick/www/api/webhooks/TelegramWebhook.java +++ b/src/main/java/com/juick/www/api/webhooks/TelegramWebhook.java @@ -32,7 +32,7 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.io.InputStream; import java.nio.charset.StandardCharsets; diff --git a/src/main/java/com/juick/www/api/webhooks/VkWebhook.java b/src/main/java/com/juick/www/api/webhooks/VkWebhook.java index 9e4477b1..d69d00be 100644 --- a/src/main/java/com/juick/www/api/webhooks/VkWebhook.java +++ b/src/main/java/com/juick/www/api/webhooks/VkWebhook.java @@ -29,7 +29,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; @@ -62,9 +62,9 @@ public class VkWebhook { if (secretKey.equals(secret)) { if (type.startsWith("donut_")) { var vkId = json.get("object").get("user_id").asLong(0); - var userId = userService.getUIDbyVKID(vkId); - if (userId > 0) { - vkService.updatePremiumStatus(userId); + var user = userService.getUserByVKID(vkId); + if (user.isPresent()) { + vkService.updatePremiumStatus(user.get().getUid()); } } return "ok"; diff --git a/src/main/java/com/juick/www/api/xnodeinfo2/Info.java b/src/main/java/com/juick/www/api/xnodeinfo2/Info.java index 2af252ed..adbd5712 100644 --- a/src/main/java/com/juick/www/api/xnodeinfo2/Info.java +++ b/src/main/java/com/juick/www/api/xnodeinfo2/Info.java @@ -17,27 +17,14 @@ package com.juick.www.api.xnodeinfo2; -import com.cliqset.xrd.Link; -import com.cliqset.xrd.XRD; import com.fasterxml.jackson.annotation.JsonView; import com.juick.service.InfoService; import com.juick.www.api.xnodeinfo2.model.*; import org.springframework.beans.factory.annotation.Value; -import org.springframework.cache.annotation.Cacheable; import org.springframework.http.MediaType; -import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.util.UriComponentsBuilder; - -import javax.inject.Inject; -import java.net.URI; -import java.time.ZonedDateTime; -import java.time.temporal.ChronoUnit; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; +import jakarta.inject.Inject; @RestController public class Info { @@ -53,18 +40,6 @@ public class Info { return infoService.getCurrentNodeInfo("1.0"); } - @GetMapping(value = "/.well-known/nodeinfo", produces = MediaType.APPLICATION_JSON_VALUE) - public XRD getNodeInfoLinks() { - Link nodeinfo = new Link(); - nodeinfo.setRel(URI.create("http://nodeinfo.diaspora.software/ns/schema/2.0")); - UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(baseUri); - uriComponentsBuilder.replacePath("/api/nodeinfo/2.0"); - nodeinfo.setHref(uriComponentsBuilder.build().toUri()); - XRD xrd = new XRD(); - xrd.setLinks(Collections.singletonList(nodeinfo)); - return xrd; - } - @GetMapping(value = "/api/nodeinfo/2.0", produces = MediaType.APPLICATION_JSON_VALUE) @JsonView(NodeInfo.NodeInfoView.class) public NodeInfo showNodeInfo() { diff --git a/src/main/java/com/juick/www/controllers/Compat.java b/src/main/java/com/juick/www/controllers/Compat.java index edd7bc29..334213be 100644 --- a/src/main/java/com/juick/www/controllers/Compat.java +++ b/src/main/java/com/juick/www/controllers/Compat.java @@ -30,7 +30,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import org.springframework.web.servlet.view.RedirectView; -import javax.inject.Inject; +import jakarta.inject.Inject; @Controller @Validated diff --git a/src/main/java/com/juick/www/controllers/Help.java b/src/main/java/com/juick/www/controllers/Help.java index ae722594..5754e55f 100644 --- a/src/main/java/com/juick/www/controllers/Help.java +++ b/src/main/java/com/juick/www/controllers/Help.java @@ -29,7 +29,7 @@ import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.util.Locale; import java.util.Objects; diff --git a/src/main/java/com/juick/www/controllers/Settings.java b/src/main/java/com/juick/www/controllers/Settings.java index d95b21b7..11f31efb 100644 --- a/src/main/java/com/juick/www/controllers/Settings.java +++ b/src/main/java/com/juick/www/controllers/Settings.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2023, Juick + * 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 @@ -23,7 +23,7 @@ import java.util.Locale; import java.util.ResourceBundle; import java.util.stream.IntStream; -import javax.inject.Inject; +import jakarta.inject.Inject; import com.juick.model.User; import com.juick.service.EmailService; @@ -150,14 +150,20 @@ public class Settings { visitor.setCountry(request.getParameter("country")); visitor.setUrl(request.getParameter("url")); visitor.setDescription(request.getParameter("descr")); - String avatarTmpPath = HttpUtils.receiveMultiPartFile(newAvatar, storageService.getTemporaryDirectory()).getHost(); - if (StringUtils.isNotEmpty(avatarTmpPath)) { - storageService.saveAvatar(avatarTmpPath, visitor); - } - if (userService.updateUserInfo(visitor)) { - result = String.format("<p>Your info is updated.</p><p><a href='/%s/'>Back to blog</a>.</p>", visitor.getName()); + try { + String avatarTmpPath = HttpUtils + .receiveMultiPartFile(newAvatar, storageService.getTemporaryDirectory()).getHost(); + if (StringUtils.isNotEmpty(avatarTmpPath)) { + storageService.saveAvatar(avatarTmpPath, visitor); + } + if (userService.updateUserInfo(visitor)) { + result = String.format("<p>Your info is updated.</p><p><a href='/%s/'>Back to blog</a>.</p>", + visitor.getName()); + } + applicationEventPublisher.publishEvent(new UpdateUserEvent(this, visitor)); + } catch (Exception e) { + result = "<p>" + e.getMessage() + ". <a href=\"/settings\">Back</a>.</p>"; } - applicationEventPublisher.publishEvent(new UpdateUserEvent(this, visitor)); break; case "jid-del": // FIXME: stop using ugnich-csv in parameters @@ -175,25 +181,29 @@ public class Settings { } break; case "email-add": - if (!emailService.verifyAddressByCode(visitor.getUid(), request.getParameter("account"))) { - String authCode = RandomStringUtils.randomAlphanumeric(8).toUpperCase(); - 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@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 = "<p>Authorization link has been sent to your email. Follow it to proceed.</p>" + - "<p><a href=\"/settings\">Back</a></p>"; + if (!emailService.isValidEmail(request.getParameter("account"))) { + result = "<p>Invalid email. <a href=\"/settings\">Back</a>.</p>"; + } else { + if (!emailService.verifyAddressByCode(visitor.getUid(), request.getParameter("account"))) { + String authCode = RandomStringUtils.randomAlphanumeric(8).toUpperCase(); + 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@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" + + "https://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 = "<p>Authorization link has been sent to your email. Follow it to proceed.</p>" + + "<p><a href=\"/settings\">Back</a></p>"; - } catch (MessagingException ex) { - logger.error("mail exception", ex); - throw new HttpBadRequestException(); + } catch (MessagingException ex) { + logger.error("mail exception", ex); + throw new HttpBadRequestException(); + } } } } diff --git a/src/main/java/com/juick/www/controllers/SignUp.java b/src/main/java/com/juick/www/controllers/SignUp.java index 50ce6955..dddefef3 100644 --- a/src/main/java/com/juick/www/controllers/SignUp.java +++ b/src/main/java/com/juick/www/controllers/SignUp.java @@ -37,7 +37,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; -import javax.inject.Inject; +import jakarta.inject.Inject; /** * @@ -92,6 +92,7 @@ public class SignUp { model.addAttribute("account", account); model.addAttribute("type", type); model.addAttribute("hash", hash); + model.addAttribute("headers", "<meta name=\"robots\" content=\"noindex\"/>"); return "views/signup"; } diff --git a/src/main/java/com/juick/www/controllers/Site.java b/src/main/java/com/juick/www/controllers/Site.java index 3af6f2c2..c5074547 100644 --- a/src/main/java/com/juick/www/controllers/Site.java +++ b/src/main/java/com/juick/www/controllers/Site.java @@ -45,7 +45,7 @@ import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.view.RedirectView; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -595,7 +595,7 @@ public class Site { fillUserModel(model, visitor, visitor); visitor.setAvatar(webApp.getAvatarWebPath(visitor)); model.addAttribute("title", "Написать"); - model.addAttribute("headers", ""); + model.addAttribute("headers", "<meta name=\"robots\" content=\"noindex\"/>"); model.addAttribute("visitor", visitor); if (body == null) { body = StringUtils.EMPTY; diff --git a/src/main/java/com/juick/www/controllers/SocialLogin.java b/src/main/java/com/juick/www/controllers/SocialLogin.java index 75099e50..510c7d62 100644 --- a/src/main/java/com/juick/www/controllers/SocialLogin.java +++ b/src/main/java/com/juick/www/controllers/SocialLogin.java @@ -53,11 +53,12 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import org.springframework.web.util.UriComponentsBuilder; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.io.IOException; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.UUID; import java.util.concurrent.ExecutionException; @@ -70,7 +71,7 @@ import java.util.stream.Collectors; @Controller public class SocialLogin { - private static final Logger logger = LoggerFactory.getLogger(SocialLogin.class); + private static final Logger logger = LoggerFactory.getLogger("Social"); public static final String AUTH_ERROR = "SocialLogin.AuthenticationError"; @@ -124,12 +125,12 @@ public class SocialLogin { @GetMapping("/_fblogin") protected String doFacebookLogin(HttpServletRequest request, @RequestParam(required = false) String code, @RequestParam(required = false) String state, - @RequestHeader(value = "referer", required = false) String referer, HttpServletResponse response, + HttpServletResponse response, HttpSession session) throws IOException, ExecutionException, InterruptedException { if (StringUtils.isBlank(code)) { String fbstate = UUID.randomUUID().toString(); if (StringUtils.isBlank(state)) { - state = Optional.ofNullable(referer).orElse("https://juick.com/"); + state = UUID.randomUUID().toString(); } userService.addFacebookState(fbstate, state); return "redirect:" + facebookAuthService.getAuthorizationUrl(fbstate); @@ -170,10 +171,12 @@ public class SocialLogin { } } if (!existingFacebookUser.get().isBanned()) { - Cookie c = new Cookie("hash", userService.getHashByUID(existingFacebookUser.get().getUid())); - c.setMaxAge(50 * 24 * 60 * 60); - response.addCookie(c); - return "redirect:" + redirectUrl; + var authentication = new RememberMeAuthenticationToken( + ((AbstractRememberMeServices) rememberMeServices).getKey(), + new JuickUser(existingFacebookUser.get()), JuickUser.USER_AUTHORITY); + SecurityContextHolder.getContext().setAuthentication(authentication); + rememberMeServices.loginSuccess(request, response, authentication); + return "redirect:/"; } else { session.setAttribute(SocialLogin.AUTH_ERROR, "User is disabled"); return "redirect:/login"; @@ -188,9 +191,9 @@ public class SocialLogin { @GetMapping("/_twitter") protected String doTwitterLogin(@RequestParam(required = false) String code, - @RequestParam(required = false) String state, - com.juick.model.User user, - HttpServletRequest request) + @RequestParam(required = false) String state, + com.juick.model.User user, + HttpServletRequest request) throws IOException, ExecutionException, InterruptedException { if (StringUtils.isBlank(code)) { @@ -229,14 +232,17 @@ public class SocialLogin { @GetMapping("/_vklogin") protected String doVKLogin(@RequestParam(required = false) String code, @RequestParam(required = false) String state, - @RequestHeader(value = "referer", required = false) String referer, - @CookieValue(required = false) String vkstate, HttpServletResponse response) + @CookieValue(required = false) String vkstate, + HttpServletRequest request, + HttpServletResponse response, + HttpSession session) throws IOException, ExecutionException, InterruptedException { if (StringUtils.isBlank(code)) { vkstate = UUID.randomUUID().toString(); Cookie c = new Cookie("vkstate", vkstate); response.addCookie(c); - return "redirect:" + vkService.getVkAuthService().getAuthorizationUrl(vkstate); + var redirect = "redirect:" + vkService.getVkAuthService().getAuthorizationUrl(vkstate); + return redirect; } if (StringUtils.isBlank(vkstate) || !vkstate.equals(state)) { @@ -265,13 +271,19 @@ public class SocialLogin { } long vkID = NumberUtils.toLong(jsonUser.id(), 0); - int uid = userService.getUIDbyVKID(vkID); - if (uid > 0) { - userService.updateVkUser(vkID, token.getAccessToken(), vkName, vkLink); - Cookie c = new Cookie("hash", userService.getHashByUID(uid)); - c.setMaxAge(50 * 24 * 60 * 60); - response.addCookie(c); - return "redirect:/" + Optional.ofNullable(referer).orElse(StringUtils.EMPTY); + var user = userService.getUserByVKID(vkID); + if (user.isPresent()) { + if (!user.get().isBanned()) { + 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:/"; + } else { + session.setAttribute(SocialLogin.AUTH_ERROR, "User is disabled"); + return "redirect:/login"; + } } else { String loginhash = UUID.randomUUID().toString(); if (!userService.createVKUser(vkID, loginhash, token.getAccessToken(), vkName, vkLink)) { @@ -290,8 +302,7 @@ public class SocialLogin { @GetMapping("/_tglogin") public String doDurovLogin(@RequestParam Map<String, String> params, @RequestParam String hash, - @RequestHeader(value = "referer", required = false) String referer, - HttpServletRequest request, HttpServletResponse response) { + HttpServletRequest request, HttpServletResponse response, HttpSession session) { 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,14 +312,19 @@ public class SocialLogin { long tgUser = Long.parseLong(params.get("id")); 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); + if (!user.get().isBanned()) { + 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:/"; + } else { + session.setAttribute(SocialLogin.AUTH_ERROR, "User is disabled"); + return "redirect:/login"; + } } else { - String username = StringUtils.defaultString(params.get("username"), params.get("first_name")); + String username = Objects.toString(params.get("username"), params.get("first_name")); List<Long> chats = telegramService.getAnonymous(); if (!chats.contains(tgUser)) { logger.info("added chat with {}", username); @@ -347,9 +363,11 @@ public class SocialLogin { com.juick.model.User user = userService.getUserByEmail(email.get()); if (!user.isAnonymous()) { if (!user.isBanned()) { - Cookie c = new Cookie("hash", userService.getHashByUID(user.getUid())); - c.setMaxAge(50 * 24 * 60 * 60); - response.addCookie(c); + var authentication = new RememberMeAuthenticationToken( + ((AbstractRememberMeServices) rememberMeServices).getKey(), + new JuickUser(user), JuickUser.USER_AUTHORITY); + SecurityContextHolder.getContext().setAuthentication(authentication); + rememberMeServices.loginSuccess(request, response, authentication); return "redirect:/"; } else { session.setAttribute(SocialLogin.AUTH_ERROR, "User is disabled"); diff --git a/src/main/java/com/juick/www/filters/AnythingFilter.java b/src/main/java/com/juick/www/filters/AnythingFilter.java index 91422807..463374ee 100644 --- a/src/main/java/com/juick/www/filters/AnythingFilter.java +++ b/src/main/java/com/juick/www/filters/AnythingFilter.java @@ -33,7 +33,7 @@ import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import org.springframework.web.util.UriComponents; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.io.IOException; @Component diff --git a/src/main/java/com/juick/www/rss/Feeds.java b/src/main/java/com/juick/www/rss/Feeds.java index f19f1505..a0608172 100644 --- a/src/main/java/com/juick/www/rss/Feeds.java +++ b/src/main/java/com/juick/www/rss/Feeds.java @@ -30,7 +30,7 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; -import javax.inject.Inject; +import jakarta.inject.Inject; import java.util.List; /** diff --git a/src/main/java/com/juick/www/rss/MessagesView.java b/src/main/java/com/juick/www/rss/MessagesView.java index cb4eea2e..b6b5e5a1 100644 --- a/src/main/java/com/juick/www/rss/MessagesView.java +++ b/src/main/java/com/juick/www/rss/MessagesView.java @@ -24,7 +24,7 @@ import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; -import javax.inject.Inject; +import jakarta.inject.Inject; import com.juick.model.Attachment; import com.juick.model.Message; diff --git a/src/main/java/com/juick/www/rss/RepliesView.java b/src/main/java/com/juick/www/rss/RepliesView.java index 80548a79..47fb46b6 100644 --- a/src/main/java/com/juick/www/rss/RepliesView.java +++ b/src/main/java/com/juick/www/rss/RepliesView.java @@ -40,7 +40,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.servlet.view.feed.AbstractRssFeedView; -import javax.annotation.Nonnull; +import jakarta.annotation.Nonnull; import java.net.URI; import java.net.URISyntaxException; import java.util.List; |