diff --git a/CHANGELOG.md b/CHANGELOG.md index d473959c9a..17c9126b5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Fixed +- Added validation of offsets availability when resetting subscription cursors. + +## [2.0.0] - 2017-08-09 + ### Changed - Changed imports format to have the same structure -### Fixed -- Added validation of offsets availability when resetting subscription cursors. +### Removed +- Removed read_scopes and write_scopes from event types +- Removed CHECK_APPLICATION_LEVEL_PERMISSIONS feature ## [1.1.3] - 2017-08-03 diff --git a/docs/_data/nakadi-event-bus-api.yaml b/docs/_data/nakadi-event-bus-api.yaml index 61fa4fdf04..db99ac8501 100644 --- a/docs/_data/nakadi-event-bus-api.yaml +++ b/docs/_data/nakadi-event-bus-api.yaml @@ -73,7 +73,7 @@ info: Other aspects of the Event Bus are at this moment to be defined and otherwise specified, not included in this version of this specification. - version: '0.8.0' + version: '0.9.0' contact: name: Team Aruha @ Zalando email: team-aruha+nakadi-maintainers@zalando.de @@ -2262,28 +2262,6 @@ definitions: authorization: $ref: '#/definitions/EventTypeAuthorization' - write_scopes: - type: array - items: - type: string - description: | - This field is used for event publishing access control. Nakadi only authorises publishers whose session - contains at least one of the scopes in this list. - If no scopes provided then anyone can publish to this event type. - - Usage of write_scopes is deprecated. - - read_scopes: - type: array - items: - type: string - description: | - This field is used for event consuming access control. Nakadi only authorises consumers whose session - contains at least one of the scopes in this list. - If no scopes provided then anyone can consume from this event type. - - Usage of read_scopes is deprecated. - created_at: type: string pattern: date-time diff --git a/src/main/java/org/zalando/nakadi/controller/CursorOperationsController.java b/src/main/java/org/zalando/nakadi/controller/CursorOperationsController.java index 234a3b5230..406ffa3d24 100644 --- a/src/main/java/org/zalando/nakadi/controller/CursorOperationsController.java +++ b/src/main/java/org/zalando/nakadi/controller/CursorOperationsController.java @@ -24,7 +24,6 @@ import org.zalando.nakadi.exceptions.runtime.CursorConversionException; import org.zalando.nakadi.exceptions.runtime.InvalidCursorOperation; import org.zalando.nakadi.exceptions.runtime.MyNakadiRuntimeException1; -import org.zalando.nakadi.exceptions.runtime.NoEventTypeException; import org.zalando.nakadi.repository.EventTypeRepository; import org.zalando.nakadi.security.Client; import org.zalando.nakadi.service.AuthorizationValidator; @@ -72,8 +71,6 @@ public CursorOperationsController(final CursorOperationsService cursorOperations public ResponseEntity getDistance(@PathVariable("eventTypeName") final String eventTypeName, @Valid @RequestBody final ValidListWrapper queries, final Client client) throws InternalNakadiException, NoSuchEventTypeException { - // TODO: remove once new authorization is in place - checkReadScopes(eventTypeName, client); final EventType eventType = eventTypeRepository.findByName(eventTypeName); authorizationValidator.authorizeStreamRead(eventType); @@ -102,8 +99,6 @@ public ResponseEntity getDistance(@PathVariable("eventTypeName") final String public ResponseEntity moveCursors(@PathVariable("eventTypeName") final String eventTypeName, @Valid @RequestBody final ValidListWrapper cursors, final Client client) throws InternalNakadiException, NoSuchEventTypeException { - // TODO: remove once new authorization is in place - checkReadScopes(eventTypeName, client); final EventType eventType = eventTypeRepository.findByName(eventTypeName); authorizationValidator.authorizeStreamRead(eventType); @@ -124,8 +119,6 @@ public ResponseEntity moveCursors(@PathVariable("eventTypeName") final String public List cursorsLag(@PathVariable("eventTypeName") final String eventTypeName, @Valid @RequestBody final ValidListWrapper cursors, final Client client) throws InternalNakadiException, NoSuchEventTypeException { - // TODO: remove once new authorization is in place - checkReadScopes(eventTypeName, client); final EventType eventType = eventTypeRepository.findByName(eventTypeName); authorizationValidator.authorizeStreamRead(eventType); @@ -163,18 +156,6 @@ private String clientErrorMessage(final InvalidCursorOperation.Reason reason) { } } - private void checkReadScopes(final String eventTypeName, final Client client) { - final EventType eventType; - try { - eventType = eventTypeRepository.findByName(eventTypeName); - client.checkScopes(eventType.getReadScopes()); - } catch (final InternalNakadiException e) { - throw new MyNakadiRuntimeException1("failed to get event type", e); - } catch (final NoSuchEventTypeException e) { - throw new NoEventTypeException(e.getMessage(), e); - } - } - private CursorLag toCursorLag(final NakadiCursorLag nakadiCursorLag) { return new CursorLag( nakadiCursorLag.getPartition(), diff --git a/src/main/java/org/zalando/nakadi/controller/EventStreamController.java b/src/main/java/org/zalando/nakadi/controller/EventStreamController.java index 9caede02b8..e2cb817490 100644 --- a/src/main/java/org/zalando/nakadi/controller/EventStreamController.java +++ b/src/main/java/org/zalando/nakadi/controller/EventStreamController.java @@ -24,7 +24,6 @@ import org.zalando.nakadi.domain.NakadiCursor; import org.zalando.nakadi.domain.PartitionStatistics; import org.zalando.nakadi.domain.Timeline; -import org.zalando.nakadi.exceptions.IllegalScopeException; import org.zalando.nakadi.exceptions.InternalNakadiException; import org.zalando.nakadi.exceptions.InvalidCursorException; import org.zalando.nakadi.exceptions.NakadiException; @@ -221,9 +220,6 @@ public StreamingResponseBody streamEvents( Collections.singletonList(eventTypeName))) { final EventType eventType = eventTypeRepository.findByName(eventTypeName); - // TODO: deprecate and remove previous authorization strategy - client.checkScopes(eventType.getReadScopes()); - authorizeStreamRead(eventTypeName); // validate parameters @@ -287,9 +283,6 @@ public StreamingResponseBody streamEvents( writeProblemResponse(response, outputStream, e.asProblem()); } catch (final InvalidCursorException e) { writeProblemResponse(response, outputStream, PRECONDITION_FAILED, e.getMessage()); - } catch (final IllegalScopeException e) { - // TODO: deprecate and remove previous authorization strategy - writeProblemResponse(response, outputStream, FORBIDDEN, e.getMessage()); } catch (final AccessDeniedException e) { writeProblemResponse(response, outputStream, FORBIDDEN, e.explain()); } catch (final Exception e) { diff --git a/src/main/java/org/zalando/nakadi/controller/ExceptionHandling.java b/src/main/java/org/zalando/nakadi/controller/ExceptionHandling.java index 9def832abb..67d5741104 100644 --- a/src/main/java/org/zalando/nakadi/controller/ExceptionHandling.java +++ b/src/main/java/org/zalando/nakadi/controller/ExceptionHandling.java @@ -11,7 +11,6 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.context.request.NativeWebRequest; import org.zalando.nakadi.exceptions.IllegalClientIdException; -import org.zalando.nakadi.exceptions.IllegalScopeException; import org.zalando.nakadi.exceptions.NakadiException; import org.zalando.nakadi.exceptions.NakadiRuntimeException; import org.zalando.nakadi.exceptions.TimelineException; @@ -84,12 +83,6 @@ public ResponseEntity accessDeniedException(final AccessDeniedException return Responses.create(Response.Status.FORBIDDEN, exception.explain(), request); } - @ExceptionHandler(IllegalScopeException.class) - public ResponseEntity handleIllegalScopeException(final IllegalScopeException exception, - final NativeWebRequest request) { - return Responses.create(Response.Status.FORBIDDEN, exception.getMessage(), request); - } - @ExceptionHandler(IllegalClientIdException.class) public ResponseEntity handleIllegalClientIdException(final IllegalClientIdException exception, final NativeWebRequest request) { diff --git a/src/main/java/org/zalando/nakadi/domain/EventTypeBase.java b/src/main/java/org/zalando/nakadi/domain/EventTypeBase.java index 1b754e4a17..9a209e2ab7 100644 --- a/src/main/java/org/zalando/nakadi/domain/EventTypeBase.java +++ b/src/main/java/org/zalando/nakadi/domain/EventTypeBase.java @@ -11,7 +11,6 @@ import javax.validation.constraints.Size; import java.util.Collections; import java.util.List; -import java.util.Set; import static java.util.Collections.unmodifiableList; @@ -58,10 +57,6 @@ public class EventTypeBase { @Valid private EventTypeAuthorization authorization; - private Set writeScopes; - - private Set readScopes; - private CompatibilityMode compatibilityMode; public EventTypeBase() { @@ -69,21 +64,18 @@ public EventTypeBase() { this.enrichmentStrategies = Collections.emptyList(); this.partitionStrategy = PartitionStrategy.RANDOM_STRATEGY; this.options = new EventTypeOptions(); - this.writeScopes = Collections.emptySet(); - this.readScopes = Collections.emptySet(); this.compatibilityMode = CompatibilityMode.FORWARD; } public EventTypeBase(final String name, final String topic, final String owningApplication, - final EventCategory category, - final List validationStrategies, - final List enrichmentStrategies, - final String partitionStrategy, - final List partitionKeyFields, final EventTypeSchemaBase schema, - final EventTypeStatistics defaultStatistic, - final EventTypeOptions options, final Set writeScopes, - final Set readScopes, - final CompatibilityMode compatibilityMode) { + final EventCategory category, + final List validationStrategies, + final List enrichmentStrategies, + final String partitionStrategy, + final List partitionKeyFields, final EventTypeSchemaBase schema, + final EventTypeStatistics defaultStatistic, + final EventTypeOptions options, + final CompatibilityMode compatibilityMode) { this.name = name; this.topic = topic; this.owningApplication = owningApplication; @@ -95,8 +87,6 @@ public EventTypeBase(final String name, final String topic, final String owningA this.schema = schema; this.defaultStatistic = defaultStatistic; this.options = options; - this.writeScopes = writeScopes; - this.readScopes = readScopes; this.compatibilityMode = compatibilityMode; } @@ -112,8 +102,6 @@ public EventTypeBase(final EventTypeBase eventType) { this.setSchema(eventType.getSchema()); this.setDefaultStatistic(eventType.getDefaultStatistic()); this.setOptions(eventType.getOptions()); - this.setWriteScopes(eventType.getWriteScopes()); - this.setReadScopes(eventType.getReadScopes()); this.setCompatibilityMode(eventType.getCompatibilityMode()); this.setAuthorization(eventType.getAuthorization()); } @@ -202,22 +190,6 @@ public void setOptions(final EventTypeOptions options) { this.options = options; } - public Set getWriteScopes() { - return Collections.unmodifiableSet(writeScopes); - } - - public void setWriteScopes(final Set writeScopes) { - this.writeScopes = writeScopes == null ? Collections.emptySet() : writeScopes; - } - - public Set getReadScopes() { - return Collections.unmodifiableSet(readScopes); - } - - public void setReadScopes(final Set readScopes) { - this.readScopes = readScopes == null ? Collections.emptySet() : readScopes; - } - public CompatibilityMode getCompatibilityMode() { return compatibilityMode; } diff --git a/src/main/java/org/zalando/nakadi/exceptions/IllegalScopeException.java b/src/main/java/org/zalando/nakadi/exceptions/IllegalScopeException.java deleted file mode 100644 index 68020e90e7..0000000000 --- a/src/main/java/org/zalando/nakadi/exceptions/IllegalScopeException.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.zalando.nakadi.exceptions; - -import java.util.Set; - -public class IllegalScopeException extends RuntimeException { - - private final Set missingScopes; - - public IllegalScopeException(final Set missingScopes) { - this.missingScopes = missingScopes; - } - - @Override - public String getMessage() { - return "Client has to have scopes: " + missingScopes; - } - -} \ No newline at end of file diff --git a/src/main/java/org/zalando/nakadi/security/Client.java b/src/main/java/org/zalando/nakadi/security/Client.java index e9f8f6c8f2..2ac13c4302 100644 --- a/src/main/java/org/zalando/nakadi/security/Client.java +++ b/src/main/java/org/zalando/nakadi/security/Client.java @@ -1,9 +1,5 @@ package org.zalando.nakadi.security; -import org.zalando.nakadi.exceptions.IllegalScopeException; - -import java.util.Set; - public abstract class Client { private final String clientId; @@ -12,8 +8,6 @@ public Client(final String clientId) { this.clientId = clientId; } - public abstract void checkScopes(Set allowedScopes) throws IllegalScopeException; - public String getClientId() { return clientId; } diff --git a/src/main/java/org/zalando/nakadi/security/ClientResolver.java b/src/main/java/org/zalando/nakadi/security/ClientResolver.java index f2a4392cde..7b0d229f97 100644 --- a/src/main/java/org/zalando/nakadi/security/ClientResolver.java +++ b/src/main/java/org/zalando/nakadi/security/ClientResolver.java @@ -20,7 +20,6 @@ import java.util.Set; import static org.zalando.nakadi.config.SecuritySettings.AuthMode.OFF; -import static org.zalando.nakadi.util.FeatureToggleService.Feature.CHECK_APPLICATION_LEVEL_PERMISSIONS; @Component public class ClientResolver implements HandlerMethodArgumentResolver { @@ -46,8 +45,7 @@ public Client resolveArgument(final MethodParameter parameter, final NativeWebRequest request, final WebDataBinderFactory binderFactory) throws Exception { final Optional clientId = Optional.ofNullable(request.getUserPrincipal()).map(Principal::getName); - if (!featureToggleService.isFeatureEnabled(CHECK_APPLICATION_LEVEL_PERMISSIONS) - || clientId.filter(settings.getAdminClientId()::equals).isPresent() + if (clientId.filter(settings.getAdminClientId()::equals).isPresent() || settings.getAuthMode() == OFF) { return new FullAccessClient(clientId.orElse(FULL_ACCESS_CLIENT_ID)); } diff --git a/src/main/java/org/zalando/nakadi/security/FullAccessClient.java b/src/main/java/org/zalando/nakadi/security/FullAccessClient.java index 6585b7b74b..9818d030d6 100644 --- a/src/main/java/org/zalando/nakadi/security/FullAccessClient.java +++ b/src/main/java/org/zalando/nakadi/security/FullAccessClient.java @@ -1,17 +1,9 @@ package org.zalando.nakadi.security; -import org.zalando.nakadi.exceptions.IllegalScopeException; - -import java.util.Set; - public class FullAccessClient extends Client { public FullAccessClient(final String clientId) { super(clientId); } - @Override - public void checkScopes(final Set allowedScopes) throws IllegalScopeException { - - } } diff --git a/src/main/java/org/zalando/nakadi/security/NakadiClient.java b/src/main/java/org/zalando/nakadi/security/NakadiClient.java index ce944fbec7..553982aa96 100644 --- a/src/main/java/org/zalando/nakadi/security/NakadiClient.java +++ b/src/main/java/org/zalando/nakadi/security/NakadiClient.java @@ -1,7 +1,5 @@ package org.zalando.nakadi.security; -import org.zalando.nakadi.exceptions.IllegalScopeException; - import java.util.Set; public class NakadiClient extends Client { @@ -12,15 +10,4 @@ public NakadiClient(final String clientId, final Set scopes) { super(clientId); this.scopes = scopes; } - - @Override - public void checkScopes(final Set allowedScopes) throws IllegalScopeException { - if (!allowedScopes.isEmpty()) { - allowedScopes.stream() - .filter(scopes::contains) - .findAny() - .orElseThrow(() -> new IllegalScopeException(allowedScopes)); - } - } - } diff --git a/src/main/java/org/zalando/nakadi/service/CursorsService.java b/src/main/java/org/zalando/nakadi/service/CursorsService.java index ee2bd4d3e6..0f2bbf4334 100644 --- a/src/main/java/org/zalando/nakadi/service/CursorsService.java +++ b/src/main/java/org/zalando/nakadi/service/CursorsService.java @@ -8,7 +8,6 @@ import org.zalando.nakadi.domain.EventTypePartition; import org.zalando.nakadi.domain.NakadiCursor; import org.zalando.nakadi.domain.Subscription; -import org.zalando.nakadi.exceptions.IllegalScopeException; import org.zalando.nakadi.exceptions.InternalNakadiException; import org.zalando.nakadi.exceptions.InvalidCursorException; import org.zalando.nakadi.exceptions.InvalidStreamIdException; @@ -17,7 +16,6 @@ import org.zalando.nakadi.exceptions.NoSuchEventTypeException; import org.zalando.nakadi.exceptions.NoSuchSubscriptionException; import org.zalando.nakadi.exceptions.ServiceUnavailableException; -import org.zalando.nakadi.exceptions.Try; import org.zalando.nakadi.exceptions.UnableProcessException; import org.zalando.nakadi.exceptions.runtime.CursorUnavailableException; import org.zalando.nakadi.exceptions.runtime.OperationTimeoutException; @@ -73,8 +71,7 @@ public CursorsService(final TimelineService timelineService, public List commitCursors(final String streamId, final String subscriptionId, final List cursors, final Client client) throws ServiceUnavailableException, InvalidCursorException, InvalidStreamIdException, - NoSuchEventTypeException, InternalNakadiException, NoSuchSubscriptionException, UnableProcessException, - IllegalScopeException { + NoSuchEventTypeException, InternalNakadiException, NoSuchSubscriptionException, UnableProcessException { if (cursors.isEmpty()) { throw new UnableProcessException("Cursors are absent"); } @@ -84,9 +81,6 @@ public List commitCursors(final String streamId, final String subscript TimeLogger.addMeasure("validateSubscriptionCursors"); validateSubscriptionCommitCursors(subscription, cursors); - TimeLogger.addMeasure("validateSubscriptionReadScopes"); - validateSubscriptionReadScopes(subscription, client); - TimeLogger.addMeasure("createSubscriptionClient"); final ZkSubscriptionClient zkClient = zkSubscriptionFactory.createClient( subscription, "subscription." + subscriptionId + "." + streamId + ".offsets"); @@ -128,7 +122,6 @@ private void validateStreamId(final List cursors, final String str public List getSubscriptionCursors(final String subscriptionId, final Client client) throws NakadiException { final Subscription subscription = subscriptionRepository.getSubscription(subscriptionId); - validateSubscriptionReadScopes(subscription, client); final ZkSubscriptionClient zkSubscriptionClient = zkSubscriptionFactory.createClient( subscription, "subscription." + subscriptionId + ".get_cursors"); final ImmutableList.Builder cursorsListBuilder = ImmutableList.builder(); @@ -147,14 +140,13 @@ public List getSubscriptionCursors(final String public void resetCursors(final String subscriptionId, final List cursors, final Client client) throws ServiceUnavailableException, NoSuchSubscriptionException, CursorUnavailableException, - UnableProcessException, IllegalScopeException, OperationTimeoutException, ZookeeperException, + UnableProcessException, OperationTimeoutException, ZookeeperException, InternalNakadiException, NoSuchEventTypeException { if (cursors.isEmpty()) { throw new UnableProcessException("Cursors are absent"); } final Subscription subscription = subscriptionRepository.getSubscription(subscriptionId); validateSubscriptionResetCursors(subscription, cursors); - validateSubscriptionReadScopes(subscription, client); final ZkSubscriptionClient zkClient = zkSubscriptionFactory.createClient( subscription, "subscription." + subscriptionId + ".reset_cursors"); @@ -208,13 +200,6 @@ private void validateCursorsBelongToSubscription(final Subscription subscription } } - private void validateSubscriptionReadScopes(final Subscription subscription, final Client client) - throws ServiceUnavailableException, NoSuchSubscriptionException, IllegalScopeException { - subscription.getEventTypes().stream().map(Try.wrap(eventTypeRepository::findByName)) - .map(Try::getOrThrow) - .forEach(eventType -> client.checkScopes(eventType.getReadScopes())); - } - private class SubscriptionCursorComparator implements Comparator { private final Map cached = new HashMap<>(); diff --git a/src/main/java/org/zalando/nakadi/service/EventPublisher.java b/src/main/java/org/zalando/nakadi/service/EventPublisher.java index 2c9f1e211c..936637d767 100644 --- a/src/main/java/org/zalando/nakadi/service/EventPublisher.java +++ b/src/main/java/org/zalando/nakadi/service/EventPublisher.java @@ -81,7 +81,6 @@ public EventPublishResult publish(final String events, final String eventTypeNam final EventType eventType = eventTypeCache.getEventType(eventTypeName); authValidator.authorizeEventTypeWrite(eventType); - client.checkScopes(eventType.getWriteScopes()); validate(batch, eventType); partition(batch, eventType); diff --git a/src/main/java/org/zalando/nakadi/service/subscription/SubscriptionService.java b/src/main/java/org/zalando/nakadi/service/subscription/SubscriptionService.java index 22687ea0d0..a7493d4a05 100644 --- a/src/main/java/org/zalando/nakadi/service/subscription/SubscriptionService.java +++ b/src/main/java/org/zalando/nakadi/service/subscription/SubscriptionService.java @@ -17,7 +17,6 @@ import org.zalando.nakadi.domain.SubscriptionBase; import org.zalando.nakadi.domain.SubscriptionEventTypeStats; import org.zalando.nakadi.domain.Timeline; -import org.zalando.nakadi.exceptions.IllegalScopeException; import org.zalando.nakadi.exceptions.InternalNakadiException; import org.zalando.nakadi.exceptions.InvalidCursorException; import org.zalando.nakadi.exceptions.NoSuchEventTypeException; @@ -93,7 +92,7 @@ public SubscriptionService(final SubscriptionDbRepository subscriptionRepository public Subscription createSubscription(final SubscriptionBase subscriptionBase, final Client client) throws TooManyPartitionsException, RepositoryProblemException, DuplicatedSubscriptionException, - NoEventTypeException, InconsistentStateException, WrongInitialCursorsException, IllegalScopeException { + NoEventTypeException, InconsistentStateException, WrongInitialCursorsException { subscriptionValidationService.validateSubscription(subscriptionBase, client); return subscriptionRepository.createSubscription(subscriptionBase); diff --git a/src/main/java/org/zalando/nakadi/service/subscription/SubscriptionValidationService.java b/src/main/java/org/zalando/nakadi/service/subscription/SubscriptionValidationService.java index dbd2420615..a772925e32 100644 --- a/src/main/java/org/zalando/nakadi/service/subscription/SubscriptionValidationService.java +++ b/src/main/java/org/zalando/nakadi/service/subscription/SubscriptionValidationService.java @@ -8,7 +8,6 @@ import org.zalando.nakadi.domain.EventTypePartition; import org.zalando.nakadi.domain.NakadiCursor; import org.zalando.nakadi.domain.SubscriptionBase; -import org.zalando.nakadi.exceptions.IllegalScopeException; import org.zalando.nakadi.exceptions.InternalNakadiException; import org.zalando.nakadi.exceptions.InvalidCursorException; import org.zalando.nakadi.exceptions.NakadiException; @@ -51,7 +50,7 @@ public SubscriptionValidationService(final TimelineService timelineService, public void validateSubscription(final SubscriptionBase subscription, final Client client) throws TooManyPartitionsException, RepositoryProblemException, NoEventTypeException, - InconsistentStateException, WrongInitialCursorsException, IllegalScopeException { + InconsistentStateException, WrongInitialCursorsException { // check that all event-types exist final Map> eventTypesOrNone = getSubscriptionEventTypesOrNone(subscription); @@ -62,9 +61,6 @@ public void validateSubscription(final SubscriptionBase subscription, final Clie .map(Optional::get) .collect(Collectors.toList()); - // check if application is allowed to read from the event-types - eventTypes.forEach(eventType -> client.checkScopes(eventType.getReadScopes())); - // check that maximum number of partitions is not exceeded final List allPartitions = getAllPartitions(eventTypes); if (allPartitions.size() > maxSubscriptionPartitions) { diff --git a/src/main/java/org/zalando/nakadi/util/FeatureToggleService.java b/src/main/java/org/zalando/nakadi/util/FeatureToggleService.java index f91630ef40..a13c6985dc 100644 --- a/src/main/java/org/zalando/nakadi/util/FeatureToggleService.java +++ b/src/main/java/org/zalando/nakadi/util/FeatureToggleService.java @@ -33,7 +33,6 @@ enum Feature { DISABLE_EVENT_TYPE_DELETION("disable_event_type_deletion"), DISABLE_SUBSCRIPTION_CREATION("disable_subscription_creation"), HIGH_LEVEL_API("high_level_api"), - CHECK_APPLICATION_LEVEL_PERMISSIONS("check_application_level_permissions"), CHECK_PARTITIONS_KEYS("check_partitions_keys"), CHECK_OWNING_APPLICATION("check_owning_application"), LIMIT_CONSUMERS_NUMBER("limit_consumers_number"), diff --git a/src/test/java/org/zalando/nakadi/controller/EventStreamControllerTest.java b/src/test/java/org/zalando/nakadi/controller/EventStreamControllerTest.java index dde468624f..a0612e3200 100644 --- a/src/test/java/org/zalando/nakadi/controller/EventStreamControllerTest.java +++ b/src/test/java/org/zalando/nakadi/controller/EventStreamControllerTest.java @@ -58,7 +58,6 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; -import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; @@ -92,7 +91,6 @@ public class EventStreamControllerTest { private static final String TEST_EVENT_TYPE_NAME = "test"; private static final String TEST_TOPIC = "test-topic"; private static final EventType EVENT_TYPE = TestUtils.buildDefaultEventType(); - private static final Set SCOPE_READ = Collections.singleton("oauth2.scope.read"); private static final String CLIENT_ID = "clientId"; private static final Client FULL_ACCESS_CLIENT = new FullAccessClient(CLIENT_ID); private static final String KAFKA_CLIENT_ID = CLIENT_ID + "-" + TEST_EVENT_TYPE_NAME; @@ -435,7 +433,7 @@ public void reportCurrentNumberOfConsumers() throws Exception { } @Test - public void testReadScope() throws Exception { + public void testRead() throws Exception { prepareScopeRead(); final ArgumentCaptor statusCaptor = getStatusCaptor(); final ArgumentCaptor contentTypeCaptor = getContentTypeCaptor(); @@ -443,30 +441,10 @@ public void testReadScope() throws Exception { when(eventStreamFactoryMock.createEventStream(any(), any(), any(), any())) .thenReturn(mock(EventStream.class)); - writeStream(SCOPE_READ); + writeStream(); assertThat(statusCaptor.getValue(), equalTo(HttpStatus.OK.value())); assertThat(contentTypeCaptor.getValue(), equalTo("application/x-json-stream")); - - clearScopes(); - } - - @Test - public void testNoReadScope() throws Exception { - prepareScopeRead(); - - final ArgumentCaptor statusCaptor = getStatusCaptor(); - final ArgumentCaptor contentTypeCaptor = getContentTypeCaptor(); - - when(eventStreamFactoryMock.createEventStream(any(), any(), any(), any())) - .thenReturn(mock(EventStream.class)); - - writeStream(Collections.emptySet()); - - assertThat(statusCaptor.getValue(), equalTo(HttpStatus.FORBIDDEN.value())); - assertThat(contentTypeCaptor.getValue(), equalTo("application/problem+json")); - - clearScopes(); } @Test @@ -483,12 +461,8 @@ public void testAccessDenied() throws Exception { assertThat(responseToString(responseBody), TestUtils.JSON_TEST_HELPER.matchesObject(expectedProblem)); } - private void clearScopes() { - EVENT_TYPE.setReadScopes(Collections.emptySet()); - } - - private void writeStream(final Set scopes) throws Exception { - final StreamingResponseBody responseBody = createStreamingResponseBody(new NakadiClient("clientId", scopes)); + private void writeStream() throws Exception { + final StreamingResponseBody responseBody = createStreamingResponseBody(new NakadiClient("clientId", null)); final OutputStream outputStream = mock(OutputStream.class); responseBody.writeTo(outputStream); } @@ -506,7 +480,6 @@ private ArgumentCaptor getStatusCaptor() { } private void prepareScopeRead() throws NakadiException, InvalidCursorException { - EVENT_TYPE.setReadScopes(SCOPE_READ); final EventConsumer.LowLevelConsumer eventConsumerMock = mock(EventConsumer.LowLevelConsumer.class); when(eventTypeRepository.findByName(TEST_EVENT_TYPE_NAME)).thenReturn(EVENT_TYPE); when(topicRepositoryMock.createEventConsumer( diff --git a/src/test/java/org/zalando/nakadi/controller/ExceptionHandlingTest.java b/src/test/java/org/zalando/nakadi/controller/ExceptionHandlingTest.java index cf07ea52e7..11639dc707 100644 --- a/src/test/java/org/zalando/nakadi/controller/ExceptionHandlingTest.java +++ b/src/test/java/org/zalando/nakadi/controller/ExceptionHandlingTest.java @@ -8,29 +8,12 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.context.request.NativeWebRequest; import org.zalando.nakadi.exceptions.IllegalClientIdException; -import org.zalando.nakadi.exceptions.IllegalScopeException; import org.zalando.problem.Problem; -import java.util.Collections; - public class ExceptionHandlingTest { private static final String OAUTH2_SCOPE_WRITE = "oauth2.scope.write"; - @Test - public void testHandleIllegalScopeException() { - final ExceptionHandling exceptionHandling = new ExceptionHandling(); - final NativeWebRequest mockedRequest = Mockito.mock(NativeWebRequest.class); - Mockito.when(mockedRequest.getHeader(Matchers.any())).thenReturn(""); - - final ResponseEntity problemResponseEntity = exceptionHandling.handleIllegalScopeException( - new IllegalScopeException(Collections.singleton(OAUTH2_SCOPE_WRITE)), mockedRequest); - - Assert.assertEquals(problemResponseEntity.getStatusCode(), HttpStatus.FORBIDDEN); - Assert.assertEquals(problemResponseEntity.getBody().getDetail().get(), - "Client has to have scopes: [" + OAUTH2_SCOPE_WRITE + "]"); - } - @Test public void testIllegalClientIdException() { final ExceptionHandling exceptionHandling = new ExceptionHandling(); diff --git a/src/test/java/org/zalando/nakadi/controller/PostSubscriptionControllerTest.java b/src/test/java/org/zalando/nakadi/controller/PostSubscriptionControllerTest.java index bcc4b000cb..dbef0193e3 100644 --- a/src/test/java/org/zalando/nakadi/controller/PostSubscriptionControllerTest.java +++ b/src/test/java/org/zalando/nakadi/controller/PostSubscriptionControllerTest.java @@ -19,7 +19,6 @@ import org.zalando.nakadi.domain.EventType; import org.zalando.nakadi.domain.Subscription; import org.zalando.nakadi.domain.SubscriptionBase; -import org.zalando.nakadi.exceptions.IllegalScopeException; import org.zalando.nakadi.exceptions.runtime.NoEventTypeException; import org.zalando.nakadi.exceptions.runtime.NoSubscriptionException; import org.zalando.nakadi.exceptions.runtime.TooManyPartitionsException; @@ -229,16 +228,6 @@ public void whenSubscriptionExistsThenReturnIt() throws Exception { .andExpect(header().doesNotExist("Content-Location")); } - @Test - public void whenPostSubscriptionWithNoReadScopeThenForbidden() throws Exception { - when(subscriptionService.getExistingSubscription(any())).thenThrow(new NoSubscriptionException("", null)); - when(subscriptionService.createSubscription(any(), any())) - .thenThrow(new IllegalScopeException(ImmutableSet.of("dummyScope"))); - - final Problem expectedProblem = Problem.valueOf(FORBIDDEN, "Client has to have scopes: [dummyScope]"); - checkForProblem(postSubscription(builder().buildSubscriptionBase()), expectedProblem); - } - @Test public void whenEventTypeIsNotAuthorizedThenForbidden() throws Exception { final Subscription subscription = mock(Subscription.class); diff --git a/src/test/java/org/zalando/nakadi/service/EventPublisherTest.java b/src/test/java/org/zalando/nakadi/service/EventPublisherTest.java index bde171aa7c..dd58773c81 100644 --- a/src/test/java/org/zalando/nakadi/service/EventPublisherTest.java +++ b/src/test/java/org/zalando/nakadi/service/EventPublisherTest.java @@ -18,7 +18,6 @@ import org.zalando.nakadi.exceptions.EnrichmentException; import org.zalando.nakadi.exceptions.EventPublishingException; import org.zalando.nakadi.exceptions.EventTypeTimeoutException; -import org.zalando.nakadi.exceptions.IllegalScopeException; import org.zalando.nakadi.exceptions.PartitioningException; import org.zalando.nakadi.exceptions.runtime.AccessDeniedException; import org.zalando.nakadi.partitioning.PartitionResolver; @@ -442,24 +441,16 @@ public void whenEnrichmentFailsThenSubsequentItemsAreAborted() throws Exception } @Test - public void testScopeWrite() throws Exception { - final EventType eventType = EventTypeTestBuilder.builder().writeScopes(SCOPE_WRITE).build(); + public void testWrite() throws Exception { + final EventType eventType = EventTypeTestBuilder.builder().build(); Mockito.when(cache.getEventType(eventType.getName())).thenReturn(eventType); mockSuccessfulValidation(eventType); final EventPublishResult result = publisher.publish(buildDefaultBatch(0).toString(), eventType.getName(), - new NakadiClient(CLIENT_ID, SCOPE_WRITE)); + new NakadiClient(CLIENT_ID, null)); Assert.assertEquals(result.getStatus(), EventPublishingStatus.SUBMITTED); } - @Test(expected = IllegalScopeException.class) - public void testNoScopeWrite() throws Exception { - final EventType eventType = EventTypeTestBuilder.builder().writeScopes(SCOPE_WRITE).build(); - Mockito.when(cache.getEventType(eventType.getName())).thenReturn(eventType); - publisher.publish(buildDefaultBatch(0).toString(), eventType.getName(), - new NakadiClient(CLIENT_ID, Collections.emptySet())); - } - private void mockFailedPublishing() throws Exception { Mockito .doThrow(EventPublishingException.class) diff --git a/src/test/java/org/zalando/nakadi/service/SubscriptionValidationServiceTest.java b/src/test/java/org/zalando/nakadi/service/SubscriptionValidationServiceTest.java index 183d4fceeb..855e91683e 100644 --- a/src/test/java/org/zalando/nakadi/service/SubscriptionValidationServiceTest.java +++ b/src/test/java/org/zalando/nakadi/service/SubscriptionValidationServiceTest.java @@ -40,8 +40,6 @@ import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; public class SubscriptionValidationServiceTest { @@ -75,7 +73,6 @@ public void setUp() throws InternalNakadiException { final EventType eventType = new EventType(); eventType.setName(etName); eventType.setTopic(topicForET(etName)); - eventType.setReadScopes(scopesForET(etName)); eventTypes.put(etName, eventType); } when(etRepo.findByNameO(any())) @@ -122,15 +119,6 @@ public void whenNoEventTypeThenException() throws Exception { } } - @Test - public void whenValidatingThenScopesAreChecked() throws Exception { - subscriptionBase.setReadFrom(SubscriptionBase.InitialPosition.BEGIN); - subscriptionValidationService.validateSubscription(subscriptionBase, client); - verify(client, times(1)).checkScopes(scopesForET(ET1)); - verify(client, times(1)).checkScopes(scopesForET(ET2)); - verify(client, times(1)).checkScopes(scopesForET(ET3)); - } - @Test(expected = TooManyPartitionsException.class) public void whenTooManyPartitionsThenException() throws Exception { when(topicRepository.listPartitionNames(argThat(isOneOf( diff --git a/src/test/java/org/zalando/nakadi/utils/EventTypeTestBuilder.java b/src/test/java/org/zalando/nakadi/utils/EventTypeTestBuilder.java index e829efce09..761245c963 100644 --- a/src/test/java/org/zalando/nakadi/utils/EventTypeTestBuilder.java +++ b/src/test/java/org/zalando/nakadi/utils/EventTypeTestBuilder.java @@ -17,9 +17,7 @@ import org.zalando.nakadi.domain.ValidationStrategyConfiguration; import org.zalando.nakadi.partitioning.PartitionStrategy; -import java.util.Collections; import java.util.List; -import java.util.Set; import static org.zalando.nakadi.utils.TestUtils.randomDate; @@ -38,8 +36,6 @@ public class EventTypeTestBuilder { private EventTypeSchema schema; private EventTypeStatistics defaultStatistic; private EventTypeOptions options; - private Set writeScopes; - private Set readScopes; private CompatibilityMode compatibilityMode; private DateTime createdAt; private DateTime updatedAt; @@ -59,8 +55,6 @@ public EventTypeTestBuilder() { "1.0.0", randomDate()); this.options = new EventTypeOptions(); this.options.setRetentionTime(172800000L); - this.writeScopes = Collections.emptySet(); - this.readScopes = Collections.emptySet(); this.compatibilityMode = CompatibilityMode.COMPATIBLE; this.createdAt = new DateTime(DateTimeZone.UTC); this.updatedAt = this.createdAt; @@ -133,16 +127,6 @@ public EventTypeTestBuilder options(final EventTypeOptions options) { return this; } - public EventTypeTestBuilder writeScopes(final Set writeScopes) { - this.writeScopes = writeScopes; - return this; - } - - public EventTypeTestBuilder readScopes(final Set readScopes) { - this.readScopes = readScopes; - return this; - } - public EventTypeTestBuilder compatibilityMode(final CompatibilityMode compatibilityMode) { this.compatibilityMode = compatibilityMode; return this; @@ -166,7 +150,7 @@ public EventTypeTestBuilder authorization(final EventTypeAuthorization authoriza public EventType build() { final EventTypeBase eventTypeBase = new EventTypeBase(name, topic, owningApplication, category, validationStrategies, enrichmentStrategies, partitionStrategy, partitionKeyFields, schema, - defaultStatistic, options, writeScopes, readScopes, compatibilityMode); + defaultStatistic, options, compatibilityMode); eventTypeBase.setAuthorization(authorization); return new EventType(eventTypeBase, this.schema.getVersion().toString(), this.createdAt, this.updatedAt); }