frankgh commented on code in PR #165: URL: https://github.com/apache/cassandra-sidecar/pull/165#discussion_r1911920537
########## server/src/main/java/org/apache/cassandra/sidecar/routes/RingHandler.java: ########## @@ -1,101 +1,38 @@ -/* Review Comment: we should preserve the license header. ########## server-common/src/main/java/org/apache/cassandra/sidecar/common/server/exceptions/SchemaUnavailableException.java: ########## @@ -16,21 +16,21 @@ * limitations under the License. */ -package org.apache.cassandra.sidecar.exceptions; +package org.apache.cassandra.sidecar.common.server.exceptions; Review Comment: let's avoid moving classes to another package. ########## server/src/main/java/org/apache/cassandra/sidecar/routes/sstableuploads/SSTableImportHandler.java: ########## @@ -75,6 +82,13 @@ protected SSTableImportHandler(InstanceMetadataFetcher metadataFetcher, this.cache = cacheFactory.ssTableImportCache(); } + @Override + public Set<Authorization> requiredAuthorizations() + { + List<String> eligibleResources = VariableAwareResource.DATA_WITH_KEYSPACE_TABLE.expandedResources(); Review Comment: we are missing the CASSANDRA.MODIFY permission here ########## server/src/test/integration/org/apache/cassandra/sidecar/testing/IntegrationTestModule.java: ########## @@ -114,7 +120,15 @@ public SidecarConfiguration configuration() "password")) .build(); AccessControlConfiguration accessControlConfiguration = accessControlConfiguration(); + CassandraInputValidationConfiguration inputValidationConfiguration + = new CassandraInputValidationConfigurationImpl(DEFAULT_FORBIDDEN_KEYSPACES, + // some tests generate table folders with - + "[a-zA-Z][a-zA-Z0-9_-]{0,47}", Review Comment: this is not correct. For the stream sstable from snapshot endpoint we will get a table from the path that has the tableId. We should remove tableId from the path to be able to correctly validate. Otherwise my suspicion is that you will always get unauthorized for the table, because it won't match the table name ########## server/src/main/java/org/apache/cassandra/sidecar/routes/KeyspaceSchemaHandler.java: ########## @@ -0,0 +1,154 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.cassandra.sidecar.routes; + +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import com.datastax.driver.core.KeyspaceMetadata; +import com.datastax.driver.core.Metadata; +import com.google.inject.Inject; +import com.google.inject.Singleton; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.vertx.core.Future; +import io.vertx.core.http.HttpServerRequest; +import io.vertx.core.net.SocketAddress; +import io.vertx.ext.auth.authorization.Authorization; +import io.vertx.ext.auth.authorization.OrAuthorization; +import io.vertx.ext.web.RoutingContext; +import org.apache.cassandra.sidecar.acl.authorization.CassandraPermissions; +import org.apache.cassandra.sidecar.acl.authorization.SidecarPermissions; +import org.apache.cassandra.sidecar.acl.authorization.VariableAwareResource; +import org.apache.cassandra.sidecar.common.response.SchemaResponse; +import org.apache.cassandra.sidecar.common.server.data.Name; +import org.apache.cassandra.sidecar.concurrent.ExecutorPools; +import org.apache.cassandra.sidecar.utils.CassandraInputValidator; +import org.apache.cassandra.sidecar.utils.InstanceMetadataFetcher; +import org.apache.cassandra.sidecar.utils.MetadataUtils; + +import static org.apache.cassandra.sidecar.utils.HttpExceptions.wrapHttpException; + +/** + * The {@link SchemaHandler} class handles schema requests + */ +@Singleton +public class KeyspaceSchemaHandler extends AbstractHandler<Name> implements AccessProtected +{ + /** + * Constructs a handler with the provided {@code metadataFetcher} + * + * @param metadataFetcher the interface to retrieve metadata + * @param executorPools executor pools for blocking executions + * @param validator a validator instance to validate Cassandra-specific input + */ + @Inject + protected KeyspaceSchemaHandler(InstanceMetadataFetcher metadataFetcher, + ExecutorPools executorPools, + CassandraInputValidator validator) + { + super(metadataFetcher, executorPools, validator); + } + + @Override + public Set<Authorization> requiredAuthorizations() + { + List<String> eligibleResources = VariableAwareResource.DATA_WITH_KEYSPACE.expandedResources(); + OrAuthorization or = OrAuthorization.create(); Review Comment: Should this just be read_schema ########## server/src/main/java/org/apache/cassandra/sidecar/routes/AccessProtectedRouteBuilder.java: ########## @@ -0,0 +1,216 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.cassandra.sidecar.routes; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.stream.Collectors; + +import io.vertx.core.Handler; +import io.vertx.core.http.HttpMethod; +import io.vertx.ext.auth.authorization.AndAuthorization; +import io.vertx.ext.auth.authorization.Authorization; +import io.vertx.ext.auth.authorization.AuthorizationContext; +import io.vertx.ext.auth.authorization.AuthorizationProvider; +import io.vertx.ext.web.Route; +import io.vertx.ext.web.Router; +import io.vertx.ext.web.RoutingContext; +import io.vertx.ext.web.handler.BodyHandler; +import org.apache.cassandra.sidecar.acl.authorization.AdminIdentityResolver; +import org.apache.cassandra.sidecar.acl.authorization.AuthorizationWithAdminBypassHandler; +import org.apache.cassandra.sidecar.common.utils.Preconditions; +import org.apache.cassandra.sidecar.config.AccessControlConfiguration; +import org.apache.cassandra.sidecar.exceptions.ConfigurationException; + +import static org.apache.cassandra.sidecar.common.ApiEndpointsV1.KEYSPACE; +import static org.apache.cassandra.sidecar.common.ApiEndpointsV1.TABLE; + +/** + * Builder for building authorized routes + */ +public class AccessProtectedRouteBuilder +{ + private final AccessControlConfiguration accessControlConfiguration; + private final AuthorizationProvider authorizationProvider; + private final AdminIdentityResolver adminIdentityResolver; + + private Router router; + private HttpMethod method; + private String endpoint; + private boolean setBodyHandler; + private final List<Handler<RoutingContext>> handlers = new ArrayList<>(); + + public AccessProtectedRouteBuilder(AccessControlConfiguration accessControlConfiguration, + AuthorizationProvider authorizationProvider, + AdminIdentityResolver adminIdentityResolver) + { + this.accessControlConfiguration = accessControlConfiguration; + this.authorizationProvider = authorizationProvider; + this.adminIdentityResolver = adminIdentityResolver; + } + + /** + * Sets {@link Router} authorized route is built for + * + * @param router Router authorized route is built for + * @return a reference to {@link AccessProtectedRouteBuilder} for chaining + */ + public AccessProtectedRouteBuilder router(Router router) + { + this.router = router; + return this; + } + + /** + * Sets {@link HttpMethod} for route + * + * @param method HttpMethod set for route + * @return a reference to {@link AccessProtectedRouteBuilder} for chaining + */ + public AccessProtectedRouteBuilder method(HttpMethod method) + { + this.method = method; + return this; + } + + /** + * Sets path for route + * + * @param endpoint REST path for route + * @return a reference to {@link AccessProtectedRouteBuilder} for chaining + */ + public AccessProtectedRouteBuilder endpoint(String endpoint) + { + this.endpoint = endpoint; + return this; + } + + /** + * Sets if BodyHandler should be created for the route. + * + * @param setBodyHandler boolean flag indicating if route requires BodyHandler + * @return a reference to {@link AccessProtectedRouteBuilder} for chaining + */ + public AccessProtectedRouteBuilder setBodyHandler(Boolean setBodyHandler) + { + this.setBodyHandler = setBodyHandler; + return this; + } + + /** + * Adds handler to handler chain of route. Handlers are ordered, they are called in order they are set in chain. + * + * @param handler handler for route + * @return a reference to {@link AccessProtectedRouteBuilder} for chaining + */ + public AccessProtectedRouteBuilder handler(Handler<RoutingContext> handler) + { + this.handlers.add(handler); + return this; + } + + /** + * Builds an authorized route. Adds {@link io.vertx.ext.web.handler.AuthorizationHandler} at top of handler + * chain if access control is enabled. + */ + public void build() + { + Preconditions.checkArgument(router != null, "Router must be set"); + Preconditions.checkArgument(method != null, "Http method must be set"); + Preconditions.checkArgument(endpoint != null && !endpoint.isEmpty(), "Endpoint must be set"); Review Comment: NIT, use `Objects.requireNonNull` instead -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: pr-unsubscr...@cassandra.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: pr-unsubscr...@cassandra.apache.org For additional commands, e-mail: pr-h...@cassandra.apache.org