All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.day.cq.analytics.sitecatalyst.util.TokenProviderProxyImpl Maven / Gradle / Ivy

package com.day.cq.analytics.sitecatalyst.util;

import com.adobe.granite.auth.oauth.AccessTokenProvider;
import com.adobe.granite.crypto.CryptoException;
import org.apache.commons.lang.StringUtils;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;

@Component
public final class TokenProviderProxyImpl implements TokenProviderProxy {

    @Reference(
            service = AccessTokenProvider.class,
            policy = ReferencePolicy.DYNAMIC,
            cardinality = ReferenceCardinality.MULTIPLE,
            target = "(&(" + ConfigurationAdmin.SERVICE_FACTORYPID + "=" + ACCESS_TOKEN_PROVIDER_FACTORY_PID + "))",
            bind = "bindAccessTokenProvider",
            unbind = "unbindAccessTokenProvider")
    // When using DS annotation a ReferenceCardinality.MULTIPLE requires
    // either a Collection or a List type variable so we use a dummy List to avoid an error
    // in the logs when service is initialized
    private volatile List tokenProviders;
    private Logger log = LoggerFactory.getLogger(getClass());

    @Reference
    private ResourceResolverFactory resourceResolverFactory;

    private Map, AccessTokenProvider> availableTokenProviders = new ConcurrentHashMap<>();

    private static final String SERVICE_NAME_ANALYTICS = "Adobe Analytics";
    private static final String SERVICE_NAME_LAUNCH = "Adobe Launch";

    private static final String ACCESS_TOKEN_PROVIDER_FACTORY_PID = "com.adobe.granite.auth.oauth.accesstoken.provider";
    private static final String ACCESS_TOKEN_PROVIDER_NAME = "name";
    private static final String ACCESS_TOKEN_PROVIDER_TITLE = "auth.token.provider.title";
    private static final String ACCESS_TOKEN_PROVIDER_CLIENTID = "auth.token.provider.client.id";
    private static final String SERVICE_PID = "service.pid";

    @Override
    public String getAccessToken(@Nonnull String name) throws CryptoException, IOException, LoginException {
        ResourceResolver resourceResolver = resourceResolverFactory
                .getServiceResourceResolver(Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, resolveServiceFromConfigName(name)));

        AccessTokenProvider accessTokenProvider = null;
        for (Map infoMap : availableTokenProviders.keySet()) {
            if (infoMap.get("name").equals(name)) {
                accessTokenProvider = availableTokenProviders.get(infoMap);
                break;
            }
        }
        if(log.isDebugEnabled())
            log.error("accessTokenProvider cannot be null");
        return accessTokenProvider != null
                ? accessTokenProvider.getAccessToken(resourceResolver, resourceResolver.getUserID(), null)
                : null;
    }

    @Override
    @Nonnull
    public Set> getTokenProvidersInfo() {
        return availableTokenProviders.keySet();
    }

    @Override
    public String getApikey(String name) {
        for (Map infoMap : availableTokenProviders.keySet()) {
            if (infoMap.get("name").equals(name)) {
                return infoMap.get("apikey");
            }
        }
        log.error("api key is null");
        return null;
    }

    @Override
    public String getServicePid(String name) {
        for (Map infoMap : availableTokenProviders.keySet()) {
            if (infoMap.get("name").equals(name)) {
                return infoMap.get("servicepid");
            }
        }
        return null;
    }

    // bind only Analytics related IMS configurations
    void bindAccessTokenProvider(AccessTokenProvider accessTokenProvider, Map props) {
        String name = PropertiesUtil.toString(props.get(ACCESS_TOKEN_PROVIDER_NAME), "");
        String title = PropertiesUtil.toString(props.get(ACCESS_TOKEN_PROVIDER_TITLE), "");
        String apikey = PropertiesUtil.toString(props.get(ACCESS_TOKEN_PROVIDER_CLIENTID), "");
        String servicepid = PropertiesUtil.toString(props.get(SERVICE_PID), "");
        if (StringUtils.isNotBlank(name) && StringUtils.isNotBlank(title)
                && StringUtils.isNotBlank(apikey) && StringUtils.isNotBlank(servicepid)) {
            Map tokenProviderInfo = new HashMap<>();
            tokenProviderInfo.put("name", name);
            tokenProviderInfo.put("title", title);
            tokenProviderInfo.put("apikey", apikey);
            tokenProviderInfo.put("servicepid", servicepid);
            availableTokenProviders.put(tokenProviderInfo, accessTokenProvider);
        }
    }

    void unbindAccessTokenProvider(AccessTokenProvider accessTokenProvider, Map props) {
        String name = PropertiesUtil.toString(props.get(ACCESS_TOKEN_PROVIDER_NAME), "");
        String title = PropertiesUtil.toString(props.get(ACCESS_TOKEN_PROVIDER_TITLE), "");
        String apikey = PropertiesUtil.toString(props.get(ACCESS_TOKEN_PROVIDER_CLIENTID), "");
        String servicepid = PropertiesUtil.toString(props.get(SERVICE_PID), "");
        if (StringUtils.isNotBlank(name) && StringUtils.isNotBlank(title)
                && StringUtils.isNotBlank(apikey) && StringUtils.isNotBlank(servicepid)) {
            Map tokenProviderInfo = new HashMap<>();
            tokenProviderInfo.put("name", name);
            tokenProviderInfo.put("title", title);
            tokenProviderInfo.put("apikey", apikey);
            tokenProviderInfo.put("servicepid", servicepid);
            availableTokenProviders.remove(tokenProviderInfo);
        }
    }

    private String resolveServiceFromConfigName(String configName) {
        try{
            if(configName.startsWith(SERVICE_NAME_ANALYTICS)){
                return SERVICE_NAME_ANALYTICS;
            } else if(configName.startsWith(SERVICE_NAME_LAUNCH)){
                return SERVICE_NAME_LAUNCH;
            } else {
                return configName;
            }
        } catch (Exception e){
            log.error(String.format("Error while resolving service from config name: %s", configName), e);
        }
        return configName;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy