mirror of
https://github.com/Athou/commafeed.git
synced 2026-11-04 19:34:47 +00:00
prevent users from referencing categories owned by other users
This commit is contained in:
@@ -39,6 +39,7 @@ import jakarta.validation.Valid;
|
||||
import jakarta.ws.rs.Consumes;
|
||||
import jakarta.ws.rs.DefaultValue;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.NotFoundException;
|
||||
import jakarta.ws.rs.POST;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.Produces;
|
||||
@@ -333,8 +334,10 @@ public class CategoryREST {
|
||||
cat.setPosition(0);
|
||||
String parentId = req.getParentId();
|
||||
if (parentId != null && !ALL.equals(parentId)) {
|
||||
FeedCategory parent = new FeedCategory();
|
||||
parent.setId(Long.valueOf(parentId));
|
||||
FeedCategory parent = feedCategoryDAO.findById(user, Long.valueOf(parentId));
|
||||
if (parent == null) {
|
||||
throw new NotFoundException("parent category not found");
|
||||
}
|
||||
cat.setParent(parent);
|
||||
}
|
||||
feedCategoryDAO.persist(cat);
|
||||
|
||||
@@ -407,13 +407,17 @@ public class FeedREST {
|
||||
Preconditions.checkNotNull(req.getUrl());
|
||||
|
||||
try {
|
||||
User user = authenticationContext.getCurrentUser();
|
||||
|
||||
FeedCategory category = null;
|
||||
if (req.getCategoryId() != null && !CategoryREST.ALL.equals(req.getCategoryId())) {
|
||||
category = feedCategoryDAO.findById(Long.valueOf(req.getCategoryId()));
|
||||
category = feedCategoryDAO.findById(user, Long.valueOf(req.getCategoryId()));
|
||||
if (category == null) {
|
||||
return Response.status(Status.NOT_FOUND).build();
|
||||
}
|
||||
}
|
||||
|
||||
FeedInfo info = fetchFeedInternal(prependHttp(req.getUrl()));
|
||||
User user = authenticationContext.getCurrentUser();
|
||||
long subscriptionId = feedSubscriptionService.subscribe(user, info.getUrl(), req.getTitle(), category, 0);
|
||||
return Response.ok(subscriptionId).build();
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.commafeed.frontend.model.Entries;
|
||||
import com.commafeed.frontend.model.Subscription;
|
||||
import com.commafeed.frontend.model.request.AddCategoryRequest;
|
||||
import com.commafeed.frontend.model.request.InitialSetupRequest;
|
||||
import com.commafeed.frontend.model.request.RegistrationRequest;
|
||||
import com.commafeed.frontend.model.request.SubscribeRequest;
|
||||
|
||||
import io.restassured.RestAssured;
|
||||
@@ -102,6 +103,26 @@ public abstract class BaseIT {
|
||||
.statusCode(200);
|
||||
}
|
||||
|
||||
protected void registerUser(String userName, String password) {
|
||||
RegistrationRequest req = new RegistrationRequest();
|
||||
req.setName(userName);
|
||||
req.setPassword(password);
|
||||
req.setEmail(userName + "@commafeed.com");
|
||||
|
||||
RestAssured.given()
|
||||
.auth()
|
||||
.none()
|
||||
.body(req)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/user/register")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
}
|
||||
|
||||
protected void authenticateAs(String userName, String password) {
|
||||
RestAssured.authentication = RestAssured.preemptive().basic(userName, password);
|
||||
}
|
||||
|
||||
protected List<HttpCookie> login() {
|
||||
return login(TestConstants.ADMIN_USERNAME, TestConstants.ADMIN_PASSWORD);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.commafeed.frontend.model.Category;
|
||||
import com.commafeed.frontend.model.Entries;
|
||||
import com.commafeed.frontend.model.Entry;
|
||||
import com.commafeed.frontend.model.UnreadCount;
|
||||
import com.commafeed.frontend.model.request.AddCategoryRequest;
|
||||
import com.commafeed.frontend.model.request.CategoryModificationRequest;
|
||||
import com.commafeed.frontend.model.request.CollapseRequest;
|
||||
import com.commafeed.frontend.model.request.IDRequest;
|
||||
@@ -87,6 +88,38 @@ class CategoryIT extends BaseIT {
|
||||
Assertions.assertEquals("test-category-1", root.getChildren().get(1).getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void addCategoryWithParent() {
|
||||
String parentId = createCategory("parent");
|
||||
|
||||
AddCategoryRequest request = new AddCategoryRequest();
|
||||
request.setName("child");
|
||||
request.setParentId(parentId);
|
||||
RestAssured.given()
|
||||
.body(request)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/category/add")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
|
||||
Category parent = getRootCategory().getChildren().getFirst();
|
||||
Assertions.assertEquals("parent", parent.getName());
|
||||
Assertions.assertEquals("child", parent.getChildren().getFirst().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void addCategoryWithUnknownParent() {
|
||||
AddCategoryRequest request = new AddCategoryRequest();
|
||||
request.setName("child");
|
||||
request.setParentId("999999");
|
||||
RestAssured.given()
|
||||
.body(request)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/category/add")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
void collapseCategory() {
|
||||
String categoryId = createCategory("test-category");
|
||||
@@ -145,6 +178,60 @@ class CategoryIT extends BaseIT {
|
||||
Assertions.assertEquals(2, counts[0].getUnreadCount());
|
||||
}
|
||||
|
||||
@Nested
|
||||
class ParentOwnedByAnotherUser {
|
||||
private static final String VICTIM = "victim";
|
||||
private static final String ATTACKER = "attacker";
|
||||
private static final String PASSWORD = "MyPassword123!";
|
||||
|
||||
private String victimCategoryId;
|
||||
|
||||
@BeforeEach
|
||||
void attemptToAddChildToVictimCategory() {
|
||||
registerUser(VICTIM, PASSWORD);
|
||||
registerUser(ATTACKER, PASSWORD);
|
||||
|
||||
authenticateAs(VICTIM, PASSWORD);
|
||||
victimCategoryId = createCategory("victim-category");
|
||||
|
||||
authenticateAs(ATTACKER, PASSWORD);
|
||||
AddCategoryRequest request = new AddCategoryRequest();
|
||||
request.setName("attacker-category");
|
||||
request.setParentId(victimCategoryId);
|
||||
RestAssured.given()
|
||||
.body(request)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/category/add")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
void victimCanDeleteCategory() {
|
||||
authenticateAs(VICTIM, PASSWORD);
|
||||
|
||||
IDRequest request = new IDRequest();
|
||||
request.setId(Long.valueOf(victimCategoryId));
|
||||
RestAssured.given()
|
||||
.body(request)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/category/delete")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
Assertions.assertEquals(0, getRootCategory().getChildren().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void victimCanDeleteAccount() {
|
||||
authenticateAs(VICTIM, PASSWORD);
|
||||
RestAssured.given()
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/user/profile/deleteAccount")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class MarkEntriesAsRead {
|
||||
@Test
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.commafeed.frontend.model.request.FeedInfoRequest;
|
||||
import com.commafeed.frontend.model.request.FeedModificationRequest;
|
||||
import com.commafeed.frontend.model.request.IDRequest;
|
||||
import com.commafeed.frontend.model.request.MarkRequest;
|
||||
import com.commafeed.frontend.model.request.SubscribeRequest;
|
||||
import com.commafeed.frontend.resource.CategoryREST;
|
||||
import com.commafeed.integration.BaseIT;
|
||||
import com.rometools.rome.feed.synd.SyndFeed;
|
||||
@@ -56,6 +57,65 @@ class FeedIT extends BaseIT {
|
||||
RestAssured.reset();
|
||||
}
|
||||
|
||||
@Nested
|
||||
class CategoryOwnedByAnotherUser {
|
||||
private static final String VICTIM = "victim";
|
||||
private static final String ATTACKER = "attacker";
|
||||
private static final String PASSWORD = "MyPassword123!";
|
||||
|
||||
private String victimCategoryId;
|
||||
|
||||
@BeforeEach
|
||||
void attemptToSubscribeInVictimCategory() {
|
||||
registerUser(VICTIM, PASSWORD);
|
||||
registerUser(ATTACKER, PASSWORD);
|
||||
|
||||
authenticateAs(VICTIM, PASSWORD);
|
||||
victimCategoryId = createCategory("victim-category");
|
||||
|
||||
authenticateAs(ATTACKER, PASSWORD);
|
||||
SubscribeRequest request = new SubscribeRequest();
|
||||
request.setUrl(getFeedUrl());
|
||||
request.setTitle("my title for this feed");
|
||||
request.setCategoryId(victimCategoryId);
|
||||
RestAssured.given()
|
||||
.body(request)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/feed/subscribe")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
void victimCanDeleteCategory() {
|
||||
authenticateAs(VICTIM, PASSWORD);
|
||||
|
||||
IDRequest request = new IDRequest();
|
||||
request.setId(Long.valueOf(victimCategoryId));
|
||||
RestAssured.given()
|
||||
.body(request)
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/category/delete")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void victimCanDeleteAccount() {
|
||||
authenticateAs(VICTIM, PASSWORD);
|
||||
RestAssured.given()
|
||||
.contentType(ContentType.JSON)
|
||||
.post("rest/user/profile/deleteAccount")
|
||||
.then()
|
||||
.statusCode(HttpStatus.SC_OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void subscriptionIsNotCreated() {
|
||||
Assertions.assertEquals(0, getCategoryEntries(CategoryREST.ALL).getEntries().size());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class Fetch {
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user