Skip to content

Commit 3fc1e24

Browse files
Sheikah45Brutus5000
authored andcommitted
Add update permission on GroupPermission to allow updates to userGroup assigned permissions
1 parent 7ada576 commit 3fc1e24

5 files changed

Lines changed: 253 additions & 2 deletions

File tree

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package com.faforever.api.data;
2+
3+
import com.faforever.api.AbstractIntegrationTest;
4+
import com.faforever.api.data.domain.GroupPermission;
5+
import com.faforever.api.security.OAuthScope;
6+
import org.junit.jupiter.api.Test;
7+
import org.springframework.http.HttpHeaders;
8+
import org.springframework.test.context.jdbc.Sql;
9+
import org.springframework.test.context.jdbc.Sql.ExecutionPhase;
10+
11+
import static com.faforever.api.data.JsonApiMediaType.JSON_API_MEDIA_TYPE;
12+
import static org.hamcrest.Matchers.hasSize;
13+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
14+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
15+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
16+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
17+
18+
@Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:sql/truncateTables.sql")
19+
@Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:sql/prepDefaultData.sql")
20+
public class GroupPermissionTest extends AbstractIntegrationTest {
21+
private static final String testPost = """
22+
{
23+
"data": {
24+
"type": "groupPermission",
25+
"attributes": {
26+
"technicalName": "test",
27+
"nameKey": "test"
28+
}
29+
}
30+
}
31+
""";
32+
33+
@Test
34+
public void emptyResultWithoutScope() throws Exception {
35+
mockMvc.perform(get("/data/groupPermission")
36+
.with(getOAuthTokenWithTestUser(NO_SCOPE, GroupPermission.ROLE_READ_USER_GROUP)))
37+
.andExpect(status().isOk())
38+
.andExpect(jsonPath("$.data", hasSize(0)));
39+
}
40+
41+
@Test
42+
public void emptyResultWithoutRole() throws Exception {
43+
mockMvc.perform(get("/data/groupPermission")
44+
.with(getOAuthTokenWithTestUser(OAuthScope._READ_SENSIBLE_USERDATA, NO_AUTHORITIES)))
45+
.andExpect(status().isOk())
46+
.andExpect(jsonPath("$.data", hasSize(0)));
47+
}
48+
49+
@Test
50+
public void canReadPermissionsWithScopeAndRole() throws Exception {
51+
mockMvc.perform(get("/data/groupPermission")
52+
.with(getOAuthTokenWithTestUser(OAuthScope._READ_SENSIBLE_USERDATA, GroupPermission.ROLE_READ_USER_GROUP)))
53+
.andExpect(status().isOk())
54+
.andExpect(jsonPath("$.data", hasSize(23)));
55+
}
56+
57+
@Test
58+
public void cannotCreatePermissionWithoutScope() throws Exception {
59+
mockMvc.perform(post("/data/groupPermission")
60+
.with(getOAuthTokenWithTestUser(NO_SCOPE, GroupPermission.ROLE_WRITE_USER_GROUP))
61+
.header(HttpHeaders.CONTENT_TYPE, JSON_API_MEDIA_TYPE)
62+
.content(testPost))
63+
.andExpect(status().isForbidden());
64+
}
65+
66+
@Test
67+
public void cannotCreatePermissionWithoutRole() throws Exception {
68+
mockMvc.perform(post("/data/groupPermission")
69+
.with(getOAuthTokenWithTestUser(OAuthScope._ADMINISTRATIVE_ACTION, NO_AUTHORITIES))
70+
.header(HttpHeaders.CONTENT_TYPE, JSON_API_MEDIA_TYPE)
71+
.content(testPost))
72+
.andExpect(status().isForbidden());
73+
}
74+
75+
@Test
76+
public void cannotCreatePermissionWithScopeAndRole() throws Exception {
77+
mockMvc.perform(post("/data/groupPermission")
78+
.with(getOAuthTokenWithTestUser(OAuthScope._ADMINISTRATIVE_ACTION, GroupPermission.ROLE_WRITE_USER_GROUP))
79+
.header(HttpHeaders.CONTENT_TYPE, JSON_API_MEDIA_TYPE)
80+
.content(testPost))
81+
.andExpect(status().isForbidden());
82+
}
83+
}
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
package com.faforever.api.data;
2+
3+
import com.faforever.api.AbstractIntegrationTest;
4+
import com.faforever.api.data.domain.GroupPermission;
5+
import com.faforever.api.security.OAuthScope;
6+
import org.junit.jupiter.api.Test;
7+
import org.springframework.http.HttpHeaders;
8+
import org.springframework.test.context.jdbc.Sql;
9+
import org.springframework.test.context.jdbc.Sql.ExecutionPhase;
10+
11+
import static com.faforever.api.data.JsonApiMediaType.JSON_API_MEDIA_TYPE;
12+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
13+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
14+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
15+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
16+
17+
@Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:sql/truncateTables.sql")
18+
@Sql(executionPhase = ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:sql/prepDefaultData.sql")
19+
public class UserGroupTest extends AbstractIntegrationTest {
20+
private static final String testPatch = """
21+
{
22+
"data": {
23+
"type": "userGroup",
24+
"id": "3",
25+
"attributes": {
26+
"public": false
27+
},
28+
"relationships": {
29+
"members": {
30+
"data": [{
31+
"type": "player",
32+
"id": "1"
33+
}, {
34+
"type": "player",
35+
"id": "2"
36+
}
37+
]
38+
},
39+
"permissions": {
40+
"data": [{
41+
"type": "groupPermission",
42+
"id": "17"
43+
}, {
44+
"type": "groupPermission",
45+
"id": "19"
46+
}
47+
]
48+
}
49+
}
50+
}
51+
}
52+
""";
53+
54+
private static final String testPost = """
55+
{
56+
"data": {
57+
"type": "userGroup",
58+
"attributes": {
59+
"technicalName": "faf_test",
60+
"nameKey": "faf.test",
61+
"public": false
62+
},
63+
"relationships": {
64+
"members": {
65+
"data": []
66+
},
67+
"permissions": {
68+
"data": [{
69+
"type": "groupPermission",
70+
"id": "17"
71+
}, {
72+
"type": "groupPermission",
73+
"id": "19"
74+
}
75+
]
76+
}
77+
}
78+
}
79+
}
80+
""";
81+
82+
@Test
83+
public void canSeePublicGroupWithoutScope() throws Exception {
84+
mockMvc.perform(get("/data/userGroup/4")
85+
.with(getOAuthTokenWithTestUser(NO_SCOPE, NO_AUTHORITIES)))
86+
.andExpect(status().isOk());
87+
}
88+
89+
@Test
90+
public void cannotSeePrivateGroupWithoutScope() throws Exception {
91+
mockMvc.perform(get("/data/userGroup/5")
92+
.with(getOAuthTokenWithTestUser(NO_SCOPE, NO_AUTHORITIES)))
93+
.andExpect(status().isForbidden());
94+
}
95+
96+
@Test
97+
public void cannotSeePrivateGroupWithoutRole() throws Exception {
98+
mockMvc.perform(get("/data/userGroup/5")
99+
.with(getOAuthTokenWithTestUser(OAuthScope._READ_SENSIBLE_USERDATA, NO_AUTHORITIES)))
100+
.andExpect(status().isForbidden());
101+
}
102+
103+
@Test
104+
public void canSeePrivateGroupWithScopeAndRole() throws Exception {
105+
mockMvc.perform(get("/data/userGroup/5")
106+
.with(getOAuthTokenWithTestUser(OAuthScope._READ_SENSIBLE_USERDATA, GroupPermission.ROLE_READ_USER_GROUP)))
107+
.andExpect(status().isOk());
108+
}
109+
110+
@Test
111+
public void cannotCreateUserGroupWithoutScope() throws Exception {
112+
mockMvc.perform(post("/data/userGroup")
113+
.with(getOAuthTokenWithTestUser(NO_SCOPE, GroupPermission.ROLE_READ_USER_GROUP))
114+
.header(HttpHeaders.CONTENT_TYPE, JSON_API_MEDIA_TYPE)
115+
.content(testPost))
116+
.andExpect(status().isForbidden());
117+
}
118+
119+
@Test
120+
public void cannotCreateUserGroupWithoutRole() throws Exception {
121+
mockMvc.perform(post("/data/userGroup")
122+
.with(getOAuthTokenWithTestUser(OAuthScope._ADMINISTRATIVE_ACTION, NO_AUTHORITIES))
123+
.header(HttpHeaders.CONTENT_TYPE, JSON_API_MEDIA_TYPE)
124+
.content(testPost))
125+
.andExpect(status().isForbidden());
126+
}
127+
128+
@Test
129+
public void canCreateUserGroupWithScopeAndRole() throws Exception {
130+
mockMvc.perform(post("/data/userGroup")
131+
.with(getOAuthTokenWithTestUser(OAuthScope._ADMINISTRATIVE_ACTION, GroupPermission.ROLE_WRITE_USER_GROUP))
132+
.header(HttpHeaders.CONTENT_TYPE, JSON_API_MEDIA_TYPE)
133+
.content(testPost))
134+
.andExpect(status().isCreated());
135+
}
136+
137+
@Test
138+
public void cannotUpdateUserGroupWithoutScope() throws Exception {
139+
mockMvc.perform(patch("/data/userGroup/3")
140+
.with(getOAuthTokenWithTestUser(NO_SCOPE, GroupPermission.ROLE_WRITE_USER_GROUP))
141+
.header(HttpHeaders.CONTENT_TYPE, JSON_API_MEDIA_TYPE)
142+
.content(testPatch))
143+
.andExpect(status().isForbidden());
144+
}
145+
146+
@Test
147+
public void cannotUpdateUserGroupWithoutRole() throws Exception {
148+
mockMvc.perform(patch("/data/userGroup/3")
149+
.with(getOAuthTokenWithTestUser(OAuthScope._ADMINISTRATIVE_ACTION, NO_AUTHORITIES))
150+
.header(HttpHeaders.CONTENT_TYPE, JSON_API_MEDIA_TYPE)
151+
.content(testPatch))
152+
.andExpect(status().isForbidden());
153+
}
154+
155+
@Test
156+
public void canUpdateUserGroupWithScopeAndRole() throws Exception {
157+
mockMvc.perform(patch("/data/userGroup/3")
158+
.with(getOAuthTokenWithTestUser(OAuthScope._ADMINISTRATIVE_ACTION, GroupPermission.ROLE_WRITE_USER_GROUP))
159+
.header(HttpHeaders.CONTENT_TYPE, JSON_API_MEDIA_TYPE)
160+
.content(testPatch))
161+
.andExpect(status().isNoContent());
162+
}
163+
}

src/inttest/resources/sql/prepDefaultData.sql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ INSERT INTO user_group (id, technical_name, name_key, parent_group_id, public)
1717
VALUES (1, 'ADMINISTRATOR', 'administrator', null, true),
1818
(2, 'MODERATOR', 'moderator', null, true),
1919
(3, 'faf_server_administrators', 'user_group.faf.server_administrators', null, true),
20-
(4, 'faf_moderators_global', 'user_group.faf.moderators.global', null, true);
20+
(4, 'faf_moderators_global', 'user_group.faf.moderators.global', null, true),
21+
(5, 'faf_illuminati', 'user_group.faf.illuminati', null, false);
2122

2223
INSERT INTO user_group (technical_name, name_key, public, parent_group_id)
2324
VALUES ('', 'user_group.faf.server_administrators', 1, @devops_id);

src/main/java/com/faforever/api/data/domain/GroupPermission.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package com.faforever.api.data.domain;
22

33
import com.faforever.api.security.elide.permission.ReadUserGroupCheck;
4+
import com.faforever.api.security.elide.permission.WriteUserGroupCheck;
45
import com.yahoo.elide.annotation.Include;
56
import com.yahoo.elide.annotation.ReadPermission;
7+
import com.yahoo.elide.annotation.UpdatePermission;
68
import lombok.Setter;
79
import org.springframework.security.core.GrantedAuthority;
810

@@ -72,6 +74,7 @@ public String getNameKey() {
7274
}
7375

7476
@ManyToMany(mappedBy = "permissions")
77+
@UpdatePermission(expression = WriteUserGroupCheck.EXPRESSION)
7578
public Set<UserGroup> getUserGroups() {
7679
return userGroups;
7780
}

src/main/java/com/faforever/api/data/domain/UserGroup.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33

44
import com.faforever.api.data.checks.UserGroupPublicCheck;
5+
import com.faforever.api.security.elide.permission.ReadUserGroupCheck;
56
import com.faforever.api.security.elide.permission.WriteUserGroupCheck;
67
import com.yahoo.elide.annotation.CreatePermission;
78
import com.yahoo.elide.annotation.Include;
@@ -27,7 +28,7 @@
2728
@Include(name = "userGroup")
2829
@UpdatePermission(expression = WriteUserGroupCheck.EXPRESSION)
2930
@CreatePermission(expression = WriteUserGroupCheck.EXPRESSION)
30-
@ReadPermission(expression = UserGroupPublicCheck.EXPRESSION + " or " + WriteUserGroupCheck.EXPRESSION)
31+
@ReadPermission(expression = UserGroupPublicCheck.EXPRESSION + " or " + ReadUserGroupCheck.EXPRESSION)
3132
@Setter
3233
public class
3334
UserGroup extends AbstractEntity<UserGroup> {

0 commit comments

Comments
 (0)