aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/juick/service
diff options
context:
space:
mode:
authorGravatar alx2019-03-16 23:56:27 +0300
committerGravatar alx2019-03-16 23:56:27 +0300
commit06105f76dbfa3b65e63ed06f9c4d5107bd49ed88 (patch)
tree5702c01cec9688039d891f4a711878706101c1c5 /src/main/java/com/juick/service
parent3ea4cd1942fa4e763034da11c5fa429407b67829 (diff)
parenta49105285d0d7719d7f222a507af2d5ac5b4bdb1 (diff)
Merge remote-tracking branch 'origin/master'
Diffstat (limited to 'src/main/java/com/juick/service')
-rw-r--r--src/main/java/com/juick/service/CrosspostService.java4
-rw-r--r--src/main/java/com/juick/service/CrosspostServiceImpl.java12
-rw-r--r--src/main/java/com/juick/service/MessagesService.java6
-rw-r--r--src/main/java/com/juick/service/MessagesServiceImpl.java143
-rw-r--r--src/main/java/com/juick/service/PMQueriesServiceImpl.java6
-rw-r--r--src/main/java/com/juick/service/TagServiceImpl.java30
-rw-r--r--src/main/java/com/juick/service/UserService.java5
-rw-r--r--src/main/java/com/juick/service/UserServiceImpl.java55
-rw-r--r--src/main/java/com/juick/service/security/HTTPSignatureAuthenticationFilter.java71
-rw-r--r--src/main/java/com/juick/service/security/HashParamAuthenticationFilter.java7
10 files changed, 218 insertions, 121 deletions
diff --git a/src/main/java/com/juick/service/CrosspostService.java b/src/main/java/com/juick/service/CrosspostService.java
index 99911250..28b9e8ab 100644
--- a/src/main/java/com/juick/service/CrosspostService.java
+++ b/src/main/java/com/juick/service/CrosspostService.java
@@ -60,9 +60,9 @@ public interface CrosspostService {
int getUIDbyFBID(long fbID);
- boolean createFacebookUser(long fbID, String loginhash, String token, String fbName, String fbLink);
+ boolean createFacebookUser(long fbID, String loginhash, String token, String fbName);
- boolean updateFacebookUser(long fbID, String token, String fbName, String fbLink);
+ boolean updateFacebookUser(long fbID, String token, String fbName);
int getUIDbyVKID(long vkID);
diff --git a/src/main/java/com/juick/service/CrosspostServiceImpl.java b/src/main/java/com/juick/service/CrosspostServiceImpl.java
index d190faba..0eeb8c78 100644
--- a/src/main/java/com/juick/service/CrosspostServiceImpl.java
+++ b/src/main/java/com/juick/service/CrosspostServiceImpl.java
@@ -180,16 +180,16 @@ public class CrosspostServiceImpl extends BaseJdbcService implements CrosspostSe
@Transactional
@Override
- public boolean createFacebookUser(long fbID, String loginhash, String token, String fbName, String fbLink) {
- return getJdbcTemplate().update("UPDATE facebook SET fb_id=?, access_token=?, fb_name=?, fb_link=? WHERE loginhash=?",
- fbID, token, fbName, fbLink, loginhash) > 0;
+ public boolean createFacebookUser(long fbID, String loginhash, String token, String fbName) {
+ return getJdbcTemplate().update("UPDATE facebook SET fb_id=?, access_token=?, fb_name=? WHERE loginhash=?",
+ fbID, token, fbName, loginhash) > 0;
}
@Transactional
@Override
- public boolean updateFacebookUser(long fbID, String token, String fbName, String fbLink) {
- return getJdbcTemplate().update("UPDATE facebook SET access_token=?,fb_name=?,fb_link=? WHERE fb_id=?",
- token, fbName, fbLink, fbID) > 0;
+ public boolean updateFacebookUser(long fbID, String token, String fbName) {
+ return getJdbcTemplate().update("UPDATE facebook SET access_token=?,fb_name=? WHERE fb_id=?",
+ token, fbName, fbID) > 0;
}
@Transactional(readOnly = true)
diff --git a/src/main/java/com/juick/service/MessagesService.java b/src/main/java/com/juick/service/MessagesService.java
index 4bcdba46..922170db 100644
--- a/src/main/java/com/juick/service/MessagesService.java
+++ b/src/main/java/com/juick/service/MessagesService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2017, Juick
+ * Copyright (C) 2008-2019, 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
@@ -29,7 +29,7 @@ import java.util.*;
* Created by aalexeev on 11/13/16.
*/
public interface MessagesService {
- int createMessage(int uid, String txt, String attachment, Collection<com.juick.Tag> tags);
+ int createMessage(int uid, String txt, String attachment, List<com.juick.Tag> tags);
int createReply(int mid, int rid, User user, String txt, String attachment);
@@ -68,7 +68,7 @@ public interface MessagesService {
User getMessageAuthor(int mid);
- List<String> getMessageRecommendations(int mid);
+ List<User> getMessageRecommendations(int mid);
List<Integer> getAll(int visitorUid, int before);
diff --git a/src/main/java/com/juick/service/MessagesServiceImpl.java b/src/main/java/com/juick/service/MessagesServiceImpl.java
index 4e5dca81..7dbfe1dd 100644
--- a/src/main/java/com/juick/service/MessagesServiceImpl.java
+++ b/src/main/java/com/juick/service/MessagesServiceImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2017, Juick
+ * Copyright (C) 2008-2019, 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
@@ -17,11 +17,14 @@
package com.juick.service;
-import com.juick.*;
+import com.juick.Message;
+import com.juick.Reaction;
+import com.juick.User;
import com.juick.model.AnonymousUser;
import com.juick.model.PrivacyOpts;
import com.juick.model.ResponseReply;
import com.juick.server.util.HttpNotFoundException;
+import com.juick.server.www.WebApp;
import com.juick.util.MessageUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
@@ -29,6 +32,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
+import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.ConnectionCallback;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
@@ -37,12 +41,24 @@ import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
+import javax.annotation.Nonnull;
import javax.inject.Inject;
import java.net.URI;
-import java.sql.*;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.sql.Types;
import java.time.Instant;
-import java.util.*;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
import java.util.stream.Collectors;
/**
@@ -59,6 +75,8 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ
private SearchService searchService;
@Inject
private ImagesService imagesService;
+ @Inject
+ private WebApp webApp;
@Value("${photos_url:https://i.juick.com/}")
private String baseImagesUrl;
@@ -75,7 +93,7 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ
user.setBanned(rs.getBoolean(6));
user.setUri(URI.create(Optional.ofNullable(rs.getString(22)).orElse(StringUtils.EMPTY)));
msg.setUser(user);
- msg.setTimestamp(rs.getTimestamp(7).toInstant());
+ msg.setCreated(rs.getTimestamp(7).toInstant());
msg.ReadOnly = rs.getBoolean(8);
msg.setPrivacy(rs.getInt(9));
msg.FriendsOnly = msg.getPrivacy() < 0;
@@ -83,7 +101,7 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ
msg.setAttachmentType(rs.getString(11));
msg.setLikes(rs.getInt(12));
msg.Hidden = rs.getBoolean(13);
- String tagsStr = rs.getString(14);
+ String tagsStr = StringUtils.defaultString(rs.getString(14));
msg.setTags(MessageUtils.parseTags(tagsStr));
msg.setRepliesBy(rs.getString(15));
msg.setText(rs.getString(16));
@@ -96,6 +114,8 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ
if (quoteUid == 0) {
quoteUser.setName(AnonymousUser.INSTANCE.getName());
quoteUser.setUri(URI.create(Optional.ofNullable(rs.getString(23)).orElse(StringUtils.EMPTY)));
+ } else {
+ quoteUser.setAvatar(webApp.getAvatarUrl(quoteUser));
}
msg.setTo(quoteUser);
msg.setUpdatedAt(rs.getTimestamp(21).toInstant());
@@ -119,7 +139,7 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ
*/
@Transactional
@Override
- public int createMessage(final int uid, final String txt, final String attachment, final Collection<com.juick.Tag> tags) {
+ public int createMessage(final int uid, final String txt, final String attachment, final List<com.juick.Tag> tags) {
SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert(getJdbcTemplate()).withTableName("messages")
.usingColumns("user_id", "attach", "ts")
.usingGeneratedKeyColumns("message_id");
@@ -132,34 +152,25 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ
}
int mid = simpleJdbcInsert.executeAndReturnKey(insertMap).intValue();
if (mid > 0) {
- String tagsNames = StringUtils.EMPTY;
-
if (CollectionUtils.isNotEmpty(tags)) {
- StringBuilder tasNamesBuilder = new StringBuilder();
- List<Object[]> params = new ArrayList<>(tags.size());
-
- boolean next = false;
-
- for (Tag tag : tags) {
- if (next) {
- tasNamesBuilder.append(" ");
- } else
- next = true;
-
- tasNamesBuilder.append(tag.getName());
- params.add(new Object[]{mid, tag.TID});
- }
- tagsNames = tasNamesBuilder.toString();
-
getJdbcTemplate().batchUpdate(
"INSERT INTO messages_tags(message_id, tag_id) VALUES (?, ?)",
- params, new int[]{Types.INTEGER, Types.INTEGER});
+ new BatchPreparedStatementSetter() {
+ @Override
+ public void setValues(@Nonnull PreparedStatement ps, int i) throws SQLException {
+ ps.setInt(1, mid);
+ ps.setInt(2, tags.get(i).TID);
+ }
+ @Override
+ public int getBatchSize() {
+ return tags.size();
+ }
+ });
}
-
getJdbcTemplate().update(
- "INSERT INTO messages_txt(message_id, tags, txt, updated_at) VALUES (?, ?, ?, ?)",
- new Object[]{mid, tagsNames, txt, Timestamp.from(now)},
- new int[]{Types.INTEGER, Types.VARCHAR, Types.VARCHAR, Types.TIMESTAMP});
+ "INSERT INTO messages_txt(message_id, txt, updated_at) VALUES (?, ?, ?)",
+ new Object[]{mid, txt, Timestamp.from(now)},
+ new int[]{Types.INTEGER, Types.VARCHAR, Types.TIMESTAMP});
getJdbcTemplate().update("UPDATE users SET lastmessage=?, last_seen=? where id=?", Timestamp.from(now), Timestamp.from(now), uid);
}
@@ -365,16 +376,18 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ
+ "messages.ts,"
+ "messages.readonly, messages.privacy, messages.replies,"
+ "messages.attach, COUNT(DISTINCT favorites.user_id) as likes, messages.hidden,"
- + "txt.tags, txt.repliesby, txt.txt, '' as q, messages.updated as updated, 0 as to_uid, "
+ + "GROUP_CONCAT(tags.name SEPARATOR ' '), txt.repliesby, txt.txt, '' as q, messages.updated as updated, 0 as to_uid, "
+ "NULL as to_name, txt.updated_at, '' as user_uri, '' as to_uri, '' as reply_uri, 0 as html FROM messages "
+ "INNER JOIN users ON messages.user_id = users.id "
+ "INNER JOIN messages_txt AS txt "
+ "ON messages.message_id = txt.message_id "
+ "LEFT JOIN favorites "
+ "ON messages.message_id = favorites.message_id AND favorites.like_id=1 "
+ + "LEFT JOIN messages_tags ON messages_tags.message_id=txt.message_id "
+ + "LEFT JOIN tags ON tags.tag_id=messages_tags.tag_id "
+ "WHERE messages.message_id = ? "
+ "GROUP BY mid, rid, replyto, uid, nick, banned, messages.ts, readonly, "
- + "privacy, replies, attach, tags, repliesby, q, updated_at, user_uri, to_uri, reply_uri, html",
+ + "privacy, replies, attach, repliesby, q, updated_at, user_uri, to_uri, reply_uri, html",
new MessageMapper(),
mid);
if (!list.isEmpty()) {
@@ -418,7 +431,7 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ
URI.create(Optional.ofNullable(rs.getString(11)).orElse(StringUtils.EMPTY)));
}
msg.setReplyto(rs.getInt(3));
- msg.setTimestamp(rs.getTimestamp(4).toInstant());
+ msg.setCreated(rs.getTimestamp(4).toInstant());
msg.setAttachmentType(rs.getString(5));
msg.setText(rs.getString(6));
String quote = rs.getString(7);
@@ -477,15 +490,21 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ
@Transactional(readOnly = true)
@Override
- public List<String> getMessageRecommendations(final int mid) {
- return getJdbcTemplate().queryForList(
- "SELECT DISTINCT users.nick FROM favorites " +
+ public List<User> getMessageRecommendations(final int mid) {
+ return getJdbcTemplate().query(
+ "SELECT DISTINCT users.id, users.nick, favorites.user_uri FROM favorites " +
"INNER JOIN users ON (favorites.message_id = ? AND favorites.user_id = users.id) " +
"INNER JOIN messages m ON favorites.message_id=m.message_id WHERE favorites.like_id=1 " +
"AND NOT EXISTS (SELECT 1 FROM bl_users WHERE " +
"(user_id = favorites.user_id AND bl_user_id = m.user_id) " +
"OR (user_id = m.user_id AND bl_user_id = favorites.user_id))",
- String.class, mid);
+ (rs, rowNum) -> {
+ User user = new User();
+ user.setUid(rs.getInt(1));
+ user.setName(rs.getString(2));
+ user.setUri(URI.create(rs.getString(3)));
+ return user;
+ }, mid);
}
@Transactional(readOnly = true)
@@ -577,29 +596,25 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ
.addValue("before", before);
List<Integer> mids = getNamedParameterJdbcTemplate().queryForList(
- "(SELECT message_id FROM messages " +
- " INNER JOIN subscr_users ON (subscr_users.suser_id = :uid AND subscr_users.user_id = messages.user_id) " +
- " WHERE " +
- (before > 0 ?
- " message_id < :before AND " : StringUtils.EMPTY) +
- " (privacy >= 0 OR (privacy >= -2 AND privacy <= -1" +
- " AND EXISTS (SELECT 1 FROM wl_users w WHERE w.wl_user_id = :uid and w.user_id = messages.user_id))) " +
- " AND NOT EXISTS (SELECT 1 FROM bl_tags bt WHERE bt.tag_id IN " +
- "(SELECT tag_id FROM messages_tags WHERE message_id = messages.message_id) and :uid = bt.user_id))" +
- " UNION " +
- " (SELECT message_id FROM messages WHERE user_id=:uid " +
- (before > 0 ?
- " AND message_id < :before " : StringUtils.EMPTY) +
+ "SELECT message_id FROM messages WHERE " +
+ "(user_id=:uid OR " +
+ "(EXISTS (SELECT 1 FROM subscr_users WHERE subscr_users.suser_id = :uid " +
+ "AND subscr_users.user_id = messages.user_id) " +
+ "AND NOT EXISTS (SELECT 1 FROM bl_tags bt WHERE bt.tag_id IN " +
+ "(SELECT tag_id FROM messages_tags WHERE message_id = messages.message_id) AND :uid = bt.user_id) " +
+ "AND (privacy >= 0 OR (privacy >= -2 AND privacy <= -1 " +
+ "AND EXISTS (SELECT 1 FROM wl_users w WHERE w.wl_user_id = :uid and w.user_id = messages.user_id)))) " +
(recommended ?
- ") UNION " +
- " (SELECT f.message_id as message_id FROM favorites f INNER JOIN messages ON " +
- "f.message_id=messages.message_id WHERE " +
- "EXISTS (SELECT 1 FROM subscr_users s WHERE s.suser_id = :uid and f.user_id = s.user_id)" +
- (before > 0 ?
- " AND f.message_id < :before " : StringUtils.EMPTY) : StringUtils.EMPTY) +
- " AND NOT EXISTS (SELECT 1 FROM bl_users b WHERE b.user_id = :uid and b.bl_user_id = messages.user_id)" +
- " AND NOT EXISTS (SELECT 1 FROM bl_tags bt WHERE bt.tag_id IN " +
- "(SELECT tag_id FROM messages_tags WHERE message_id = messages.message_id) and :uid = bt.user_id)) " +
+ "OR (EXISTS (SELECT 1 FROM favorites WHERE favorites.message_id=messages.message_id " +
+ "AND favorites.user_id IN (SELECT user_id FROM subscr_users WHERE suser_id=:uid)) " +
+ "AND NOT EXISTS (SELECT 1 FROM bl_tags bt WHERE bt.tag_id IN (SELECT tag_id FROM messages_tags " +
+ "WHERE message_id = messages.message_id) and :uid = bt.user_id) " +
+ "AND (privacy >= 0 OR (privacy >= -2 AND privacy <= -1 " +
+ "AND EXISTS (SELECT 1 FROM wl_users w " +
+ "WHERE w.wl_user_id = :uid and w.user_id = messages.user_id)))) " +
+ "AND NOT EXISTS (SELECT 1 FROM bl_users b WHERE b.user_id = :uid and b.bl_user_id = messages.user_id)" : StringUtils.EMPTY) +
+ ") " +
+ (before > 0 ? "AND message_id < :before " : StringUtils.EMPTY) +
"ORDER BY message_id DESC LIMIT 20",
sqlParameterSource,
Integer.class);
@@ -871,7 +886,7 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ
+ "messages.ts,"
+ "messages.readonly,messages.privacy, messages.replies-COUNT(DISTINCT banned.reply_id) as replies,"
+ "messages.attach,COUNT(DISTINCT favorites.user_id) AS likes,messages.hidden,"
- + "messages_txt.tags,messages_txt.repliesby, messages_txt.txt, '' as q, "
+ + "GROUP_CONCAT(tags.name SEPARATOR ' '), messages_txt.repliesby, messages_txt.txt, '' as q, "
+ "messages.updated, 0 as to_uid, NULL as to_name, messages_txt.updated_at, '' as m_user_uri, "
+ "'' as to_uri, '' as msg_reply_uri, 0 as html "
+ "FROM (messages INNER JOIN messages_txt "
@@ -881,9 +896,11 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ
+ "ON messages.message_id = favorites.message_id AND favorites.like_id=1 "
+ "LEFT JOIN banned "
+ "ON messages.message_id = banned.message_id "
+ + "LEFT JOIN messages_tags ON messages_tags.message_id=messages_txt.message_id "
+ + "LEFT JOIN tags ON tags.tag_id=messages_tags.tag_id "
+ "WHERE messages.message_id IN (:ids) GROUP BY "
+ "messages.message_id, rid, replyto, messages.user_id, users.nick, usr_banned, messages.ts, "
- + "messages.readonly, messages.privacy, messages.attach, messages.hidden, messages_txt.tags, "
+ + "messages.readonly, messages.privacy, messages.attach, messages.hidden, "
+ "messages_txt.repliesby, messages_txt.txt, q, messages.updated, to_uid, to_name, updated_at, "
+ "m_user_uri, msg_reply_uri, html",
new MapSqlParameterSource("ids", mids)
@@ -971,7 +988,7 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ
"ORDER BY replies.reply_id ASC",
new MapSqlParameterSource("mid", mid).addValue("uid", user.getUid()),
new MessageMapper());
- if (replies.size() > 0) {
+ if (replies.size() > 0 && !user.isAnonymous()) {
setRead(user, mid);
}
replies.forEach(i -> i.setEntities(MessageUtils.getEntities(i)));
@@ -1143,7 +1160,7 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ
@Override
public boolean updateReplyUri(Message reply, URI replyUri) {
- return jdbcTemplate.update("UPDATE replies SET reply_uri=?, html=1 WHERE message_id=? AND reply_id=?",
+ return jdbcTemplate.update("UPDATE replies SET reply_uri=?, html=0 WHERE message_id=? AND reply_id=?",
replyUri.toASCIIString(), reply.getMid(), reply.getRid()) > 0;
}
diff --git a/src/main/java/com/juick/service/PMQueriesServiceImpl.java b/src/main/java/com/juick/service/PMQueriesServiceImpl.java
index 712e4b0e..f1f98024 100644
--- a/src/main/java/com/juick/service/PMQueriesServiceImpl.java
+++ b/src/main/java/com/juick/service/PMQueriesServiceImpl.java
@@ -105,7 +105,7 @@ public class PMQueriesServiceImpl extends BaseJdbcService implements PMQueriesSe
user.setName(rs.getString(4));
msg.setUser(user);
msg.setText(rs.getString(2).trim());
- msg.setTimestamp(rs.getTimestamp(3).toInstant());
+ msg.setCreated(rs.getTimestamp(3).toInstant());
return msg;
});
}
@@ -122,7 +122,7 @@ public class PMQueriesServiceImpl extends BaseJdbcService implements PMQueriesSe
msg.getUser().setUid(rs.getInt(1));
msg.getUser().setName(rs.getString(2));
msg.setText(rs.getString(3).trim());
- msg.setTimestamp(rs.getTimestamp(4).toInstant());
+ msg.setCreated(rs.getTimestamp(4).toInstant());
return msg;
},
uid);
@@ -141,7 +141,7 @@ public class PMQueriesServiceImpl extends BaseJdbcService implements PMQueriesSe
msg.getUser().setUid(rs.getInt(1));
msg.getUser().setName(rs.getString(2));
msg.setText(rs.getString(3).trim());
- msg.setTimestamp(rs.getTimestamp(4).toInstant());
+ msg.setCreated(rs.getTimestamp(4).toInstant());
return msg;
},
uid);
diff --git a/src/main/java/com/juick/service/TagServiceImpl.java b/src/main/java/com/juick/service/TagServiceImpl.java
index 42159d3b..95a1a309 100644
--- a/src/main/java/com/juick/service/TagServiceImpl.java
+++ b/src/main/java/com/juick/service/TagServiceImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2017, Juick
+ * Copyright (C) 2008-2019, 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
@@ -20,10 +20,10 @@ package com.juick.service;
import com.juick.Tag;
import com.juick.User;
import com.juick.model.TagStats;
-import com.juick.util.StreamUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
+import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.support.GeneratedKeyHolder;
@@ -31,6 +31,7 @@ import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
+import javax.annotation.Nonnull;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@@ -199,21 +200,28 @@ public class TagServiceImpl extends BaseJdbcService implements TagService {
"DELETE FROM messages_tags WHERE message_id = :mid AND tag_id in (:ids)",
new MapSqlParameterSource().addValue("ids", idsForDelete).addValue("mid", mid));
- newTags.stream().filter(t -> !currentTags.contains(t))
- .forEach(t -> getJdbcTemplate().update("INSERT INTO messages_tags(message_id,tag_id) VALUES (?,?)", mid, t.TID));
-
- List<Tag> result = getMessageTags(mid).stream()
+ List<Tag> addedTags = newTags.stream().filter(t -> !currentTags.contains(t)).collect(Collectors.toList());
+ getJdbcTemplate().batchUpdate("INSERT INTO messages_tags(message_id,tag_id) VALUES (?,?)", new BatchPreparedStatementSetter() {
+ @Override
+ public void setValues(@Nonnull PreparedStatement ps, int i) throws SQLException {
+ ps.setInt(1, mid);
+ ps.setInt(2, addedTags.get(i).TID);
+ }
+ @Override
+ public int getBatchSize() {
+ return addedTags.size();
+ }
+ });
+
+ return getMessageTags(mid).stream()
.map(TagStats::getTag).collect(Collectors.toList());
- jdbcTemplate.update("UPDATE messages_txt SET tags=? WHERE message_id=?", result.stream()
- .map(Tag::getName).collect(Collectors.joining(" ")), mid);
- return result;
}
@Override
public Pair<String, List<Tag>> fromString(final String txt) {
String firstLine = txt.split("\\n", 2)[0];
- Supplier<Stream<String>> tagsStream = () -> StreamUtils.takeWhile(Arrays.stream(firstLine.split("\\ ")),
- t -> !t.equals("*") && t.startsWith("*"));
+ Supplier<Stream<String>> tagsStream = () -> Arrays.stream(firstLine.split("\\ "))
+ .takeWhile(t -> !t.equals("*") && t.startsWith("*"));
int tagsLength = tagsStream.get().collect(Collectors.joining(" ")).length();
String body = txt.substring(tagsLength);
List<Tag> tags = tagsStream.get().map(t -> getTag(t.substring(1), true))
diff --git a/src/main/java/com/juick/service/UserService.java b/src/main/java/com/juick/service/UserService.java
index 832f978a..3a51dffb 100644
--- a/src/main/java/com/juick/service/UserService.java
+++ b/src/main/java/com/juick/service/UserService.java
@@ -20,7 +20,6 @@ package com.juick.service;
import com.juick.Message;
import com.juick.User;
import com.juick.model.Auth;
-import com.juick.model.UserInfo;
import javax.annotation.Nonnull;
import java.time.Instant;
@@ -75,9 +74,9 @@ public interface UserService {
int setUserOptionInt(int uid, String option, int value);
- UserInfo getUserInfo(User user);
+ User getUserInfo(User user);
- boolean updateUserInfo(User user, UserInfo info);
+ boolean updateUserInfo(User info);
boolean getCanMedia(int uid);
diff --git a/src/main/java/com/juick/service/UserServiceImpl.java b/src/main/java/com/juick/service/UserServiceImpl.java
index 93904139..bcfb8dac 100644
--- a/src/main/java/com/juick/service/UserServiceImpl.java
+++ b/src/main/java/com/juick/service/UserServiceImpl.java
@@ -21,7 +21,6 @@ import com.juick.Message;
import com.juick.User;
import com.juick.model.AnonymousUser;
import com.juick.model.Auth;
-import com.juick.model.UserInfo;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
@@ -121,7 +120,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService {
return -1;
}
- int uid = holder.getKey().intValue();
+ int uid = holder.getKeys().size() > 1 ? (int)holder.getKeys().get("id") : holder.getKey().intValue();
getJdbcTemplate().update("INSERT INTO useroptions(user_id) VALUES (?)", uid);
getJdbcTemplate().update("INSERT INTO subscr_users(user_id, suser_id) VALUES (2, ?)", uid);
@@ -133,7 +132,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService {
@Override
public Optional<User> getUserByUID(final int uid) {
List<User> list = getJdbcTemplate().query(
- "SELECT u.id, u.nick, u.passw, u.banned, u.last_seen, " +
+ "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 " +
@@ -148,7 +147,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService {
public User getUserByName(final String username) {
if (StringUtils.isNotBlank(username)) {
List<User> list = getJdbcTemplate().query(
- "SELECT u.id, u.nick, u.passw, u.banned, u.last_seen, " +
+ "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 " +
@@ -167,7 +166,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService {
public User getUserByEmail(String email) {
if (StringUtils.isNotBlank(email)) {
List<User> list = getJdbcTemplate().query(
- "SELECT u.id, u.nick, u.passw, u.banned, u.last_seen, " +
+ "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 " +
@@ -189,7 +188,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService {
if (StringUtils.isNotBlank(jid)) {
List<User> list = getJdbcTemplate().query(
- "SELECT u.id, u.nick, u.passw, u.banned, u.last_seen," +
+ "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 " +
@@ -211,7 +210,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService {
return Collections.emptyList();
return getNamedParameterJdbcTemplate().query(
- "SELECT u.id, u.nick, u.passw, u.banned, u.last_seen," +
+ "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 " +
@@ -228,7 +227,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService {
return Collections.emptyList();
return getNamedParameterJdbcTemplate().query(
- "SELECT u.id, u.nick, u.passw, u.banned, u.last_seen," +
+ "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 " +
@@ -288,7 +287,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService {
public com.juick.User getUserByHash(final String hash) {
if (StringUtils.isNotBlank(hash)) {
List<User> list = getJdbcTemplate().query(
- "SELECT logins.user_id, u.nick, u.passw, u.banned, u.last_seen," +
+ "SELECT DISTINCT logins.user_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 logins INNER JOIN users u ON logins.user_id = u.id " +
"LEFT JOIN facebook f ON f.user_id = u.id " +
@@ -326,7 +325,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService {
public int checkPassword(final String username, final String password) {
if (StringUtils.isNotBlank(username)) {
List<User> list = getJdbcTemplate().query(
- "SELECT u.id, u.nick, u.passw, u.banned, u.last_seen," +
+ "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 " +
@@ -375,29 +374,31 @@ public class UserServiceImpl extends BaseJdbcService implements UserService {
@Transactional(readOnly = true)
@Override
- public UserInfo getUserInfo(final User user) {
- List<UserInfo> list = getJdbcTemplate().query(
- "SELECT fullname, country, url, descr FROM usersinfo WHERE user_id = ?",
- ((rs, rowNum) -> {
- UserInfo info = new UserInfo();
- info.setFullName(rs.getString(1));
- info.setCountry(rs.getString(2));
- info.setUrl(rs.getString(3));
- info.setDescription(rs.getString(4));
- return info;
- }),
- user.getUid());
-
- return list.isEmpty() ? new UserInfo() : list.get(0);
+ public User getUserInfo(final User user) {
+ try {
+ getJdbcTemplate().queryForObject(
+ "SELECT fullname, country, url, descr FROM usersinfo WHERE user_id = ?",
+ ((rs, rowNum) -> {
+ user.setFullName(rs.getString(1));
+ user.setCountry(rs.getString(2));
+ user.setUrl(rs.getString(3));
+ user.setDescription(rs.getString(4));
+ return user;
+ }),
+ user.getUid());
+ } catch (EmptyResultDataAccessException e) {
+ return user;
+ }
+ return user;
}
@Transactional
@Override
- public boolean updateUserInfo(final User user, final UserInfo info) {
+ public boolean updateUserInfo(final User info) {
try {
return getJdbcTemplate().update(
"INSERT INTO usersinfo(user_id, fullname, country, url, descr) VALUES (?, ?, ?, ?, ?)",
- user.getUid(),
+ info.getUid(),
info.getFullName(),
info.getCountry(),
info.getUrl(),
@@ -408,7 +409,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService {
info.getCountry(),
info.getUrl(),
info.getDescription(),
- user.getUid()) > 0;
+ info.getUid()) > 0;
}
}
diff --git a/src/main/java/com/juick/service/security/HTTPSignatureAuthenticationFilter.java b/src/main/java/com/juick/service/security/HTTPSignatureAuthenticationFilter.java
new file mode 100644
index 00000000..44d97207
--- /dev/null
+++ b/src/main/java/com/juick/service/security/HTTPSignatureAuthenticationFilter.java
@@ -0,0 +1,71 @@
+package com.juick.service.security;
+
+import com.juick.User;
+import com.juick.server.SignatureManager;
+import com.juick.service.UserService;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.security.authentication.AnonymousAuthenticationToken;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import javax.annotation.Nonnull;
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public class HTTPSignatureAuthenticationFilter extends OncePerRequestFilter {
+
+ private final SignatureManager signatureManager;
+ private final UserService userService;
+
+
+ public HTTPSignatureAuthenticationFilter(
+ final SignatureManager signatureManager,
+ final UserService userService) {
+ this.signatureManager = signatureManager;
+ this.userService = userService;
+ }
+ @Override
+ protected void doFilterInternal(@Nonnull HttpServletRequest request, @Nonnull HttpServletResponse response, @Nonnull FilterChain filterChain) throws IOException, ServletException {
+ if (authenticationIsRequired()) {
+ Map<String, String> headers = Collections.list(request.getHeaderNames())
+ .stream()
+ .collect(Collectors.toMap(String::toLowerCase, request::getHeader));
+ if (StringUtils.isNotEmpty(headers.get("signature"))) {
+ User user = signatureManager.verifySignature(request.getMethod(), request.getRequestURI(), headers);
+ String userUri = user.getUri().toString();
+ if (!user.isAnonymous() || userUri.length() > 0) {
+ if (userUri.length() == 0) {
+ User userWithPassword = userService.getUserByName(user.getName());
+ userWithPassword.setAuthHash(userService.getHashByUID(userWithPassword.getUid()));
+ Authentication authentication = new UsernamePasswordAuthenticationToken(userWithPassword.getName(), userWithPassword.getCredentials());
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+ } else {
+ Authentication authentication = new AnonymousAuthenticationToken(userUri, user, Collections.singletonList(new SimpleGrantedAuthority("ROLE_ANONYMOUS")));
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+ }
+ }
+ }
+ }
+
+ filterChain.doFilter(request, response);
+ }
+
+ private boolean authenticationIsRequired() {
+ Authentication existingAuth = SecurityContextHolder.getContext().getAuthentication();
+
+ return existingAuth == null ||
+ !existingAuth.isAuthenticated() ||
+ existingAuth instanceof AnonymousAuthenticationToken;
+ }
+}
diff --git a/src/main/java/com/juick/service/security/HashParamAuthenticationFilter.java b/src/main/java/com/juick/service/security/HashParamAuthenticationFilter.java
index 9215d09a..2fd5a2a7 100644
--- a/src/main/java/com/juick/service/security/HashParamAuthenticationFilter.java
+++ b/src/main/java/com/juick/service/security/HashParamAuthenticationFilter.java
@@ -30,6 +30,7 @@ import org.springframework.util.Assert;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.WebUtils;
+import javax.annotation.Nonnull;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
@@ -59,9 +60,9 @@ public class HashParamAuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(
- HttpServletRequest request,
- HttpServletResponse response,
- FilterChain filterChain) throws ServletException, IOException {
+ @Nonnull HttpServletRequest request,
+ @Nonnull HttpServletResponse response,
+ @Nonnull FilterChain filterChain) throws ServletException, IOException {
String hash = getHashFromRequest(request);