http://git-wip-us.apache.org/repos/asf/sentry/blob/e62fa28d/sentry-solr/solr-sentry-core/src/main/java/org/apache/solr/sentry/SecureRequestHandlerUtil.java ---------------------------------------------------------------------- diff --git a/sentry-solr/solr-sentry-core/src/main/java/org/apache/solr/sentry/SecureRequestHandlerUtil.java b/sentry-solr/solr-sentry-core/src/main/java/org/apache/solr/sentry/SecureRequestHandlerUtil.java deleted file mode 100644 index be9642b..0000000 --- a/sentry-solr/solr-sentry-core/src/main/java/org/apache/solr/sentry/SecureRequestHandlerUtil.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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.solr.sentry; - -import java.util.EnumSet; -import java.util.Set; -import org.apache.sentry.core.model.search.SearchModelAction; -import org.apache.solr.request.SolrQueryRequest; - -/** - * Utility functions for Secure (sentry-aware) versions of RequestHandlers - */ -public class SecureRequestHandlerUtil { - public static final Set<SearchModelAction> QUERY_ONLY = EnumSet.of(SearchModelAction.QUERY); - public static final Set<SearchModelAction> UPDATE_ONLY = EnumSet.of(SearchModelAction.UPDATE); - public static final Set<SearchModelAction> QUERY_AND_UPDATE = EnumSet.of(SearchModelAction.QUERY, SearchModelAction.UPDATE); - - // Hack to provide a test-only version of SentryIndexAuthorizationSingleton - public static SentryIndexAuthorizationSingleton testOverride = null; - - /** - * Attempt to authorize an administrative action. - * - * @param req request to check - * @param andActions set of actions to check - * @param checkCollection check the collection the action is on, or only "admin"? - * @param collection only relevant if checkCollection==true, - * use collection (if non-null) instead pulling collection name from req (if null) - */ - public static void checkSentryAdmin(SolrQueryRequest req, Set<SearchModelAction> andActions, - String operation, boolean checkCollection, String collection) { - checkSentry(req, andActions, operation, true, checkCollection, collection); - } - - /** - * Attempt to authorize a collection action. The collection - * name will be pulled from the request. - */ - public static void checkSentryCollection(SolrQueryRequest req, Set<SearchModelAction> andActions, String operation) { - checkSentry(req, andActions, operation, false, false, null); - } - - /** - * Attempt to sync collection privileges with Sentry when the metadata has changed. - * ex: When the collection has been deleted, the privileges related to the collection - * were also needed to drop. When the collection has been renamed, the privileges must been - * renamed too. - */ - public static void syncDeleteCollection(String collection) { - final SentryIndexAuthorizationSingleton sentryInstance = - (testOverride == null)?SentryIndexAuthorizationSingleton.getInstance():testOverride; - sentryInstance.deleteCollection(collection); - } - - private static void checkSentry(SolrQueryRequest req, Set<SearchModelAction> andActions, - String operation, boolean admin, boolean checkCollection, String collection) { - // Sentry currently does have AND support for actions; need to check - // actions one at a time - final SentryIndexAuthorizationSingleton sentryInstance = - (testOverride == null)?SentryIndexAuthorizationSingleton.getInstance():testOverride; - for (SearchModelAction action : andActions) { - if (admin) { - sentryInstance.authorizeAdminAction(req, EnumSet.of(action), operation, checkCollection, collection); - } else { - sentryInstance.authorizeCollectionAction(req, EnumSet.of(action), operation); - } - } - } -}
http://git-wip-us.apache.org/repos/asf/sentry/blob/e62fa28d/sentry-solr/solr-sentry-core/src/main/java/org/apache/solr/sentry/SentryIndexAuthorizationSingleton.java ---------------------------------------------------------------------- diff --git a/sentry-solr/solr-sentry-core/src/main/java/org/apache/solr/sentry/SentryIndexAuthorizationSingleton.java b/sentry-solr/solr-sentry-core/src/main/java/org/apache/solr/sentry/SentryIndexAuthorizationSingleton.java deleted file mode 100644 index 8bd93ad..0000000 --- a/sentry-solr/solr-sentry-core/src/main/java/org/apache/solr/sentry/SentryIndexAuthorizationSingleton.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * 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.solr.sentry; - -import java.net.URL; -import java.util.Set; - -import javax.servlet.http.HttpServletRequest; - -import org.apache.sentry.binding.solr.authz.SentrySolrAuthorizationException; -import org.apache.sentry.binding.solr.authz.SolrAuthzBinding; -import org.apache.sentry.binding.solr.conf.SolrAuthzConf; -import org.apache.sentry.core.common.Subject; -import org.apache.sentry.core.model.search.Collection; -import org.apache.sentry.core.model.search.SearchModelAction; -import org.apache.solr.common.SolrException; -import org.apache.solr.core.SolrCore; -import org.apache.solr.request.LocalSolrQueryRequest; -import org.apache.solr.request.SolrQueryRequest; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SentryIndexAuthorizationSingleton { - - private static final Logger LOG = - LoggerFactory.getLogger(SentryIndexAuthorizationSingleton.class); - - /** - * Java system property for specifying location of sentry-site.xml - */ - public static final String propertyName = "solr.authorization.sentry.site"; - - /** - * {@link HttpServletRequest} attribute for requesting user name - */ - public static final String USER_NAME = "solr.user.name"; - - /** - * {@link HttpServletRequest} attribute for requesting do as user. - */ - public static final String DO_AS_USER_NAME = "solr.do.as.user.name"; - - private static final SentryIndexAuthorizationSingleton INSTANCE = - new SentryIndexAuthorizationSingleton(System.getProperty(propertyName)); - - private final SolrAuthzBinding binding; - private final AuditLogger auditLogger = new AuditLogger(); - - private SentryIndexAuthorizationSingleton(String sentrySiteLocation) { - SolrAuthzBinding tmpBinding = null; - try { - if (sentrySiteLocation != null && sentrySiteLocation.length() > 0) { - tmpBinding = - new SolrAuthzBinding(new SolrAuthzConf(new URL("file://" + sentrySiteLocation))); - LOG.info("SolrAuthzBinding created successfully"); - } else { - LOG.info("SolrAuthzBinding not created because " + propertyName - + " not set, sentry not enabled"); - } - } catch (Exception ex) { - LOG.error("Unable to create SolrAuthzBinding", ex); - } - binding = tmpBinding; - } - - public static SentryIndexAuthorizationSingleton getInstance() { - return INSTANCE; - } - - /** - * Returns true iff Sentry index authorization checking is enabled - */ - public boolean isEnabled() { - return binding != null; - } - - /** - * Attempt to authorize an administrative action. - * - * @param req request to check - * @param actions set of actions to check - * @param checkCollection check the collection the action is on, or only "admin"? - * @param collection only relevant if checkCollection==true, - * use collection (if non-null) instead pulling collection name from req (if null) - */ - public void authorizeAdminAction(SolrQueryRequest req, - Set<SearchModelAction> actions, String operation, boolean checkCollection, String collection) - throws SolrException { - authorizeCollectionAction(req, actions, operation, "admin", true); - if (checkCollection) { - // Let's not error out if we can't find the collection associated with an - // admin action, it's pretty complicated to get all the possible administrative - // actions correct. Instead, let's warn in the log and address any issues we - // find. - authorizeCollectionAction(req, actions, operation, collection, false); - } - } - - /** - * Attempt to authorize a collection action. The collection - * name will be pulled from the request. - */ - public void authorizeCollectionAction(SolrQueryRequest req, - Set<SearchModelAction> actions, String operation) throws SolrException { - authorizeCollectionAction(req, actions, operation, null, true); - } - - /** - * Attempt to authorize a collection action. - * - * @param req request to check - * @param actions set of actions to check - * @param collectionName the collection to check. If null, the collection - * name is pulled from the request - * @param errorIfNoCollection is true, throw an exception if collection - * cannot be located - */ - public void authorizeCollectionAction(SolrQueryRequest req, - Set<SearchModelAction> actions, String operation, String collectionName, - boolean errorIfNoCollection) - throws SolrException { - - Subject superUser = new Subject(System.getProperty("solr.authorization.superuser", "solr")); - Subject userName = new Subject(getUserName(req)); - long eventTime = req.getStartTime(); - String paramString = req.getParamString(); - String impersonator = getImpersonatorName(req); - - String ipAddress = null; - HttpServletRequest sreq = (HttpServletRequest) req.getContext().get("httpRequest"); - if (sreq != null) { - try { - ipAddress = sreq.getRemoteAddr(); - } catch (AssertionError e) { - // ignore - // This is a work-around for "Unexpected method call getRemoteAddr()" - // exception during unit test mocking at - // com.sun.proxy.$Proxy28.getRemoteAddr(Unknown Source) - } - } - - String newCollectionName = collectionName; - if (newCollectionName == null) { - SolrCore solrCore = req.getCore(); - if (solrCore == null) { - String msg = "Unable to locate collection for sentry to authorize because " - + "no SolrCore attached to request"; - if (errorIfNoCollection) { - auditLogger.log(userName.getName(), impersonator, ipAddress, - operation, paramString, eventTime, AuditLogger.UNAUTHORIZED, ""); - throw new SolrException(SolrException.ErrorCode.UNAUTHORIZED, msg); - } else { // just warn - LOG.warn(msg); - auditLogger.log(userName.getName(), impersonator, ipAddress, - operation, paramString, eventTime, AuditLogger.ALLOWED, ""); - return; - } - } - newCollectionName = solrCore.getCoreDescriptor().getCloudDescriptor().getCollectionName(); - } - - Collection collection = new Collection(newCollectionName); - try { - if (!superUser.getName().equals(userName.getName())) { - binding.authorizeCollection(userName, collection, actions); - } - } catch (SentrySolrAuthorizationException ex) { - auditLogger.log(userName.getName(), impersonator, ipAddress, - operation, paramString, eventTime, AuditLogger.UNAUTHORIZED, newCollectionName); - throw new SolrException(SolrException.ErrorCode.UNAUTHORIZED, ex); - } - - auditLogger.log(userName.getName(), impersonator, ipAddress, - operation, paramString, eventTime, AuditLogger.ALLOWED, newCollectionName); - } - - /** - * Get the roles associated with the user - * @param userName to get roles for - * @return The roles associated with the user - */ - public Set<String> getRoles(String userName) { - if (binding == null) { - return null; - } - return binding.getRoles(userName); - } - - /** - * Get the user name associated with the request - * - * @param req the request - * @return the user name associated with the request - */ - public String getUserName(SolrQueryRequest req) throws SolrException { - if (binding == null) { - throw new SolrException(SolrException.ErrorCode.UNAUTHORIZED, - "Solr binding was not created successfully. Defaulting to no access"); - } - SolrCore solrCore = req.getCore(); - HttpServletRequest httpServletRequest = (HttpServletRequest)req.getContext().get("httpRequest"); - - // LocalSolrQueryRequests won't have the HttpServletRequest because there is no - // http request associated with it. - if (httpServletRequest == null && !(req instanceof LocalSolrQueryRequest)) { - StringBuilder builder = new StringBuilder("Unable to locate HttpServletRequest"); - if (solrCore != null && !solrCore.getSolrConfig().getBool( - "requestDispatcher/requestParsers/@addHttpRequestToContext", true)) { - builder.append(", ensure requestDispatcher/requestParsers/@addHttpRequestToContext is set to true"); - } - throw new SolrException(SolrException.ErrorCode.UNAUTHORIZED, builder.toString()); - } - - String superUser = System.getProperty("solr.authorization.superuser", "solr"); - // If a local request, treat it like a super user request; i.e. it is equivalent to an - // http request from the same process. - return req instanceof LocalSolrQueryRequest? - superUser : (String)httpServletRequest.getAttribute(USER_NAME); - } - - private String getImpersonatorName(SolrQueryRequest req) { - HttpServletRequest httpServletRequest = (HttpServletRequest)req.getContext().get("httpRequest"); - if (httpServletRequest != null) { - return (String)httpServletRequest.getAttribute(DO_AS_USER_NAME); - } - return null; - } - - /** - * Attempt to notify the Sentry service when deleting collection happened - * @param collection - * @throws SolrException - */ - public void deleteCollection(String collection) throws SolrException { - try { - binding.deleteCollectionPrivilege(collection); - } catch (SentrySolrAuthorizationException ex) { - throw new SolrException(SolrException.ErrorCode.UNAUTHORIZED, ex); - } - } -} http://git-wip-us.apache.org/repos/asf/sentry/blob/e62fa28d/sentry-solr/solr-sentry-handlers/pom.xml ---------------------------------------------------------------------- diff --git a/sentry-solr/solr-sentry-handlers/pom.xml b/sentry-solr/solr-sentry-handlers/pom.xml index 5b024db..72961fa 100644 --- a/sentry-solr/solr-sentry-handlers/pom.xml +++ b/sentry-solr/solr-sentry-handlers/pom.xml @@ -51,23 +51,23 @@ limitations under the License. </dependency> <dependency> <groupId>org.apache.sentry</groupId> - <artifactId>sentry-core-model-search</artifactId> + <artifactId>sentry-core-model-solr</artifactId> </dependency> <dependency> <groupId>org.apache.sentry</groupId> - <artifactId>sentry-provider-common</artifactId> + <artifactId>sentry-binding-solr</artifactId> </dependency> <dependency> <groupId>org.apache.sentry</groupId> - <artifactId>sentry-provider-file</artifactId> + <artifactId>sentry-provider-common</artifactId> </dependency> <dependency> <groupId>org.apache.sentry</groupId> - <artifactId>sentry-policy-common</artifactId> + <artifactId>sentry-provider-file</artifactId> </dependency> <dependency> <groupId>org.apache.sentry</groupId> - <artifactId>solr-sentry-core</artifactId> + <artifactId>sentry-policy-common</artifactId> </dependency> <dependency> <groupId>org.apache.solr</groupId> http://git-wip-us.apache.org/repos/asf/sentry/blob/e62fa28d/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/SecureDocumentAnalysisRequestHandler.java ---------------------------------------------------------------------- diff --git a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/SecureDocumentAnalysisRequestHandler.java b/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/SecureDocumentAnalysisRequestHandler.java deleted file mode 100644 index 1c1f6f8..0000000 --- a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/SecureDocumentAnalysisRequestHandler.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.solr.handler; - -import org.apache.solr.request.SolrQueryRequest; -import org.apache.solr.response.SolrQueryResponse; -import org.apache.solr.sentry.SecureRequestHandlerUtil; - -/** - * Secure (sentry-aware) version of DocumentAnalysisRequestHandler - */ -public class SecureDocumentAnalysisRequestHandler extends DocumentAnalysisRequestHandler { - @Override - public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception { - SecureRequestHandlerUtil.checkSentryCollection(req, SecureRequestHandlerUtil.QUERY_ONLY, getClass().getName()); - super.handleRequestBody(req, rsp); - } -} http://git-wip-us.apache.org/repos/asf/sentry/blob/e62fa28d/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/SecureFieldAnalysisRequestHandler.java ---------------------------------------------------------------------- diff --git a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/SecureFieldAnalysisRequestHandler.java b/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/SecureFieldAnalysisRequestHandler.java deleted file mode 100644 index 62f9a19..0000000 --- a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/SecureFieldAnalysisRequestHandler.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.solr.handler; - -import org.apache.solr.request.SolrQueryRequest; -import org.apache.solr.response.SolrQueryResponse; -import org.apache.solr.sentry.SecureRequestHandlerUtil; - -/** - * Secure (sentry-aware) version of FieldAnalysisRequestHandler - */ -public class SecureFieldAnalysisRequestHandler extends FieldAnalysisRequestHandler { - @Override - public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception { - SecureRequestHandlerUtil.checkSentryCollection(req, SecureRequestHandlerUtil.QUERY_ONLY, getClass().getName()); - super.handleRequestBody(req, rsp); - } -} http://git-wip-us.apache.org/repos/asf/sentry/blob/e62fa28d/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/SecureRealTimeGetHandler.java ---------------------------------------------------------------------- diff --git a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/SecureRealTimeGetHandler.java b/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/SecureRealTimeGetHandler.java deleted file mode 100644 index db182ef..0000000 --- a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/SecureRealTimeGetHandler.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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.solr.handler; - - -import org.apache.solr.handler.component.RealTimeGetComponent; -import org.apache.solr.handler.component.SecureRealTimeGetComponent; - -import java.util.ArrayList; -import java.util.List; - -public class SecureRealTimeGetHandler extends RealTimeGetHandler { - @Override - protected List<String> getDefaultComponents() - { - List<String> names = new ArrayList<>(1); - names.add(RealTimeGetComponent.COMPONENT_NAME); - names.add(SecureRealTimeGetComponent.COMPONENT_NAME); - return names; - } -} http://git-wip-us.apache.org/repos/asf/sentry/blob/e62fa28d/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/SecureReplicationHandler.java ---------------------------------------------------------------------- diff --git a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/SecureReplicationHandler.java b/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/SecureReplicationHandler.java deleted file mode 100644 index bdcd830..0000000 --- a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/SecureReplicationHandler.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.solr.handler; - -import org.apache.solr.request.SolrQueryRequest; -import org.apache.solr.response.SolrQueryResponse; -import org.apache.solr.sentry.SecureRequestHandlerUtil; - -/** - * Secure (sentry-aware) version of ReplicationHandler - */ -public class SecureReplicationHandler extends ReplicationHandler { - @Override - public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception { - String collection = null; - if (req.getCore() == null) { - // if the request doesn't have a core, let's use the core stored on the - // request handler - collection = core.getCoreDescriptor().getCloudDescriptor().getCollectionName(); - } - SecureRequestHandlerUtil.checkSentryAdmin(req, SecureRequestHandlerUtil.QUERY_AND_UPDATE, getClass().getName(), true, collection); - super.handleRequestBody(req, rsp); - } -} http://git-wip-us.apache.org/repos/asf/sentry/blob/e62fa28d/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/admin/SecureAdminHandlers.java ---------------------------------------------------------------------- diff --git a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/admin/SecureAdminHandlers.java b/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/admin/SecureAdminHandlers.java deleted file mode 100644 index 44db3b4..0000000 --- a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/admin/SecureAdminHandlers.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * 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.solr.handler.admin; - -import java.io.IOException; -import java.util.Map; - -import org.apache.solr.common.SolrException; -import org.apache.solr.core.CoreContainer; -import org.apache.solr.core.SolrCore; -import org.apache.solr.request.SolrQueryRequest; -import org.apache.solr.request.SolrRequestHandler; -import org.apache.solr.response.SolrQueryResponse; -import org.apache.solr.sentry.SecureRequestHandlerUtil; -import org.apache.solr.util.plugin.SolrCoreAware; -import org.apache.zookeeper.KeeperException; - -/** - * Secure version of AdminHandlers that creates Sentry-aware AdminHandlers. - */ -public class SecureAdminHandlers extends AdminHandlers { - - protected static class StandardHandler { - private final String name; - private final SolrRequestHandler handler; - - public StandardHandler( String n, SolrRequestHandler h ) - { - this.name = n; - this.handler = h; - } - } - - /** - * NOTE: ideally we'd just override the list of admin handlers, but - * since AdminHandlers in solr doesn't allow it, let's just copy the - * entire function. This is deprecated in Solr 5.0, so we should do something - * different with Solr 5.0 anyway. - */ - @Override - public void inform(SolrCore core) - { - String path = null; - for( Map.Entry<String, SolrRequestHandler> entry : core.getRequestHandlers().entrySet() ) { - if( entry.getValue() == this ) { - path = entry.getKey(); - break; - } - } - if( path == null ) { - throw new SolrException( SolrException.ErrorCode.SERVER_ERROR, - "The AdminHandler is not registered with the current core." ); - } - if( !path.startsWith( "/" ) ) { - throw new SolrException( SolrException.ErrorCode.SERVER_ERROR, - "The AdminHandler needs to be registered to a path. Typically this is '/admin'" ); - } - // Remove the parent handler - core.registerRequestHandler(path, null); - if( !path.endsWith( "/" ) ) { - path += "/"; - } - - StandardHandler[] list = new StandardHandler[] { - new StandardHandler( "luke", new SecureLukeRequestHandler() ), - new StandardHandler( "system", new SecureSystemInfoHandler() ), - new StandardHandler( "mbeans", new SecureSolrInfoMBeanHandler() ), - new StandardHandler( "plugins", new SecurePluginInfoHandler() ), - new StandardHandler( "threads", new SecureThreadDumpHandler() ), - new StandardHandler( "properties", new SecurePropertiesRequestHandler() ), - new StandardHandler( "logging", new SecureLoggingHandler() ), - new StandardHandler( "file", new SecureShowFileRequestHandler() ) - }; - - for( StandardHandler handler : list ) { - if( core.getRequestHandler( path+handler.name ) == null ) { - handler.handler.init( initArgs ); - core.registerRequestHandler( path+handler.name, handler.handler ); - if( handler.handler instanceof SolrCoreAware ) { - ((SolrCoreAware)handler.handler).inform(core); - } - } - } - } - - public static class SecureLoggingHandler extends LoggingHandler { - public SecureLoggingHandler(CoreContainer cc) { - super(cc); - } - - public SecureLoggingHandler() { - super(); - } - - @Override - public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception { - // logging handler can be used both to read and change logs - SecureRequestHandlerUtil.checkSentryAdmin(req, SecureRequestHandlerUtil.QUERY_AND_UPDATE, getClass().getName(), false, null); - super.handleRequestBody(req, rsp); - } - } - - public static class SecureLukeRequestHandler extends LukeRequestHandler { - @Override - public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception { - SecureRequestHandlerUtil.checkSentryAdmin(req, SecureRequestHandlerUtil.QUERY_ONLY, getClass().getName(), true, null); - super.handleRequestBody(req, rsp); - } - } - - public static class SecurePluginInfoHandler extends PluginInfoHandler { - @Override - public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception { - SecureRequestHandlerUtil.checkSentryAdmin(req, SecureRequestHandlerUtil.QUERY_ONLY, getClass().getName(), true, null); - super.handleRequestBody(req, rsp); - } - } - - public static class SecurePropertiesRequestHandler extends PropertiesRequestHandler { - @Override - public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws IOException { - SecureRequestHandlerUtil.checkSentryAdmin(req, SecureRequestHandlerUtil.QUERY_ONLY, getClass().getName(), false, null); - super.handleRequestBody(req, rsp); - } - } - - public static class SecureShowFileRequestHandler extends ShowFileRequestHandler { - @Override - public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) - throws IOException, KeeperException, InterruptedException { - SecureRequestHandlerUtil.checkSentryAdmin(req, SecureRequestHandlerUtil.QUERY_ONLY, getClass().getName(), true, null); - super.handleRequestBody(req, rsp); - } - } - - public static class SecureSolrInfoMBeanHandler extends SolrInfoMBeanHandler { - @Override - public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception { - SecureRequestHandlerUtil.checkSentryAdmin(req, SecureRequestHandlerUtil.QUERY_ONLY, getClass().getName(), true, null); - super.handleRequestBody(req, rsp); - } - } - - public static class SecureSystemInfoHandler extends SystemInfoHandler { - public SecureSystemInfoHandler() { - super(); - } - - public SecureSystemInfoHandler(CoreContainer cc) { - super(cc); - } - - @Override - public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception { - // this may or may not have the core - SolrCore core = req.getCore(); - SecureRequestHandlerUtil.checkSentryAdmin(req, SecureRequestHandlerUtil.QUERY_ONLY, getClass().getName(), core != null, null); - super.handleRequestBody(req, rsp); - } - } - - public static class SecureThreadDumpHandler extends ThreadDumpHandler { - @Override - public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws IOException { - SecureRequestHandlerUtil.checkSentryAdmin(req, SecureRequestHandlerUtil.QUERY_ONLY, getClass().getName(), false, null); - super.handleRequestBody(req, rsp); - } - } -} http://git-wip-us.apache.org/repos/asf/sentry/blob/e62fa28d/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/admin/SecureCollectionsHandler.java ---------------------------------------------------------------------- diff --git a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/admin/SecureCollectionsHandler.java b/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/admin/SecureCollectionsHandler.java deleted file mode 100644 index b5edf20..0000000 --- a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/admin/SecureCollectionsHandler.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.apache.solr.handler.admin; - -/* - * 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. - */ - -import org.apache.solr.common.params.SolrParams; -import org.apache.solr.common.params.CollectionParams.CollectionAction; -import org.apache.solr.common.params.CoreAdminParams; -import org.apache.solr.request.SolrQueryRequest; -import org.apache.solr.response.SolrQueryResponse; -import org.apache.solr.sentry.SecureRequestHandlerUtil; -import org.apache.solr.core.CoreContainer; - -/** - * Secure (sentry-aware) version of CollectionsHandler - */ -public class SecureCollectionsHandler extends CollectionsHandler { - - public SecureCollectionsHandler() { - super(); - } - - public SecureCollectionsHandler(final CoreContainer coreContainer) { - super(coreContainer); - } - - @Override - public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception { - // Pick the action - SolrParams params = req.getParams(); - CollectionAction action = null; - String a = params.get(CoreAdminParams.ACTION); - String collection = null; - if (a != null) { - action = CollectionAction.get(a); - } - if (action != null) { - switch (action) { - case CREATE: - case DELETE: - case RELOAD: - case CREATEALIAS: // FixMe: do we need to check the underlying "collections" as well? - case DELETEALIAS: - { - collection = req.getParams().required().get("name"); - break; - } - case SYNCSHARD: - case SPLITSHARD: - case DELETESHARD: { - collection = req.getParams().required().get("collection"); - break; - } - default: { - collection = null; - break; - } - } - } - // all actions require UPDATE privileges - SecureRequestHandlerUtil.checkSentryAdmin(req, SecureRequestHandlerUtil.UPDATE_ONLY, - (action != null ? "CollectionAction." + action.toString() : getClass().getName() + "/" + a), true, collection); - super.handleRequestBody(req, rsp); - - /** - * Attempt to sync collection privileges with Sentry when the metadata has changed. - * ex: When the collection has been deleted, the privileges related to the collection - * were also needed to drop. - */ - if (CollectionAction.DELETE.equals(action)) { - SecureRequestHandlerUtil.syncDeleteCollection(collection); - } - - } -} http://git-wip-us.apache.org/repos/asf/sentry/blob/e62fa28d/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/admin/SecureCoreAdminHandler.java ---------------------------------------------------------------------- diff --git a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/admin/SecureCoreAdminHandler.java b/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/admin/SecureCoreAdminHandler.java deleted file mode 100644 index ff6e281..0000000 --- a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/admin/SecureCoreAdminHandler.java +++ /dev/null @@ -1,181 +0,0 @@ -package org.apache.solr.handler.admin; - -/* - * 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. - */ - -import org.apache.solr.common.params.CoreAdminParams; -import org.apache.solr.common.params.CoreAdminParams.CoreAdminAction; -import org.apache.solr.common.params.SolrParams; -import org.apache.solr.core.CoreContainer; -import org.apache.solr.core.CoreDescriptor; -import org.apache.solr.core.SolrCore; -import org.apache.solr.request.SolrQueryRequest; -import org.apache.solr.response.SolrQueryResponse; -import org.apache.solr.sentry.SecureRequestHandlerUtil; - -/** - * Secure (sentry-aware) version of CoreAdminHandler - */ -public class SecureCoreAdminHandler extends CoreAdminHandler { - - public SecureCoreAdminHandler() { - super(); - } - - public SecureCoreAdminHandler(final CoreContainer coreContainer) { - super(coreContainer); - } - - private String getCollectionFromCoreName(String coreName) { - SolrCore solrCore = null; - try { - if (coreName != null && !coreName.equals("")) { - solrCore = coreContainer.getCore(coreName); - if (solrCore != null) { - return solrCore.getCoreDescriptor().getCloudDescriptor().getCollectionName(); - } - } - } finally { - if (solrCore != null) { - solrCore.close(); - } - } - return null; - } - - @Override - public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception { - SolrParams params = req.getParams(); - CoreAdminAction action = CoreAdminAction.STATUS; - String a = params.get(CoreAdminParams.ACTION); - if (a != null) { - action = CoreAdminAction.get(a); - if (action == null) { - // some custom action -- let's reqiure QUERY and UPDATE - SecureRequestHandlerUtil.checkSentryAdmin( - req, - SecureRequestHandlerUtil.QUERY_AND_UPDATE, - "CoreAdminAction." + a, - true, - null); - } - } - String collection = null; - boolean checkCollection = true; - if (action != null) { - switch (action) { - case RENAME: - case UNLOAD: - case RELOAD: - case SWAP: - case MERGEINDEXES: - case SPLIT: - case PREPRECOVERY: - case REQUESTRECOVERY: - case REQUESTSYNCSHARD: { - String cname = params.get(CoreAdminParams.CORE,""); - collection = getCollectionFromCoreName(cname); - break; - } - case CREATE: { - CoreDescriptor coreDescriptor = buildCoreDescriptor(params, coreContainer); - if (coreDescriptor != null) { - collection = coreDescriptor.getCloudDescriptor().getCollectionName(); - } - break; - } - case REQUESTAPPLYUPDATES: - case REQUESTBUFFERUPDATES: { - String cname = params.get(CoreAdminParams.NAME, ""); - collection = getCollectionFromCoreName(cname); - break; - } - case STATUS: - // CORE is an optional param for STATUS, but since the - // non-parameterized version returns all the core info, it doesn't - // make sense to check for core permissions. - case PERSIST: - case CREATEALIAS: - case DELETEALIAS: - case LOAD: - case LOAD_ON_STARTUP: - case TRANSIENT: - case REQUESTSTATUS: - case OVERSEEROP: - default: { - // these are actions that are not core related or not actually - // handled by the CoreAdminHandler - checkCollection = false; - break; - } - } - - switch (action) { - case STATUS: - case REQUESTSTATUS: { - SecureRequestHandlerUtil.checkSentryAdmin( - req, - SecureRequestHandlerUtil.QUERY_ONLY, - "CoreAdminAction." + action.toString(), - checkCollection, - collection); - break; - } - case LOAD: - case UNLOAD: - case RELOAD: - case CREATE: - case PERSIST: - case SWAP: - case RENAME: - case MERGEINDEXES: - case SPLIT: - case PREPRECOVERY: - case REQUESTRECOVERY: - case REQUESTSYNCSHARD: - case REQUESTAPPLYUPDATES: - // these next few aren't handled by the CoreAdminHandler currently, - // but let's check them just in case something changes - case CREATEALIAS: - case DELETEALIAS: - case LOAD_ON_STARTUP: - case TRANSIENT: - case REQUESTBUFFERUPDATES: - case OVERSEEROP: { - SecureRequestHandlerUtil.checkSentryAdmin( - req, - SecureRequestHandlerUtil.UPDATE_ONLY, - "CoreAdminAction." + action.toString(), - checkCollection, - collection); - break; - } - default: { - // some custom action -- let's reqiure QUERY and UPDATE - SecureRequestHandlerUtil.checkSentryAdmin( - req, - SecureRequestHandlerUtil.QUERY_AND_UPDATE, - "CoreAdminAction." + action.toString(), - checkCollection, - collection); - break; - } - } - } - super.handleRequestBody(req, rsp); - } -} http://git-wip-us.apache.org/repos/asf/sentry/blob/e62fa28d/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/admin/SecureInfoHandler.java ---------------------------------------------------------------------- diff --git a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/admin/SecureInfoHandler.java b/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/admin/SecureInfoHandler.java deleted file mode 100644 index 628d1d7..0000000 --- a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/admin/SecureInfoHandler.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.apache.solr.handler.admin; - -/* - * 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. - */ - -import org.apache.solr.core.CoreContainer; - -/** - * Secure version of InfoHandler that uses Sentry-aware request handlers - */ -public class SecureInfoHandler extends InfoHandler { - - public SecureInfoHandler(final CoreContainer coreContainer) { - super(coreContainer); - - setPropertiesHandler( new SecureAdminHandlers.SecurePropertiesRequestHandler() ); - setThreadDumpHandler( new SecureAdminHandlers.SecureThreadDumpHandler() ); - setLoggingHandler( new SecureAdminHandlers.SecureLoggingHandler(coreContainer) ); - setSystemInfoHandler( new SecureAdminHandlers.SecureSystemInfoHandler(coreContainer) ); - } - -} http://git-wip-us.apache.org/repos/asf/sentry/blob/e62fa28d/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/component/QueryDocAuthorizationComponent.java ---------------------------------------------------------------------- diff --git a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/component/QueryDocAuthorizationComponent.java b/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/component/QueryDocAuthorizationComponent.java index 933db43..2338ab8 100644 --- a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/component/QueryDocAuthorizationComponent.java +++ b/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/component/QueryDocAuthorizationComponent.java @@ -17,23 +17,24 @@ package org.apache.solr.handler.component; -import org.apache.lucene.index.Term; -import org.apache.lucene.search.BooleanClause; -import org.apache.lucene.search.BooleanQuery; -import org.apache.lucene.search.Query; -import org.apache.lucene.search.TermQuery; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; + +import org.apache.sentry.binding.solr.authz.SentrySolrPluginImpl; import org.apache.solr.common.SolrException; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.params.SolrParams; import org.apache.solr.common.util.NamedList; -import org.apache.solr.sentry.SentryIndexAuthorizationSingleton; -import com.google.common.annotations.VisibleForTesting; +import org.apache.solr.core.SolrCore; +import org.apache.solr.request.LocalSolrQueryRequest; +import org.apache.solr.request.SolrQueryRequest; +import org.apache.solr.security.AuthorizationPlugin; + import java.io.IOException; import java.util.Set; +import javax.servlet.http.HttpServletRequest; + public class QueryDocAuthorizationComponent extends SearchComponent { private static final Logger LOG = @@ -42,21 +43,11 @@ public class QueryDocAuthorizationComponent extends SearchComponent public static final String DEFAULT_AUTH_FIELD = "sentry_auth"; public static final String ALL_ROLES_TOKEN_PROP = "allRolesToken"; public static final String ENABLED_PROP = "enabled"; - private SentryIndexAuthorizationSingleton sentryInstance; + private static final String superUser = System.getProperty("solr.authorization.superuser", "solr"); private String authField; private String allRolesToken; private boolean enabled; - public QueryDocAuthorizationComponent() { - this(SentryIndexAuthorizationSingleton.getInstance()); - } - - @VisibleForTesting - public QueryDocAuthorizationComponent(SentryIndexAuthorizationSingleton sentryInstance) { - super(); - this.sentryInstance = sentryInstance; - } - @Override public void init(NamedList args) { SolrParams params = SolrParams.toSolrParams(args); @@ -89,43 +80,28 @@ public class QueryDocAuthorizationComponent extends SearchComponent return null; } - private BooleanClause getBooleanClause(String authField, String value) { - Term t = new Term(authField, value); - return new BooleanClause(new TermQuery(t), BooleanClause.Occur.SHOULD); - } - - public Query getFilterQuery(Set<String> roles) { - if (roles != null && roles.size() > 0) { - BooleanQuery query = new BooleanQuery(); - for (String role : roles) { - query.add(getBooleanClause(authField, role)); - } - if (allRolesToken != null && !allRolesToken.isEmpty()) { - query.add(getBooleanClause(authField, allRolesToken)); - } - return query; - } - - return null; - } - @Override public void prepare(ResponseBuilder rb) throws IOException { if (!enabled) { return; } - String userName = sentryInstance.getUserName(rb.req); - String superUser = System.getProperty("solr.authorization.superuser", "solr"); + String userName = getUserName(rb.req); if (superUser.equals(userName)) { return; } - Set<String> roles = sentryInstance.getRoles(userName); - if (roles != null && roles.size() > 0) { + + Set<String> roles = getRoles(rb.req, userName); + if (roles != null && !roles.isEmpty()) { String filterQuery = getFilterQueryStr(roles); + ModifiableSolrParams newParams = new ModifiableSolrParams(rb.req.getParams()); newParams.add("fq", filterQuery); rb.req.setParams(newParams); + if (LOG.isDebugEnabled()) { + LOG.debug("Adding filter query {} for user {} with roles {}", new Object[] {filterQuery, userName, roles}); + } + } else { throw new SolrException(SolrException.ErrorCode.UNAUTHORIZED, "Request from user: " + userName + @@ -142,12 +118,56 @@ public class QueryDocAuthorizationComponent extends SearchComponent return "Handle Query Document Authorization"; } - @Override - public String getSource() { - return "$URL$"; - } - public boolean getEnabled() { return enabled; } + + /** + * This method return the user name from the provided {@linkplain SolrQueryRequest} + */ + private String getUserName (SolrQueryRequest req) { + // If a local request, treat it like a super user request; i.e. it is equivalent to an + // http request from the same process. + if (req instanceof LocalSolrQueryRequest) { + return superUser; + } + + SolrCore solrCore = req.getCore(); + + HttpServletRequest httpServletRequest = (HttpServletRequest)req.getContext().get("httpRequest"); + if (httpServletRequest == null) { + StringBuilder builder = new StringBuilder("Unable to locate HttpServletRequest"); + if (solrCore != null && solrCore.getSolrConfig().getBool( + "requestDispatcher/requestParsers/@addHttpRequestToContext", true) == false) { + builder.append(", ensure requestDispatcher/requestParsers/@addHttpRequestToContext is set to true in solrconfig.xml"); + } + throw new SolrException(SolrException.ErrorCode.UNAUTHORIZED, builder.toString()); + } + + String userName = httpServletRequest.getRemoteUser(); + if (userName == null) { + userName = SentrySolrPluginImpl.getShortUserName(httpServletRequest.getUserPrincipal()); + } + if (userName == null) { + throw new SolrException(SolrException.ErrorCode.UNAUTHORIZED, "This request is not authenticated."); + } + + return userName; + } + + /** + * This method returns the roles associated with the specified <code>userName</code> + */ + private Set<String> getRoles (SolrQueryRequest req, String userName) { + SolrCore solrCore = req.getCore(); + + AuthorizationPlugin plugin = solrCore.getCoreContainer().getAuthorizationPlugin(); + if (!(plugin instanceof SentrySolrPluginImpl)) { + throw new SolrException(SolrException.ErrorCode.UNAUTHORIZED, getClass().getSimpleName() + + " can only be used with Sentry authorization plugin for Solr"); + } + + return ((SentrySolrPluginImpl)plugin).getRoles(userName); + } + } http://git-wip-us.apache.org/repos/asf/sentry/blob/e62fa28d/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/component/QueryIndexAuthorizationComponent.java ---------------------------------------------------------------------- diff --git a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/component/QueryIndexAuthorizationComponent.java b/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/component/QueryIndexAuthorizationComponent.java deleted file mode 100644 index 5fbb743..0000000 --- a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/component/QueryIndexAuthorizationComponent.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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.solr.handler.component; - -import org.apache.solr.common.util.StrUtils; -import org.apache.solr.sentry.SentryIndexAuthorizationSingleton; -import org.apache.sentry.core.model.search.SearchModelAction; -import com.google.common.annotations.VisibleForTesting; -import java.io.IOException; -import java.util.EnumSet; -import java.util.List; - -public class QueryIndexAuthorizationComponent extends SearchComponent -{ - private static final String OPERATION_NAME = "query"; - private SentryIndexAuthorizationSingleton sentryInstance; - - public QueryIndexAuthorizationComponent() { - this(SentryIndexAuthorizationSingleton.getInstance()); - } - - @VisibleForTesting - public QueryIndexAuthorizationComponent(SentryIndexAuthorizationSingleton sentryInstance) { - super(); - this.sentryInstance = sentryInstance; - } - - @Override - public void prepare(ResponseBuilder rb) throws IOException { - sentryInstance.authorizeCollectionAction( - rb.req, EnumSet.of(SearchModelAction.QUERY), OPERATION_NAME); - String collections = rb.req.getParams().get("collection"); - if (collections != null) { - List<String> collectionList = StrUtils.splitSmart(collections, ",", true); - // this may be an alias request: check each collection listed in "collections". - // NOTE1: this may involve checking a collection twice, because the collection - // on which this component is running may also be in the collections list, - // but this simplifies the logic. We don't want to only check the collections in the - // list, because the user can spoof this by adding collections to non-alias requests. - - // NOTE2: we only need to do this for queries, not for updates, because updates are only - // written to the first alias in the collection list, so are guaranteed to undergo the - // correct sentry check - for (String coll : collectionList) { - sentryInstance.authorizeCollectionAction(rb.req, EnumSet.of(SearchModelAction.QUERY), - OPERATION_NAME, coll, true); - } - } - } - - @Override - public void process(ResponseBuilder rb) throws IOException { - } - - @Override - public String getDescription() { - return "Handle Query Index Authorization"; - } - - @Override - public String getSource() { - return "$URL$"; - } -} http://git-wip-us.apache.org/repos/asf/sentry/blob/e62fa28d/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/component/SecureRealTimeGetComponent.java ---------------------------------------------------------------------- diff --git a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/component/SecureRealTimeGetComponent.java b/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/component/SecureRealTimeGetComponent.java deleted file mode 100644 index 7d55a7f..0000000 --- a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/handler/component/SecureRealTimeGetComponent.java +++ /dev/null @@ -1,356 +0,0 @@ -/* - * 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.solr.handler.component; - -import org.apache.lucene.document.Document; -import org.apache.lucene.index.AtomicReaderContext; -import org.apache.lucene.index.IndexableField; -import org.apache.lucene.document.Field; -import org.apache.lucene.search.Query; -import org.apache.lucene.search.Scorer; -import org.apache.lucene.search.Weight; -import org.apache.lucene.util.BytesRef; - -import org.apache.solr.common.SolrDocument; -import org.apache.solr.common.SolrDocumentList; -import org.apache.solr.common.SolrException; -import org.apache.solr.core.SolrCore; -import org.apache.solr.schema.FieldType; -import org.apache.solr.schema.SchemaField; -import org.apache.solr.request.SolrQueryRequest; -import org.apache.solr.response.SolrQueryResponse; -import org.apache.solr.response.transform.DocTransformer; -import org.apache.solr.response.transform.DocTransformers; -import org.apache.solr.response.transform.TransformContext; -import org.apache.solr.schema.IndexSchema; -import org.apache.solr.search.SolrIndexSearcher; -import org.apache.solr.search.SolrReturnFields; -import org.apache.solr.sentry.SentryIndexAuthorizationSingleton; -import org.apache.solr.update.AddUpdateCommand; -import org.apache.solr.update.UpdateCommand; -import org.apache.solr.update.UpdateLog; -import org.apache.solr.util.RefCounted; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.annotations.VisibleForTesting; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -public class SecureRealTimeGetComponent extends SearchComponent -{ - private static final Logger LOG = - LoggerFactory.getLogger(SecureRealTimeGetComponent.class); - public static final String ID_FIELD_NAME = "_reserved_sentry_id"; - public static final String COMPONENT_NAME = "secureGet"; - - private SentryIndexAuthorizationSingleton sentryInstance; - - public SecureRealTimeGetComponent() { - this(SentryIndexAuthorizationSingleton.getInstance()); - } - - @VisibleForTesting - public SecureRealTimeGetComponent(SentryIndexAuthorizationSingleton sentryInstance) { - super(); - this.sentryInstance = sentryInstance; - } - - @Override - public void prepare(ResponseBuilder rb) throws IOException { - QueryDocAuthorizationComponent docComponent = - (QueryDocAuthorizationComponent)rb.req.getCore().getSearchComponent("queryDocAuthorization"); - if (docComponent != null) { - String userName = sentryInstance.getUserName(rb.req); - String superUser = (System.getProperty("solr.authorization.superuser", "solr")); - // security is never applied to the super user; for example, if solr internally is using - // real time get for replica synchronization, we need to return all the documents. - if (docComponent.getEnabled() && !superUser.equals(userName)) { - Set<String> roles = sentryInstance.getRoles(userName); - if (roles != null && roles.size() > 0) { - SolrReturnFields savedReturnFields = (SolrReturnFields)rb.rsp.getReturnFields(); - if (savedReturnFields == null) { - throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, - "Not able to authorize request because ReturnFields is null"); - } - DocTransformer savedTransformer = savedReturnFields.getTransformer(); - Query filterQuery = docComponent.getFilterQuery(roles); - if (filterQuery != null) { - SolrReturnFields solrReturnFields = new AddDocIdReturnFields(rb.req, savedTransformer, filterQuery); - rb.rsp.setReturnFields(solrReturnFields); - } else { - throw new SolrException(SolrException.ErrorCode.UNAUTHORIZED, - "Request from user: " + userName + - "rejected because filter query was unable to be generated"); - } - } else { - throw new SolrException(SolrException.ErrorCode.UNAUTHORIZED, - "Request from user: " + userName + - " rejected because user is not associated with any roles"); - } - } - } else { - throw new SolrException(SolrException.ErrorCode.UNAUTHORIZED, - "RealTimeGetRequest request " + - " rejected because \"queryDocAuthorization\" component not defined"); - } - } - - @Override - public void process(ResponseBuilder rb) throws IOException { - if (!(rb.rsp.getReturnFields() instanceof AddDocIdReturnFields)) { - LOG.info("Skipping application of SecureRealTimeGetComponent because " - + " return field wasn't applied in prepare phase"); - return; - } - - final SolrQueryResponse rsp = rb.rsp; - ResponseFormatDocs responseFormatDocs = getResponseFormatDocs(rsp); - if (responseFormatDocs == null) { - return; // no documents to check - } - final SolrDocumentList docList = responseFormatDocs.getDocList(); - final AddDocIdReturnFields addDocIdRf = (AddDocIdReturnFields)rb.rsp.getReturnFields(); - final Query filterQuery = addDocIdRf.getFilterQuery(); - final DocTransformer transformer = addDocIdRf.getOriginalTransformer(); - - // we replaced the original transfer in order to add the document id, reapply it here - // so return documents in the correct format. - if (transformer != null) { - TransformContext context = new TransformContext(); - context.req = rb.req; - transformer.setContext(context); - } - - SolrCore core = rb.req.getCore(); - UpdateLog ulog = core.getUpdateHandler().getUpdateLog(); - SchemaField idField = core.getLatestSchema().getUniqueKeyField(); - FieldType fieldType = idField.getType(); - boolean openedRealTimeSearcher = false; - RefCounted<SolrIndexSearcher> searcherHolder = core.getRealtimeSearcher(); - - SolrDocumentList docListToReturn = new SolrDocumentList(); - try { - SolrIndexSearcher searcher = searcherHolder.get(); - for (SolrDocument doc : docList) { - // -1 doc id indicates this value was read from log; we need to open - // a new real time searcher to run the filter query against - if (Integer.valueOf(-1).equals(doc.get(ID_FIELD_NAME)) && !openedRealTimeSearcher) { - searcherHolder.decref(); - // hack to clear ulog maps since we don't have - // openRealtimeSearcher API from SOLR-8436 - AddUpdateCommand cmd = new AddUpdateCommand(rb.req); - cmd.setFlags(UpdateCommand.REPLAY); - ulog.add(cmd, true); - - searcherHolder = core.getRealtimeSearcher(); - searcher = searcherHolder.get(); - openedRealTimeSearcher = true; - } - - int docid = getFilteredInternalDocId(doc, idField, fieldType, filterQuery, searcher); - if (docid < 0) { - continue; - } - Document luceneDocument = searcher.doc(docid); - SolrDocument newDoc = toSolrDoc(luceneDocument, core.getLatestSchema()); - if( transformer != null ) { - transformer.transform(newDoc, docid); - } - docListToReturn.add(newDoc); - } - } finally { - searcherHolder.decref(); - searcherHolder = null; - } - if (responseFormatDocs.getUseResponseField()) { - rsp.getValues().remove("response"); - docListToReturn.setNumFound(docListToReturn.size()); - rsp.add("response", docListToReturn); - } else { - rsp.getValues().remove("doc"); - rsp.add("doc", docListToReturn.size() > 0 ? docListToReturn.get(0) : null); - } - } - - private static SolrDocument toSolrDoc(Document doc, IndexSchema schema) { - SolrDocument out = new SolrDocument(); - for ( IndexableField f : doc.getFields() ) { - // Make sure multivalued fields are represented as lists - Object existing = out.get(f.name()); - if (existing == null) { - SchemaField sf = schema.getFieldOrNull(f.name()); - - // don't return copyField targets - if (sf != null && schema.isCopyFieldTarget(sf)) { - continue; - } - - if (sf != null && sf.multiValued()) { - List<Object> vals = new ArrayList<>(); - vals.add( f ); - out.setField( f.name(), vals ); - } - else{ - out.setField( f.name(), f ); - } - } - else { - out.addField( f.name(), f ); - } - } - return out; - } - - // get the response format to use and the documents to check - private static ResponseFormatDocs getResponseFormatDocs(final SolrQueryResponse rsp) { - SolrDocumentList docList = (SolrDocumentList)rsp.getValues().get("response"); - SolrDocument singleDoc = (SolrDocument)rsp.getValues().get("doc"); - if (docList == null && singleDoc == null) { - return null; // no documents to filter - } - if (docList != null && singleDoc != null) { - throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, - "Not able to filter secure reponse, RealTimeGet returned both a doc list and " + - "an individual document"); - } - final boolean useResponseField = docList != null; - if (docList == null) { - docList = new SolrDocumentList(); - docList.add(singleDoc); - } - return new ResponseFormatDocs(useResponseField, docList); - } - - /** - * @param doc SolrDocument to check - * @param idField field where the id is stored - * @param fieldType type of id field - * @param filterQuery Query to filter by - * @param searcher SolrIndexSearcher on which to apply the filter query - * @returns the internal docid, or -1 if doc is not found or doesn't match filter - */ - private static int getFilteredInternalDocId(SolrDocument doc, SchemaField idField, FieldType fieldType, - Query filterQuery, SolrIndexSearcher searcher) throws IOException { - int docid = -1; - Field f = (Field)doc.getFieldValue(idField.getName()); - String idStr = f.stringValue(); - BytesRef idBytes = new BytesRef(); - fieldType.readableToIndexed(idStr, idBytes); - // get the internal document id - long segAndId = searcher.lookupId(idBytes); - - // if docid is valid, run it through the filter - if (segAndId >= 0) { - int segid = (int) segAndId; - AtomicReaderContext ctx = searcher.getTopReaderContext().leaves().get((int) (segAndId >> 32)); - docid = segid + ctx.docBase; - Weight weight = filterQuery.createWeight(searcher); - Scorer scorer = weight.scorer(ctx, null); - if (scorer == null || segid != scorer.advance(segid)) { - // filter doesn't match. - docid = -1; - } - } - return docid; - } - - @Override - public String getDescription() { - return "Handle Query Document Authorization for RealTimeGet"; - } - - @Override - public String getSource() { - return "$URL$"; - } - - private static class ResponseFormatDocs { - private boolean useResponseField; - private SolrDocumentList docList; - - public ResponseFormatDocs(boolean useResponseField, SolrDocumentList docList) { - this.useResponseField = useResponseField; - this.docList = docList; - } - - public boolean getUseResponseField() { return useResponseField; } - public SolrDocumentList getDocList() { return docList; } - } - - // ReturnField that adds a transformer to store the document id - private static class AddDocIdReturnFields extends SolrReturnFields { - private DocTransformer transformer; - private DocTransformer originalTransformer; - private Query filterQuery; - - public AddDocIdReturnFields(SolrQueryRequest req, DocTransformer docTransformer, - Query filterQuery) { - super(req); - this.originalTransformer = docTransformer; - this.filterQuery = filterQuery; - final DocTransformers docTransformers = new DocTransformers(); - if (originalTransformer != null) { - docTransformers.addTransformer(originalTransformer); - } - docTransformers.addTransformer(new DocIdAugmenter(ID_FIELD_NAME)); - this.transformer = docTransformers; - } - - @Override - public DocTransformer getTransformer() { - return transformer; - } - - public DocTransformer getOriginalTransformer() { - return originalTransformer; - } - - public Query getFilterQuery() { - return filterQuery; - } - } - - // the Solr DocIdAugmenterFactory does not store negative doc ids; - // we do here. - private static class DocIdAugmenter extends DocTransformer - { - private final String name; - - public DocIdAugmenter( String display ) - { - this.name = display; - } - - @Override - public String getName() - { - return name; - } - - @Override - public void transform(SolrDocument doc, int docid) { - doc.setField( name, docid ); - } - } - -} http://git-wip-us.apache.org/repos/asf/sentry/blob/e62fa28d/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/update/processor/UpdateIndexAuthorizationProcessor.java ---------------------------------------------------------------------- diff --git a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/update/processor/UpdateIndexAuthorizationProcessor.java b/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/update/processor/UpdateIndexAuthorizationProcessor.java deleted file mode 100644 index d995a7d..0000000 --- a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/update/processor/UpdateIndexAuthorizationProcessor.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.apache.solr.update.processor; - -/* - * 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. - */ - -import org.apache.solr.common.SolrException; -import org.apache.solr.request.SolrQueryRequest; -import org.apache.solr.response.SolrQueryResponse; -import org.apache.solr.sentry.SentryIndexAuthorizationSingleton; -import org.apache.solr.update.AddUpdateCommand; -import org.apache.solr.update.CommitUpdateCommand; -import org.apache.solr.update.DeleteUpdateCommand; -import org.apache.solr.update.MergeIndexesCommand; -import org.apache.solr.update.RollbackUpdateCommand; -import org.apache.sentry.core.model.search.SearchModelAction; - -import com.google.common.annotations.VisibleForTesting; - -import java.io.IOException; -import java.util.EnumSet; - -public class UpdateIndexAuthorizationProcessor extends UpdateRequestProcessor { - - private SolrQueryRequest req; - private SentryIndexAuthorizationSingleton sentryInstance; - - public UpdateIndexAuthorizationProcessor(SolrQueryRequest req, - SolrQueryResponse rsp, UpdateRequestProcessor next) { //NOPMD - this(SentryIndexAuthorizationSingleton.getInstance(), req, next); - } - - @VisibleForTesting - public UpdateIndexAuthorizationProcessor(SentryIndexAuthorizationSingleton sentryInstance, - SolrQueryRequest req, UpdateRequestProcessor next) { - super(next); - this.sentryInstance = sentryInstance; - this.req = req; - } - - private void authorizeCollectionAction(String operation) throws SolrException { - sentryInstance.authorizeCollectionAction( - req, EnumSet.of(SearchModelAction.UPDATE), operation); - } - - @Override - public void processAdd(AddUpdateCommand cmd) throws IOException { - authorizeCollectionAction(cmd.name()); - super.processAdd(cmd); - } - - @Override - public void processDelete(DeleteUpdateCommand cmd) throws IOException { - String operation = cmd.name(); - if (cmd.isDeleteById()) { - operation += "ById"; - } else { - operation += "ByQuery"; - } - authorizeCollectionAction(operation); - super.processDelete(cmd); - } - - @Override - public void processMergeIndexes(MergeIndexesCommand cmd) throws IOException { - authorizeCollectionAction(cmd.name()); - super.processMergeIndexes(cmd); - } - - @Override - public void processCommit(CommitUpdateCommand cmd) throws IOException - { - authorizeCollectionAction(cmd.name()); - super.processCommit(cmd); - } - - @Override - public void processRollback(RollbackUpdateCommand cmd) throws IOException - { - authorizeCollectionAction(cmd.name()); - super.processRollback(cmd); - } - - @Override - public void finish() throws IOException { - authorizeCollectionAction("finish"); - super.finish(); - } - -} http://git-wip-us.apache.org/repos/asf/sentry/blob/e62fa28d/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/update/processor/UpdateIndexAuthorizationProcessorFactory.java ---------------------------------------------------------------------- diff --git a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/update/processor/UpdateIndexAuthorizationProcessorFactory.java b/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/update/processor/UpdateIndexAuthorizationProcessorFactory.java deleted file mode 100644 index 07f7f28..0000000 --- a/sentry-solr/solr-sentry-handlers/src/main/java/org/apache/solr/update/processor/UpdateIndexAuthorizationProcessorFactory.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.apache.solr.update.processor; - -/* - * 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. - */ - -import org.apache.solr.common.util.NamedList; -import org.apache.solr.request.SolrQueryRequest; -import org.apache.solr.response.SolrQueryResponse; - -/** - * Factory for Sentry's index-level update authorization. - * Required to implement RunAlways so users can't bypass sentry checks. - */ -public class UpdateIndexAuthorizationProcessorFactory - extends UpdateRequestProcessorFactory - implements UpdateRequestProcessorFactory.RunAlways { - - @Override - public void init(NamedList args) { - } - - @Override - public UpdateIndexAuthorizationProcessor getInstance(SolrQueryRequest req, - SolrQueryResponse rsp, UpdateRequestProcessor next) { - return new UpdateIndexAuthorizationProcessor(req, rsp, next); - } -} http://git-wip-us.apache.org/repos/asf/sentry/blob/e62fa28d/sentry-solr/solr-sentry-handlers/src/main/resources/sentry-handlers/solr/collection1/lib/classes/empty-file-main-lib.txt ---------------------------------------------------------------------- diff --git a/sentry-solr/solr-sentry-handlers/src/main/resources/sentry-handlers/solr/collection1/lib/classes/empty-file-main-lib.txt b/sentry-solr/solr-sentry-handlers/src/main/resources/sentry-handlers/solr/collection1/lib/classes/empty-file-main-lib.txt deleted file mode 100644 index 8b13789..0000000 --- a/sentry-solr/solr-sentry-handlers/src/main/resources/sentry-handlers/solr/collection1/lib/classes/empty-file-main-lib.txt +++ /dev/null @@ -1 +0,0 @@ - http://git-wip-us.apache.org/repos/asf/sentry/blob/e62fa28d/sentry-solr/solr-sentry-handlers/src/test/java/org/apache/solr/handler/TestSecureAnalysisHandlers.java ---------------------------------------------------------------------- diff --git a/sentry-solr/solr-sentry-handlers/src/test/java/org/apache/solr/handler/TestSecureAnalysisHandlers.java b/sentry-solr/solr-sentry-handlers/src/test/java/org/apache/solr/handler/TestSecureAnalysisHandlers.java deleted file mode 100644 index 28406e2..0000000 --- a/sentry-solr/solr-sentry-handlers/src/test/java/org/apache/solr/handler/TestSecureAnalysisHandlers.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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.solr.handler; - -import org.apache.solr.cloud.CloudDescriptor; -import org.apache.solr.core.SolrCore; -import org.apache.solr.request.SolrQueryRequest; -import org.apache.solr.request.SolrRequestHandler; -import org.apache.solr.sentry.SentryTestBase; -import org.apache.solr.sentry.SentrySingletonTestInstance; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -public class TestSecureAnalysisHandlers extends SentryTestBase { - - private static SolrCore core; - private static CloudDescriptor cloudDescriptor; - - @BeforeClass - public static void beforeClass() throws Exception { - core = createCore("solrconfig-secureadmin.xml", "schema-minimal.xml"); - // store the CloudDescriptor, because we will overwrite it with a mock - // and restore it later - cloudDescriptor = core.getCoreDescriptor().getCloudDescriptor(); - // ensure the SentrySingletonTestInstance is initialized - SentrySingletonTestInstance.getInstance(); - } - - @AfterClass - public static void afterClass() throws Exception { - closeCore(core, cloudDescriptor); - core = null; - cloudDescriptor = null; - } - - @Override - public void setUp() throws Exception { - super.setUp(core); - } - - private SolrQueryRequest getAnalysisRequest(String collection, String user) - throws Exception { - SolrQueryRequest request = getRequest(); - return prepareCollAndUser(core, request, collection, user); - } - - private void verifyQueryAccess(SolrRequestHandler handler) throws Exception { - verifyAuthorized(handler, getAnalysisRequest("collection1", "junit")); - verifyAuthorized(handler, getAnalysisRequest("queryCollection", "junit")); - verifyUnauthorized(handler, getAnalysisRequest("bogusCollection", "junit"), - "bogusCollection", "junit"); - verifyUnauthorized(handler, getAnalysisRequest("updateCollection", "junit"), - "updateCollection", "junit"); - } - - @Test - public void testSecureFieldAnalysisRequestHandler() throws Exception { - SolrRequestHandler handler = core.getRequestHandler("/analysis/field"); - verifyQueryAccess(handler); - } - - @Test - public void testDocumentAnalysisRequestHandler() throws Exception { - SolrRequestHandler handler = core.getRequestHandler("/analysis/document"); - verifyQueryAccess(handler); - } -} http://git-wip-us.apache.org/repos/asf/sentry/blob/e62fa28d/sentry-solr/solr-sentry-handlers/src/test/java/org/apache/solr/handler/TestSecureReplicationHandler.java ---------------------------------------------------------------------- diff --git a/sentry-solr/solr-sentry-handlers/src/test/java/org/apache/solr/handler/TestSecureReplicationHandler.java b/sentry-solr/solr-sentry-handlers/src/test/java/org/apache/solr/handler/TestSecureReplicationHandler.java deleted file mode 100644 index 6367814..0000000 --- a/sentry-solr/solr-sentry-handlers/src/test/java/org/apache/solr/handler/TestSecureReplicationHandler.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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.solr.handler; - -import org.apache.solr.cloud.CloudDescriptor; -import org.apache.solr.core.SolrCore; -import org.apache.solr.request.SolrRequestHandler; -import org.apache.solr.sentry.SentryTestBase; -import org.apache.solr.sentry.SentrySingletonTestInstance; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -public class TestSecureReplicationHandler extends SentryTestBase { - - private static SolrCore core; - private static CloudDescriptor cloudDescriptor; - - @BeforeClass - public static void beforeClass() throws Exception { - core = createCore("solrconfig-secureadmin.xml", "schema-minimal.xml"); - // store the CloudDescriptor, because we will overwrite it with a mock - // and restore it later - cloudDescriptor = core.getCoreDescriptor().getCloudDescriptor(); - // ensure the SentrySingletonTestInstance is initialized - SentrySingletonTestInstance.getInstance(); - } - - @AfterClass - public static void afterClass() throws Exception { - closeCore(core, cloudDescriptor); - core = null; - cloudDescriptor = null; - } - - @Override - public void setUp() throws Exception { - super.setUp(core); - } - - @Test - public void testSecureReplicationHandler() throws Exception { - SolrRequestHandler handler = core.getRequestHandler("/replication"); - verifyAuthorized(handler, prepareCollAndUser(core, getRequest(), "collection1", "junit", false)); - verifyUnauthorized(handler, prepareCollAndUser(core, getRequest(), "queryCollection", "junit", false), "queryCollection", "junit"); - verifyUnauthorized(handler, prepareCollAndUser(core, getRequest(), "bogusCollection", "junit", false), "bogusCollection", "junit"); - verifyUnauthorized(handler, prepareCollAndUser(core, getRequest(), "updateCollection", "junit", false), "updateCollection", "junit"); - } -}