001/*
002 * acme4j - Java ACME client
003 *
004 * Copyright (C) 2024 Richard "Shred" Körber
005 *   http://acme4j.shredzone.org
006 *
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
013 */
014package org.shredzone.acme4j.it;
015
016import static org.assertj.core.api.Assertions.assertThat;
017import static org.assertj.core.api.Assertions.assertThatNoException;
018
019import java.net.MalformedURLException;
020import java.net.URL;
021
022import org.junit.jupiter.api.Test;
023import org.shredzone.acme4j.Session;
024import org.shredzone.acme4j.connector.Resource;
025import org.shredzone.acme4j.exception.AcmeException;
026
027/**
028 * A very simple test to check if all provider URIs are still pointing to a directory
029 * resource.
030 * <p>
031 * If one of these tests fails, it could be an indicator that the corresponding directory
032 * URL has been changed on CA side, or that EAR or auto-renewal features have been
033 * changed.
034 * <p>
035 * These integration tests require a network connection.
036 */
037public class ProviderIT {
038
039    /**
040     * Test Let's Encrypt
041     */
042    @Test
043    public void testLetsEncrypt() throws AcmeException, MalformedURLException {
044        var session = new Session("acme://letsencrypt.org");
045        assertThat(session.getMetadata().getWebsite()).hasValue(new URL("https://letsencrypt.org"));
046        assertThatNoException().isThrownBy(() -> session.resourceUrl(Resource.NEW_ACCOUNT));
047        assertThat(session.getMetadata().isExternalAccountRequired()).isFalse();
048        assertThat(session.getMetadata().isAutoRenewalEnabled()).isFalse();
049
050        var sessionStage = new Session("acme://letsencrypt.org/staging");
051        assertThat(sessionStage.getMetadata().getWebsite()).hasValue(new URL("https://letsencrypt.org/docs/staging-environment/"));
052        assertThatNoException().isThrownBy(() -> sessionStage.resourceUrl(Resource.NEW_ACCOUNT));
053        assertThat(sessionStage.getMetadata().isExternalAccountRequired()).isFalse();
054        assertThat(sessionStage.getMetadata().isAutoRenewalEnabled()).isFalse();
055    }
056
057    /**
058     * Test Pebble
059     */
060    @Test
061    public void testPebble() throws AcmeException, MalformedURLException {
062        var session = new Session("acme://pebble");
063        assertThat(session.getMetadata().getWebsite()).isEmpty();
064        assertThatNoException().isThrownBy(() -> session.resourceUrl(Resource.NEW_ACCOUNT));
065        assertThat(session.getMetadata().isExternalAccountRequired()).isFalse();
066        assertThat(session.getMetadata().isAutoRenewalEnabled()).isFalse();
067    }
068
069    /**
070     * Test ssl.com
071     */
072    @Test
073    public void testSslCom() throws AcmeException, MalformedURLException {
074        var sessionEcc = new Session("acme://ssl.com/ecc");
075        assertThat(sessionEcc.getMetadata().getWebsite()).hasValue(new URL("https://www.ssl.com"));
076        assertThatNoException().isThrownBy(() -> sessionEcc.resourceUrl(Resource.NEW_ACCOUNT));
077        assertThat(sessionEcc.getMetadata().isExternalAccountRequired()).isTrue();
078        assertThat(sessionEcc.getMetadata().isAutoRenewalEnabled()).isFalse();
079
080        var sessionRsa = new Session("acme://ssl.com/rsa");
081        assertThat(sessionRsa.getMetadata().getWebsite()).hasValue(new URL("https://www.ssl.com"));
082        assertThatNoException().isThrownBy(() -> sessionRsa.resourceUrl(Resource.NEW_ACCOUNT));
083        assertThat(sessionRsa.getMetadata().isExternalAccountRequired()).isTrue();
084        assertThat(sessionRsa.getMetadata().isAutoRenewalEnabled()).isFalse();
085
086        var sessionEccStage = new Session("acme://ssl.com/staging/ecc");
087        assertThat(sessionEccStage.getMetadata().getWebsite()).hasValue(new URL("https://www.ssl.com"));
088        assertThatNoException().isThrownBy(() -> sessionEccStage.resourceUrl(Resource.NEW_ACCOUNT));
089        assertThat(sessionEccStage.getMetadata().isExternalAccountRequired()).isTrue();
090        assertThat(sessionEccStage.getMetadata().isAutoRenewalEnabled()).isFalse();
091
092        var sessionRsaStage = new Session("acme://ssl.com/staging/rsa");
093        assertThat(sessionRsaStage.getMetadata().getWebsite()).hasValue(new URL("https://www.ssl.com"));
094        assertThatNoException().isThrownBy(() -> sessionRsaStage.resourceUrl(Resource.NEW_ACCOUNT));
095        assertThat(sessionRsaStage.getMetadata().isExternalAccountRequired()).isTrue();
096        assertThat(sessionRsaStage.getMetadata().isAutoRenewalEnabled()).isFalse();
097
098        // If these tests fail, the metadata have been fixed on server side. Then remove
099        // the patch at ZeroSSLAcmeProvider, and update the documentation.
100        var sessionEABCheck = new Session("https://acme.ssl.com/sslcom-dv-ecc");
101        assertThat(sessionEABCheck.getMetadata().isExternalAccountRequired()).isFalse();
102        var sessionEABCheckStage = new Session("https://acme-try.ssl.com/sslcom-dv-ecc");
103        assertThat(sessionEABCheckStage.getMetadata().isExternalAccountRequired()).isFalse();
104    }
105
106    /**
107     * Test ZeroSSL
108     */
109    @Test
110    public void testZeroSsl() throws AcmeException, MalformedURLException {
111        var session = new Session("acme://zerossl.com");
112        assertThat(session.getMetadata().getWebsite()).hasValue(new URL("https://zerossl.com"));
113        assertThatNoException().isThrownBy(() -> session.resourceUrl(Resource.NEW_ACCOUNT));
114        assertThat(session.getMetadata().isExternalAccountRequired()).isTrue();
115        assertThat(session.getMetadata().isAutoRenewalEnabled()).isFalse();
116
117        // ZeroSSL has no documented staging server (as of February 2024)
118    }
119
120}