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.exception; 015 016import java.net.MalformedURLException; 017import java.net.URI; 018import java.net.URL; 019import java.util.Optional; 020 021import edu.umd.cs.findbugs.annotations.Nullable; 022import org.shredzone.acme4j.Problem; 023 024/** 025 * The user is required to take manual action as indicated. 026 * <p> 027 * Usually this exception is thrown when the terms of service have changed, and the CA 028 * requires an agreement to the new terms before proceeding. 029 */ 030public class AcmeUserActionRequiredException extends AcmeServerException { 031 private static final long serialVersionUID = 7719055447283858352L; 032 033 private final @Nullable URI tosUri; 034 035 /** 036 * Creates a new {@link AcmeUserActionRequiredException}. 037 * 038 * @param problem 039 * {@link Problem} that caused the exception 040 * @param tosUri 041 * {@link URI} of the terms-of-service document to accept, may be 042 * {@code null} 043 */ 044 public AcmeUserActionRequiredException(Problem problem, @Nullable URI tosUri) { 045 super(problem); 046 this.tosUri = tosUri; 047 } 048 049 /** 050 * Returns the {@link URI} of the terms-of-service document to accept. Empty 051 * if the server did not provide a link to such a document. 052 */ 053 public Optional<URI> getTermsOfServiceUri() { 054 return Optional.ofNullable(tosUri); 055 } 056 057 /** 058 * Returns the {@link URL} of a document that gives instructions on the actions to be 059 * taken by a human. 060 */ 061 public URL getInstance() { 062 var instance = getProblem().getInstance() 063 .orElseThrow(() -> new AcmeProtocolException("Instance URL required, but missing.")); 064 065 try { 066 return instance.toURL(); 067 } catch (MalformedURLException ex) { 068 throw new AcmeProtocolException("Bad instance URL: " + instance, ex); 069 } 070 } 071 072 @Override 073 public String toString() { 074 return getProblem().getInstance() 075 .map(uri -> "Please visit " + uri + " - details: " + getProblem()) 076 .orElseGet(super::toString); 077 } 078 079}