001/* 002 * acme4j - Java ACME client 003 * 004 * Copyright (C) 2016 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.assertThat; 017import static org.junit.jupiter.api.Assertions.assertThrows; 018 019import java.io.ByteArrayInputStream; 020import java.io.ByteArrayOutputStream; 021import java.io.ObjectInputStream; 022import java.io.ObjectOutputStream; 023import java.net.URL; 024import java.nio.charset.StandardCharsets; 025 026import org.junit.jupiter.api.Test; 027import org.shredzone.acme4j.toolbox.TestUtils; 028 029/** 030 * Unit tests for {@link AcmeResource}. 031 */ 032public class AcmeResourceTest { 033 034 /** 035 * Test constructors and setters 036 */ 037 @Test 038 public void testConstructor() throws Exception { 039 var login = TestUtils.login(); 040 var location = new URL("http://example.com/acme/resource"); 041 042 assertThrows(NullPointerException.class, () -> new DummyResource(null, null)); 043 044 var resource = new DummyResource(login, location); 045 assertThat(resource.getLogin()).isEqualTo(login); 046 assertThat(resource.getLocation()).isEqualTo(location); 047 } 048 049 /** 050 * Test if {@link AcmeResource} is properly serialized. 051 */ 052 @Test 053 public void testSerialization() throws Exception { 054 var login = TestUtils.login(); 055 var location = new URL("http://example.com/acme/resource"); 056 057 // Create a Challenge for testing 058 var challenge = new DummyResource(login, location); 059 assertThat(challenge.getLogin()).isEqualTo(login); 060 061 // Serialize it 062 byte[] serialized; 063 try (var baos = new ByteArrayOutputStream()) { 064 try (var out = new ObjectOutputStream(baos)) { 065 out.writeObject(challenge); 066 } 067 serialized = baos.toByteArray(); 068 } 069 070 // Make sure there is no PrivateKey in the stream 071 var str = new String(serialized, StandardCharsets.ISO_8859_1); 072 assertThat(str).as("serialized stream contains a PrivateKey") 073 .doesNotContain("Ljava/security/PrivateKey"); 074 075 // Deserialize to new object 076 DummyResource restored; 077 try (var bais = new ByteArrayInputStream(serialized); 078 var in = new ObjectInputStream(bais)) { 079 var obj = in.readObject(); 080 assertThat(obj).isInstanceOf(DummyResource.class); 081 restored = (DummyResource) obj; 082 } 083 assertThat(restored).isNotSameAs(challenge); 084 085 // Make sure the restored object is not attached to a login 086 assertThrows(IllegalStateException.class, restored::getLogin); 087 088 // Rebind to login 089 restored.rebind(login); 090 091 // Make sure the new login is set 092 assertThat(restored.getLogin()).isEqualTo(login); 093 } 094 095 /** 096 * Test if a rebind attempt fails. 097 */ 098 @Test 099 public void testRebind() { 100 assertThrows(IllegalStateException.class, () -> { 101 var login = TestUtils.login(); 102 var location = new URL("http://example.com/acme/resource"); 103 104 var resource = new DummyResource(login, location); 105 assertThat(resource.getLogin()).isEqualTo(login); 106 107 var login2 = TestUtils.login(); 108 resource.rebind(login2); // fails to rebind to another login 109 }); 110 } 111 112 /** 113 * Minimum implementation of {@link AcmeResource}. 114 */ 115 private static class DummyResource extends AcmeResource { 116 private static final long serialVersionUID = 7188822681353082472L; 117 public DummyResource(Login login, URL location) { 118 super(login, location); 119 } 120 } 121 122}