fix unction rbac.hasGlobalAdminRole() and add integration tests

This commit is contained in:
Michael Hoennig 2024-11-29 16:08:55 +01:00
parent b36712076d
commit 3633ca29d9
2 changed files with 63 additions and 10 deletions

View File

@ -46,15 +46,15 @@ create or replace function rbac.hasGlobalAdminRole()
stable -- leakproof stable -- leakproof
language plpgsql as $$ language plpgsql as $$
declare declare
currentSubjectOrAssumedRolesUuids text; assumedRoles text;
begin begin
begin begin
currentSubjectOrAssumedRolesUuids := current_setting('hsadminng.currentSubjectOrAssumedRolesUuids'); assumedRoles := current_setting('hsadminng.assumedRoles');
exception exception
when others then when others then
currentSubjectOrAssumedRolesUuids := null; assumedRoles := null;
end; end;
return currentSubjectOrAssumedRolesUuids is null or length(currentSubjectOrAssumedRolesUuids) = 0; return TRIM(COALESCE(assumedRoles, '')) = '' and rbac.isGlobalAdmin();
end; $$; end; $$;
--// --//

View File

@ -1,8 +1,8 @@
package net.hostsharing.hsadminng.rbac.context; package net.hostsharing.hsadminng.rbac.context;
import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.mapper.StandardMapper;
import net.hostsharing.hsadminng.mapper.Array; import net.hostsharing.hsadminng.mapper.Array;
import net.hostsharing.hsadminng.mapper.StandardMapper;
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
import net.hostsharing.hsadminng.rbac.test.JpaAttempt; import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -13,6 +13,8 @@ import org.springframework.context.annotation.ComponentScan;
import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -32,6 +34,9 @@ class ContextIntegrationTests {
@Autowired @Autowired
private JpaAttempt jpaAttempt; private JpaAttempt jpaAttempt;
@PersistenceContext
private EntityManager em;
@Test @Test
void defineWithoutHttpServletRequestUsesCallStack() { void defineWithoutHttpServletRequestUsesCallStack() {
@ -43,7 +48,7 @@ class ContextIntegrationTests {
@Test @Test
@Transactional @Transactional
void defineWithcurrentSubjectButWithoutAssumedRoles() { void defineWithCurrentSubjectButWithoutAssumedRoles() {
// when // when
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
@ -60,7 +65,7 @@ class ContextIntegrationTests {
} }
@Test @Test
void defineWithoutcurrentSubjectButWithAssumedRoles() { void defineWithoutCurrentSubjectButWithAssumedRoles() {
// when // when
final var result = jpaAttempt.transacted(() -> final var result = jpaAttempt.transacted(() ->
context.define(null, "rbactest.package#yyy00:ADMIN") context.define(null, "rbactest.package#yyy00:ADMIN")
@ -73,7 +78,7 @@ class ContextIntegrationTests {
} }
@Test @Test
void defineWithUnknowncurrentSubject() { void defineWithUnknownCurrentSubject() {
// when // when
final var result = jpaAttempt.transacted(() -> final var result = jpaAttempt.transacted(() ->
context.define("unknown@example.org") context.define("unknown@example.org")
@ -87,7 +92,7 @@ class ContextIntegrationTests {
@Test @Test
@Transactional @Transactional
void defineWithcurrentSubjectAndAssumedRoles() { void defineWithCurrentSubjectAndAssumedRoles() {
// given // given
context.define("superuser-alex@hostsharing.net", "rbactest.customer#xxx:OWNER;rbactest.customer#yyy:OWNER"); context.define("superuser-alex@hostsharing.net", "rbactest.customer#xxx:OWNER;rbactest.customer#yyy:OWNER");
@ -102,7 +107,7 @@ class ContextIntegrationTests {
} }
@Test @Test
public void defineContextWithcurrentSubjectAndAssumeInaccessibleRole() { public void defineContextWithCurrentSubjectAndAssumeInaccessibleRole() {
// when // when
final var result = jpaAttempt.transacted(() -> final var result = jpaAttempt.transacted(() ->
context.define("customer-admin@xxx.example.com", "rbactest.package#yyy00:ADMIN") context.define("customer-admin@xxx.example.com", "rbactest.package#yyy00:ADMIN")
@ -113,4 +118,52 @@ class ContextIntegrationTests {
jakarta.persistence.PersistenceException.class, jakarta.persistence.PersistenceException.class,
"ERROR: [403] subject customer-admin@xxx.example.com has no permission to assume role rbactest.package#yyy00:ADMIN"); "ERROR: [403] subject customer-admin@xxx.example.com has no permission to assume role rbactest.package#yyy00:ADMIN");
} }
@Test
public void hasGlobalAdminRoleIsTrueForGlobalAdminWithoutAssumedRole() {
final var hsGlobalAdminRole = jpaAttempt.transacted(() -> {
// given
context.define("superuser-alex@hostsharing.net");
// when
return (boolean) em.createNativeQuery("select rbac.hasGlobalAdminRole()").getSingleResult();
}
);
// then
assertThat(hsGlobalAdminRole.returnedValue()).isTrue();
}
@Test
public void hasGlobalAdminRoleIsTrueForGlobalAdminWithAssumedRole() {
final var hsGlobalAdminRole = jpaAttempt.transacted(() -> {
// given
context.define("superuser-alex@hostsharing.net", "rbactest.package#yyy00:ADMIN");
// when
return (boolean) em.createNativeQuery("select rbac.hasGlobalAdminRole()").getSingleResult();
});
// when
// then
assertThat(hsGlobalAdminRole.returnedValue()).isFalse();
}
@Test
public void hasGlobalAdminRoleIsFalseForNonGlobalAdminWithoutAssumedRole() {
final var hsGlobalAdminRole = jpaAttempt.transacted(() -> {
// given
context.define("customer-admin@xxx.example.com");
// when
return (boolean) em.createNativeQuery("select rbac.hasGlobalAdminRole()").getSingleResult();
}
);
// then
assertThat(hsGlobalAdminRole.returnedValue()).isFalse();
}
} }