001/*
002 *   Copyright 2024 Vonage
003 *
004 *   Licensed under the Apache License, Version 2.0 (the "License");
005 *   you may not use this file except in compliance with the License.
006 *   You may obtain a copy of the License at
007 *
008 *        http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *   Unless required by applicable law or agreed to in writing, software
011 *   distributed under the License is distributed on an "AS IS" BASIS,
012 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *   See the License for the specific language governing permissions and
014 *   limitations under the License.
015 */
016package com.vonage.client.auth;
017
018import java.util.*;
019
020public class VonageUnacceptableAuthException extends VonageAuthException {
021    private static final Map<Class<?>, String> AUTH_DESCRIPTION_MAP = new HashMap<>();
022
023    private final Iterable<AuthMethod> availableAuths;
024    private final Iterable<Class<? extends AuthMethod>> acceptableAuthClasses;
025
026    static {
027        AUTH_DESCRIPTION_MAP.put(ApiKeyHeaderAuthMethod.class, "API Key and Secret");
028        AUTH_DESCRIPTION_MAP.put(SignatureAuthMethod.class, "API Key and Signature Secret");
029        AUTH_DESCRIPTION_MAP.put(JWTAuthMethod.class, "Application ID and Private Key");
030    }
031
032    public VonageUnacceptableAuthException(Collection<AuthMethod> availableAuths, Collection<Class<? extends AuthMethod>> acceptableAuthClasses) {
033        this.availableAuths = new ArrayList<>(availableAuths);
034        this.acceptableAuthClasses = new ArrayList<>(acceptableAuthClasses);
035    }
036
037    public String getMessage() {
038        return generateErrorMessage();
039    }
040
041    private String generateErrorMessage() {
042        SortedSet<String> availableTypes = new TreeSet<>();
043        for (AuthMethod auth : availableAuths) {
044            availableTypes.add(AUTH_DESCRIPTION_MAP.getOrDefault(auth.getClass(), auth.getClass().getSimpleName()));
045        }
046
047        SortedSet<String> acceptableTypes = new TreeSet<>();
048        for (Class<?> klass : acceptableAuthClasses) {
049            acceptableTypes.add(AUTH_DESCRIPTION_MAP.getOrDefault(klass, klass.getSimpleName()));
050        }
051
052        return String.format(
053                "No acceptable authentication type could be found. " +
054                "Acceptable types are: %s. Supplied types were: %s",
055                String.join(", ", acceptableTypes),
056                String.join(", ", availableTypes)
057        );
058    }
059}