AEM CS - Assets Metadata Based Combination Custom Restriction Providers

Goal

AEM Cloud Service : 2022.3.6582.20220307T234020Z-220100 (March 07, 2022)

Before you proceed, check the latest Metadata driven permissions in product

System wise, for dam-users, when assetCategory metadata of an asset is RESTRICTED show it only when assetUsage is set to CALIFORNIA (so when assetUsage is set to TEXAS its hidden for dam-users)

Demo | Package Install | Github


Asset Metadata


Restricted + California = Allow


Restricted + California = Deny



Solution

1) Add the assetCategory restriction apps.experienceaem.assets.core.acls.EAEMAssetCategoryRestriction

package apps.experienceaem.assets.core.acls;

import org.apache.commons.lang3.StringUtils;
import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionPattern;

public class EAEMAssetCategoryRestriction  implements RestrictionPattern {
    private final String restrictedValue;
    public static final String ASSET_CATEGORY = "assetCategory";

    EAEMAssetCategoryRestriction(String restrictedValue) {
        this.restrictedValue = restrictedValue;
    }

    public boolean matches(Tree tree, PropertyState propertyState) {
        PropertyState property = tree.getChild(JcrConstants.JCR_CONTENT).getChild("metadata").getProperty(ASSET_CATEGORY);

        if(property == null){
            if(restrictedValue.equals("EMPTY")){
                return true;
            }
            return false;
        }

        String value = property.getValue(Type.STRING);

        if(restrictedValue.equals("EMPTY") && StringUtils.isEmpty(value)){
            return true;
        }

        return restrictedValue.equalsIgnoreCase(value);
    }

    public boolean matches(String path) {
        return false;
    }

    public boolean matches() {
        return false;
    }
}


2) Add the assetUsage restriction apps.experienceaem.assets.core.acls.EAEMAssetUsageRestriction

package apps.experienceaem.assets.core.acls;

import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionPattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class EAEMAssetUsageRestriction implements RestrictionPattern {
    private static final Logger log = LoggerFactory.getLogger(EAEMAssetUsageRestriction.class);

    private final String usageValue;
    public static final String ASSET_USAGE = "assetUsage";

    EAEMAssetUsageRestriction(String usageValue) {
        this.usageValue = usageValue;
    }

    public boolean matches(Tree tree, PropertyState propertyState) {
        PropertyState property = tree.getChild(JcrConstants.JCR_CONTENT).getChild("metadata").getProperty(ASSET_USAGE);

        if(property == null){
            return false;
        }

        String value = property.getValue(Type.STRING);

        return usageValue.equalsIgnoreCase(value);
    }

    public boolean matches(String path) {
        return false;
    }

    public boolean matches() {
        return false;
    }
}


3) Add the restriction provider apps.experienceaem.assets.core.acls.EAEMRestrictionProvider

package apps.experienceaem.assets.core.acls;

import com.google.common.collect.ImmutableMap;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.*;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Component(
        service = RestrictionProvider.class
)
public class EAEMRestrictionProvider extends AbstractRestrictionProvider {
    private static final Logger log = LoggerFactory.getLogger(EAEMRestrictionProvider.class);

    public EAEMRestrictionProvider() {
        super(supportedRestrictions());
    }

    private static Map<String, RestrictionDefinition> supportedRestrictions() {
        RestrictionDefinition assetCategoryRes = new RestrictionDefinitionImpl(EAEMAssetCategoryRestriction.ASSET_CATEGORY,
                Type.STRING, false);
        RestrictionDefinition assetUsageRes = new RestrictionDefinitionImpl(EAEMAssetUsageRestriction.ASSET_USAGE,
                Type.STRING, false);
        return ImmutableMap.of(assetCategoryRes.getName(), assetCategoryRes, assetUsageRes.getName(), assetUsageRes);
    }

    @Override
    public RestrictionPattern getPattern(String oakPath, Tree tree) {
        if (oakPath == null) {
            return RestrictionPattern.EMPTY;
        } else {
            List<RestrictionPattern> patterns = new ArrayList(2);

            PropertyState assetCategoryProperty = tree.getProperty(EAEMAssetCategoryRestriction.ASSET_CATEGORY);

            if (assetCategoryProperty != null) {
                patterns.add(new EAEMAssetCategoryRestriction(assetCategoryProperty.getValue(Type.STRING)));
            }

            PropertyState assetUsageProperty = tree.getProperty(EAEMAssetUsageRestriction.ASSET_USAGE);

            if (assetUsageProperty != null) {
                patterns.add(new EAEMAssetUsageRestriction(assetUsageProperty.getValue(Type.STRING)));
            }

            return CompositePattern.create(patterns);
        }
    }

    @Override
    public RestrictionPattern getPattern(String oakPath, Set<Restriction> restrictions) {
        if (oakPath == null || restrictions.isEmpty()) {
            return RestrictionPattern.EMPTY;
        } else {
            List<RestrictionPattern> patterns = new ArrayList(2);

            for (Restriction r : restrictions) {
                String name = r.getDefinition().getName();

                if (EAEMAssetCategoryRestriction.ASSET_CATEGORY.equals(name)) {
                    patterns.add(new EAEMAssetCategoryRestriction(r.getProperty().getValue(Type.STRING)));
                }else if (EAEMAssetUsageRestriction.ASSET_USAGE.equals(name)) {
                    patterns.add(new EAEMAssetUsageRestriction(r.getProperty().getValue(Type.STRING)));
                } else {
                    log.debug("Ignoring unsupported restriction " + name);
                }
            }

            return CompositePattern.create(patterns);
        }
    }
}


No comments:

Post a Comment