ProxyService.java
package jasper.service;
import io.micrometer.core.annotation.Timed;
import jasper.component.FileCache;
import jasper.component.Proxy;
import jasper.errors.NotAvailableException;
import jasper.errors.NotFoundException;
import jasper.plugin.Cache;
import jasper.repository.RefRepository;
import jasper.security.Auth;
import jasper.service.dto.DtoMapper;
import jasper.service.dto.RefDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.io.InputStream;
import java.util.Optional;
import static jasper.plugin.Cache.getCache;
import static jasper.security.AuthoritiesConstants.USER;
@Service
public class ProxyService {
@Autowired
RefRepository refRepository;
@Autowired
Auth auth;
@Autowired
Optional<FileCache> fileCache;
@Autowired
Proxy proxy;
@Autowired
DtoMapper mapper;
@PreAuthorize("@auth.hasRole('USER') && @auth.subOrigin(#origin)")
@Timed(value = "jasper.service", extraTags = {"service", "proxy"}, histogram = true)
public void preFetch(String url, String origin, boolean thumbnail) {
if (fileCache.isEmpty()) throw new NotAvailableException();
fileCache.get().preFetch(url, origin, thumbnail);
}
@PreAuthorize("@auth.subOrigin(#origin)")
@Timed(value = "jasper.service", extraTags = {"service", "proxy"}, histogram = true)
public InputStream fetchIfExists(String url, String origin) {
if (fileCache.isEmpty()) throw new NotAvailableException();
if (!refRepository.existsByUrlAndOrigin(url, origin)) throw new NotFoundException("Cache not found");
return fileCache.get().fetch(url, origin);
}
@PreAuthorize("@auth.subOrigin(#origin)")
@Timed(value = "jasper.service", extraTags = {"service", "proxy"}, histogram = true)
public RefDto stat(String url, String origin, boolean thumbnail) {
// Only require role for new scrapes
if (!url.startsWith("cache:") && !auth.hasRole(USER) && !refRepository.existsByUrlAndOrigin(url, origin)) throw new AccessDeniedException("Requires USER role to scrape.");
return mapper.domainToDto(thumbnail
? proxy.statThumbnail(url, origin)
: proxy.stat(url, origin));
}
@PreAuthorize("@auth.subOrigin(#origin)")
@Timed(value = "jasper.service", extraTags = {"service", "proxy"}, histogram = true)
public Cache cache(String url, String origin, boolean thumbnail) {
return getCache(thumbnail
? proxy.statThumbnail(url, origin)
: proxy.stat(url, origin));
}
@PreAuthorize("@auth.subOrigin(#origin)")
@Timed(value = "jasper.service", extraTags = {"service", "proxy"}, histogram = true)
public InputStream fetch(String url, String origin, boolean thumbnail) {
// Only require role for new scrapes
if (!url.startsWith("cache:") && !auth.minFetchRole() && !refRepository.existsByUrlAndOrigin(url, origin)) {
throw new AccessDeniedException("Not found and not allowed to scrape.");
}
return thumbnail
? proxy.fetchThumbnail(url, origin)
: proxy.fetch(url, origin);
}
@PreAuthorize("@auth.hasRole('USER') && @auth.subOrigin(#origin)")
@Timed(value = "jasper.service", extraTags = {"service", "proxy"}, histogram = true)
public RefDto save(String origin, String title, InputStream in, String mime) throws IOException {
if (fileCache.isEmpty()) throw new NotAvailableException();
return mapper.domainToDto(fileCache.get().save(origin, title, in, mime, "plugin/file", auth.getUserTag() == null ? null : auth.getUserTag().tag));
}
@PreAuthorize("@auth.hasRole('MOD') && @auth.subOrigin(#origin)")
@Timed(value = "jasper.service", extraTags = {"service", "proxy"}, histogram = true)
public void push(String url, String origin, InputStream in) throws IOException {
if (fileCache.isEmpty()) throw new NotAvailableException();
fileCache.get().push(url, origin, in);
}
@PreAuthorize("@auth.hasRole('MOD') && @auth.subOrigin(#origin)")
@Timed(value = "jasper.service", extraTags = {"service", "proxy"}, histogram = true)
public void clearDeleted(String origin) {
if (fileCache.isEmpty()) throw new NotAvailableException();
fileCache.get().clearDeleted(origin);
}
}