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

dev.fitko.fitconnect.core.zbp.ZBPApiService Maven / Gradle / Ivy

package dev.fitko.fitconnect.core.zbp;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nimbusds.jose.jwk.RSAKey;
import dev.fitko.fitconnect.api.config.ZBPCertConfig;
import dev.fitko.fitconnect.api.config.defaults.ZBPEnvironment;
import dev.fitko.fitconnect.api.domain.zbp.ZBPEnvelope;
import dev.fitko.fitconnect.api.domain.zbp.attachment.ZBPApiAttachment;
import dev.fitko.fitconnect.api.domain.zbp.message.CreateMessageResponse;
import dev.fitko.fitconnect.api.exceptions.internal.RestApiException;
import dev.fitko.fitconnect.api.services.http.HttpClient;
import dev.fitko.fitconnect.core.crypto.utils.CertUtils;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;

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

import static dev.fitko.fitconnect.core.http.HttpHeaders.ZBP_PEM_COOKIE_NAME;

public class ZBPApiService {

    public static final String MAILBOX_MESSAGE_PATH = "/v6/mailbox/messages";
    public static final String CREATE_STATE_PATH = "/v6/mailbox/applications/states";
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    private final HttpClient httpClient;
    private final String baseUrl;
    private final ZBPEnvironment environment;
    private final ZBPCertConfig certConfig;

    public ZBPApiService(final HttpClient httpClient, final ZBPEnvironment environment, ZBPCertConfig certConfig) {
        this.httpClient = httpClient;
        this.baseUrl = environment.getBaseUrl();
        this.environment = environment;
        this.certConfig = certConfig;
    }

    /**
     * Insert a new message with optional attachments to the user mailbox.
     *
     * @param signingKey  key to sign the access token
     * @param envelope    the signed envelope that contains the message payload
     * @param attachments the attachments for the message, if empty no attachments will be sent
     * @return {@link CreateMessageResponse}
     * @throws RestApiException if there was a technical error sending the message
     */
    public CreateMessageResponse sendMessageToMailbox(final RSAKey signingKey, String signer, final ZBPEnvelope envelope, final List attachments) throws RestApiException {
        final String url = String.format(baseUrl + MAILBOX_MESSAGE_PATH);
        try {
            final String token = TokenGenerator.buildToken(signingKey, signer);
            final Map headers = buildHeaders(token, "multipart/form-data");
            final MultipartBody multipartBody = buildMultipartBody(envelope, attachments);
            return httpClient.put(url, headers, multipartBody, CreateMessageResponse.class).getBody();
        } catch (final Exception e) {
            throw new RestApiException("Could not send message to zbp mailbox", e);
        }
    }

    /**
     * Create a new state for a given
     *
     * @param signingKey          key to sign the access token
     * @param createStateEnvelope the signed envelope that contains the signed state payload
     * @throws RestApiException if there was a technical error creating the state
     */
    public void createNewState(final RSAKey signingKey, String signer, final ZBPEnvelope createStateEnvelope) throws RestApiException {
        final String url = String.format(baseUrl + CREATE_STATE_PATH);
        try {
            final String token = TokenGenerator.buildToken(signingKey, signer);
            final Map headers = buildHeaders(token, "application/json");
            httpClient.post(url, headers, createStateEnvelope, Void.class);
        } catch (final Exception e) {
            throw new RestApiException("Could not create application state", e);
        }
    }

    private MultipartBody buildMultipartBody(final ZBPEnvelope messageEnvelope, final List attachments) {
        var multipartBodyBuilder = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("json", writeToString(messageEnvelope));

        for (ZBPApiAttachment attachment : attachments) {
            final RequestBody requestBody = RequestBody.create(MediaType.parse(attachment.getMimeType()), attachment.getData());
            multipartBodyBuilder.addFormDataPart("files", attachment.getFilename(), requestBody);
        }

        return multipartBodyBuilder.build();
    }

    private Map buildHeaders(String bearerToken, String contentType) {
        final HashMap headers = new HashMap<>();
        headers.put("Authorization", "Bearer " + bearerToken);
        headers.put("Content-Type", contentType);

        if (environment.isSendCertAsCookie()) {
            headers.put("Cookie", ZBP_PEM_COOKIE_NAME + "=" + CertUtils.removeMarker(certConfig.getClientCertificate()));
        }

        return headers;
    }

    private String writeToString(ZBPEnvelope envelope) {
        try {
            return OBJECT_MAPPER.writeValueAsString(envelope);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy