forked from Archives/Athou_commafeed
@@ -15,14 +15,12 @@ public class CommaFeedVersion {
|
|||||||
private final String version;
|
private final String version;
|
||||||
private final String gitCommit;
|
private final String gitCommit;
|
||||||
|
|
||||||
public CommaFeedVersion() {
|
public CommaFeedVersion() throws IOException {
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
try (InputStream stream = getClass().getResourceAsStream("/git.properties")) {
|
try (InputStream stream = getClass().getResourceAsStream("/git.properties")) {
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
properties.load(stream);
|
properties.load(stream);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.version = properties.getProperty("git.build.version", "unknown");
|
this.version = properties.getProperty("git.build.version", "unknown");
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import java.util.stream.Stream;
|
|||||||
import jakarta.inject.Singleton;
|
import jakarta.inject.Singleton;
|
||||||
import jakarta.ws.rs.core.CacheControl;
|
import jakarta.ws.rs.core.CacheControl;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.hc.client5.http.DnsResolver;
|
import org.apache.hc.client5.http.DnsResolver;
|
||||||
import org.apache.hc.client5.http.SystemDefaultDnsResolver;
|
import org.apache.hc.client5.http.SystemDefaultDnsResolver;
|
||||||
@@ -55,6 +56,7 @@ import com.google.common.net.HttpHeaders;
|
|||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.Lombok;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -67,12 +69,12 @@ import nl.altindag.ssl.apache5.util.Apache5SslUtils;
|
|||||||
@Singleton
|
@Singleton
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class HttpGetter {
|
public class HttpGetter {
|
||||||
|
private static final DnsResolver DNS_RESOLVER = SystemDefaultDnsResolver.INSTANCE;
|
||||||
|
|
||||||
private final CommaFeedConfiguration config;
|
private final CommaFeedConfiguration config;
|
||||||
private final InstantSource instantSource;
|
private final InstantSource instantSource;
|
||||||
private final CloseableHttpClient client;
|
private final CloseableHttpClient client;
|
||||||
private final Cache<HttpRequest, HttpResponse> cache;
|
private final Cache<HttpRequest, HttpResponse> cache;
|
||||||
private final DnsResolver dnsResolver = SystemDefaultDnsResolver.INSTANCE;
|
|
||||||
|
|
||||||
public HttpGetter(CommaFeedConfiguration config, InstantSource instantSource, CommaFeedVersion version, MetricRegistry metrics) {
|
public HttpGetter(CommaFeedConfiguration config, InstantSource instantSource, CommaFeedVersion version, MetricRegistry metrics) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
@@ -93,7 +95,7 @@ public class HttpGetter {
|
|||||||
metrics.registerGauge(MetricRegistry.name(getClass(), "pool", "pending"), () -> connectionManager.getTotalStats().getPending());
|
metrics.registerGauge(MetricRegistry.name(getClass(), "pool", "pending"), () -> connectionManager.getTotalStats().getPending());
|
||||||
metrics.registerGauge(MetricRegistry.name(getClass(), "cache", "size"), () -> cache == null ? 0 : cache.size());
|
metrics.registerGauge(MetricRegistry.name(getClass(), "cache", "size"), () -> cache == null ? 0 : cache.size());
|
||||||
metrics.registerGauge(MetricRegistry.name(getClass(), "cache", "memoryUsage"),
|
metrics.registerGauge(MetricRegistry.name(getClass(), "cache", "memoryUsage"),
|
||||||
() -> cache == null ? 0 : cache.asMap().values().stream().mapToInt(e -> e.content != null ? e.content.length : 0).sum());
|
() -> cache == null ? 0 : cache.asMap().values().stream().mapToInt(e -> ArrayUtils.getLength(e.content)).sum());
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpResult get(String url)
|
public HttpResult get(String url)
|
||||||
@@ -120,7 +122,7 @@ public class HttpGetter {
|
|||||||
if (e.getCause() instanceof IOException ioe) {
|
if (e.getCause() instanceof IOException ioe) {
|
||||||
throw ioe;
|
throw ioe;
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException(e);
|
throw Lombok.sneakyThrow(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,7 +163,7 @@ public class HttpGetter {
|
|||||||
throw new HostNotAllowedException(null);
|
throw new HostNotAllowedException(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
InetAddress[] addresses = dnsResolver.resolve(host);
|
InetAddress[] addresses = DNS_RESOLVER.resolve(host);
|
||||||
if (Stream.of(addresses).anyMatch(this::isPrivateAddress)) {
|
if (Stream.of(addresses).anyMatch(this::isPrivateAddress)) {
|
||||||
throw new HostNotAllowedException(host);
|
throw new HostNotAllowedException(host);
|
||||||
}
|
}
|
||||||
@@ -274,7 +276,7 @@ public class HttpGetter {
|
|||||||
.setDefaultTlsConfig(TlsConfig.custom().setHandshakeTimeout(Timeout.of(config.httpClient().sslHandshakeTimeout())).build())
|
.setDefaultTlsConfig(TlsConfig.custom().setHandshakeTimeout(Timeout.of(config.httpClient().sslHandshakeTimeout())).build())
|
||||||
.setMaxConnPerRoute(poolSize)
|
.setMaxConnPerRoute(poolSize)
|
||||||
.setMaxConnTotal(poolSize)
|
.setMaxConnTotal(poolSize)
|
||||||
.setDnsResolver(dnsResolver)
|
.setDnsResolver(DNS_RESOLVER)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ public class YoutubeFaviconFetcher extends AbstractFaviconFetcher {
|
|||||||
|
|
||||||
JsonNode channelId = objectMapper.readTree(playlistBytes).at(PLAYLIST_CHANNEL_ID);
|
JsonNode channelId = objectMapper.readTree(playlistBytes).at(PLAYLIST_CHANNEL_ID);
|
||||||
if (channelId.isMissingNode()) {
|
if (channelId.isMissingNode()) {
|
||||||
return null;
|
return new byte[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
return fetchForChannel(googleAuthKey, channelId.asText());
|
return fetchForChannel(googleAuthKey, channelId.asText());
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ public class FeedRefreshUpdater {
|
|||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
log.error("interrupted while waiting for lock for {} : {}", feed.getUrl(), e.getMessage(), e);
|
log.error("interrupted while waiting for lock for {} : {}", feed.getUrl(), e.getMessage(), e);
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
} finally {
|
} finally {
|
||||||
if (locked1) {
|
if (locked1) {
|
||||||
lock1.unlock();
|
lock1.unlock();
|
||||||
|
|||||||
@@ -20,12 +20,14 @@ import com.commafeed.backend.feed.parser.TextDirectionDetector;
|
|||||||
import com.commafeed.backend.model.FeedSubscription;
|
import com.commafeed.backend.model.FeedSubscription;
|
||||||
import com.commafeed.frontend.model.Entry;
|
import com.commafeed.frontend.model.Entry;
|
||||||
|
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility methods related to feed handling
|
* Utility methods related to feed handling
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@UtilityClass
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class FeedUtils {
|
public class FeedUtils {
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import java.util.stream.Collectors;
|
|||||||
import jakarta.inject.Singleton;
|
import jakarta.inject.Singleton;
|
||||||
|
|
||||||
import com.commafeed.CommaFeedConfiguration;
|
import com.commafeed.CommaFeedConfiguration;
|
||||||
import com.commafeed.backend.dao.FeedDAO;
|
|
||||||
import com.commafeed.backend.dao.FeedEntryStatusDAO;
|
import com.commafeed.backend.dao.FeedEntryStatusDAO;
|
||||||
import com.commafeed.backend.dao.FeedSubscriptionDAO;
|
import com.commafeed.backend.dao.FeedSubscriptionDAO;
|
||||||
import com.commafeed.backend.feed.FeedRefreshEngine;
|
import com.commafeed.backend.feed.FeedRefreshEngine;
|
||||||
@@ -25,16 +24,14 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
@Singleton
|
@Singleton
|
||||||
public class FeedSubscriptionService {
|
public class FeedSubscriptionService {
|
||||||
|
|
||||||
private final FeedDAO feedDAO;
|
|
||||||
private final FeedEntryStatusDAO feedEntryStatusDAO;
|
private final FeedEntryStatusDAO feedEntryStatusDAO;
|
||||||
private final FeedSubscriptionDAO feedSubscriptionDAO;
|
private final FeedSubscriptionDAO feedSubscriptionDAO;
|
||||||
private final FeedService feedService;
|
private final FeedService feedService;
|
||||||
private final FeedRefreshEngine feedRefreshEngine;
|
private final FeedRefreshEngine feedRefreshEngine;
|
||||||
private final CommaFeedConfiguration config;
|
private final CommaFeedConfiguration config;
|
||||||
|
|
||||||
public FeedSubscriptionService(FeedDAO feedDAO, FeedEntryStatusDAO feedEntryStatusDAO, FeedSubscriptionDAO feedSubscriptionDAO,
|
public FeedSubscriptionService(FeedEntryStatusDAO feedEntryStatusDAO, FeedSubscriptionDAO feedSubscriptionDAO, FeedService feedService,
|
||||||
FeedService feedService, FeedRefreshEngine feedRefreshEngine, CommaFeedConfiguration config) {
|
FeedRefreshEngine feedRefreshEngine, CommaFeedConfiguration config) {
|
||||||
this.feedDAO = feedDAO;
|
|
||||||
this.feedEntryStatusDAO = feedEntryStatusDAO;
|
this.feedEntryStatusDAO = feedEntryStatusDAO;
|
||||||
this.feedSubscriptionDAO = feedSubscriptionDAO;
|
this.feedSubscriptionDAO = feedSubscriptionDAO;
|
||||||
this.feedService = feedService;
|
this.feedService = feedService;
|
||||||
|
|||||||
@@ -147,18 +147,17 @@ public class AdminREST {
|
|||||||
Map<Long, UserModel> users = new HashMap<>();
|
Map<Long, UserModel> users = new HashMap<>();
|
||||||
for (UserRole role : userRoleDAO.findAll()) {
|
for (UserRole role : userRoleDAO.findAll()) {
|
||||||
User u = role.getUser();
|
User u = role.getUser();
|
||||||
Long key = u.getId();
|
UserModel userModel = users.computeIfAbsent(u.getId(), k -> {
|
||||||
UserModel userModel = users.get(key);
|
UserModel um = new UserModel();
|
||||||
if (userModel == null) {
|
um.setId(u.getId());
|
||||||
userModel = new UserModel();
|
um.setName(u.getName());
|
||||||
userModel.setId(u.getId());
|
um.setEmail(u.getEmail());
|
||||||
userModel.setName(u.getName());
|
um.setEnabled(!u.isDisabled());
|
||||||
userModel.setEmail(u.getEmail());
|
um.setCreated(u.getCreated());
|
||||||
userModel.setEnabled(!u.isDisabled());
|
um.setLastLogin(u.getLastLogin());
|
||||||
userModel.setCreated(u.getCreated());
|
return um;
|
||||||
userModel.setLastLogin(u.getLastLogin());
|
});
|
||||||
users.put(key, userModel);
|
|
||||||
}
|
|
||||||
if (role.getRole() == Role.ADMIN) {
|
if (role.getRole() == Role.ADMIN) {
|
||||||
userModel.setAdmin(true);
|
userModel.setAdmin(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public class WebSocketEndpoint {
|
|||||||
private final WebSocketSessions sessions;
|
private final WebSocketSessions sessions;
|
||||||
|
|
||||||
@OnOpen
|
@OnOpen
|
||||||
public void onOpen(Session session) {
|
public void onOpen(Session session) throws IOException {
|
||||||
User user = authenticationContext.getCurrentUser();
|
User user = authenticationContext.getCurrentUser();
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
reject(session);
|
reject(session);
|
||||||
@@ -53,12 +53,8 @@ public class WebSocketEndpoint {
|
|||||||
sessions.remove(session);
|
sessions.remove(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reject(Session session) {
|
private void reject(Session session) throws IOException {
|
||||||
try {
|
session.close(new CloseReason(CloseCodes.VIOLATED_POLICY, "unauthorized"));
|
||||||
session.close(new CloseReason(CloseCodes.VIOLATED_POLICY, "unauthorized"));
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package com.commafeed.security;
|
package com.commafeed.security;
|
||||||
|
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
|
@UtilityClass
|
||||||
public class Roles {
|
public class Roles {
|
||||||
public static final String USER = "USER";
|
public static final String USER = "USER";
|
||||||
public static final String ADMIN = "ADMIN";
|
public static final String ADMIN = "ADMIN";
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import org.junit.jupiter.api.Test;
|
|||||||
class TextDirectionDetectorTest {
|
class TextDirectionDetectorTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEstimateDirection() {
|
void testEstimateDirection() {
|
||||||
Assertions.assertEquals(TextDirectionDetector.Direction.LEFT_TO_RIGHT, TextDirectionDetector.detect(""));
|
Assertions.assertEquals(TextDirectionDetector.Direction.LEFT_TO_RIGHT, TextDirectionDetector.detect(""));
|
||||||
Assertions.assertEquals(TextDirectionDetector.Direction.LEFT_TO_RIGHT, TextDirectionDetector.detect(" "));
|
Assertions.assertEquals(TextDirectionDetector.Direction.LEFT_TO_RIGHT, TextDirectionDetector.detect(" "));
|
||||||
Assertions.assertEquals(TextDirectionDetector.Direction.LEFT_TO_RIGHT, TextDirectionDetector.detect("! (...)"));
|
Assertions.assertEquals(TextDirectionDetector.Direction.LEFT_TO_RIGHT, TextDirectionDetector.detect("! (...)"));
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class OPMLExporterTest {
|
|||||||
private final List<FeedSubscription> subscriptions = new ArrayList<>();
|
private final List<FeedSubscription> subscriptions = new ArrayList<>();
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void init() {
|
void init() {
|
||||||
user.setName("John Doe");
|
user.setName("John Doe");
|
||||||
|
|
||||||
cat1.setId(1L);
|
cat1.setId(1L);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class FeedEntryFilteringServiceTest {
|
|||||||
private FeedEntry entry;
|
private FeedEntry entry;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void init() {
|
void init() {
|
||||||
config = Mockito.mock(CommaFeedConfiguration.class, Mockito.RETURNS_DEEP_STUBS);
|
config = Mockito.mock(CommaFeedConfiguration.class, Mockito.RETURNS_DEEP_STUBS);
|
||||||
Mockito.when(config.feedRefresh().filteringExpressionEvaluationTimeout()).thenReturn(Duration.ofSeconds(30));
|
Mockito.when(config.feedRefresh().filteringExpressionEvaluationTimeout()).thenReturn(Duration.ofSeconds(30));
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class UserServiceTest {
|
|||||||
private UserService userService;
|
private UserService userService;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void init() {
|
void init() {
|
||||||
userService = new UserService(feedCategoryDAO, feedSubscriptionDAO, userDAO, userRoleDAO, userSettingsDAO,
|
userService = new UserService(feedCategoryDAO, feedSubscriptionDAO, userDAO, userRoleDAO, userSettingsDAO,
|
||||||
passwordEncryptionService, commaFeedConfiguration, postLoginActivities);
|
passwordEncryptionService, commaFeedConfiguration, postLoginActivities);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user