com.enonic.cms.web.portal.services.UserServicesAccessManagerImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.enonic.cms.web.portal.services.UserServicesAccessManagerImpl.java

Source

/*
 * Copyright 2000-2013 Enonic AS
 * http://www.enonic.com/license
 */
package com.enonic.cms.web.portal.services;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import javax.annotation.PostConstruct;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.enonic.cms.core.structure.SiteKey;
import com.enonic.cms.core.structure.SiteProperties;
import com.enonic.cms.core.structure.SitePropertiesListener;
import com.enonic.cms.core.structure.SitePropertiesService;
import com.enonic.cms.core.structure.SitePropertyNames;
import com.enonic.cms.core.structure.SiteService;

@Component
public class UserServicesAccessManagerImpl implements UserServicesAccessManager, SitePropertiesListener {

    private static enum AccessPermission {
        ALLOW, DENY,
    }

    private static final String ACCESS_RULE_ALL = "*";

    private static final AccessPermission DEFAULT_ACCESS_RULE = AccessPermission.DENY;

    private SitePropertiesService sitePropertiesService;

    private SiteService siteService;

    private ConcurrentMap<SiteKey, ConcurrentMap<String, AccessPermission>> sitesAccessRules;

    public UserServicesAccessManagerImpl() {
        sitesAccessRules = new ConcurrentHashMap<SiteKey, ConcurrentMap<String, AccessPermission>>();
    }

    @PostConstruct
    public void postConstruct() {
        sitePropertiesService.registerSitePropertiesListener(this);
    }

    @Override
    public boolean isOperationAllowed(SiteKey site, String service, String operation) {
        siteService.checkSiteExist(site);

        ConcurrentMap<String, AccessPermission> siteRules = getRulesForSite(site);
        AccessPermission access = applyAccessRules(service, operation, siteRules);

        return access == AccessPermission.ALLOW;
    }

    private AccessPermission applyAccessRules(String service, String operation,
            ConcurrentMap<String, AccessPermission> siteRules) {
        // search for specific rule: "service.operation"
        AccessPermission accessServiceOperation = siteRules.get(service + "." + operation);
        if (accessServiceOperation != null) {
            return accessServiceOperation;
        }

        // search for generic rule: "service.*"
        AccessPermission accessService = siteRules.get(service + ".*");
        if (accessService != null) {
            siteRules.putIfAbsent(service + "." + operation, accessService);
            return accessService;
        }

        // no rule found -> return default and cache value
        AccessPermission defaultAccess = siteRules.get(ACCESS_RULE_ALL);
        siteRules.putIfAbsent(service + "." + operation, defaultAccess);
        return defaultAccess;
    }

    private ConcurrentMap<String, AccessPermission> getRulesForSite(SiteKey site) {
        ConcurrentMap<String, AccessPermission> rules = sitesAccessRules.get(site);
        if (rules == null) {
            initSiteRules(site);
            rules = sitesAccessRules.get(site);
        }
        return rules;
    }

    @Override
    public void sitePropertiesLoaded(final SiteProperties siteProperties) {
        // nothing
    }

    @Override
    public void sitePropertiesReloaded(final SiteProperties siteProperties) {
        sitesAccessRules.remove(siteProperties.getSiteKey());
        initSiteRules(siteProperties.getSiteKey());
    }

    private void initSiteRules(SiteKey site) {
        ConcurrentMap<String, AccessPermission> siteRules = new ConcurrentHashMap<String, AccessPermission>();

        String allowRules = sitePropertiesService.getSiteProperty(site,
                SitePropertyNames.HTTP_SERVICES_ALLOW_PROPERTY);
        String denyRules = sitePropertiesService.getSiteProperty(site,
                SitePropertyNames.HTTP_SERVICES_DENY_PROPERTY);
        parseAndAddRules(allowRules, AccessPermission.ALLOW, siteRules, site);
        parseAndAddRules(denyRules, AccessPermission.DENY, siteRules, site);

        siteRules.putIfAbsent(ACCESS_RULE_ALL, DEFAULT_ACCESS_RULE);

        sitesAccessRules.putIfAbsent(site, siteRules);
    }

    private void parseAndAddRules(String accessRules, AccessPermission accessPermission,
            ConcurrentMap<String, AccessPermission> siteRules, SiteKey site) {
        accessRules = StringUtils.trimToEmpty(accessRules);
        String[] ruleItems = accessRules.split(",");
        for (String ruleItem : ruleItems) {
            ruleItem = ruleItem.trim();
            if (ruleItem.isEmpty()) {
                continue;
            }
            if (siteRules.containsKey(ruleItem)) {
                throw new IllegalArgumentException(
                        "Duplicated value for http service access rule '" + ruleItem + "' on site " + site);
            }
            siteRules.put(ruleItem, accessPermission);
        }
    }

    @Autowired
    public void setSitePropertiesService(SitePropertiesService sitePropertiesService) {
        this.sitePropertiesService = sitePropertiesService;
    }

    @Autowired
    public void setSiteService(SiteService siteService) {
        this.siteService = siteService;
    }

}