Fine-grained permissions (#2535)

* Fine-grained permissions

Adds support for permissions of type <permission>(/<rsql filter scope>)

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>

* Apply review fixes

---------

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2025-07-10 13:51:49 +03:00
committed by GitHub
parent 7e8dd046e0
commit 21581c4ea4
69 changed files with 1492 additions and 1487 deletions

View File

@@ -39,7 +39,7 @@ import org.eclipse.hawkbit.repository.event.remote.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent;
import org.eclipse.hawkbit.repository.event.remote.TargetAttributesRequestedEvent;
import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent;
import org.eclipse.hawkbit.repository.jpa.RepositoryApplicationConfiguration;
import org.eclipse.hawkbit.repository.jpa.JpaRepositoryConfiguration;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.DistributionSet;
@@ -60,13 +60,17 @@ import org.springframework.amqp.support.converter.AbstractJavaTypeMapper;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.TestPropertySource;
@ActiveProfiles({ "test" })
/**
* Feature: Component Tests - Device Management Federation API<br/>
* Story: AmqpMessage Dispatcher Service Test
*/
@SpringBootTest(classes = { RepositoryApplicationConfiguration.class }, webEnvironment = SpringBootTest.WebEnvironment.NONE)
@ActiveProfiles({ "test" })
@SpringBootTest(classes = { JpaRepositoryConfiguration.class }, webEnvironment = SpringBootTest.WebEnvironment.NONE)
@TestPropertySource(properties = {
"spring.main.allow-bean-definition-overriding=true",
"spring.cloud.bus.enabled=true" })
class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
private static final String TENANT = "DEFAULT";

View File

@@ -71,15 +71,14 @@ import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConversionException;
import org.springframework.amqp.support.converter.MessageConverter;
@ExtendWith(MockitoExtension.class)
/**
* Feature: Component Tests - Device Management Federation API<br/>
* Story: AmqpMessage Handler Service Test
*/
@ExtendWith(MockitoExtension.class)
class AmqpMessageHandlerServiceTest {
private static final String FAIL_MESSAGE_AMQP_REJECT_REASON = AmqpRejectAndDontRequeueException.class
.getSimpleName() + " was expected, ";
private static final String FAIL_MESSAGE_AMQP_REJECT_REASON = AmqpRejectAndDontRequeueException.class.getSimpleName() + " was expected, ";
private static final String VIRTUAL_HOST = "vHost";
private static final String TENANT = "DEFAULT";

View File

@@ -31,11 +31,11 @@ import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConversionException;
@ExtendWith(MockitoExtension.class)
/**
* Feature: Component Tests - Device Management Federation API<br/>
* Story: Base Amqp Service Test
*/
@ExtendWith(MockitoExtension.class)
class BaseAmqpServiceTest {
@Mock

View File

@@ -42,7 +42,7 @@ import org.eclipse.hawkbit.integration.listener.ReplyToListener;
import org.eclipse.hawkbit.matcher.SoftwareModuleJsonMatcher;
import org.eclipse.hawkbit.rabbitmq.test.AbstractAmqpIntegrationTest;
import org.eclipse.hawkbit.rabbitmq.test.AmqpTestConfiguration;
import org.eclipse.hawkbit.repository.jpa.RepositoryApplicationConfiguration;
import org.eclipse.hawkbit.repository.jpa.JpaRepositoryConfiguration;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
@@ -66,7 +66,7 @@ import org.springframework.util.CollectionUtils;
*/
@ContextConfiguration(classes = {
DmfApiConfiguration.class, DmfTestConfiguration.class,
RepositoryApplicationConfiguration.class, AmqpTestConfiguration.class })
JpaRepositoryConfiguration.class, AmqpTestConfiguration.class })
abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpIntegrationTest {
protected static final String TENANT_EXIST = "DEFAULT";
@@ -93,9 +93,9 @@ abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpIntegratio
}
protected <T> T waitUntilIsPresent(final Callable<Optional<T>> callable) {
await().until(() -> SecurityContextSwitch.runAsPrivileged(() -> callable.call().isPresent()));
await().until(() -> SecurityContextSwitch.callAsPrivileged(() -> callable.call().isPresent()));
try {
return SecurityContextSwitch.runAsPrivileged(() -> callable.call().get());
return SecurityContextSwitch.callAsPrivileged(() -> callable.call().get());
} catch (final Exception e) {
return null;
}
@@ -367,7 +367,7 @@ abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpIntegratio
waitUntilIsPresent(() -> controllerManagement.getByControllerId(controllerId));
await().untilAsserted(() -> {
try {
final Map<String, String> controllerAttributes = SecurityContextSwitch.runAsPrivileged(
final Map<String, String> controllerAttributes = SecurityContextSwitch.callAsPrivileged(
() -> targetManagement.getControllerAttributes(controllerId));
assertThat(controllerAttributes).hasSameSizeAs(attributes);
assertThat(controllerAttributes).containsAllEntriesOf(attributes);

View File

@@ -794,7 +794,7 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
}
private void waitUntil(final Callable<Boolean> callable) {
await().until(() -> SecurityContextSwitch.runAsPrivileged(callable));
await().until(() -> SecurityContextSwitch.callAsPrivileged(callable));
}
private void assertLatestMultiActionMessageContainsInstallMessages(final String controllerId,

View File

@@ -1231,7 +1231,7 @@ class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServiceIntegr
private void assertAction(final Long actionId, final int messages, final Status... expectedActionStates) {
await().untilAsserted(() -> {
try {
SecurityContextSwitch.runAsPrivileged(() -> {
SecurityContextSwitch.callAsPrivileged(() -> {
final List<ActionStatus> actionStatusList = deploymentManagement.findActionStatusByAction(actionId, PAGE).getContent();
// Check correlation ID
@@ -1265,7 +1265,7 @@ class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServiceIntegr
final Status... expectedActionStates) {
await().untilAsserted(() -> {
try {
SecurityContextSwitch.runAsPrivileged(() -> {
SecurityContextSwitch.callAsPrivileged(() -> {
final List<ActionStatus> actionStatusList = deploymentManagement
.findActionStatusByAction(actionId, PAGE).getContent();
assertThat(actionStatusList).hasSize(statusListCount);