001/*
002 * acme4j - Java ACME client
003 *
004 * Copyright (C) 2018 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;
015
016import static org.assertj.core.api.Assertions.*;
017import static org.junit.jupiter.api.Assertions.assertThrows;
018
019import java.net.InetAddress;
020import java.net.UnknownHostException;
021
022import org.junit.jupiter.api.Test;
023import org.shredzone.acme4j.exception.AcmeProtocolException;
024import org.shredzone.acme4j.toolbox.JSONBuilder;
025
026/**
027 * Unit tests for {@link Identifier}.
028 */
029public class IdentifierTest {
030
031    @Test
032    public void testConstants() {
033        assertThat(Identifier.TYPE_DNS).isEqualTo("dns");
034        assertThat(Identifier.TYPE_IP).isEqualTo("ip");
035    }
036
037    @Test
038    public void testGetters() {
039        var id1 = new Identifier("foo", "123.456");
040        assertThat(id1.getType()).isEqualTo("foo");
041        assertThat(id1.getValue()).isEqualTo("123.456");
042        assertThat(id1.toString()).isEqualTo("foo=123.456");
043        var map1 = id1.toMap();
044        assertThat(map1).hasSize(2);
045        assertThat(map1.get("type")).isEqualTo("foo");
046        assertThat(map1.get("value")).isEqualTo("123.456");
047
048        var jb = new JSONBuilder();
049        jb.put("type", "bar");
050        jb.put("value", "654.321");
051        var id2 = new Identifier(jb.toJSON());
052        assertThat(id2.getType()).isEqualTo("bar");
053        assertThat(id2.getValue()).isEqualTo("654.321");
054        assertThat(id2.toString()).isEqualTo("bar=654.321");
055        var map2 = id2.toMap();
056        assertThat(map2).hasSize(2);
057        assertThat(map2.get("type")).isEqualTo("bar");
058        assertThat(map2.get("value")).isEqualTo("654.321");
059    }
060
061    @Test
062    public void testDns() {
063        var id1 = Identifier.dns("example.com");
064        assertThat(id1.getType()).isEqualTo(Identifier.TYPE_DNS);
065        assertThat(id1.getValue()).isEqualTo("example.com");
066        assertThat(id1.getDomain()).isEqualTo("example.com");
067
068        var id2 = Identifier.dns("ëxämþlë.com");
069        assertThat(id2.getType()).isEqualTo(Identifier.TYPE_DNS);
070        assertThat(id2.getValue()).isEqualTo("xn--xml-qla7ae5k.com");
071        assertThat(id2.getDomain()).isEqualTo("xn--xml-qla7ae5k.com");
072    }
073
074    @Test
075    public void testNoDns() {
076        assertThrows(AcmeProtocolException.class, () ->
077            new Identifier("foo", "example.com").getDomain()
078        );
079    }
080
081    @Test
082    public void testIp() throws UnknownHostException {
083        var id1 = Identifier.ip(InetAddress.getByName("192.0.2.2"));
084        assertThat(id1.getType()).isEqualTo(Identifier.TYPE_IP);
085        assertThat(id1.getValue()).isEqualTo("192.0.2.2");
086        assertThat(id1.getIP().getHostAddress()).isEqualTo("192.0.2.2");
087
088        var id2 = Identifier.ip(InetAddress.getByName("2001:db8:85a3::8a2e:370:7334"));
089        assertThat(id2.getType()).isEqualTo(Identifier.TYPE_IP);
090        assertThat(id2.getValue()).isEqualTo("2001:db8:85a3:0:0:8a2e:370:7334");
091        assertThat(id2.getIP().getHostAddress()).isEqualTo("2001:db8:85a3:0:0:8a2e:370:7334");
092
093        var id3 = Identifier.ip("192.0.2.99");
094        assertThat(id3.getType()).isEqualTo(Identifier.TYPE_IP);
095        assertThat(id3.getValue()).isEqualTo("192.0.2.99");
096        assertThat(id3.getIP().getHostAddress()).isEqualTo("192.0.2.99");
097    }
098
099    @Test
100    public void testNoIp() {
101        assertThrows(AcmeProtocolException.class, () ->
102            new Identifier("foo", "example.com").getIP()
103        );
104    }
105
106    @Test
107    public void testAncestorDomain() {
108        var id1 = Identifier.dns("foo.bar.example.com");
109        var id1a = id1.withAncestorDomain("example.com");
110        assertThat(id1a).isNotSameAs(id1);
111        assertThat(id1a.getType()).isEqualTo(Identifier.TYPE_DNS);
112        assertThat(id1a.getValue()).isEqualTo("foo.bar.example.com");
113        assertThat(id1a.getDomain()).isEqualTo("foo.bar.example.com");
114        assertThat(id1a.toMap()).contains(
115                entry("type", "dns"),
116                entry("value", "foo.bar.example.com"),
117                entry("ancestorDomain", "example.com")
118        );
119        assertThat(id1a.toString()).isEqualTo("{ancestorDomain=example.com, type=dns, value=foo.bar.example.com}");
120
121        var id2 = Identifier.dns("föö.ëxämþlë.com").withAncestorDomain("ëxämþlë.com");
122        assertThat(id2.getType()).isEqualTo(Identifier.TYPE_DNS);
123        assertThat(id2.getValue()).isEqualTo("xn--f-1gaa.xn--xml-qla7ae5k.com");
124        assertThat(id2.getDomain()).isEqualTo("xn--f-1gaa.xn--xml-qla7ae5k.com");
125        assertThat(id2.toMap()).contains(
126                entry("type", "dns"),
127                entry("value", "xn--f-1gaa.xn--xml-qla7ae5k.com"),
128                entry("ancestorDomain", "xn--xml-qla7ae5k.com")
129        );
130
131        var id3 = Identifier.dns("foo.bar.example.com").withAncestorDomain("example.com");
132        assertThat(id3.equals(id1)).isFalse();
133        assertThat(id3.equals(id1a)).isTrue();
134
135        assertThatExceptionOfType(AcmeProtocolException.class).isThrownBy(() ->
136                Identifier.ip("192.0.2.99").withAncestorDomain("example.com")
137        );
138
139        assertThatNullPointerException().isThrownBy(() ->
140                Identifier.dns("example.org").withAncestorDomain(null)
141        );
142    }
143
144    @Test
145    public void testAllowSubdomainAuth() {
146        var id1 = Identifier.dns("example.com");
147        var id1a = id1.allowSubdomainAuth();
148        assertThat(id1a).isNotSameAs(id1);
149        assertThat(id1a.getType()).isEqualTo(Identifier.TYPE_DNS);
150        assertThat(id1a.getValue()).isEqualTo("example.com");
151        assertThat(id1a.getDomain()).isEqualTo("example.com");
152        assertThat(id1a.toMap()).contains(
153                entry("type", "dns"),
154                entry("value", "example.com"),
155                entry("subdomainAuthAllowed", true)
156        );
157        assertThat(id1a.toString()).isEqualTo("{subdomainAuthAllowed=true, type=dns, value=example.com}");
158
159        var id3 = Identifier.dns("example.com").allowSubdomainAuth();
160        assertThat(id3.equals(id1)).isFalse();
161        assertThat(id3.equals(id1a)).isTrue();
162
163        assertThatExceptionOfType(AcmeProtocolException.class).isThrownBy(() ->
164                Identifier.ip("192.0.2.99").allowSubdomainAuth()
165        );
166    }
167
168    @Test
169    public void testEquals() {
170        var idRef = new Identifier("foo", "123.456");
171
172        var id1 = new Identifier("foo", "123.456");
173        assertThat(idRef.equals(id1)).isTrue();
174        assertThat(id1.equals(idRef)).isTrue();
175
176        var id2 = new Identifier("bar", "654.321");
177        assertThat(idRef.equals(id2)).isFalse();
178
179        var id3 = new Identifier("foo", "555.666");
180        assertThat(idRef.equals(id3)).isFalse();
181
182        var id4 = new Identifier("sna", "123.456");
183        assertThat(idRef.equals(id4)).isFalse();
184
185        assertThat(idRef.equals(new Object())).isFalse();
186        assertThat(idRef.equals(null)).isFalse();
187    }
188
189    @Test
190    public void testNull() {
191        assertThrows(NullPointerException.class, () -> new Identifier(null, "123.456"));
192        assertThrows(NullPointerException.class, () -> new Identifier("foo", null));
193    }
194
195}