Github user ictmalili commented on a diff in the pull request:

    https://github.com/apache/incubator-hawq/pull/1092#discussion_r96558333
  
    --- Diff: 
ranger-plugin/service/src/main/java/org/apache/hawq/ranger/authorization/RangerHawqAuthorizer.java
 ---
    @@ -0,0 +1,263 @@
    +/*
    + * 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.hawq.ranger.authorization;
    +
    +import org.apache.commons.collections.CollectionUtils;
    +import org.apache.commons.collections.MapUtils;
    +import org.apache.commons.lang.StringUtils;
    +import org.apache.commons.logging.Log;
    +import org.apache.commons.logging.LogFactory;
    +import org.apache.hawq.ranger.authorization.model.AuthorizationRequest;
    +import org.apache.hawq.ranger.authorization.model.AuthorizationResponse;
    +import org.apache.hawq.ranger.authorization.model.HawqPrivilege;
    +import org.apache.hawq.ranger.authorization.model.HawqResource;
    +import org.apache.hawq.ranger.authorization.model.ResourceAccess;
    +import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
    +import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl;
    +import org.apache.ranger.plugin.policyengine.RangerAccessResource;
    +import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl;
    +import org.apache.ranger.plugin.policyengine.RangerAccessResult;
    +import org.apache.ranger.plugin.service.RangerBasePlugin;
    +
    +import java.util.Collections;
    +import java.util.HashSet;
    +import java.util.Map;
    +import java.util.Set;
    +
    +import static org.apache.hawq.ranger.authorization.Utils.HAWQ;
    +
    +/**
    + * Authorizer implementation that uses Ranger to make access decision. 
Implemented as a singleton.
    + */
    +public class RangerHawqAuthorizer implements HawqAuthorizer {
    +
    +    private static final Log LOG = 
LogFactory.getLog(RangerHawqAuthorizer.class);
    +
    +    private static final RangerHawqAuthorizer INSTANCE = new 
RangerHawqAuthorizer();
    +
    +    private RangerBasePlugin rangerPlugin;
    +
    +    /**
    +     * Returns the instance of the RangerHawqAuthorizer.
    +     * @return the singleton instance
    +     */
    +    public static RangerHawqAuthorizer getInstance() {
    +        return INSTANCE;
    +    }
    +
    +    /**
    +     * Constructor. Initializes Ranger Base Plugin to fetch policies from 
Ranger.
    +     */
    +    private RangerHawqAuthorizer() {
    +
    +        LOG.info("Initializing RangerHawqAuthorizer");
    +
    +        String appId = Utils.getAppId();
    +
    +        LOG.info(String.format("Initializing RangerBasePlugin for service 
%s:%s", HAWQ, appId));
    +        rangerPlugin = new RangerBasePlugin(HAWQ, appId);
    +        rangerPlugin.init();
    +        LOG.info(String.format("Initialized RangerBasePlugin for service 
%s:%s", HAWQ, appId));
    +    }
    +
    +    @Override
    +    public AuthorizationResponse isAccessAllowed(AuthorizationRequest 
request) {
    +
    +        // validate request to make sure no data is missing
    +        validateRequest(request);
    +
    +        // prepare response object
    +        AuthorizationResponse response = new AuthorizationResponse();
    +        response.setRequestId(request.getRequestId());
    +        Set<ResourceAccess> access = new HashSet<>();
    +        response.setAccess(access);
    +
    +        // iterate over resource requests, augment processed ones with the 
decision and add to the response
    +        for (ResourceAccess resourceAccess : request.getAccess()) {
    +            boolean accessAllowed = authorizeResource(resourceAccess, 
request.getUser());
    +            resourceAccess.setAllowed(accessAllowed);
    +            access.add(resourceAccess);
    +        }
    +
    +        return response;
    +    }
    +
    +    /**
    +     * Authorizes access to a single resource for a given user.
    +     *
    +     * @param resourceAccess resource to authorize access to
    +     * @param user user requesting authorization
    +     * @return true if access is authorized, false otherwise
    +     */
    +    private boolean authorizeResource(ResourceAccess resourceAccess, 
String user) {
    +
    +        if (LOG.isDebugEnabled()) {
    +            LOG.debug(String.format("Request: access for user=%s to 
resource=%s with privileges=%s",
    +                user, resourceAccess.getResource(), 
resourceAccess.getPrivileges()));
    +        }
    +
    +        RangerAccessResourceImpl rangerResource = new 
RangerAccessResourceImpl();
    +        //resource.setOwnerUser();
    +        for (Map.Entry<HawqResource, String> resourceEntry : 
resourceAccess.getResource().entrySet()) {
    +            rangerResource.setValue(resourceEntry.getKey().name(), 
resourceEntry.getValue());
    +        }
    +
    +        boolean accessAllowed = true;
    +        // iterate over all privileges requested
    +        for (HawqPrivilege privilege : resourceAccess.getPrivileges()) {
    +            // TODO not clear how we will get user groups -- Kerberos case 
?
    +            Set<String> userGroups = Collections.emptySet();
    +            boolean privilegeAuthorized = 
authorizeResourcePrivilege(rangerResource, privilege.name(), user, userGroups);
    +            // ALL model of evaluation -- all privileges must be 
authorized for access to be allowed
    +            if (!privilegeAuthorized) {
    +                accessAllowed = false;
    +                break; // terminate early if even a single privilege is 
not authorized
    +            }
    +        }
    +
    +        if (LOG.isDebugEnabled()) {
    +            LOG.debug(String.format("Decision: accessAllowed=%s for 
user=%s to resource=%s with privileges=%s",
    +                    accessAllowed, user, resourceAccess.getResource(), 
resourceAccess.getPrivileges()));
    +        }
    +
    +        return accessAllowed;
    +    }
    +
    +    /**
    +     * Authorizes access of a given type (privilege) to a single resource 
for a given user.
    +     *
    +     * @param rangerResource resource to authorize access to
    +     * @param accessType privilege requested for a given resource
    +     * @param user user requesting authorization
    +     * @param userGroups groups a user belongs to
    +     * @return true if access is authorized, false otherwise
    +     */
    +    private boolean authorizeResourcePrivilege(RangerAccessResource 
rangerResource, String accessType, String user, Set<String> userGroups) {
    +
    +        Map<String, String> resourceMap = rangerResource.getAsMap();
    +        String database = resourceMap.get(HawqResource.database.name());
    +        String schema = resourceMap.get(HawqResource.schema.name());
    +        int resourceSize = resourceMap.size();
    +
    +        // special handling for non-leaf policies
    +        if (accessType.equals(HawqPrivilege.create.name()) && database != 
null && schema == null && resourceSize == 1) {
    --- End diff --
    
    What's the meaning of resourceSize valued as 1 and 2? Could you add some 
comments in the code here? Thanks


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at [email protected] or file a JIRA ticket
with INFRA.
---

Reply via email to