mirror of
https://github.com/HangarMC/Hangar.git
synced 2025-02-17 15:01:42 +08:00
limit permission check perms to api key scope, closes #808
also adds proper DB based integration tests for the perm controller
This commit is contained in:
parent
2b43e0aa4d
commit
75e2759ea5
13
pom.xml
13
pom.xml
@ -39,6 +39,8 @@
|
||||
|
||||
<apache-commons-lang.version>3.12.0</apache-commons-lang.version>
|
||||
<jwt.version>4.0.0</jwt.version>
|
||||
<!-- test -->
|
||||
<pg.version>1.17.3</pg.version>
|
||||
|
||||
<!-- plugins -->
|
||||
<maven-compiler-plugin.version>3.10.1</maven-compiler-plugin.version>
|
||||
@ -246,6 +248,17 @@
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>${pg.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-inline</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -42,7 +42,7 @@ public class JDBIConfig {
|
||||
|
||||
@Bean
|
||||
DataSource dataSource(@Value("${spring.datasource.url}") String url, @Value("${spring.datasource.username}") String username, @Value("${spring.datasource.password}") String password) {
|
||||
HikariDataSource dataSource = DataSourceBuilder.create().type(HikariDataSource.class).url(url).username(username).password(password).driverClassName("org.postgresql.Driver").build();
|
||||
HikariDataSource dataSource = DataSourceBuilder.create().type(HikariDataSource.class).url(url).username(username).password(password).build();
|
||||
dataSource.setPoolName(UUID.randomUUID().toString());
|
||||
return dataSource;
|
||||
}
|
||||
|
@ -52,12 +52,15 @@ public class PermissionsController extends HangarComponent implements IPermissio
|
||||
private Pair<PermissionType, Permission> getPermissionsInScope(String author, String slug, String organization) {
|
||||
if (author != null && slug != null && organization == null) { // author & slug
|
||||
Permission perms = permissionService.getProjectPermissions(getHangarUserId(), author, slug);
|
||||
perms = getHangarPrincipal().getPossiblePermissions().intersect(perms);
|
||||
return new ImmutablePair<>(PermissionType.PROJECT, perms);
|
||||
} else if (author == null && slug == null && organization == null) { // current user (I don't think there's a need to see other user's global permissions)
|
||||
Permission perms = permissionService.getGlobalPermissions(getHangarUserId());
|
||||
perms = getHangarPrincipal().getPossiblePermissions().intersect(perms);
|
||||
return new ImmutablePair<>(PermissionType.GLOBAL, perms);
|
||||
} else if (author == null && slug == null) { // just org
|
||||
Permission perms = permissionService.getOrganizationPermissions(getHangarUserId(), organization);
|
||||
perms = getHangarPrincipal().getPossiblePermissions().intersect(perms);
|
||||
return new ImmutablePair<>(PermissionType.ORGANIZATION, perms);
|
||||
} else {
|
||||
throw new HangarApiException(HttpStatus.BAD_REQUEST, "Incorrect request parameters");
|
||||
|
@ -1,15 +1,21 @@
|
||||
package io.papermc.hangar;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@Disabled // would require a DB on test
|
||||
@SpringBootTest
|
||||
import io.papermc.hangar.controller.ApplicationController;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
class HangarApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private ApplicationController controller;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
assertThat(this.controller).isNotNull();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,75 @@
|
||||
package io.papermc.hangar.controller.api.v1;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import io.papermc.hangar.model.api.auth.ApiSession;
|
||||
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc
|
||||
class PermissionsControllerTest {
|
||||
|
||||
private static final String all = "a02f13bb-4329-4c85-984a-a817daacedcd.a240400b-bde2-4f4b-a432-ad7f9fb3ee0b";
|
||||
private static final String seeHidden = "bcbca881-87ba-4136-880d-4b387cb6cf03.14424bbc-9f4c-460e-ae13-cb4c4bae76d2";
|
||||
private static final String projectOnly = "b28dbeee-e1b6-44db-aa0d-a641208517ea.71c46fb3-47fc-4a12-8421-a121649fcb1d";
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
private String getJwt(String apiKey) throws Exception {
|
||||
String response = this.mockMvc.perform(post("/api/v1/authenticate?apiKey=" + apiKey)).andReturn().getResponse().getContentAsString();
|
||||
ApiSession apiSession = objectMapper.readValue(response, ApiSession.class);
|
||||
return apiSession.getToken();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHasAllWithProjectOnly() throws Exception {
|
||||
this.mockMvc.perform(get("/api/v1/permissions/hasAll?permissions=create_organization&permissions=create_project")
|
||||
.header("Authorization", "HangarAuth " + getJwt(projectOnly)))
|
||||
.andExpect(jsonPath("$.result").value(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHasAllWithAll() throws Exception {
|
||||
this.mockMvc.perform(get("/api/v1/permissions/hasAll?permissions=create_organization&permissions=create_project")
|
||||
.header("Authorization", "HangarAuth " + getJwt(all)))
|
||||
.andExpect(jsonPath("$.result").value(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHasAnyWithProjectOnly() throws Exception {
|
||||
this.mockMvc.perform(get("/api/v1/permissions/hasAny?permissions=create_organization&permissions=create_project")
|
||||
.header("Authorization", "HangarAuth " + getJwt(projectOnly)))
|
||||
.andExpect(jsonPath("$.result").value(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHasAnyWithAll() throws Exception {
|
||||
this.mockMvc.perform(get("/api/v1/permissions/hasAny?permissions=create_organization&permissions=create_project")
|
||||
.header("Authorization", "HangarAuth " + getJwt(all)))
|
||||
.andExpect(jsonPath("$.result").value(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHiddenProjectSeeHidden() throws Exception {
|
||||
this.mockMvc.perform(get("/api/v1/permissions/?author=paper&slug=Test")
|
||||
.header("Authorization", "HangarAuth " + getJwt(seeHidden)))
|
||||
.andExpect(jsonPath("$.permissionBinString").value("10000000000000000000000000"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testHiddenProjectProjectOnly() throws Exception {
|
||||
this.mockMvc.perform(get("/api/v1/permissions/?author=paper&slug=Test")
|
||||
.header("Authorization", "HangarAuth " + getJwt(projectOnly)))
|
||||
.andExpect(jsonPath("$.permissionBinString").value("100000000"));
|
||||
}
|
||||
}
|
20
src/test/resources/application-test.yml
Normal file
20
src/test/resources/application-test.yml
Normal file
@ -0,0 +1,20 @@
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:tc:postgresql:12.8:///
|
||||
username: ""
|
||||
password: ""
|
||||
|
||||
flyway:
|
||||
default-schema: public
|
||||
schemas: public
|
||||
locations:
|
||||
- classpath:db/test_migrations
|
||||
- classpath:db/migration
|
||||
- classpath:db/dummy_data
|
||||
baseline-version: 0.0
|
||||
|
||||
fake-user:
|
||||
enabled: true
|
||||
name: test
|
||||
username: test
|
||||
email: test@papermc.io
|
@ -0,0 +1,9 @@
|
||||
INSERT INTO api_keys (id, created_at, name, owner_id, token_identifier, token, raw_key_permissions)
|
||||
VALUES (1, '2022-07-30 18:14:43.016556 +00:00', 'all', 1, 'a02f13bb-4329-4c85-984a-a817daacedcd', '92453bc498244ba555e4533894cee3c764a4f0a1daec18ca77cb3712dda1d888', '0000000000000000000011110000111100001111001100001111011111110111');
|
||||
INSERT INTO api_keys (id, created_at, name, owner_id, token_identifier, token, raw_key_permissions)
|
||||
VALUES (2, '2022-07-30 18:19:52.775045 +00:00', 'onlyProject', 1, 'b28dbeee-e1b6-44db-aa0d-a641208517ea', '1bbdf12a58684e947d020d4a6856fae0025a037428c8d72429bdef3af1177f5b', '0000000000000000000000000000000000000000000000000000000100000000');
|
||||
INSERT INTO api_keys (id, created_at, name, owner_id, token_identifier, token, raw_key_permissions)
|
||||
VALUES (3, '2022-07-30 18:42:24.280005 +00:00', 'seeHidden', 1, 'bcbca881-87ba-4136-880d-4b387cb6cf03', '4c903e22e01448afc8ab50becc9d15152ec5131b6d54b24b443b3453fc85e5cb', '0000000000000000000000000000000000000010000000000000000000000000');
|
||||
|
||||
INSERT INTO projects (id, created_at, name, slug, owner_name, owner_id, topic_id, post_id, category, description, visibility, keywords, homepage, issues, source, support, license_type, license_name, license_url, forum_sync, donation_enabled, donation_subject, sponsors, wiki)
|
||||
VALUES (2, '2022-07-26 07:35:56.341943 +00:00', 'Test', 'Test', 'paper', 3, null, null, 0, 'Test', 1, '', null, null, null, null, 'Unspecified', null, null, true, false, null, '', null);
|
Loading…
Reference in New Issue
Block a user