org.dcache.gridsite.DelegationHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.dcache.gridsite.DelegationHandler.java

Source

/*
 * dCache - http://www.dcache.org/
 *
 * Copyright (C) 2016 Deutsches Elektronen-Synchrotron
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.dcache.gridsite;

import com.google.common.base.Throwables;
import com.google.common.net.InetAddresses;
import org.springframework.beans.factory.annotation.Required;

import javax.security.auth.Subject;
import javax.xml.rpc.holders.StringHolder;

import java.rmi.RemoteException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Calendar;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import diskCacheV111.util.CacheException;
import diskCacheV111.util.PermissionDeniedCacheException;
import diskCacheV111.util.TimeoutCacheException;

import org.dcache.auth.LoginStrategy;
import org.dcache.auth.Origin;
import org.dcache.cells.CellStub;
import org.dcache.delegation.gridsite2.Delegation;
import org.dcache.delegation.gridsite2.DelegationException;
import org.dcache.srm.util.Axis;
import org.dcache.util.CertificateFactories;
import org.dcache.util.Version;

import static java.util.Arrays.asList;

public class DelegationHandler implements Delegation {
    private static final String INTERFACE_VERSION = "2.0.0";
    private static final String VERSION = Version.of(DelegationHandler.class).getVersion();

    private final CertificateFactory cf = CertificateFactories.newX509CertificateFactory();

    private CellStub delegationServiceStub;

    private LoginStrategy loginStrategy;

    @Required
    public void setDelegationServiceStub(CellStub delegationServiceStub) {
        this.delegationServiceStub = delegationServiceStub;
    }

    @Required
    public void setLoginStrategy(LoginStrategy loginStrategy) {
        this.loginStrategy = loginStrategy;
    }

    @Override
    public String getVersion() {
        return VERSION;
    }

    @Override
    public String getInterfaceVersion() {
        return INTERFACE_VERSION;
    }

    private Subject login() throws DelegationException {
        try {
            Subject subject = new Subject();
            X509Certificate[] chain = Axis.getCertificateChain()
                    .orElseThrow(() -> new DelegationException("User supplied no certificate."));
            subject.getPublicCredentials().add(cf.generateCertPath(asList(chain)));
            subject.getPrincipals().add(new Origin(InetAddresses.forString(Axis.getRemoteAddress())));
            return loginStrategy.login(subject).getSubject();
        } catch (CertificateException e) {
            throw new DelegationException("Failed to process certificate chain.");
        } catch (PermissionDeniedCacheException e) {
            throw new DelegationException("User is not authorized.");
        } catch (TimeoutCacheException e) {
            throw new DelegationException("Internal timeout.");
        } catch (CacheException e) {
            throw new DelegationException(e.getMessage());
        }
    }

    private <T> T get(Future<T> future) throws RemoteException, DelegationException {
        try {
            return future.get();
        } catch (InterruptedException e) {
            throw new DelegationException("Server shutdown.");
        } catch (ExecutionException e) {
            Throwables.throwIfInstanceOf(e.getCause(), RemoteException.class);
            Throwables.throwIfUnchecked(e.getCause());
            throw new RuntimeException(e.getCause());
        }
    }

    @Override
    public String getServiceMetadata(String key) throws RemoteException, DelegationException {
        GetServiceMetaDataRequest request = new GetServiceMetaDataRequest(key);
        return get(delegationServiceStub.send(request, GetServiceMetaDataResponse.class)).getMetaData();
    }

    @Override
    public String getProxyReq(String delegationID) throws RemoteException, DelegationException {
        GetProxyReqRequest request = new GetProxyReqRequest(login(), delegationID);
        return get(delegationServiceStub.send(request, GetProxyReqResponse.class)).getProxyReq();
    }

    @Override
    public void getNewProxyReq(StringHolder proxyRequest, StringHolder delegationID)
            throws RemoteException, DelegationException {
        GetNewProxyReqRequest request = new GetNewProxyReqRequest(login());
        GetNewProxyReqResponse response = get(delegationServiceStub.send(request, GetNewProxyReqResponse.class));
        proxyRequest.value = response.getProxyRequest();
        delegationID.value = response.getDelegationID();
    }

    @Override
    public void putProxy(String delegationID, String proxy) throws RemoteException, DelegationException {
        PutProxyRequest request = new PutProxyRequest(login(), delegationID, proxy);
        get(delegationServiceStub.send(request, PutProxyResponse.class));
    }

    @Override
    public String renewProxyReq(String delegationID) throws RemoteException, DelegationException {
        RenewProxyReqRequest request = new RenewProxyReqRequest(login(), delegationID);
        return get(delegationServiceStub.send(request, RenewProxyReqResponse.class)).getCertificateSigningRequest();
    }

    @Override
    public Calendar getTerminationTime(String delegationID) throws RemoteException, DelegationException {
        GetTerminationTimeRequest request = new GetTerminationTimeRequest(login(), delegationID);
        return get(delegationServiceStub.send(request, GetTerminationTimeResponse.class)).getTerminationTime();
    }

    @Override
    public void destroy(String delegationID) throws RemoteException, DelegationException {
        DestroyRequest request = new DestroyRequest(login(), delegationID);
        get(delegationServiceStub.send(request, DestroyResponse.class));
    }
}