@@ -16,7 +16,6 @@ limitations under the License.
1616
1717using System ;
1818using System . IO ;
19- using System . Linq ;
2019using System . Threading ;
2120using System . Threading . Tasks ;
2221
@@ -50,6 +49,19 @@ public static async Task<T> FromFileAsync<T>(string credentialPath, Cancellation
5049 return await FromStreamAsync < T > ( fileStream , cancellationToken ) . ConfigureAwait ( false ) ;
5150 }
5251
52+ /// <summary>
53+ /// Creates a credential of the specified type from a file that contains JSON credential data.
54+ /// </summary>
55+ /// <param name="credentialPath">The path to the credential file.</param>
56+ /// <param name="credentialType">The type of credential to be loaded. Valid strings can be found in <see cref="JsonCredentialParameters"/>.</param>
57+ /// <param name="cancellationToken">The cancellation token to cancel the operation.</param>
58+ /// <returns>The created credential.</returns>
59+ public static async Task < GoogleCredential > FromFileAsync ( string credentialPath , string credentialType , CancellationToken cancellationToken )
60+ {
61+ using FileStream fileStream = File . OpenRead ( credentialPath ) ;
62+ return await FromStreamAsync ( fileStream , credentialType , cancellationToken ) . ConfigureAwait ( false ) ;
63+ }
64+
5365 /// <summary>
5466 /// Creates a credential of the specified type from a file that contains JSON credential data.
5567 /// </summary>
@@ -62,6 +74,18 @@ public static T FromFile<T>(string credentialPath)
6274 return FromStream < T > ( fileStream ) ;
6375 }
6476
77+ /// <summary>
78+ /// Creates a credential of the specified type from a file that contains JSON credential data.
79+ /// </summary>
80+ /// <param name="credentialPath">The path to the credential file.</param>
81+ /// <param name="credentialType">The type of credential to be loaded. Valid strings can be found in <see cref="JsonCredentialParameters"/>.</param>
82+ /// <returns>The created credential.</returns>
83+ public static GoogleCredential FromFile ( string credentialPath , string credentialType )
84+ {
85+ using FileStream fileStream = File . OpenRead ( credentialPath ) ;
86+ return FromStream ( fileStream , credentialType ) ;
87+ }
88+
6589 /// <summary>
6690 /// Creates a credential of the specified type from a stream that contains JSON credential data.
6791 /// </summary>
@@ -83,6 +107,27 @@ public static async Task<T> FromStreamAsync<T>(Stream stream, CancellationToken
83107 return FromJsonParameters < T > ( jsonCredentialParameters ) ;
84108 }
85109
110+ /// <summary>
111+ /// Creates a credential of the specified type from a stream that contains JSON credential data.
112+ /// </summary>
113+ /// <param name="stream">The stream that contains the JSON credential data.</param>
114+ /// <param name="credentialType">The type of credential to be loaded. Valid strings can be found in <see cref="JsonCredentialParameters"/>.</param>
115+ /// <param name="cancellationToken">The cancellation token to cancel the operation.</param>
116+ /// <returns>The created credential.</returns>
117+ private static async Task < GoogleCredential > FromStreamAsync ( Stream stream , string credentialType , CancellationToken cancellationToken )
118+ {
119+ JsonCredentialParameters jsonCredentialParameters ;
120+ try
121+ {
122+ jsonCredentialParameters = await NewtonsoftJsonSerializer . Instance . DeserializeAsync < JsonCredentialParameters > ( stream , cancellationToken ) . ConfigureAwait ( false ) ;
123+ }
124+ catch ( Exception e )
125+ {
126+ throw new InvalidOperationException ( JsonDeserializationErrorMessage , e ) ;
127+ }
128+ return FromJsonParameters ( jsonCredentialParameters , credentialType ) ;
129+ }
130+
86131 /// <summary>
87132 /// Creates a credential of the specified type from a stream that contains JSON credential data.
88133 /// </summary>
@@ -103,6 +148,26 @@ public static T FromStream<T>(Stream stream)
103148 return FromJsonParameters < T > ( jsonCredentialParameters ) ;
104149 }
105150
151+ /// <summary>
152+ /// Creates a credential of the specified type from a stream that contains JSON credential data.
153+ /// </summary>
154+ /// <param name="stream">The stream that contains the JSON credential data.</param>
155+ /// <param name="credentialType">The type of credential to be loaded. Valid strings can be found in <see cref="JsonCredentialParameters"/>.</param>
156+ /// <returns>The created credential.</returns>
157+ private static GoogleCredential FromStream ( Stream stream , string credentialType )
158+ {
159+ JsonCredentialParameters jsonCredentialParameters ;
160+ try
161+ {
162+ jsonCredentialParameters = NewtonsoftJsonSerializer . Instance . Deserialize < JsonCredentialParameters > ( stream ) ;
163+ }
164+ catch ( Exception e )
165+ {
166+ throw new InvalidOperationException ( JsonDeserializationErrorMessage , e ) ;
167+ }
168+ return FromJsonParameters ( jsonCredentialParameters , credentialType ) ;
169+ }
170+
106171 /// <summary>
107172 /// Creates a credential of the specified type from a string that contains JSON credential data.
108173 /// </summary>
@@ -123,6 +188,26 @@ public static T FromJson<T>(string json)
123188 return FromJsonParameters < T > ( jsonCredentialParameters ) ;
124189 }
125190
191+ /// <summary>
192+ /// Creates a credential of the specified type from a string that contains JSON credential data.
193+ /// </summary>
194+ /// <param name="json">The string that contains the JSON credential data.</param>
195+ /// <param name="credentialType">The type of credential to be loaded. Valid strings can be found in <see cref="JsonCredentialParameters"/>.</param>
196+ /// <returns>The created credential.</returns>
197+ public static GoogleCredential FromJson ( string json , string credentialType )
198+ {
199+ JsonCredentialParameters jsonCredentialParameters ;
200+ try
201+ {
202+ jsonCredentialParameters = NewtonsoftJsonSerializer . Instance . Deserialize < JsonCredentialParameters > ( json ) ;
203+ }
204+ catch ( Exception e )
205+ {
206+ throw new InvalidOperationException ( JsonDeserializationErrorMessage , e ) ;
207+ }
208+ return FromJsonParameters ( jsonCredentialParameters , credentialType ) ;
209+ }
210+
126211 /// <summary>
127212 /// Creates a credential of the specified type from JSON credential parameters.
128213 /// </summary>
@@ -136,27 +221,53 @@ public static T FromJson<T>(string json)
136221 /// </exception>
137222 internal static T FromJsonParameters < T > ( JsonCredentialParameters credentialParameters )
138223 {
139- if ( CreateCredential ( credentialParameters , typeof ( T ) ) is T credentialAsT )
224+ credentialParameters . ThrowIfNull ( nameof ( credentialParameters ) ) ;
225+ if ( FromJsonParameters ( credentialParameters , typeof ( T ) ) is T credentialAsT )
140226 {
141227 return credentialAsT ;
142228 }
143229
144230 throw new InvalidOperationException (
145231 $ "Found incompatible credential types, '{ credentialParameters . Type } ' and '{ typeof ( T ) . FullName } , even though a check"
146232 + " should have already taken place. We should never reach here, there's a bug in the code." ) ;
233+ }
147234
148- static IGoogleCredential CreateCredential ( JsonCredentialParameters credentialParameters , Type targetCredentialType ) =>
149- credentialParameters . ThrowIfNull ( nameof ( credentialParameters ) ) . Type switch
150- {
151- JsonCredentialParameters . AuthorizedUserCredentialType => CreateUserCredentialFromParameters ( credentialParameters , targetCredentialType ) ,
152- JsonCredentialParameters . ServiceAccountCredentialType => CreateServiceAccountCredentialFromParameters ( credentialParameters , targetCredentialType ) ,
153- JsonCredentialParameters . ExternalAccountCredentialType => CreateExternalCredentialFromParameters ( credentialParameters , targetCredentialType ) ,
154- JsonCredentialParameters . ImpersonatedServiceAccountCredentialType => CreateImpersonatedServiceAccountCredentialFromParameters ( credentialParameters , targetCredentialType ) ,
155- JsonCredentialParameters . ExternalAccountAuthorizedUserCredentialType => CreateExternalAccountAuthorizedUserCredentialFromParameters ( credentialParameters , targetCredentialType ) ,
156- _ => throw new InvalidOperationException ( $ "Error creating credential from JSON or JSON parameters. Unrecognized credential type { credentialParameters . Type } .") ,
157- } ;
235+ /// <summary>
236+ /// Creates a credential of the specified type from JSON credential parameters.
237+ /// </summary>
238+ /// <param name="credentialParameters">The JSON credential parameters.</param>
239+ /// <param name="credentialType">The type of credential to be loaded. Valid strings can be found in <see cref="JsonCredentialParameters"/>.</param>
240+ /// <returns>The created credential.</returns>
241+ /// <exception cref="InvalidOperationException">
242+ /// Thrown if the <paramref name="credentialType"/> is unrecognized,
243+ /// or if the credential data is incompatible with the requested type.
244+ /// </exception>
245+ private static GoogleCredential FromJsonParameters ( JsonCredentialParameters credentialParameters , string credentialType )
246+ {
247+ credentialParameters . ThrowIfNull ( nameof ( credentialParameters ) ) ;
248+ if ( credentialParameters . Type != credentialType )
249+ {
250+ throw new InvalidOperationException ( $ "The credential type { credentialParameters . Type } is not compatible with the requested type { credentialType } ") ;
251+ }
252+
253+ // Type checking has already occurred so target type may be set to the generic IGoogleCredential which all credentials implement.
254+ Type targetType = typeof ( IGoogleCredential ) ;
255+ var rawCredentialType = FromJsonParameters ( credentialParameters , targetType ) ;
256+
257+ return rawCredentialType . ToGoogleCredential ( ) ;
158258 }
159259
260+ private static IGoogleCredential FromJsonParameters ( JsonCredentialParameters credentialParameters , Type targetCredentialType ) =>
261+ credentialParameters . ThrowIfNull ( nameof ( credentialParameters ) ) . Type switch
262+ {
263+ JsonCredentialParameters . AuthorizedUserCredentialType => CreateUserCredentialFromParameters ( credentialParameters , targetCredentialType ) ,
264+ JsonCredentialParameters . ServiceAccountCredentialType => CreateServiceAccountCredentialFromParameters ( credentialParameters , targetCredentialType ) ,
265+ JsonCredentialParameters . ExternalAccountCredentialType => CreateExternalCredentialFromParameters ( credentialParameters , targetCredentialType ) ,
266+ JsonCredentialParameters . ImpersonatedServiceAccountCredentialType => CreateImpersonatedServiceAccountCredentialFromParameters ( credentialParameters , targetCredentialType ) ,
267+ JsonCredentialParameters . ExternalAccountAuthorizedUserCredentialType => CreateExternalAccountAuthorizedUserCredentialFromParameters ( credentialParameters , targetCredentialType ) ,
268+ _ => throw new InvalidOperationException ( $ "Error creating credential from JSON or JSON parameters. Unrecognized credential type { credentialParameters . Type } .")
269+ } ;
270+
160271 /// <summary>
161272 /// Validates actual type can be cast to target type.
162273 /// </summary>
0 commit comments