1 /* 2 * Copyright 2015, Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * * Neither the name of Google Inc. nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 package com.google.auth; 33 34 import java.io.IOException; 35 import java.io.Serializable; 36 import java.net.URI; 37 import java.util.List; 38 import java.util.Map; 39 import java.util.concurrent.Executor; 40 41 /** Represents an abstract authorized identity instance. */ 42 public abstract class Credentials implements Serializable { 43 44 private static final long serialVersionUID = 808575179767517313L; 45 46 public static final String GOOGLE_DEFAULT_UNIVERSE = "googleapis.com"; 47 48 /** 49 * A constant string name describing the authentication technology. 50 * 51 * <p>E.g. “OAuth2”, “SSL”. For use by the transport layer to determine whether it supports the 52 * type of authentication in the case where {@link Credentials#hasRequestMetadataOnly} is false. 53 * Also serves as a debugging helper. 54 * 55 * @return The type of authentication used. 56 */ getAuthenticationType()57 public abstract String getAuthenticationType(); 58 59 /** 60 * Gets the universe domain for the credential in a blocking manner, refreshing tokens if 61 * required. 62 * 63 * @return a universe domain value in the format some-domain.xyz. By default, returns the Google 64 * universe domain googleapis.com. 65 * @throws IOException extending classes might have to do remote calls to determine the universe 66 * domain. The exception must implement {@link Retryable} and {@code isRetryable()} will 67 * return true if the operation may be retried. 68 */ getUniverseDomain()69 public String getUniverseDomain() throws IOException { 70 return GOOGLE_DEFAULT_UNIVERSE; 71 } 72 73 /** 74 * Get the current request metadata, refreshing tokens if required. 75 * 76 * <p>This should be called by the transport layer on each request, and the data should be 77 * populated in headers or other context. The operation can block and fail to complete and may do 78 * things such as refreshing access tokens. 79 * 80 * <p>The convention for handling binary data is for the key in the returned map to end with 81 * {@code "-bin"} and for the corresponding values to be base64 encoded. 82 * 83 * @return The request metadata used for populating headers or other context. 84 * @throws IOException if there was an error getting up-to-date access. 85 */ getRequestMetadata()86 public Map<String, List<String>> getRequestMetadata() throws IOException { 87 return getRequestMetadata(null); 88 } 89 90 /** 91 * Get the current request metadata without blocking. 92 * 93 * <p>This should be called by the transport layer on each request, and the data should be 94 * populated in headers or other context. The implementation can either call the callback inline 95 * or asynchronously. Either way it should <strong>never block</strong> in this method. The 96 * executor is provided for tasks that may block. 97 * 98 * <p>The default implementation will just call {@link #getRequestMetadata(URI)} then the callback 99 * from the given executor. 100 * 101 * <p>The convention for handling binary data is for the key in the returned map to end with 102 * {@code "-bin"} and for the corresponding values to be base64 encoded. 103 * 104 * @param uri URI of the entry point for the request. 105 * @param executor Executor to perform the request. 106 * @param callback Callback to execute when the request is finished. 107 */ getRequestMetadata( final URI uri, Executor executor, final RequestMetadataCallback callback)108 public void getRequestMetadata( 109 final URI uri, Executor executor, final RequestMetadataCallback callback) { 110 executor.execute( 111 new Runnable() { 112 @Override 113 public void run() { 114 blockingGetToCallback(uri, callback); 115 } 116 }); 117 } 118 119 /** 120 * Call {@link #getRequestMetadata(URI)} and pass the result or error to the callback. 121 * 122 * @param uri URI of the entry point for the request. 123 * @param callback Callback handler to execute when the metadata completes. 124 */ blockingGetToCallback(URI uri, RequestMetadataCallback callback)125 protected final void blockingGetToCallback(URI uri, RequestMetadataCallback callback) { 126 Map<String, List<String>> result; 127 try { 128 result = getRequestMetadata(uri); 129 } catch (Throwable e) { 130 callback.onFailure(e); 131 return; 132 } 133 callback.onSuccess(result); 134 } 135 136 /** 137 * Get the current request metadata in a blocking manner, refreshing tokens if required. 138 * 139 * <p>This should be called by the transport layer on each request, and the data should be 140 * populated in headers or other context. The operation can block and fail to complete and may do 141 * things such as refreshing access tokens. 142 * 143 * <p>The convention for handling binary data is for the key in the returned map to end with 144 * {@code "-bin"} and for the corresponding values to be base64 encoded. 145 * 146 * @param uri URI of the entry point for the request. 147 * @return The request metadata used for populating headers or other context. 148 * @throws IOException if there was an error getting up-to-date access. The exception should 149 * implement {@link Retryable} and {@code isRetryable()} will return true if the operation may 150 * be retried. 151 */ getRequestMetadata(URI uri)152 public abstract Map<String, List<String>> getRequestMetadata(URI uri) throws IOException; 153 154 /** 155 * Whether the credentials have metadata entries that should be added to each request. 156 * 157 * <p>This should be called by the transport layer to see if {@link 158 * Credentials#getRequestMetadata} should be used for each request. 159 * 160 * @return Whether or not the transport layer should call {@link Credentials#getRequestMetadata} 161 */ hasRequestMetadata()162 public abstract boolean hasRequestMetadata(); 163 164 /** 165 * Indicates whether or not the Auth mechanism works purely by including request metadata. 166 * 167 * <p>This is meant for the transport layer. If this is true a transport does not need to take 168 * actions other than including the request metadata. If this is false, a transport must 169 * specifically know about the authentication technology to support it, and should fail to accept 170 * the credentials otherwise. 171 * 172 * @return Whether or not the Auth mechanism works purely by including request metadata. 173 */ hasRequestMetadataOnly()174 public abstract boolean hasRequestMetadataOnly(); 175 176 /** 177 * Refresh the authorization data, discarding any cached state. 178 * 179 * <p>For use by the transport to allow retry after getting an error indicating there may be 180 * invalid tokens or other cached state. 181 * 182 * @throws IOException if there was an error getting up-to-date access. 183 */ refresh()184 public abstract void refresh() throws IOException; 185 } 186