From 0105964f67839adc6a08076e166267a681d2b7c1 Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Fri, 7 May 2021 05:48:57 -0700 Subject: [PATCH 01/15] Enable OIDC auth code flow --- .../Auth/AbstractOidcProviderConfigTest.cs | 15 ++++++ .../Auth/OidcProviderConfigFixture.cs | 3 ++ .../Auth/Providers/OidcProviderConfigTest.cs | 49 +++++++++++++++++-- .../Auth/Providers/OidcProviderConfig.cs | 49 +++++++++++++++++++ .../Auth/Providers/OidcProviderConfigArgs.cs | 44 +++++++++++++++++ 5 files changed, 156 insertions(+), 4 deletions(-) diff --git a/FirebaseAdmin/FirebaseAdmin.IntegrationTests/Auth/AbstractOidcProviderConfigTest.cs b/FirebaseAdmin/FirebaseAdmin.IntegrationTests/Auth/AbstractOidcProviderConfigTest.cs index f124bf92..d23d7a44 100644 --- a/FirebaseAdmin/FirebaseAdmin.IntegrationTests/Auth/AbstractOidcProviderConfigTest.cs +++ b/FirebaseAdmin/FirebaseAdmin.IntegrationTests/Auth/AbstractOidcProviderConfigTest.cs @@ -46,6 +46,9 @@ public void CreateProviderConfig() Assert.True(config.Enabled); Assert.Equal("OIDC_CLIENT_ID", config.ClientId); Assert.Equal("https://oidc.com/issuer", config.Issuer); + Assert.Equal("OIDC_CLIENT_SECRET", config.ClientSecret); + Assert.True(config.ResponseType.Code); + Assert.Null(config.ResponseType.IDToken); } [Fact] @@ -59,6 +62,9 @@ public async Task GetProviderConfig() Assert.True(config.Enabled); Assert.Equal("OIDC_CLIENT_ID", config.ClientId); Assert.Equal("https://oidc.com/issuer", config.Issuer); + Assert.Equal("OIDC_CLIENT_SECRET", config.ClientSecret); + Assert.True(config.ResponseType.Code); + Assert.Null(config.ResponseType.IDToken); } [Fact] @@ -84,6 +90,9 @@ public async Task ListProviderConfig() Assert.True(config.Enabled); Assert.Equal("OIDC_CLIENT_ID", config.ClientId); Assert.Equal("https://oidc.com/issuer", config.Issuer); + Assert.Equal("OIDC_CLIENT_SECRET", config.ClientSecret); + Assert.True(config.ResponseType.Code); + Assert.Null(config.ResponseType.IDToken); } [Fact] @@ -97,6 +106,9 @@ public async Task UpdateProviderConfig() Enabled = false, ClientId = "UPDATED_OIDC_CLIENT_ID", Issuer = "https://oidc.com/updated-issuer", + ClientSecret = "UPDATED_OIDC_CLIENT_SECRET", + CodeResponseType = false, + IDTokenResponseType = true, }; var config = await this.auth.UpdateProviderConfigAsync(args); @@ -106,6 +118,9 @@ public async Task UpdateProviderConfig() Assert.False(config.Enabled); Assert.Equal("UPDATED_OIDC_CLIENT_ID", config.ClientId); Assert.Equal("https://oidc.com/updated-issuer", config.Issuer); + Assert.Equal("UPDATED_OIDC_CLIENT_SECRET", config.ClientSecret); + Assert.Null(config.ResponseType.Code); + Assert.True(config.ResponseType.IDToken); } [Fact] diff --git a/FirebaseAdmin/FirebaseAdmin.IntegrationTests/Auth/OidcProviderConfigFixture.cs b/FirebaseAdmin/FirebaseAdmin.IntegrationTests/Auth/OidcProviderConfigFixture.cs index 2b3b0d25..f84b6865 100644 --- a/FirebaseAdmin/FirebaseAdmin.IntegrationTests/Auth/OidcProviderConfigFixture.cs +++ b/FirebaseAdmin/FirebaseAdmin.IntegrationTests/Auth/OidcProviderConfigFixture.cs @@ -31,6 +31,9 @@ public OidcProviderConfigFixture() Enabled = true, ClientId = "OIDC_CLIENT_ID", Issuer = "https://oidc.com/issuer", + ClientSecret = "OIDC_CLIENT_SECRET", + CodeResponseType = true, + IDTokenResponseType = false, }; this.ProviderConfig = this.Auth.CreateProviderConfigAsync(args).Result; } diff --git a/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs b/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs index 3286ce3e..cd322004 100644 --- a/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs +++ b/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs @@ -33,7 +33,12 @@ public class OidcProviderConfigTest ""clientId"": ""CLIENT_ID"", ""issuer"": ""https://oidc.com/issuer"", ""displayName"": ""oidcProviderName"", - ""enabled"": true + ""enabled"": true, + ""clientSecret"": ""CLIENT_SECRET"", + ""responseType"": { + ""code"": true, + ""idToken"": true + } }"; private static readonly IList ListConfigsResponses = new List() @@ -135,6 +140,9 @@ public async Task CreateConfig(ProviderTestConfig config) Enabled = true, ClientId = "CLIENT_ID", Issuer = "https://oidc.com/issuer", + ClientSecret = "CLIENT_SECRET", + CodeResponseType = true, + IDTokenResponseType = true, }; var provider = await auth.CreateProviderConfigAsync(args); @@ -147,11 +155,14 @@ public async Task CreateConfig(ProviderTestConfig config) var body = NewtonsoftJsonSerializer.Instance.Deserialize( handler.LastRequestBody); - Assert.Equal(4, body.Count); + Assert.Equal(6, body.Count); Assert.Equal("oidcProviderName", body["displayName"]); Assert.True((bool)body["enabled"]); Assert.Equal("CLIENT_ID", body["clientId"]); Assert.Equal("https://oidc.com/issuer", body["issuer"]); + Assert.Equal("CLIENT_SECRET", body["clientSecret"]); + Assert.True((bool)body["responseType"]["code"]); + Assert.True((bool)body["responseType"]["idToken"]); } [Theory] @@ -252,6 +263,9 @@ public async Task UpdateConfig(ProviderTestConfig config) Enabled = true, ClientId = "CLIENT_ID", Issuer = "https://oidc.com/issuer", + ClientSecret = "CLIENT_SECRET", + CodeResponseType = true, + IDTokenResponseType = true, }; var provider = await auth.UpdateProviderConfigAsync(args); @@ -260,16 +274,19 @@ public async Task UpdateConfig(ProviderTestConfig config) Assert.Equal(1, handler.Requests.Count); var request = handler.Requests[0]; Assert.Equal(ProviderTestConfig.PatchMethod, request.Method); - var mask = "clientId,displayName,enabled,issuer"; + var mask = "clientId,clientSecret,displayName,enabled,issuer,responseType.code,responseType.idToken"; config.AssertRequest($"oauthIdpConfigs/oidc.provider?updateMask={mask}", request); var body = NewtonsoftJsonSerializer.Instance.Deserialize( handler.LastRequestBody); - Assert.Equal(4, body.Count); + Assert.Equal(6, body.Count); Assert.Equal("oidcProviderName", body["displayName"]); Assert.True((bool)body["enabled"]); Assert.Equal("CLIENT_ID", body["clientId"]); Assert.Equal("https://oidc.com/issuer", body["issuer"]); + Assert.Equal("CLIENT_SECRET", body["clientSecret"]); + Assert.True((bool)body["responseType"]["code"]); + Assert.True((bool)body["responseType"]["idToken"]); } [Theory] @@ -621,6 +638,9 @@ private void AssertOidcProviderConfig(OidcProviderConfig provider) Assert.True(provider.Enabled); Assert.Equal("CLIENT_ID", provider.ClientId); Assert.Equal("https://oidc.com/issuer", provider.Issuer); + Assert.Equal("CLIENT_SECRET", provider.ClientSecret); + Assert.True(provider.ResponseType.Code); + Assert.True(provider.ResponseType.IDToken); } public class InvalidCreateArgs : IEnumerable @@ -682,6 +702,17 @@ public IEnumerator MakeEnumerator() }, "Malformed issuer string: not a url", }; + yield return new object[] + { + new OidcProviderConfigArgs() + { + ProviderId = "oidc.provider", + ClientId = "CLIENT_ID", + Issuer = "https://oidc.com/issuer", + CodeResponseType = true, + }, + "Client Secret must not be null or empty for code response type", + }; } IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator(); @@ -754,6 +785,16 @@ public IEnumerator MakeEnumerator() }, "Malformed issuer string: not a url", }; + yield return new object[] + { + new OidcProviderConfigArgs() + { + ProviderId = "oidc.provider", + Issuer = "https://oidc.com/issuer", + CodeResponseType = true, + }, + "Client Secret must not be null or empty for code response type", + }; } IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator(); diff --git a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfig.cs b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfig.cs index d72f4342..8d50d3c6 100644 --- a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfig.cs +++ b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfig.cs @@ -27,6 +27,8 @@ internal OidcProviderConfig(Request request) { this.ClientId = request.ClientId; this.Issuer = request.Issuer; + this.ClientSecret = request.ClientSecret; + this.ResponseType = new ResponseTypeArgs(request.ResponseType); } /// @@ -63,6 +65,47 @@ internal OidcProviderConfig(Request request) /// public string Issuer { get; } + /// + /// Gets the Client Secret used to verify code based response types. + /// + public string ClientSecret { get; } + + /// + /// Gets what response types are being used for this OIDC config. + /// + public ResponseTypeArgs ResponseType { get; } + + /// + /// Represents the response types beinf used for this OIDC config. + /// + public class ResponseTypeArgs + { + internal ResponseTypeArgs(ResponseTypeJson request) + { + this.Code = request.Code; + this.IDToken = request.IDToken; + } + + /// + /// Gets a value indicating whether this OIDC provider uses a code based response type. + /// + public bool? Code { get; } + + /// + /// Gets a value indicating whether this OIDC provider uses an ID-token based response type. + /// + public bool? IDToken { get; } + } + + internal sealed class ResponseTypeJson + { + [JsonProperty("code")] + internal bool? Code { get; set; } + + [JsonProperty("idToken")] + internal bool? IDToken { get; set; } + } + internal sealed new class Request : AuthProviderConfig.Request { [JsonProperty("clientId")] @@ -70,6 +113,12 @@ internal OidcProviderConfig(Request request) [JsonProperty("issuer")] internal string Issuer { get; set; } + + [JsonProperty("clientSecret")] + internal string ClientSecret { get; set; } + + [JsonProperty("responseType")] + internal ResponseTypeJson ResponseType { get; set; } } } } diff --git a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs index 0d756e83..08519f81 100644 --- a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs +++ b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs @@ -56,6 +56,21 @@ public sealed class OidcProviderConfigArgs : AuthProviderConfigArgs public string Issuer { get; set; } + /// + /// Gets or sets the Client Secret used to verify code based response types. + /// + public string ClientSecret { get; set; } + + /// + /// Gets or sets a value indicating whether this OIDC provider uses an ID-token based response type. + /// + public bool? IDTokenResponseType { get; set; } + + /// + /// Gets or sets a value indicating whether this OIDC provider uses a code based response type. + /// + public bool? CodeResponseType { get; set; } + internal override AuthProviderConfig.Request ToCreateRequest() { var req = new OidcProviderConfig.Request() @@ -64,7 +79,17 @@ internal override AuthProviderConfig.Request ToCreateRequest() Enabled = this.Enabled, ClientId = this.ClientId, Issuer = this.Issuer, + ClientSecret = this.ClientSecret, }; + if (this.CodeResponseType != null || this.IDTokenResponseType != null) + { + req.ResponseType = new OidcProviderConfig.ResponseTypeJson() + { + Code = this.CodeResponseType, + IDToken = this.IDTokenResponseType, + }; + } + if (string.IsNullOrEmpty(req.ClientId)) { throw new ArgumentException("Client ID must not be null or empty."); @@ -79,6 +104,11 @@ internal override AuthProviderConfig.Request ToCreateRequest() throw new ArgumentException($"Malformed issuer string: {req.Issuer}"); } + if (req.ResponseType?.Code == true && string.IsNullOrEmpty(req.ClientSecret)) + { + throw new ArgumentException("Client Secret must not be null or empty for code response type"); + } + return req; } @@ -90,7 +120,16 @@ internal override AuthProviderConfig.Request ToUpdateRequest() Enabled = this.Enabled, ClientId = this.ClientId, Issuer = this.Issuer, + ClientSecret = this.ClientSecret, }; + if (this.CodeResponseType != null || this.IDTokenResponseType != null) + { + req.ResponseType = new OidcProviderConfig.ResponseTypeJson() + { + Code = this.CodeResponseType, + IDToken = this.IDTokenResponseType, + }; + } if (req.ClientId == string.Empty) { @@ -106,6 +145,11 @@ internal override AuthProviderConfig.Request ToUpdateRequest() throw new ArgumentException($"Malformed issuer string: {req.Issuer}"); } + if (req.ResponseType?.Code == true && string.IsNullOrEmpty(req.ClientSecret)) + { + throw new ArgumentException("Client Secret must not be null or empty for code response type"); + } + return req; } From d49e5ab340a46112cfc1e252277abf9e5c8abcfe Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Fri, 4 Jun 2021 09:05:28 -0700 Subject: [PATCH 02/15] Changes requested by hiranya911 --- .../Auth/AbstractOidcProviderConfigTest.cs | 16 +++++----- .../Auth/Providers/OidcProviderConfigTest.cs | 15 +++++++-- .../Auth/Providers/OidcProviderConfig.cs | 32 +++++-------------- .../Auth/Providers/OidcProviderConfigArgs.cs | 9 ++++-- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/FirebaseAdmin/FirebaseAdmin.IntegrationTests/Auth/AbstractOidcProviderConfigTest.cs b/FirebaseAdmin/FirebaseAdmin.IntegrationTests/Auth/AbstractOidcProviderConfigTest.cs index d23d7a44..fb54f5ac 100644 --- a/FirebaseAdmin/FirebaseAdmin.IntegrationTests/Auth/AbstractOidcProviderConfigTest.cs +++ b/FirebaseAdmin/FirebaseAdmin.IntegrationTests/Auth/AbstractOidcProviderConfigTest.cs @@ -47,8 +47,8 @@ public void CreateProviderConfig() Assert.Equal("OIDC_CLIENT_ID", config.ClientId); Assert.Equal("https://oidc.com/issuer", config.Issuer); Assert.Equal("OIDC_CLIENT_SECRET", config.ClientSecret); - Assert.True(config.ResponseType.Code); - Assert.Null(config.ResponseType.IDToken); + Assert.True(config.CodeResponseType); + Assert.False(config.IDTokenResponseType); } [Fact] @@ -63,8 +63,8 @@ public async Task GetProviderConfig() Assert.Equal("OIDC_CLIENT_ID", config.ClientId); Assert.Equal("https://oidc.com/issuer", config.Issuer); Assert.Equal("OIDC_CLIENT_SECRET", config.ClientSecret); - Assert.True(config.ResponseType.Code); - Assert.Null(config.ResponseType.IDToken); + Assert.True(config.CodeResponseType); + Assert.False(config.IDTokenResponseType); } [Fact] @@ -91,8 +91,8 @@ public async Task ListProviderConfig() Assert.Equal("OIDC_CLIENT_ID", config.ClientId); Assert.Equal("https://oidc.com/issuer", config.Issuer); Assert.Equal("OIDC_CLIENT_SECRET", config.ClientSecret); - Assert.True(config.ResponseType.Code); - Assert.Null(config.ResponseType.IDToken); + Assert.True(config.CodeResponseType); + Assert.False(config.IDTokenResponseType); } [Fact] @@ -119,8 +119,8 @@ public async Task UpdateProviderConfig() Assert.Equal("UPDATED_OIDC_CLIENT_ID", config.ClientId); Assert.Equal("https://oidc.com/updated-issuer", config.Issuer); Assert.Equal("UPDATED_OIDC_CLIENT_SECRET", config.ClientSecret); - Assert.Null(config.ResponseType.Code); - Assert.True(config.ResponseType.IDToken); + Assert.False(config.CodeResponseType); + Assert.True(config.IDTokenResponseType); } [Fact] diff --git a/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs b/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs index cd322004..6a68acaa 100644 --- a/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs +++ b/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs @@ -639,8 +639,8 @@ private void AssertOidcProviderConfig(OidcProviderConfig provider) Assert.Equal("CLIENT_ID", provider.ClientId); Assert.Equal("https://oidc.com/issuer", provider.Issuer); Assert.Equal("CLIENT_SECRET", provider.ClientSecret); - Assert.True(provider.ResponseType.Code); - Assert.True(provider.ResponseType.IDToken); + Assert.True(provider.CodeResponseType); + Assert.True(provider.IDTokenResponseType); } public class InvalidCreateArgs : IEnumerable @@ -795,6 +795,17 @@ public IEnumerator MakeEnumerator() }, "Client Secret must not be null or empty for code response type", }; + yield return new object[] + { + new OidcProviderConfigArgs() + { + ProviderId = "oidc.provider", + Issuer = "https://oidc.com/issuer", + CodeResponseType = false, + IDTokenResponseType = false, + }, + "At least one response type must be returned.", + }; } IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator(); diff --git a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfig.cs b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfig.cs index 8d50d3c6..6190271d 100644 --- a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfig.cs +++ b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfig.cs @@ -28,7 +28,8 @@ internal OidcProviderConfig(Request request) this.ClientId = request.ClientId; this.Issuer = request.Issuer; this.ClientSecret = request.ClientSecret; - this.ResponseType = new ResponseTypeArgs(request.ResponseType); + this.IDTokenResponseType = request.ResponseType.IDToken == true; + this.CodeResponseType = request.ResponseType.Code == true; } /// @@ -71,33 +72,16 @@ internal OidcProviderConfig(Request request) public string ClientSecret { get; } /// - /// Gets what response types are being used for this OIDC config. + /// Gets a value indicating whether an ID Token response type will be provided. /// - public ResponseTypeArgs ResponseType { get; } + public bool IDTokenResponseType { get; } /// - /// Represents the response types beinf used for this OIDC config. + /// Gets a value indicating whether an Code type response type will be provided. /// - public class ResponseTypeArgs - { - internal ResponseTypeArgs(ResponseTypeJson request) - { - this.Code = request.Code; - this.IDToken = request.IDToken; - } - - /// - /// Gets a value indicating whether this OIDC provider uses a code based response type. - /// - public bool? Code { get; } - - /// - /// Gets a value indicating whether this OIDC provider uses an ID-token based response type. - /// - public bool? IDToken { get; } - } + public bool CodeResponseType { get; } - internal sealed class ResponseTypeJson + internal sealed class ResponseTypeInfo { [JsonProperty("code")] internal bool? Code { get; set; } @@ -118,7 +102,7 @@ internal sealed class ResponseTypeJson internal string ClientSecret { get; set; } [JsonProperty("responseType")] - internal ResponseTypeJson ResponseType { get; set; } + internal ResponseTypeInfo ResponseType { get; set; } } } } diff --git a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs index 08519f81..54dc5f73 100644 --- a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs +++ b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs @@ -83,7 +83,7 @@ internal override AuthProviderConfig.Request ToCreateRequest() }; if (this.CodeResponseType != null || this.IDTokenResponseType != null) { - req.ResponseType = new OidcProviderConfig.ResponseTypeJson() + req.ResponseType = new OidcProviderConfig.ResponseTypeInfo() { Code = this.CodeResponseType, IDToken = this.IDTokenResponseType, @@ -124,7 +124,7 @@ internal override AuthProviderConfig.Request ToUpdateRequest() }; if (this.CodeResponseType != null || this.IDTokenResponseType != null) { - req.ResponseType = new OidcProviderConfig.ResponseTypeJson() + req.ResponseType = new OidcProviderConfig.ResponseTypeInfo() { Code = this.CodeResponseType, IDToken = this.IDTokenResponseType, @@ -150,6 +150,11 @@ internal override AuthProviderConfig.Request ToUpdateRequest() throw new ArgumentException("Client Secret must not be null or empty for code response type"); } + if (req.ResponseType?.Code == false && req.ResponseType?.IDToken == false) + { + throw new ArgumentException("At least one response type must be returned."); + } + return req; } From b013c480b02783b9d8717a33b5e05e77c21a2bc4 Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Mon, 7 Jun 2021 07:13:42 -0700 Subject: [PATCH 03/15] More changes requested by hiranya911 --- .../Auth/AbstractOidcProviderConfigTest.cs | 10 +++++----- .../Auth/OidcProviderConfigFixture.cs | 2 +- .../Auth/Providers/OidcProviderConfigTest.cs | 20 +++++++++++++++---- .../Auth/Providers/OidcProviderConfig.cs | 6 +++--- .../Auth/Providers/OidcProviderConfigArgs.cs | 17 ++++++++++------ 5 files changed, 36 insertions(+), 19 deletions(-) diff --git a/FirebaseAdmin/FirebaseAdmin.IntegrationTests/Auth/AbstractOidcProviderConfigTest.cs b/FirebaseAdmin/FirebaseAdmin.IntegrationTests/Auth/AbstractOidcProviderConfigTest.cs index fb54f5ac..caf15058 100644 --- a/FirebaseAdmin/FirebaseAdmin.IntegrationTests/Auth/AbstractOidcProviderConfigTest.cs +++ b/FirebaseAdmin/FirebaseAdmin.IntegrationTests/Auth/AbstractOidcProviderConfigTest.cs @@ -48,7 +48,7 @@ public void CreateProviderConfig() Assert.Equal("https://oidc.com/issuer", config.Issuer); Assert.Equal("OIDC_CLIENT_SECRET", config.ClientSecret); Assert.True(config.CodeResponseType); - Assert.False(config.IDTokenResponseType); + Assert.False(config.IdTokenResponseType); } [Fact] @@ -64,7 +64,7 @@ public async Task GetProviderConfig() Assert.Equal("https://oidc.com/issuer", config.Issuer); Assert.Equal("OIDC_CLIENT_SECRET", config.ClientSecret); Assert.True(config.CodeResponseType); - Assert.False(config.IDTokenResponseType); + Assert.False(config.IdTokenResponseType); } [Fact] @@ -92,7 +92,7 @@ public async Task ListProviderConfig() Assert.Equal("https://oidc.com/issuer", config.Issuer); Assert.Equal("OIDC_CLIENT_SECRET", config.ClientSecret); Assert.True(config.CodeResponseType); - Assert.False(config.IDTokenResponseType); + Assert.False(config.IdTokenResponseType); } [Fact] @@ -108,7 +108,7 @@ public async Task UpdateProviderConfig() Issuer = "https://oidc.com/updated-issuer", ClientSecret = "UPDATED_OIDC_CLIENT_SECRET", CodeResponseType = false, - IDTokenResponseType = true, + IdTokenResponseType = true, }; var config = await this.auth.UpdateProviderConfigAsync(args); @@ -120,7 +120,7 @@ public async Task UpdateProviderConfig() Assert.Equal("https://oidc.com/updated-issuer", config.Issuer); Assert.Equal("UPDATED_OIDC_CLIENT_SECRET", config.ClientSecret); Assert.False(config.CodeResponseType); - Assert.True(config.IDTokenResponseType); + Assert.True(config.IdTokenResponseType); } [Fact] diff --git a/FirebaseAdmin/FirebaseAdmin.IntegrationTests/Auth/OidcProviderConfigFixture.cs b/FirebaseAdmin/FirebaseAdmin.IntegrationTests/Auth/OidcProviderConfigFixture.cs index f84b6865..3d4aecc4 100644 --- a/FirebaseAdmin/FirebaseAdmin.IntegrationTests/Auth/OidcProviderConfigFixture.cs +++ b/FirebaseAdmin/FirebaseAdmin.IntegrationTests/Auth/OidcProviderConfigFixture.cs @@ -33,7 +33,7 @@ public OidcProviderConfigFixture() Issuer = "https://oidc.com/issuer", ClientSecret = "OIDC_CLIENT_SECRET", CodeResponseType = true, - IDTokenResponseType = false, + IdTokenResponseType = false, }; this.ProviderConfig = this.Auth.CreateProviderConfigAsync(args).Result; } diff --git a/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs b/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs index 6a68acaa..e711328f 100644 --- a/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs +++ b/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs @@ -142,7 +142,7 @@ public async Task CreateConfig(ProviderTestConfig config) Issuer = "https://oidc.com/issuer", ClientSecret = "CLIENT_SECRET", CodeResponseType = true, - IDTokenResponseType = true, + IdTokenResponseType = true, }; var provider = await auth.CreateProviderConfigAsync(args); @@ -265,7 +265,7 @@ public async Task UpdateConfig(ProviderTestConfig config) Issuer = "https://oidc.com/issuer", ClientSecret = "CLIENT_SECRET", CodeResponseType = true, - IDTokenResponseType = true, + IdTokenResponseType = true, }; var provider = await auth.UpdateProviderConfigAsync(args); @@ -640,7 +640,7 @@ private void AssertOidcProviderConfig(OidcProviderConfig provider) Assert.Equal("https://oidc.com/issuer", provider.Issuer); Assert.Equal("CLIENT_SECRET", provider.ClientSecret); Assert.True(provider.CodeResponseType); - Assert.True(provider.IDTokenResponseType); + Assert.True(provider.IdTokenResponseType); } public class InvalidCreateArgs : IEnumerable @@ -713,6 +713,18 @@ public IEnumerator MakeEnumerator() }, "Client Secret must not be null or empty for code response type", }; + yield return new object[] + { + new OidcProviderConfigArgs() + { + ProviderId = "oidc.provider", + ClientId = "CLIENT_ID", + Issuer = "https://oidc.com/issuer", + CodeResponseType = false, + IdTokenResponseType = false, + }, + "At least one response type must be returned.", + }; } IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator(); @@ -802,7 +814,7 @@ public IEnumerator MakeEnumerator() ProviderId = "oidc.provider", Issuer = "https://oidc.com/issuer", CodeResponseType = false, - IDTokenResponseType = false, + IdTokenResponseType = false, }, "At least one response type must be returned.", }; diff --git a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfig.cs b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfig.cs index 6190271d..303f8639 100644 --- a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfig.cs +++ b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfig.cs @@ -28,7 +28,7 @@ internal OidcProviderConfig(Request request) this.ClientId = request.ClientId; this.Issuer = request.Issuer; this.ClientSecret = request.ClientSecret; - this.IDTokenResponseType = request.ResponseType.IDToken == true; + this.IdTokenResponseType = request.ResponseType.IdToken == true; this.CodeResponseType = request.ResponseType.Code == true; } @@ -74,7 +74,7 @@ internal OidcProviderConfig(Request request) /// /// Gets a value indicating whether an ID Token response type will be provided. /// - public bool IDTokenResponseType { get; } + public bool IdTokenResponseType { get; } /// /// Gets a value indicating whether an Code type response type will be provided. @@ -87,7 +87,7 @@ internal sealed class ResponseTypeInfo internal bool? Code { get; set; } [JsonProperty("idToken")] - internal bool? IDToken { get; set; } + internal bool? IdToken { get; set; } } internal sealed new class Request : AuthProviderConfig.Request diff --git a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs index 54dc5f73..e5d9ca75 100644 --- a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs +++ b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs @@ -64,7 +64,7 @@ public sealed class OidcProviderConfigArgs : AuthProviderConfigArgs /// Gets or sets a value indicating whether this OIDC provider uses an ID-token based response type. /// - public bool? IDTokenResponseType { get; set; } + public bool? IdTokenResponseType { get; set; } /// /// Gets or sets a value indicating whether this OIDC provider uses a code based response type. @@ -81,12 +81,12 @@ internal override AuthProviderConfig.Request ToCreateRequest() Issuer = this.Issuer, ClientSecret = this.ClientSecret, }; - if (this.CodeResponseType != null || this.IDTokenResponseType != null) + if (this.CodeResponseType != null || this.IdTokenResponseType != null) { req.ResponseType = new OidcProviderConfig.ResponseTypeInfo() { Code = this.CodeResponseType, - IDToken = this.IDTokenResponseType, + IdToken = this.IdTokenResponseType, }; } @@ -109,6 +109,11 @@ internal override AuthProviderConfig.Request ToCreateRequest() throw new ArgumentException("Client Secret must not be null or empty for code response type"); } + if (req.ResponseType?.Code == false && req.ResponseType?.IdToken == false) + { + throw new ArgumentException("At least one response type must be returned."); + } + return req; } @@ -122,12 +127,12 @@ internal override AuthProviderConfig.Request ToUpdateRequest() Issuer = this.Issuer, ClientSecret = this.ClientSecret, }; - if (this.CodeResponseType != null || this.IDTokenResponseType != null) + if (this.CodeResponseType != null || this.IdTokenResponseType != null) { req.ResponseType = new OidcProviderConfig.ResponseTypeInfo() { Code = this.CodeResponseType, - IDToken = this.IDTokenResponseType, + IdToken = this.IdTokenResponseType, }; } @@ -150,7 +155,7 @@ internal override AuthProviderConfig.Request ToUpdateRequest() throw new ArgumentException("Client Secret must not be null or empty for code response type"); } - if (req.ResponseType?.Code == false && req.ResponseType?.IDToken == false) + if (req.ResponseType?.Code == false && req.ResponseType?.IdToken == false) { throw new ArgumentException("At least one response type must be returned."); } From 313bf193d822ce3a19d7578cd6aab31774b7bfbd Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Tue, 15 Jun 2021 14:38:26 -0700 Subject: [PATCH 04/15] Update FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs Co-authored-by: Kevin Cheung --- .../Auth/Providers/OidcProviderConfigTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs b/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs index e711328f..064de158 100644 --- a/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs +++ b/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs @@ -700,7 +700,7 @@ public IEnumerator MakeEnumerator() ClientId = "CLIENT_ID", Issuer = "not a url", }, - "Malformed issuer string: not a url", + "Malformed issuer string: not a URL.", }; yield return new object[] { From 4a758622f4c00e34cd00cc78ae8efb734caee17e Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Tue, 15 Jun 2021 14:38:32 -0700 Subject: [PATCH 05/15] Update FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs Co-authored-by: Kevin Cheung --- .../Auth/Providers/OidcProviderConfigTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs b/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs index 064de158..f9af29d2 100644 --- a/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs +++ b/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs @@ -711,7 +711,7 @@ public IEnumerator MakeEnumerator() Issuer = "https://oidc.com/issuer", CodeResponseType = true, }, - "Client Secret must not be null or empty for code response type", + "Client secret must not be null or empty for 'code' response type.", }; yield return new object[] { From e394087183b076f9e2895b0e1b3e45280f01bc14 Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Tue, 15 Jun 2021 14:38:38 -0700 Subject: [PATCH 06/15] Update FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs Co-authored-by: Kevin Cheung --- .../Auth/Providers/OidcProviderConfigTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs b/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs index f9af29d2..34faef0f 100644 --- a/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs +++ b/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs @@ -795,7 +795,7 @@ public IEnumerator MakeEnumerator() ProviderId = "oidc.provider", Issuer = "not a url", }, - "Malformed issuer string: not a url", + "Malformed issuer string: not a URL.", }; yield return new object[] { From 2698574a31296ca0a4c1f92af7fb2999e4b3d34f Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Tue, 15 Jun 2021 14:38:46 -0700 Subject: [PATCH 07/15] Update FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs Co-authored-by: Kevin Cheung --- .../Auth/Providers/OidcProviderConfigTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs b/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs index 34faef0f..29e30545 100644 --- a/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs +++ b/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs @@ -805,7 +805,7 @@ public IEnumerator MakeEnumerator() Issuer = "https://oidc.com/issuer", CodeResponseType = true, }, - "Client Secret must not be null or empty for code response type", + "Client secret must not be null or empty for 'code' response type.", }; yield return new object[] { From f6ec0be40e333e79b1c0085b74f96c984e45f61b Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Tue, 15 Jun 2021 14:38:51 -0700 Subject: [PATCH 08/15] Update FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfig.cs Co-authored-by: Kevin Cheung --- .../FirebaseAdmin/Auth/Providers/OidcProviderConfig.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfig.cs b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfig.cs index 303f8639..7fcc04e5 100644 --- a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfig.cs +++ b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfig.cs @@ -67,7 +67,7 @@ internal OidcProviderConfig(Request request) public string Issuer { get; } /// - /// Gets the Client Secret used to verify code based response types. + /// Gets the client secret, which is used to verify Code response types. /// public string ClientSecret { get; } From c574aed144a69276e42acf8501b3b2fbb6a43f09 Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Tue, 15 Jun 2021 14:38:56 -0700 Subject: [PATCH 09/15] Update FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs Co-authored-by: Kevin Cheung --- .../FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs index e5d9ca75..3e4b4aae 100644 --- a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs +++ b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs @@ -57,7 +57,7 @@ public sealed class OidcProviderConfigArgs : AuthProviderConfigArgs - /// Gets or sets the Client Secret used to verify code based response types. + /// Gets or sets the client secret, which is used to verify Code response types. /// public string ClientSecret { get; set; } From 46b448bc651fcb7f297594149d705362f09f2fc0 Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Tue, 15 Jun 2021 14:39:02 -0700 Subject: [PATCH 10/15] Update FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs Co-authored-by: Kevin Cheung --- .../FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs index 3e4b4aae..42ad0292 100644 --- a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs +++ b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs @@ -62,7 +62,7 @@ public sealed class OidcProviderConfigArgs : AuthProviderConfigArgs - /// Gets or sets a value indicating whether this OIDC provider uses an ID-token based response type. + /// Gets or sets a value indicating whether this OIDC provider uses an ID Token response type. /// public bool? IdTokenResponseType { get; set; } From 515ea37fa112249a92dbd6d3c4b8f589a91e696d Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Tue, 15 Jun 2021 14:39:07 -0700 Subject: [PATCH 11/15] Update FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs Co-authored-by: Kevin Cheung --- .../FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs index 42ad0292..bd23367d 100644 --- a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs +++ b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs @@ -67,7 +67,7 @@ public sealed class OidcProviderConfigArgs : AuthProviderConfigArgs - /// Gets or sets a value indicating whether this OIDC provider uses a code based response type. + /// Gets or sets a value indicating whether this OIDC provider uses a Code response type. /// public bool? CodeResponseType { get; set; } From 90e131ed7c55b3762a98711dd0e465a776f0ac2f Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Tue, 15 Jun 2021 14:39:12 -0700 Subject: [PATCH 12/15] Update FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs Co-authored-by: Kevin Cheung --- .../FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs index bd23367d..5df91cb4 100644 --- a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs +++ b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs @@ -106,7 +106,7 @@ internal override AuthProviderConfig.Request ToCreateRequest() if (req.ResponseType?.Code == true && string.IsNullOrEmpty(req.ClientSecret)) { - throw new ArgumentException("Client Secret must not be null or empty for code response type"); + throw new ArgumentException("Client secret must not be null or empty for code response type."); } if (req.ResponseType?.Code == false && req.ResponseType?.IdToken == false) From bda0561e2c8387dd33dd665bb21054621176b19d Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Tue, 15 Jun 2021 14:39:18 -0700 Subject: [PATCH 13/15] Update FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs Co-authored-by: Kevin Cheung --- .../FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs index 5df91cb4..e1c8e28a 100644 --- a/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs +++ b/FirebaseAdmin/FirebaseAdmin/Auth/Providers/OidcProviderConfigArgs.cs @@ -152,7 +152,7 @@ internal override AuthProviderConfig.Request ToUpdateRequest() if (req.ResponseType?.Code == true && string.IsNullOrEmpty(req.ClientSecret)) { - throw new ArgumentException("Client Secret must not be null or empty for code response type"); + throw new ArgumentException("Client secret must not be null or empty for code response type."); } if (req.ResponseType?.Code == false && req.ResponseType?.IdToken == false) From 7e4000aacfc3eef6ee41debc64ab416a69847540 Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Tue, 15 Jun 2021 16:10:31 -0700 Subject: [PATCH 14/15] Fixing tests --- .../Auth/Providers/OidcProviderConfigTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs b/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs index 29e30545..24c142bf 100644 --- a/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs +++ b/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs @@ -711,7 +711,7 @@ public IEnumerator MakeEnumerator() Issuer = "https://oidc.com/issuer", CodeResponseType = true, }, - "Client secret must not be null or empty for 'code' response type.", + "Client secret must not be null or empty for code response type.", }; yield return new object[] { @@ -805,7 +805,7 @@ public IEnumerator MakeEnumerator() Issuer = "https://oidc.com/issuer", CodeResponseType = true, }, - "Client secret must not be null or empty for 'code' response type.", + "Client secret must not be null or empty for code response type.", }; yield return new object[] { From cb5416252fb67500391c1f5c8911faad9fbea200 Mon Sep 17 00:00:00 2001 From: Ryan Kohler Date: Wed, 16 Jun 2021 04:29:04 -0700 Subject: [PATCH 15/15] Fixing tests --- .../Auth/Providers/OidcProviderConfigTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs b/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs index 24c142bf..d68094f5 100644 --- a/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs +++ b/FirebaseAdmin/FirebaseAdmin.Tests/Auth/Providers/OidcProviderConfigTest.cs @@ -700,7 +700,7 @@ public IEnumerator MakeEnumerator() ClientId = "CLIENT_ID", Issuer = "not a url", }, - "Malformed issuer string: not a URL.", + "Malformed issuer string: not a url", }; yield return new object[] { @@ -795,7 +795,7 @@ public IEnumerator MakeEnumerator() ProviderId = "oidc.provider", Issuer = "not a url", }, - "Malformed issuer string: not a URL.", + "Malformed issuer string: not a url", }; yield return new object[] {