Package org.uberfire.security.impl.authz

Source Code of org.uberfire.security.impl.authz.RuntimeResourceDecisionManager

/*
* Copyright 2012 JBoss Inc
*
* Licensed 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.uberfire.security.impl.authz;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.uberfire.security.Resource;
import org.uberfire.security.Role;
import org.uberfire.security.Subject;
import org.uberfire.security.annotations.All;
import org.uberfire.security.annotations.Authorized;
import org.uberfire.security.annotations.Deny;
import org.uberfire.security.authz.AuthorizationResult;
import org.uberfire.security.authz.ResourceDecisionManager;
import org.uberfire.security.authz.RoleDecisionManager;
import org.uberfire.security.authz.RolesResource;
import org.uberfire.security.authz.RuntimeResource;
import org.uberfire.security.authz.VotingStrategy;
import org.uberfire.commons.data.Cacheable;

import static org.uberfire.commons.validation.PortablePreconditions.*;
import static org.uberfire.security.authz.AuthorizationResult.*;

public class RuntimeResourceDecisionManager implements ResourceDecisionManager {

    private static final UnanimousBasedVoter ALL_VOTER = new UnanimousBasedVoter();
    private static final AffirmativeBasedVoter DEFAULT_VOTER = new AffirmativeBasedVoter();

    private final RuntimeAuthzCache cache = new RuntimeAuthzCache();

    private final RuntimeResourceManager resourceManager;

    public RuntimeResourceDecisionManager(final RuntimeResourceManager resourceManager) {
        this.resourceManager = resourceManager;
    }

    @Override
    public boolean supports(final Resource resource) {
        if (resource == null) {
            return false;
        }
        if (resource instanceof RuntimeResource) {
            return true;
        }
        return false;
    }

    @Override
    public AuthorizationResult decide(final Resource resource, final Subject subject, final RoleDecisionManager roleDecisionManager) {
        checkNotNull("roleDecisionManager", roleDecisionManager);
        if (!(resource instanceof RuntimeResource)) {
            throw new IllegalArgumentException("Parameter named 'resource' is not instance of clazz 'RuntimeResource'!");
        }
        boolean refreshCache = false;
        if (resource instanceof Cacheable) {
            refreshCache = ((Cacheable) resource).requiresRefresh();
        }
        final RuntimeResource runtimeResource = (RuntimeResource) resource;

        if (cache.notContains(subject, runtimeResource) || refreshCache) {
            if (!resourceManager.requiresAuthentication(runtimeResource)) {
                return ACCESS_ABSTAIN;
            }

            final RuntimeResourceManager.RuntimeRestriction restriction = resourceManager.getRestriction(runtimeResource);

            if (restriction == null || restriction.isEmpty()) {
                return ACCESS_ABSTAIN;
            }

            boolean invertResult = false;
            VotingStrategy votingStrategy = null;

            for (final String trait : restriction.getTraits()) {
                if (trait.equals(All.class.getName())) {
                    votingStrategy = ALL_VOTER;
                } else if (trait.equals(Authorized.class.getName())) {
                    if (subject != null) {
                        return ACCESS_GRANTED;
                    }
                } else if (trait.equals(Deny.class.getName())) {
                    invertResult = true;
                }
            }

            if (votingStrategy == null) {
                votingStrategy = DEFAULT_VOTER;
            }

            final RolesResource rolesResource = new RolesResource() {
                @Override
                public Collection<Role> getRoles() {
                    return restriction.getRoles();
                }
            };

            final AuthorizationResult result = votingStrategy.vote(roleDecisionManager.decide(rolesResource, subject));

            if (invertResult) {
                cache.put(subject, runtimeResource, result.invert());
            } else {
                cache.put(subject, runtimeResource, result);
            }
            if (resource instanceof Cacheable) {
                ((Cacheable) resource).markAsCached();
            }
        }

        return cache.get(subject, runtimeResource);
    }

    class RuntimeAuthzCache {

        final Map<String, Map<String, AuthorizationResult>> internal = new HashMap<String, Map<String, AuthorizationResult>>();

        public boolean notContains(final Subject subject, final RuntimeResource resource) {

            final Map<String, AuthorizationResult> result = internal.get(resource.getSignatureId());
            if (result == null) {
                return true;
            }

            return !result.containsKey(subject.getName());
        }

        public void put(final Subject subject, final RuntimeResource resource, final AuthorizationResult authzResult) {
            if (!internal.containsKey(resource.getSignatureId())) {
                internal.put(resource.getSignatureId(), new HashMap<String, AuthorizationResult>());
            }
            final Map<String, AuthorizationResult> result = internal.get(resource.getSignatureId());
            AuthorizationResult knowValue = result.get(subject.getName());
            if (result.containsKey(subject.getName()) && knowValue.equals(authzResult)) {
                return;
            }
            result.put(subject.getName(), authzResult);
        }

        public AuthorizationResult get(final Subject subject, final RuntimeResource resource) {
            final Map<String, AuthorizationResult> result = internal.get(resource.getSignatureId());
            if (result == null) {
                return ACCESS_DENIED;
            }

            final AuthorizationResult decision = result.get(subject.getName());
            if (decision == null) {
                return ACCESS_DENIED;
            }

            return decision;
        }
    }
}
TOP

Related Classes of org.uberfire.security.impl.authz.RuntimeResourceDecisionManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.