Package io.fathom.cloud.secrets.services

Source Code of io.fathom.cloud.secrets.services.SecretServiceImpl

package io.fathom.cloud.secrets.services;

import io.fathom.cloud.CloudException;
import io.fathom.cloud.keyczar.KeyczarFactory;
import io.fathom.cloud.protobuf.SecretsModel.SecretRecordData;
import io.fathom.cloud.protobuf.SecretsModel.SecretRecordItemData;
import io.fathom.cloud.server.auth.Auth;
import io.fathom.cloud.server.model.Project;
import io.fathom.cloud.services.Attachments;
import io.fathom.cloud.services.AuthService;
import io.fathom.cloud.services.SecretService;
import io.fathom.cloud.services.Attachments.ClientApp;

import java.util.List;

import javax.inject.Inject;
import javax.inject.Singleton;

import org.keyczar.AesKey;
import org.keyczar.Crypter;
import org.keyczar.KeyczarUtils;
import org.keyczar.exceptions.KeyczarException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fathomdb.Configuration;
import com.google.common.collect.Lists;
import com.google.inject.persist.Transactional;
import com.google.protobuf.ByteString;

@Singleton
@Transactional
public class SecretServiceImpl implements SecretService {
    private static final Logger log = LoggerFactory.getLogger(SecretServiceImpl.class);

    @Inject
    KeyczarFactory keyczarFactory;

    @Inject
    Attachments attachments;

    @Inject
    AuthService authService;

    @Inject
    SecretRepository repository;

    @Inject
    Configuration config;

    ClientApp clientApp;

    ClientApp getClientApp() throws CloudException {
        if (clientApp == null) {
            Project project = authService.findSystemProject();
            if (project == null) {
                throw new IllegalStateException("Cannot find system project");
            }

            String appName = config.lookup("secrets.appname", "org.openstack::secrets");

            String appSecret = config.find("secrets.appsecret");
            if (appSecret == null) {
                // We rely on the project secret...
                log.warn("Using default app-secret");
                appSecret = "notasecret";
            }

            this.clientApp = attachments.findClientAppByName(project, appName, appSecret);
            if (clientApp == null) {
                throw new IllegalStateException("Secret store not configured as an application");
            }
        }
        return clientApp;
    }

    @Override
    public List<Secret> list(Auth auth, Project project) throws CloudException {
        Crypter crypter = getSecret(auth, project);

        List<Secret> secrets = Lists.newArrayList();
        for (SecretRecordData data : repository.getSecrets(project).list()) {
            secrets.add(new SecretImpl(project, data, crypter));
        }
        return secrets;
    }

    private Crypter getSecret(Auth auth, Project project) throws CloudException {
        byte[] secret = attachments.findProjectSecret(getClientApp(), auth, project);
        AesKey key;
        if (secret == null) {
            key = KeyczarUtils.generateSymmetricKey();
            secret = KeyczarUtils.pack(key);
            attachments.setProjectSecret(getClientApp(), auth, project, secret);
        } else {
            try {
                key = KeyczarUtils.unpack(secret);
            } catch (KeyczarException e) {
                throw new CloudException("Error unpacking key", e);
            }
        }

        return KeyczarUtils.buildCrypter(key);
    }

    @Override
    public Secret find(Auth auth, Project project, long id) throws CloudException {
        Crypter crypter = getSecret(auth, project);

        SecretRecordData data = repository.getSecrets(project).find(id);
        if (data == null) {
            return null;
        }

        return new SecretImpl(project, data, crypter);
    }

    @Override
    public Secret deleteKey(Auth auth, Project project, long id) throws CloudException {
        Crypter crypter = getSecret(auth, project);

        SecretRecordData data = repository.getSecrets(project).delete(id);
        if (data == null) {
            return null;
        }

        return new SecretImpl(project, data, crypter);
    }

    @Override
    public Secret setSecretItem(Auth auth, Secret secret, String key, byte[] data) throws CloudException {
        SecretImpl secretImpl = (SecretImpl) secret;
        secretImpl = (SecretImpl) find(auth, secretImpl.getProject(), secretImpl.getData().getId());
        SecretRecordData secretData = secretImpl.getData();

        SecretRecordData.Builder b = SecretRecordData.newBuilder(secretData);
        SecretRecordItemData.Builder item = null;
        for (SecretRecordItemData.Builder i : b.getItemBuilderList()) {
            if (i.getKey().equals(key)) {
                item = i;
                break;
            }
        }
        if (item == null) {
            item = b.addItemBuilder();
            item.setKey(key);
        }

        Crypter crypter = secretImpl.getCrypter();
        byte[] ciphertext;
        try {
            ciphertext = crypter.encrypt(data);
        } catch (KeyczarException e) {
            throw new IllegalStateException("Error encrypting secret", e);
        }
        item.setCiphertext(ByteString.copyFrom(ciphertext));

        Project project = secretImpl.getProject();

        secretData = repository.getSecrets(project).update(b);
        return new SecretImpl(project, secretData, crypter);
    }

    @Override
    public Secret create(Auth auth, Project project, SecretInfo secretInfo) throws CloudException {
        Crypter crypter = getSecret(auth, project);

        SecretRecordData.Builder b = SecretRecordData.newBuilder();
        if (secretInfo.name != null) {
            b.setName(secretInfo.name);
        }
        if (secretInfo.algorithm != null) {
            b.setAlgorithm(secretInfo.algorithm);
        }
        if (secretInfo.keySize != 0) {
            b.setKeySize(secretInfo.keySize);
        }
        if (secretInfo.subject != null) {
            b.setSubject(secretInfo.subject);
        }

        SecretRecordData secretData = repository.getSecrets(project).create(b);
        return new SecretImpl(project, secretData, crypter);
    }

}
TOP

Related Classes of io.fathom.cloud.secrets.services.SecretServiceImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.