001/* 002 * acme4j - Java ACME client 003 * 004 * Copyright (C) 2017 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.pebble; 015 016import static org.assertj.core.api.Assertions.assertThat; 017import static org.junit.jupiter.api.Assertions.assertThrows; 018 019import java.net.URI; 020import java.security.KeyPair; 021 022import org.junit.jupiter.api.Test; 023import org.shredzone.acme4j.Account; 024import org.shredzone.acme4j.AccountBuilder; 025import org.shredzone.acme4j.Login; 026import org.shredzone.acme4j.Session; 027import org.shredzone.acme4j.Status; 028import org.shredzone.acme4j.exception.AcmeException; 029import org.shredzone.acme4j.exception.AcmeServerException; 030import org.shredzone.acme4j.exception.AcmeUnauthorizedException; 031 032/** 033 * Account related integration tests. 034 */ 035public class AccountIT extends PebbleITBase { 036 037 /** 038 * Create a new account, then bind it to a second session. 039 */ 040 @Test 041 public void testCreate() throws AcmeException { 042 var keyPair = createKeyPair(); 043 var session = new Session(pebbleURI()); 044 045 // Register a new user 046 var login = new AccountBuilder() 047 .addContact("mailto:acme@example.com") 048 .agreeToTermsOfService() 049 .useKeyPair(keyPair) 050 .createLogin(session); 051 052 var location = login.getAccountLocation(); 053 assertIsPebbleUrl(location); 054 055 // Check registered data 056 var acct = login.getAccount(); 057 assertThat(acct.getLocation()).isEqualTo(location); 058 assertThat(acct.getContacts()).contains(URI.create("mailto:acme@example.com")); 059 assertThat(acct.getStatus()).isEqualTo(Status.VALID); 060 061 // Bind another Account object 062 var session2 = new Session(pebbleURI()); 063 var login2 = new Login(location, keyPair, session2); 064 assertThat(login2.getAccountLocation()).isEqualTo(location); 065 var acct2 = login2.getAccount(); 066 assertThat(acct2.getLocation()).isEqualTo(location); 067 assertThat(acct2.getContacts()).contains(URI.create("mailto:acme@example.com")); 068 assertThat(acct2.getStatus()).isEqualTo(Status.VALID); 069 } 070 071 /** 072 * Register the same key pair twice. 073 */ 074 @Test 075 public void testReCreate() throws AcmeException { 076 var keyPair = createKeyPair(); 077 078 // Register a new user 079 var session1 = new Session(pebbleURI()); 080 var login1 = new AccountBuilder() 081 .addContact("mailto:acme@example.com") 082 .agreeToTermsOfService() 083 .useKeyPair(keyPair) 084 .createLogin(session1); 085 086 var location1 = login1.getAccountLocation(); 087 assertIsPebbleUrl(location1); 088 089 // Try to register the same account again 090 var session2 = new Session(pebbleURI()); 091 var login2 = new AccountBuilder() 092 .addContact("mailto:acme@example.com") 093 .agreeToTermsOfService() 094 .useKeyPair(keyPair) 095 .createLogin(session2); 096 097 var location2 = login2.getAccountLocation(); 098 assertIsPebbleUrl(location2); 099 100 assertThat(location1).isEqualTo(location2); 101 } 102 103 /** 104 * Create a new account. Locate it via onlyExisting. 105 */ 106 @Test 107 public void testCreateOnlyExisting() throws AcmeException { 108 var keyPair = createKeyPair(); 109 110 var session1 = new Session(pebbleURI()); 111 var login1 = new AccountBuilder() 112 .agreeToTermsOfService() 113 .useKeyPair(keyPair) 114 .createLogin(session1); 115 116 var location1 = login1.getAccountLocation(); 117 assertIsPebbleUrl(location1); 118 119 var session2 = new Session(pebbleURI()); 120 var login2 = new AccountBuilder() 121 .onlyExisting() 122 .useKeyPair(keyPair) 123 .createLogin(session2); 124 125 var location2 = login2.getAccountLocation(); 126 assertIsPebbleUrl(location2); 127 128 assertThat(location1).isEqualTo(location2); 129 } 130 131 /** 132 * Locate a non-existing account via onlyExisting. Make sure an accountDoesNotExist 133 * error is returned. 134 */ 135 @Test 136 public void testNotExisting() { 137 var ex = assertThrows(AcmeServerException.class, () -> { 138 KeyPair keyPair = createKeyPair(); 139 Session session = new Session(pebbleURI()); 140 new AccountBuilder().onlyExisting().useKeyPair(keyPair).create(session); 141 }); 142 assertThat(ex.getType()).isEqualTo(URI.create("urn:ietf:params:acme:error:accountDoesNotExist")); 143 } 144 145 /** 146 * Modify the contacts of an account. 147 */ 148 @Test 149 public void testModify() throws AcmeException { 150 var keyPair = createKeyPair(); 151 var session = new Session(pebbleURI()); 152 153 var acct = new AccountBuilder() 154 .addContact("mailto:acme@example.com") 155 .agreeToTermsOfService() 156 .useKeyPair(keyPair) 157 .create(session); 158 var location = acct.getLocation(); 159 assertIsPebbleUrl(location); 160 161 acct.modify().addContact("mailto:acme2@example.com").commit(); 162 163 assertThat(acct.getContacts()).contains( 164 URI.create("mailto:acme@example.com"), 165 URI.create("mailto:acme2@example.com")); 166 167 // Still the same after updating 168 acct.update(); 169 assertThat(acct.getContacts()).contains( 170 URI.create("mailto:acme@example.com"), 171 URI.create("mailto:acme2@example.com")); 172 } 173 174 /** 175 * Change the account key. 176 */ 177 @Test 178 public void testKeyChange() throws AcmeException { 179 var keyPair = createKeyPair(); 180 var session = new Session(pebbleURI()); 181 182 var acct = new AccountBuilder() 183 .agreeToTermsOfService() 184 .useKeyPair(keyPair) 185 .create(session); 186 var location = acct.getLocation(); 187 188 var newKeyPair = createKeyPair(); 189 acct.changeKey(newKeyPair); 190 191 assertThrows(AcmeServerException.class, () -> { 192 Session sessionOldKey = new Session(pebbleURI()); 193 Account oldAccount = sessionOldKey.login(location, keyPair).getAccount(); 194 oldAccount.update(); 195 }, "Old account key is still accessible"); 196 197 var sessionNewKey = new Session(pebbleURI()); 198 var newAccount = sessionNewKey.login(location, newKeyPair).getAccount(); 199 assertThat(newAccount.getStatus()).isEqualTo(Status.VALID); 200 } 201 202 /** 203 * Deactivate an account. 204 */ 205 @Test 206 public void testDeactivate() throws AcmeException { 207 var keyPair = createKeyPair(); 208 var session = new Session(pebbleURI()); 209 210 var acct = new AccountBuilder() 211 .agreeToTermsOfService() 212 .useKeyPair(keyPair) 213 .create(session); 214 var location = acct.getLocation(); 215 216 acct.deactivate(); 217 218 // Make sure it is deactivated now... 219 assertThat(acct.getStatus()).isEqualTo(Status.DEACTIVATED); 220 221 // Make sure account cannot be accessed any more... 222 var ex = assertThrows(AcmeUnauthorizedException.class, 223 () -> { 224 Session session2 = new Session(pebbleURI()); 225 Account acct2 = session2.login(location, keyPair).getAccount(); 226 acct2.update(); 227 }, "Account can still be accessed"); 228 assertThat(ex.getMessage()).isEqualTo("Account has been deactivated"); 229 } 230 231}