mirror of
https://github.com/TeamPiped/Piped-Backend.git
synced 2024-08-14 23:51:41 +00:00
Merge pull request #412 from TeamPiped/status-code-errors
Implement status code error errors.
This commit is contained in:
commit
84fa3f5d64
22 changed files with 236 additions and 87 deletions
|
@ -19,8 +19,8 @@ import me.kavin.piped.server.handlers.auth.FeedHandlers;
|
|||
import me.kavin.piped.server.handlers.auth.UserHandlers;
|
||||
import me.kavin.piped.utils.*;
|
||||
import me.kavin.piped.utils.resp.DeleteUserRequest;
|
||||
import me.kavin.piped.utils.resp.ErrorResponse;
|
||||
import me.kavin.piped.utils.resp.LoginRequest;
|
||||
import me.kavin.piped.utils.resp.StackTraceResponse;
|
||||
import me.kavin.piped.utils.resp.SubscriptionUpdateRequest;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
|
@ -455,9 +455,13 @@ public class ServerLauncher extends MultithreadedHttpServerLauncher {
|
|||
|
||||
e = ExceptionHandler.handle(e, path);
|
||||
|
||||
if (e instanceof ErrorResponse error) {
|
||||
return getJsonResponse(error.getCode(), error.getContent(), "private");
|
||||
}
|
||||
|
||||
try {
|
||||
return getJsonResponse(500, Constants.mapper
|
||||
.writeValueAsBytes(new ErrorResponse(ExceptionUtils.getStackTrace(e), e.getMessage())), "private");
|
||||
.writeValueAsBytes(new StackTraceResponse(ExceptionUtils.getStackTrace(e), e.getMessage())), "private");
|
||||
} catch (JsonProcessingException ex) {
|
||||
return HttpResponse.ofCode(500);
|
||||
}
|
||||
|
|
|
@ -139,10 +139,13 @@ public class ChannelHandlers {
|
|||
throws IOException, ExtractionException {
|
||||
|
||||
if (StringUtils.isEmpty(prevpageStr))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("nextpage is a required parameter"));
|
||||
|
||||
Page prevpage = mapper.readValue(prevpageStr, Page.class);
|
||||
|
||||
if (prevpage == null)
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("nextpage is a required parameter"));
|
||||
|
||||
ListExtractor.InfoItemsPage<StreamInfoItem> info = ChannelInfo.getMoreItems(YOUTUBE_SERVICE,
|
||||
"https://youtube.com/channel/" + channelId, prevpage);
|
||||
|
||||
|
@ -164,7 +167,7 @@ public class ChannelHandlers {
|
|||
throws IOException, ExtractionException {
|
||||
|
||||
if (StringUtils.isEmpty(data))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("data is a required parameter"));
|
||||
|
||||
YouTubeChannelTabHandler tabHandler = mapper.readValue(data, YouTubeChannelTabHandlerMixin.class);
|
||||
|
||||
|
@ -184,12 +187,15 @@ public class ChannelHandlers {
|
|||
public static byte[] channelTabPageResponse(String data, String prevPageStr) throws Exception {
|
||||
|
||||
if (StringUtils.isEmpty(data))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("data is a required parameter"));
|
||||
|
||||
YouTubeChannelTabHandler tabHandler = mapper.readValue(data, YouTubeChannelTabHandlerMixin.class);
|
||||
|
||||
Page prevPage = mapper.readValue(prevPageStr, Page.class);
|
||||
|
||||
if (prevPage == null)
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("nextpage is a required parameter"));
|
||||
|
||||
var info = ChannelTabInfo.getMoreItems(YOUTUBE_SERVICE, tabHandler, prevPage);
|
||||
|
||||
String nextpage = null;
|
||||
|
|
|
@ -9,6 +9,7 @@ import com.rometools.rome.io.SyndFeedOutput;
|
|||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import me.kavin.piped.consts.Constants;
|
||||
import me.kavin.piped.server.handlers.auth.AuthPlaylistHandlers;
|
||||
import me.kavin.piped.utils.ExceptionHandler;
|
||||
import me.kavin.piped.utils.obj.ContentItem;
|
||||
import me.kavin.piped.utils.obj.Playlist;
|
||||
import me.kavin.piped.utils.obj.StreamsPage;
|
||||
|
@ -35,7 +36,7 @@ public class PlaylistHandlers {
|
|||
public static byte[] playlistResponse(String playlistId) throws ExtractionException, IOException {
|
||||
|
||||
if (StringUtils.isBlank(playlistId))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("playlistId is a required parameter"));
|
||||
|
||||
if (playlistId.matches("[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"))
|
||||
return AuthPlaylistHandlers.playlistPipedResponse(playlistId);
|
||||
|
@ -70,10 +71,13 @@ public class PlaylistHandlers {
|
|||
throws IOException, ExtractionException {
|
||||
|
||||
if (StringUtils.isEmpty(prevpageStr))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("nextpage is a required parameter"));
|
||||
|
||||
Page prevpage = mapper.readValue(prevpageStr, Page.class);
|
||||
|
||||
if (prevpage == null)
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("nextpage is a required parameter"));
|
||||
|
||||
ListExtractor.InfoItemsPage<StreamInfoItem> info = PlaylistInfo.getMoreItems(YOUTUBE_SERVICE,
|
||||
"https://www.youtube.com/playlist?list=" + playlistId, prevpage);
|
||||
|
||||
|
@ -94,7 +98,7 @@ public class PlaylistHandlers {
|
|||
public static byte[] playlistRSSResponse(String playlistId) throws ExtractionException, IOException, FeedException {
|
||||
|
||||
if (StringUtils.isBlank(playlistId))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("playlistId is a required parameter"));
|
||||
|
||||
if (playlistId.matches("[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"))
|
||||
return AuthPlaylistHandlers.playlistPipedRSSResponse(playlistId);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package me.kavin.piped.server.handlers;
|
||||
|
||||
import me.kavin.piped.utils.ExceptionHandler;
|
||||
import me.kavin.piped.utils.obj.ContentItem;
|
||||
import me.kavin.piped.utils.obj.SearchResults;
|
||||
import me.kavin.piped.utils.resp.InvalidRequestResponse;
|
||||
|
@ -24,7 +25,7 @@ public class SearchHandlers {
|
|||
throws IOException, ExtractionException {
|
||||
|
||||
if (StringUtils.isEmpty(query))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("query is a required parameter"));
|
||||
|
||||
return mapper.writeValueAsBytes(YOUTUBE_SERVICE.getSuggestionExtractor().suggestionList(query));
|
||||
|
||||
|
@ -34,7 +35,7 @@ public class SearchHandlers {
|
|||
throws IOException, ExtractionException {
|
||||
|
||||
if (StringUtils.isEmpty(query))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("query is a required parameter"));
|
||||
|
||||
return mapper.writeValueAsBytes(Arrays.asList(
|
||||
query,
|
||||
|
@ -62,10 +63,13 @@ public class SearchHandlers {
|
|||
throws IOException, ExtractionException {
|
||||
|
||||
if (StringUtils.isEmpty(prevpageStr))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("nextpage is a required parameter"));
|
||||
|
||||
Page prevpage = mapper.readValue(prevpageStr, Page.class);
|
||||
|
||||
if (prevpage == null)
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("nextpage is a required parameter"));
|
||||
|
||||
ListExtractor.InfoItemsPage<InfoItem> pages = SearchInfo.getMoreItems(YOUTUBE_SERVICE,
|
||||
YOUTUBE_SERVICE.getSearchQHFactory().fromQuery(q, Collections.singletonList(filter), null), prevpage);
|
||||
|
||||
|
|
|
@ -212,7 +212,7 @@ public class StreamHandlers {
|
|||
public static byte[] commentsPageResponse(String videoId, String prevpageStr) throws Exception {
|
||||
|
||||
if (StringUtils.isEmpty(prevpageStr))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("nextpage is a required parameter"));
|
||||
|
||||
Page prevpage = mapper.readValue(prevpageStr, Page.class);
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package me.kavin.piped.server.handlers;
|
||||
|
||||
import me.kavin.piped.utils.ExceptionHandler;
|
||||
import me.kavin.piped.utils.obj.ContentItem;
|
||||
import me.kavin.piped.utils.resp.InvalidRequestResponse;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
|
@ -20,8 +21,7 @@ public class TrendingHandlers {
|
|||
throws ExtractionException, IOException {
|
||||
|
||||
if (region == null)
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("region is a required parameter"));
|
||||
|
||||
KioskList kioskList = YOUTUBE_SERVICE.getKioskList();
|
||||
kioskList.forceContentCountry(new ContentCountry(region));
|
||||
|
|
|
@ -13,6 +13,7 @@ import jakarta.persistence.criteria.JoinType;
|
|||
import me.kavin.piped.consts.Constants;
|
||||
import me.kavin.piped.utils.DatabaseHelper;
|
||||
import me.kavin.piped.utils.DatabaseSessionFactory;
|
||||
import me.kavin.piped.utils.ExceptionHandler;
|
||||
import me.kavin.piped.utils.URLUtils;
|
||||
import me.kavin.piped.utils.obj.ContentItem;
|
||||
import me.kavin.piped.utils.obj.Playlist;
|
||||
|
@ -44,6 +45,10 @@ import static me.kavin.piped.utils.URLUtils.substringYouTube;
|
|||
|
||||
public class AuthPlaylistHandlers {
|
||||
public static byte[] playlistPipedResponse(String playlistId) throws IOException {
|
||||
|
||||
if (StringUtils.isBlank(playlistId))
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("playlistId is a required parameter"));
|
||||
|
||||
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
|
||||
var cb = s.getCriteriaBuilder();
|
||||
var cq = cb.createQuery(me.kavin.piped.utils.obj.db.Playlist.class);
|
||||
|
@ -81,6 +86,9 @@ public class AuthPlaylistHandlers {
|
|||
public static byte[] playlistPipedRSSResponse(String playlistId)
|
||||
throws FeedException {
|
||||
|
||||
if (StringUtils.isBlank(playlistId))
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("playlistId is required parameter"));
|
||||
|
||||
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
|
||||
var cb = s.getCriteriaBuilder();
|
||||
var cq = cb.createQuery(me.kavin.piped.utils.obj.db.Playlist.class);
|
||||
|
@ -121,12 +129,12 @@ public class AuthPlaylistHandlers {
|
|||
public static byte[] createPlaylist(String session, String name) throws IOException {
|
||||
|
||||
if (StringUtils.isBlank(session) || StringUtils.isBlank(name))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("session and name are required parameters"));
|
||||
|
||||
User user = DatabaseHelper.getUserFromSession(session);
|
||||
|
||||
if (user == null)
|
||||
return mapper.writeValueAsBytes(new AuthenticationFailureResponse());
|
||||
ExceptionHandler.throwErrorResponse(new AuthenticationFailureResponse());
|
||||
|
||||
try (Session s = DatabaseSessionFactory.createSession()) {
|
||||
var playlist = new me.kavin.piped.utils.obj.db.Playlist(name, user, "https://i.ytimg.com/");
|
||||
|
@ -145,12 +153,12 @@ public class AuthPlaylistHandlers {
|
|||
public static byte[] renamePlaylistResponse(String session, String playlistId, String newName) throws IOException {
|
||||
|
||||
if (StringUtils.isBlank(session) || StringUtils.isBlank(playlistId))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("session and playlistId are required parameters"));
|
||||
|
||||
User user = DatabaseHelper.getUserFromSession(session);
|
||||
|
||||
if (user == null)
|
||||
return mapper.writeValueAsBytes(new AuthenticationFailureResponse());
|
||||
ExceptionHandler.throwErrorResponse(new AuthenticationFailureResponse());
|
||||
|
||||
try (Session s = DatabaseSessionFactory.createSession()) {
|
||||
var playlist = DatabaseHelper.getPlaylistFromId(s, playlistId);
|
||||
|
@ -177,12 +185,12 @@ public class AuthPlaylistHandlers {
|
|||
public static byte[] deletePlaylistResponse(String session, String playlistId) throws IOException {
|
||||
|
||||
if (StringUtils.isBlank(session) || StringUtils.isBlank(playlistId))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("session and playlistId are required parameters"));
|
||||
|
||||
User user = DatabaseHelper.getUserFromSession(session);
|
||||
|
||||
if (user == null)
|
||||
return mapper.writeValueAsBytes(new AuthenticationFailureResponse());
|
||||
ExceptionHandler.throwErrorResponse(new AuthenticationFailureResponse());
|
||||
|
||||
try (Session s = DatabaseSessionFactory.createSession()) {
|
||||
var playlist = DatabaseHelper.getPlaylistFromId(s, playlistId);
|
||||
|
@ -207,12 +215,12 @@ public class AuthPlaylistHandlers {
|
|||
public static byte[] addToPlaylistResponse(String session, String playlistId, String videoId) throws IOException, ExtractionException {
|
||||
|
||||
if (StringUtils.isBlank(session) || StringUtils.isBlank(playlistId) || StringUtils.isBlank(videoId))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("session, playlistId and videoId are required parameters"));
|
||||
|
||||
var user = DatabaseHelper.getUserFromSession(session);
|
||||
|
||||
if (user == null)
|
||||
return mapper.writeValueAsBytes(new AuthenticationFailureResponse());
|
||||
ExceptionHandler.throwErrorResponse(new AuthenticationFailureResponse());
|
||||
|
||||
try (Session s = DatabaseSessionFactory.createSession()) {
|
||||
var cb = s.getCriteriaBuilder();
|
||||
|
@ -268,7 +276,7 @@ public class AuthPlaylistHandlers {
|
|||
public static byte[] removeFromPlaylistResponse(String session, String playlistId, int index) throws IOException {
|
||||
|
||||
if (StringUtils.isBlank(session) || StringUtils.isBlank(playlistId))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("session and playlistId are required parameters"));
|
||||
|
||||
try (Session s = DatabaseSessionFactory.createSession()) {
|
||||
var cb = s.getCriteriaBuilder();
|
||||
|
@ -304,12 +312,12 @@ public class AuthPlaylistHandlers {
|
|||
public static byte[] importPlaylistResponse(String session, String playlistId) throws IOException, ExtractionException {
|
||||
|
||||
if (StringUtils.isBlank(session) || StringUtils.isBlank(playlistId))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("session and playlistId are required parameters"));
|
||||
|
||||
var user = DatabaseHelper.getUserFromSession(session);
|
||||
|
||||
if (user == null)
|
||||
return mapper.writeValueAsBytes(new AuthenticationFailureResponse());
|
||||
ExceptionHandler.throwErrorResponse(new AuthenticationFailureResponse());
|
||||
|
||||
final String url = "https://www.youtube.com/playlist?list=" + playlistId;
|
||||
|
||||
|
@ -380,14 +388,14 @@ public class AuthPlaylistHandlers {
|
|||
public static byte[] playlistsResponse(String session) throws IOException {
|
||||
|
||||
if (StringUtils.isBlank(session))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("session is a required parameter"));
|
||||
|
||||
try (Session s = DatabaseSessionFactory.createSession()) {
|
||||
|
||||
User user = DatabaseHelper.getUserFromSession(session, s);
|
||||
|
||||
if (user == null)
|
||||
return mapper.writeValueAsBytes(new AuthenticationFailureResponse());
|
||||
ExceptionHandler.throwErrorResponse(new AuthenticationFailureResponse());
|
||||
|
||||
var playlists = new ObjectArrayList<>();
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ public class FeedHandlers {
|
|||
throws IOException {
|
||||
|
||||
if (StringUtils.isBlank(session) || StringUtils.isBlank(channelId))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("session and channelId are required parameters"));
|
||||
|
||||
try (Session s = DatabaseSessionFactory.createSession()) {
|
||||
|
||||
|
@ -66,7 +66,8 @@ public class FeedHandlers {
|
|||
}
|
||||
|
||||
|
||||
return mapper.writeValueAsBytes(new AuthenticationFailureResponse());
|
||||
ExceptionHandler.throwErrorResponse(new AuthenticationFailureResponse());
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -74,7 +75,7 @@ public class FeedHandlers {
|
|||
public static byte[] isSubscribedResponse(String session, String channelId) throws IOException {
|
||||
|
||||
if (StringUtils.isBlank(session) || StringUtils.isBlank(channelId))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("session and channelId are required parameters"));
|
||||
|
||||
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
|
||||
var cb = s.getCriteriaBuilder();
|
||||
|
@ -94,7 +95,7 @@ public class FeedHandlers {
|
|||
public static byte[] feedResponse(String session) throws IOException {
|
||||
|
||||
if (StringUtils.isBlank(session))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("session is a required parameter"));
|
||||
|
||||
User user = DatabaseHelper.getUserFromSession(session);
|
||||
|
||||
|
@ -133,13 +134,14 @@ public class FeedHandlers {
|
|||
}
|
||||
}
|
||||
|
||||
return mapper.writeValueAsBytes(new AuthenticationFailureResponse());
|
||||
ExceptionHandler.throwErrorResponse(new AuthenticationFailureResponse());
|
||||
return null;
|
||||
}
|
||||
|
||||
public static byte[] feedResponseRSS(String session) throws IOException, FeedException {
|
||||
public static byte[] feedResponseRSS(String session) throws FeedException {
|
||||
|
||||
if (StringUtils.isBlank(session))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("session is a required parameter"));
|
||||
|
||||
User user = DatabaseHelper.getUserFromSession(session);
|
||||
|
||||
|
@ -201,7 +203,8 @@ public class FeedHandlers {
|
|||
}
|
||||
}
|
||||
|
||||
return mapper.writeValueAsBytes(new AuthenticationFailureResponse());
|
||||
ExceptionHandler.throwErrorResponse(new AuthenticationFailureResponse());
|
||||
return null;
|
||||
}
|
||||
|
||||
public static byte[] unauthenticatedFeedResponse(String[] channelIds) throws Exception {
|
||||
|
@ -255,8 +258,7 @@ public class FeedHandlers {
|
|||
.collect(Collectors.toUnmodifiableSet());
|
||||
|
||||
if (filtered.isEmpty())
|
||||
return mapper.writeValueAsBytes(mapper.createObjectNode()
|
||||
.put("error", "No valid channel IDs provided"));
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("No valid channel IDs provided"));
|
||||
|
||||
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
|
||||
|
||||
|
@ -378,7 +380,7 @@ public class FeedHandlers {
|
|||
public static byte[] importResponse(String session, String[] channelIds, boolean override) throws IOException {
|
||||
|
||||
if (StringUtils.isBlank(session))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("session is a required parameter"));
|
||||
|
||||
User user = DatabaseHelper.getUserFromSessionWithSubscribed(session);
|
||||
|
||||
|
@ -422,14 +424,15 @@ public class FeedHandlers {
|
|||
return mapper.writeValueAsBytes(new AcceptedResponse());
|
||||
}
|
||||
|
||||
return mapper.writeValueAsBytes(new AuthenticationFailureResponse());
|
||||
ExceptionHandler.throwErrorResponse(new AuthenticationFailureResponse());
|
||||
return null;
|
||||
}
|
||||
|
||||
public static byte[] subscriptionsResponse(String session)
|
||||
throws IOException {
|
||||
|
||||
if (StringUtils.isBlank(session))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("session is a required parameter"));
|
||||
|
||||
User user = DatabaseHelper.getUserFromSession(session);
|
||||
|
||||
|
@ -461,7 +464,8 @@ public class FeedHandlers {
|
|||
}
|
||||
}
|
||||
|
||||
return mapper.writeValueAsBytes(new AuthenticationFailureResponse());
|
||||
ExceptionHandler.throwErrorResponse(new AuthenticationFailureResponse());
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
|
@ -473,6 +477,9 @@ public class FeedHandlers {
|
|||
.filter(id -> id.matches("[A-Za-z\\d_-]+"))
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
|
||||
if (filtered.isEmpty())
|
||||
return mapper.writeValueAsBytes(Collections.EMPTY_LIST);
|
||||
|
||||
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
|
||||
|
||||
CriteriaBuilder cb = s.getCriteriaBuilder();
|
||||
|
@ -498,7 +505,7 @@ public class FeedHandlers {
|
|||
throws IOException {
|
||||
|
||||
if (StringUtils.isBlank(session) || StringUtils.isBlank(channelId))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("session and channelId are required parameters"));
|
||||
|
||||
User user = DatabaseHelper.getUserFromSession(session);
|
||||
|
||||
|
@ -513,7 +520,8 @@ public class FeedHandlers {
|
|||
|
||||
}
|
||||
|
||||
return mapper.writeValueAsBytes(new AuthenticationFailureResponse());
|
||||
ExceptionHandler.throwErrorResponse(new AuthenticationFailureResponse());
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,12 +7,12 @@ import jakarta.persistence.criteria.Root;
|
|||
import me.kavin.piped.consts.Constants;
|
||||
import me.kavin.piped.utils.DatabaseHelper;
|
||||
import me.kavin.piped.utils.DatabaseSessionFactory;
|
||||
import me.kavin.piped.utils.ExceptionHandler;
|
||||
import me.kavin.piped.utils.RequestUtils;
|
||||
import me.kavin.piped.utils.obj.db.User;
|
||||
import me.kavin.piped.utils.resp.*;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.StatelessSession;
|
||||
import org.springframework.security.crypto.argon2.Argon2PasswordEncoder;
|
||||
|
@ -31,16 +31,13 @@ public class UserHandlers {
|
|||
public static byte[] registerResponse(String user, String pass) throws IOException {
|
||||
|
||||
if (Constants.DISABLE_REGISTRATION)
|
||||
return mapper.writeValueAsBytes(new DisabledRegistrationResponse());
|
||||
ExceptionHandler.throwErrorResponse(new DisabledRegistrationResponse());
|
||||
|
||||
if (StringUtils.isBlank(user) || StringUtils.isBlank(pass))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse());
|
||||
|
||||
if (user.length() > 24)
|
||||
return mapper.writeValueAsBytes(
|
||||
mapper.createObjectNode()
|
||||
.put("error", "The username must be less than 24 characters")
|
||||
);
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("The username must be less than 24 characters"));
|
||||
|
||||
user = user.toLowerCase();
|
||||
|
||||
|
@ -52,7 +49,7 @@ public class UserHandlers {
|
|||
boolean registered = s.createQuery(cr).uniqueResult() != null;
|
||||
|
||||
if (registered)
|
||||
return mapper.writeValueAsBytes(new AlreadyRegisteredResponse());
|
||||
ExceptionHandler.throwErrorResponse(new AlreadyRegisteredResponse());
|
||||
|
||||
if (Constants.COMPROMISED_PASSWORD_CHECK) {
|
||||
String sha1Hash = DigestUtils.sha1Hex(pass).toUpperCase();
|
||||
|
@ -63,7 +60,7 @@ public class UserHandlers {
|
|||
.split("\n");
|
||||
for (String entry : entries)
|
||||
if (StringUtils.substringBefore(entry, ":").equals(suffix))
|
||||
return mapper.writeValueAsBytes(new CompromisedPasswordResponse());
|
||||
ExceptionHandler.throwErrorResponse(new CompromisedPasswordResponse());
|
||||
}
|
||||
|
||||
User newuser = new User(user, argon2PasswordEncoder.encode(pass), Set.of());
|
||||
|
@ -87,7 +84,7 @@ public class UserHandlers {
|
|||
throws IOException {
|
||||
|
||||
if (user == null || pass == null)
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("username and password are required parameters"));
|
||||
|
||||
user = user.toLowerCase();
|
||||
|
||||
|
@ -106,33 +103,30 @@ public class UserHandlers {
|
|||
}
|
||||
}
|
||||
|
||||
return mapper.writeValueAsBytes(new IncorrectCredentialsResponse());
|
||||
ExceptionHandler.throwErrorResponse(new IncorrectCredentialsResponse());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] deleteUserResponse(String session, String pass) throws IOException {
|
||||
|
||||
if (StringUtils.isBlank(session) || StringUtils.isBlank(pass))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("session and password are required parameters"));
|
||||
|
||||
try (Session s = DatabaseSessionFactory.createSession()) {
|
||||
User user = DatabaseHelper.getUserFromSession(session);
|
||||
|
||||
if (user == null)
|
||||
return mapper.writeValueAsBytes(new AuthenticationFailureResponse());
|
||||
ExceptionHandler.throwErrorResponse(new AuthenticationFailureResponse());
|
||||
|
||||
String hash = user.getPassword();
|
||||
|
||||
if (!hashMatch(hash, pass))
|
||||
return mapper.writeValueAsBytes(new IncorrectCredentialsResponse());
|
||||
ExceptionHandler.throwErrorResponse(new IncorrectCredentialsResponse());
|
||||
|
||||
try {
|
||||
var tr = s.beginTransaction();
|
||||
s.remove(user);
|
||||
tr.commit();
|
||||
} catch (Exception e) {
|
||||
return mapper.writeValueAsBytes(new ErrorResponse(ExceptionUtils.getStackTrace(e), e.getMessage()));
|
||||
}
|
||||
var tr = s.beginTransaction();
|
||||
s.remove(user);
|
||||
tr.commit();
|
||||
|
||||
return mapper.writeValueAsBytes(new DeleteUserResponse(user.getUsername()));
|
||||
}
|
||||
|
@ -141,7 +135,7 @@ public class UserHandlers {
|
|||
public static byte[] logoutResponse(String session) throws JsonProcessingException {
|
||||
|
||||
if (StringUtils.isBlank(session))
|
||||
return mapper.writeValueAsBytes(new InvalidRequestResponse());
|
||||
ExceptionHandler.throwErrorResponse(new InvalidRequestResponse("session is a required parameter"));
|
||||
|
||||
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
|
||||
var tr = s.beginTransaction();
|
||||
|
|
40
src/main/java/me/kavin/piped/utils/ErrorResponse.java
Normal file
40
src/main/java/me/kavin/piped/utils/ErrorResponse.java
Normal file
|
@ -0,0 +1,40 @@
|
|||
package me.kavin.piped.utils;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
import static me.kavin.piped.consts.Constants.mapper;
|
||||
|
||||
public class ErrorResponse extends Exception {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final int code;
|
||||
|
||||
private final byte[] content;
|
||||
|
||||
public ErrorResponse(int code, byte[] content) {
|
||||
this.code = code;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public ErrorResponse(IStatusCode statusObj) throws JsonProcessingException {
|
||||
this.code = statusObj.getStatusCode();
|
||||
this.content = mapper.writeValueAsBytes(statusObj);
|
||||
}
|
||||
|
||||
public ErrorResponse(int code, Object content) throws JsonProcessingException {
|
||||
this.code = code;
|
||||
this.content = mapper.writeValueAsBytes(content);
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public byte[] getContent() {
|
||||
return content;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
package me.kavin.piped.utils;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import io.sentry.Sentry;
|
||||
import me.kavin.piped.consts.Constants;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
|
||||
|
||||
import java.util.concurrent.CompletionException;
|
||||
|
@ -29,4 +31,20 @@ public class ExceptionHandler {
|
|||
|
||||
return e;
|
||||
}
|
||||
|
||||
public static void throwErrorResponse(IStatusCode statusObj) {
|
||||
try {
|
||||
ExceptionUtils.rethrow(new ErrorResponse(statusObj));
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void throwErrorResponse(int code, Object content) {
|
||||
try {
|
||||
ExceptionUtils.rethrow(new ErrorResponse(code, content));
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
10
src/main/java/me/kavin/piped/utils/IStatusCode.java
Normal file
10
src/main/java/me/kavin/piped/utils/IStatusCode.java
Normal file
|
@ -0,0 +1,10 @@
|
|||
package me.kavin.piped.utils;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
public interface IStatusCode {
|
||||
|
||||
@JsonIgnore
|
||||
public int getStatusCode();
|
||||
|
||||
}
|
|
@ -1,8 +1,12 @@
|
|||
package me.kavin.piped.utils;
|
||||
|
||||
import com.grack.nanojson.*;
|
||||
import com.grack.nanojson.JsonArray;
|
||||
import com.grack.nanojson.JsonObject;
|
||||
import com.grack.nanojson.JsonParser;
|
||||
import com.grack.nanojson.JsonWriter;
|
||||
import me.kavin.piped.consts.Constants;
|
||||
import me.kavin.piped.utils.resp.InvalidRequestResponse;
|
||||
import me.kavin.piped.utils.resp.SimpleErrorMessage;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -13,7 +17,7 @@ import java.security.NoSuchAlgorithmException;
|
|||
public class SponsorBlockUtils {
|
||||
|
||||
public static String getSponsors(String id, String categories)
|
||||
throws IOException, NoSuchAlgorithmException, JsonParserException {
|
||||
throws IOException, NoSuchAlgorithmException {
|
||||
|
||||
if (StringUtils.isEmpty(categories))
|
||||
return Constants.mapper.writeValueAsString(new InvalidRequestResponse());
|
||||
|
@ -35,8 +39,9 @@ public class SponsorBlockUtils {
|
|||
}
|
||||
}
|
||||
|
||||
return Constants.mapper.writeValueAsString(Constants.mapper.createObjectNode()
|
||||
.put("error", "All SponsorBlock servers are down"));
|
||||
ExceptionHandler.throwErrorResponse(new SimpleErrorMessage("All SponsorBlock servers are down"));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String toSha256(final String videoId) throws NoSuchAlgorithmException {
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
package me.kavin.piped.utils.resp;
|
||||
|
||||
public class AlreadyRegisteredResponse {
|
||||
import me.kavin.piped.utils.IStatusCode;
|
||||
|
||||
public class AlreadyRegisteredResponse implements IStatusCode {
|
||||
|
||||
public String error = "The username you have used is already taken.";
|
||||
|
||||
@Override
|
||||
public int getStatusCode() {
|
||||
return 400;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
package me.kavin.piped.utils.resp;
|
||||
|
||||
public class AuthenticationFailureResponse {
|
||||
import me.kavin.piped.utils.IStatusCode;
|
||||
|
||||
public class AuthenticationFailureResponse implements IStatusCode {
|
||||
|
||||
public String error = "An invalid Session ID was provided.";
|
||||
|
||||
@Override
|
||||
public int getStatusCode() {
|
||||
return 401;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
package me.kavin.piped.utils.resp;
|
||||
|
||||
public class CompromisedPasswordResponse {
|
||||
import me.kavin.piped.utils.IStatusCode;
|
||||
|
||||
public class CompromisedPasswordResponse implements IStatusCode {
|
||||
|
||||
public String error = "The password you have entered has already been compromised.";
|
||||
|
||||
@Override
|
||||
public int getStatusCode() {
|
||||
return 400;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
package me.kavin.piped.utils.resp;
|
||||
|
||||
public class DisabledRegistrationResponse {
|
||||
import me.kavin.piped.utils.IStatusCode;
|
||||
|
||||
public class DisabledRegistrationResponse implements IStatusCode {
|
||||
|
||||
public String error = "This instance has registrations disabled.";
|
||||
|
||||
@Override
|
||||
public int getStatusCode() {
|
||||
return 400;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
package me.kavin.piped.utils.resp;
|
||||
|
||||
public class ErrorResponse {
|
||||
|
||||
public final String error, message;
|
||||
|
||||
public ErrorResponse(String error, String message) {
|
||||
this.error = error;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,13 @@
|
|||
package me.kavin.piped.utils.resp;
|
||||
|
||||
public class IncorrectCredentialsResponse {
|
||||
import me.kavin.piped.utils.IStatusCode;
|
||||
|
||||
public class IncorrectCredentialsResponse implements IStatusCode {
|
||||
|
||||
public String error = "The username or password you have entered is incorrect.";
|
||||
|
||||
@Override
|
||||
public int getStatusCode() {
|
||||
return 401;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,21 @@
|
|||
package me.kavin.piped.utils.resp;
|
||||
|
||||
public class InvalidRequestResponse {
|
||||
import me.kavin.piped.utils.IStatusCode;
|
||||
|
||||
public String error = "Invalid request sent.";
|
||||
public class InvalidRequestResponse implements IStatusCode {
|
||||
|
||||
public String error;
|
||||
|
||||
public InvalidRequestResponse(String error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public InvalidRequestResponse() {
|
||||
this.error = "Invalid request sent.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatusCode() {
|
||||
return 400;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
package me.kavin.piped.utils.resp;
|
||||
|
||||
import me.kavin.piped.utils.IStatusCode;
|
||||
|
||||
public record SimpleErrorMessage(String error) implements IStatusCode {
|
||||
@Override
|
||||
public int getStatusCode() {
|
||||
return 500;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package me.kavin.piped.utils.resp;
|
||||
|
||||
public record StackTraceResponse(String error, String message) {
|
||||
|
||||
}
|
Loading…
Reference in a new issue