OAuthUtil.java 12.3 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.granite.crypto.CryptoException
 *  com.adobe.granite.crypto.CryptoSupport
 *  com.adobe.granite.keystore.KeyStoreService
 *  com.adobe.granite.security.user.UserManagementService
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.jcr.security.Privilege
 *  org.apache.commons.lang.RandomStringUtils
 *  org.apache.jackrabbit.api.JackrabbitSession
 *  org.apache.jackrabbit.api.security.user.Authorizable
 *  org.apache.jackrabbit.api.security.user.Group
 *  org.apache.jackrabbit.api.security.user.User
 *  org.apache.jackrabbit.api.security.user.UserManager
 *  org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils
 *  org.apache.sling.api.resource.PersistenceException
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.osgi.framework.InvalidSyntaxException
 *  org.osgi.service.cm.Configuration
 *  org.osgi.service.cm.ConfigurationAdmin
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.cq.dam.mac.sync.helper.impl.util;

import com.adobe.cq.dam.mac.sync.helper.impl.Claim;
import com.adobe.granite.crypto.CryptoException;
import com.adobe.granite.crypto.CryptoSupport;
import com.adobe.granite.keystore.KeyStoreService;
import com.adobe.granite.security.user.UserManagementService;
import java.io.IOException;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.Principal;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.security.Privilege;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.jackrabbit.api.JackrabbitSession;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.ResourceResolver;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class OAuthUtil {
    private static final Logger LOG = LoggerFactory.getLogger(OAuthUtil.class);
    private static final String ACCESS_TOKEN_PROVIDER_FACTORY_PID = "com.adobe.granite.auth.oauth.accesstoken.provider";
    private static final String ACCESS_TOKEN_PROVIDER_DEFAULT_CLAIM = "auth.token.provider.default.claims";
    private static final String ACCESS_TOKEN_PROVIDER_CLIENT_ID = "auth.token.provider.client.id";
    private static final String ACCESS_TOKEN_PROVIDER_SCOPE = "auth.token.provider.scope";
    private static final String ACCESS_TOKEN_PROVIDER_ENDPOINT = "auth.token.provider.endpoint";
    private static final String REPLICATION_HTTP_PID = "com.day.cq.replication.impl.transport.Http";
    public static final String ACCESS_TOKEN_PROVIDER_KEYPAIR_ALIAS = "auth.token.provider.keypair.alias";
    private static final String CLIENT_ORG_SUFFIX = "@AdobeClient";
    private static final String KEYPAIR_ALGORITHM = "RSA";
    private static final String KEYPAIR_ALIAS = "replication";
    private static final String MP_KEYPAIR_ALIAS = "mpreplication";

    public static String updateAccessTokenProvider(ConfigurationAdmin configurationAdmin, String oAuthClientId, String scopes, String audience) throws IOException {
        return OAuthUtil.updateAccessTokenProvider(configurationAdmin, oAuthClientId, scopes, audience, "replication");
    }

    public static String updateAccessTokenProvider(ConfigurationAdmin configurationAdmin, String oAuthClientId, String scopes, String audience, String keypairAlias) throws IOException {
        Hashtable<String, String> properties;
        Configuration configuration = null;
        try {
            Configuration[] configurations = configurationAdmin.listConfigurations("(&(service.factoryPid=com.adobe.granite.auth.oauth.accesstoken.provider))");
            if (configurations != null) {
                for (Configuration config : configurations) {
                    String configAlias = (String)config.getProperties().get("auth.token.provider.keypair.alias");
                    if (!keypairAlias.equals(configAlias)) continue;
                    configuration = config;
                    LOG.info("found configuration");
                    configuration.delete();
                    configuration = null;
                }
            }
        }
        catch (InvalidSyntaxException e) {
            throw new RuntimeException((Throwable)e);
        }
        if (configuration == null) {
            LOG.info("creating configuration");
            configuration = configurationAdmin.createFactoryConfiguration("com.adobe.granite.auth.oauth.accesstoken.provider", null);
        }
        if ((properties = configuration.getProperties()) == null) {
            properties = new Hashtable<String, String>();
        }
        String[] claims = (String[])properties.get("auth.token.provider.default.claims");
        ArrayList<String> claimList = new ArrayList<String>();
        if (claims != null) {
            for (String claim : claims) {
                Claim defClaim = new Claim(claim);
                if (Claim.CLAIM_TYPE_SUB.equals(defClaim.getClaimType())) {
                    claimList.add(new Claim(Claim.CLAIM_TYPE_SUB, oAuthClientId + "@AdobeClient").getClaim());
                    continue;
                }
                if (Claim.CLAIM_TYPE_ISS.equals(defClaim.getClaimType())) {
                    claimList.add(new Claim(Claim.CLAIM_TYPE_ISS, oAuthClientId).getClaim());
                    continue;
                }
                if (Claim.CLAIM_TYPE_SCOPE.equals(defClaim.getClaimType())) {
                    claimList.add(new Claim(Claim.CLAIM_TYPE_SCOPE, scopes).getClaim());
                    continue;
                }
                if (Claim.CLAIM_TYPE_AUD.equals(defClaim.getClaimType())) {
                    claimList.add(new Claim(Claim.CLAIM_TYPE_AUD, audience).getClaim());
                    continue;
                }
                claimList.add(claim);
            }
        } else {
            claimList.add(new Claim(Claim.CLAIM_TYPE_SUB, oAuthClientId + "@AdobeClient").getClaim());
            claimList.add(new Claim(Claim.CLAIM_TYPE_ISS, oAuthClientId).getClaim());
            claimList.add(new Claim(Claim.CLAIM_TYPE_SCOPE, scopes).getClaim());
            claimList.add(new Claim(Claim.CLAIM_TYPE_AUD, audience).getClaim());
        }
        properties.put("auth.token.provider.client.id", oAuthClientId);
        properties.put("auth.token.provider.default.claims", (String)claimList.toArray(new String[0]));
        properties.put("auth.token.provider.keypair.alias", keypairAlias);
        properties.put("auth.token.provider.scope", scopes);
        properties.put("auth.token.provider.endpoint", audience);
        configuration.update(properties);
        return configuration.getPid();
    }

    public static KeyPair createKeyPair(ResourceResolver rr, String userID, CryptoSupport crypto, KeyStoreService keyStoreService) throws CryptoException {
        return OAuthUtil.createKeyPair(rr, userID, crypto, keyStoreService, "replication");
    }

    public static KeyPair createKeyPair(ResourceResolver rr, String userID, CryptoSupport crypto, KeyStoreService keyStoreService, String keypairAlias) throws CryptoException {
        OAuthUtil.createKeyStore(rr, userID, keyStoreService);
        KeyPair keyPair = keyStoreService.getKeyStoreKeyPair(rr, userID, keypairAlias);
        if (keyPair == null) {
            keyPair = crypto.createKeyPair("RSA");
            keyStoreService.addKeyStoreKeyPair(rr, userID, keyPair, keypairAlias);
        }
        return keyPair;
    }

    private static void createKeyStore(ResourceResolver rr, String userID, KeyStoreService keyStoreService) {
        if (!keyStoreService.keyStoreExists(rr, userID)) {
            String pssd = RandomStringUtils.random((int)15);
            keyStoreService.createKeyStore(rr, userID, pssd.toCharArray());
            pssd = null;
        }
    }

    public static PublicKey getPublicKey(ResourceResolver rr, String userID, CryptoSupport crypto, KeyStoreService keyStoreService) throws CryptoException {
        KeyPair keyPair = OAuthUtil.createKeyPair(rr, userID, crypto, keyStoreService);
        return keyPair.getPublic();
    }

    public static PublicKey getPublicKey(ResourceResolver rr, String userID, CryptoSupport crypto, KeyStoreService keyStoreService, String keypairAlias) throws CryptoException {
        KeyPair keyPair = OAuthUtil.createKeyPair(rr, userID, crypto, keyStoreService, keypairAlias);
        return keyPair.getPublic();
    }

    public static String getReplicationUserId(String tenant) {
        return "mac-" + tenant + "-replication";
    }

    public static String createReplicationUser(ResourceResolver rr, String tenantID, UserManagementService userManagementService) throws RepositoryException {
        Session session = (Session)rr.adaptTo(Session.class);
        UserManager userManager = ((JackrabbitSession)session).getUserManager();
        final String userID = OAuthUtil.getReplicationUserId(tenantID);
        Authorizable authorizable = userManager.getAuthorizable(userID);
        Privilege[] privileges = AccessControlUtils.privilegesFromNames((Session)session, (String[])new String[]{"{http://www.jcp.org/jcr/1.0}read", "{http://www.jcp.org/jcr/1.0}nodeTypeManagement", "{http://www.jcp.org/jcr/1.0}write"});
        if (authorizable == null) {
            String path = userManagementService.getUserRootPath() + "/mac/" + tenantID;
            Principal principal = new Principal(){

                @Override
                public String getName() {
                    return userID;
                }
            };
            authorizable = userManager.createUser(userID, null, principal, path);
            AccessControlUtils.addAccessControlEntry((Session)session, (String)"/content/dam/projects", (Principal)authorizable.getPrincipal(), (Privilege[])privileges, (boolean)true);
            AccessControlUtils.addAccessControlEntry((Session)session, (String)"/var/dam/remoteassetusages", (Principal)authorizable.getPrincipal(), (Privilege[])privileges, (boolean)true);
        }
        AccessControlUtils.addAccessControlEntry((Session)session, (String)"/content/dam/collections", (Principal)authorizable.getPrincipal(), (Privilege[])privileges, (boolean)true);
        try {
            Group replicationGrp = OAuthUtil.createGroup(userManager, session);
            if (!replicationGrp.isMember(authorizable)) {
                replicationGrp.addMember(authorizable);
            }
        }
        catch (PersistenceException e) {
            throw new RuntimeException("could not create dam mac namespace group");
        }
        if (!userManager.isAutoSave()) {
            session.save();
        }
        if (session.hasPendingChanges()) {
            session.save();
        }
        return authorizable.getID();
    }

    private static Group createGroup(UserManager userManager, Session session) throws RepositoryException, PersistenceException {
        String groupId = "dam-mac-replication";
        String intermediatePath = "mac";
        Authorizable auth = userManager.getAuthorizable("dam-mac-replication");
        if (auth != null) {
            return (Group)auth;
        }
        LOG.info("Creating Group {}", (Object)"dam-mac-replication");
        Group replicationGroup = userManager.createGroup(new Principal(){

            @Override
            public String getName() {
                return "dam-mac-replication";
            }
        }, "mac");
        Authorizable damGroup = userManager.getAuthorizable("dam-users");
        if (damGroup == null) {
            throw new RuntimeException("dam-users group is missing");
        }
        Group damUsers = null;
        if (!(damGroup instanceof Group)) {
            throw new RuntimeException("dam-users should be a group");
        }
        damUsers = (Group)damGroup;
        if (!damUsers.isMember((Authorizable)replicationGroup)) {
            damUsers.addMember((Authorizable)replicationGroup);
        }
        return replicationGroup;
    }

}