From 78ae3e2b42789960dad3ce40ad4bd26c23534024 Mon Sep 17 00:00:00 2001 From: Christopher Zell Date: Fri, 15 Dec 2023 14:52:58 +0100 Subject: [PATCH] refactor: remove unused classes SaaS and SM can be handled with old CamundaCloudTokenProvider --- .../Impl/Builder/OAuth2TokenProviderTest.cs | 336 ------------------ .../Builder/IOAuth2TokenProviderBuilder.cs | 63 ---- Client/Impl/Builder/OAuth2TokenProvider.cs | 89 ----- .../Builder/OAuth2TokenProviderBuilder.cs | 64 ---- 4 files changed, 552 deletions(-) delete mode 100644 Client.UnitTests/Impl/Builder/OAuth2TokenProviderTest.cs delete mode 100644 Client/Api/Builder/IOAuth2TokenProviderBuilder.cs delete mode 100644 Client/Impl/Builder/OAuth2TokenProvider.cs delete mode 100644 Client/Impl/Builder/OAuth2TokenProviderBuilder.cs diff --git a/Client.UnitTests/Impl/Builder/OAuth2TokenProviderTest.cs b/Client.UnitTests/Impl/Builder/OAuth2TokenProviderTest.cs deleted file mode 100644 index 2bbd0e0f..00000000 --- a/Client.UnitTests/Impl/Builder/OAuth2TokenProviderTest.cs +++ /dev/null @@ -1,336 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; -using Newtonsoft.Json; -using NUnit.Framework; -using Zeebe.Client.Impl.Misc; - -namespace Zeebe.Client.Impl.Builder -{ - [TestFixture] - public class OAuth2TokenProviderTest - { - private HttpMessageHandlerStub MessageHandlerStub { get; set; } - private OAuth2TokenProvider TokenProvider { get; set; } - private string TokenStoragePath { get; set; } - private static long ExpiresIn { get; set; } - private static string Token { get; set; } - - private static string _requestUri; - private static string _clientId; - private static string _clientSecret; - private static string _audience; - - [SetUp] - public void Init() - { - _requestUri = "https://local.de"; - _clientId = "ID"; - _clientSecret = "SECRET"; - _audience = "AUDIENCE"; - TokenProvider = new OAuth2TokenProviderBuilder() - .UseAuthServer(_requestUri) - .UseClientId(_clientId) - .UseClientSecret(_clientSecret) - .UseAudience(_audience) - .Build(); - - MessageHandlerStub = new HttpMessageHandlerStub(); - TokenProvider.SetHttpMessageHandler(MessageHandlerStub); - TokenStoragePath = Path.GetTempPath() + ".zeebe/"; - TokenProvider.TokenStoragePath = TokenStoragePath; - ExpiresIn = 3600; - Token = "REQUESTED_TOKEN"; - } - - [TearDown] - public void CleanUp() - { - Directory.Delete(TokenStoragePath, true); - TokenProvider.Dispose(); - } - - private class HttpMessageHandlerStub : HttpMessageHandler - { - public int RequestCount { get; set; } - private bool _disposed = false; - - protected override async Task SendAsync(HttpRequestMessage request, - CancellationToken cancellationToken) - { - CheckDisposed(); - Assert.AreEqual(request.RequestUri, _requestUri); - var content = await request.Content.ReadAsStringAsync(cancellationToken); - - var formFields = GetFormFields(content); - Assert.AreEqual(formFields["client_id"], _clientId); - Assert.AreEqual(formFields["client_secret"], _clientSecret); - Assert.AreEqual(formFields["audience"], _audience); - - RequestCount++; - var responseMessage = new HttpResponseMessage(HttpStatusCode.OK) - { - Content = new StringContent(@"{ - ""access_token"":""" + Token + @""", - ""token_type"":""bearer"", - ""expires_in"": " + ExpiresIn + @", - ""refresh_token"":""IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk"", - ""scope"":""create""}"), - }; - - return responseMessage; - } - - protected override void Dispose(bool disposing) - { - base.Dispose(disposing); - _disposed = true; - } - - private void CheckDisposed() - { - if (_disposed) - { - throw new ObjectDisposedException("HttpMessageHandlerStub"); - } - } - } - - [Test] - public async Task ShouldRequestCredentials() - { - // given - - // when - var token = await TokenProvider.GetAccessTokenForRequestAsync(); - - // then - Assert.AreEqual("REQUESTED_TOKEN", token); - Assert.AreEqual(1, MessageHandlerStub.RequestCount); - } - - [Test] - public async Task ShouldStoreCredentials() - { - // given - - // when - var token = await TokenProvider.GetAccessTokenForRequestAsync(); - - // then - Assert.AreEqual("REQUESTED_TOKEN", token); - var files = Directory.GetFiles(TokenStoragePath); - Assert.AreEqual(1, files.Length); - var tokenFile = files[0]; - var content = File.ReadAllText(tokenFile); - var credentials = JsonConvert.DeserializeObject>(content); - Assert.AreEqual(credentials["AUDIENCE"].Token, token); - } - - [Test] - public async Task ShouldStoreMultipleCredentials() - { - // given - await TokenProvider.GetAccessTokenForRequestAsync(); - var otherProvider = new OAuth2TokenProviderBuilder() - .UseAuthServer(_requestUri) - .UseClientId(_clientId = "OTHERID") - .UseClientSecret(_clientSecret = "OTHERSECRET") - .UseAudience(_audience = "OTHER_AUDIENCE") - .Build(); - otherProvider.SetHttpMessageHandler(MessageHandlerStub); - otherProvider.TokenStoragePath = TokenStoragePath; - Token = "OTHER_TOKEN"; - - // when - var token = await otherProvider.GetAccessTokenForRequestAsync(); - - // then - Assert.AreEqual("OTHER_TOKEN", token); - var files = Directory.GetFiles(TokenStoragePath); - Assert.AreEqual(1, files.Length); - var tokenFile = files[0]; - var content = File.ReadAllText(tokenFile); - var credentials = JsonConvert.DeserializeObject>(content); - - Assert.AreEqual(credentials.Count, 2); - Assert.AreEqual(token, credentials["OTHER_AUDIENCE"].Token); - Assert.AreEqual("REQUESTED_TOKEN", credentials["AUDIENCE"].Token); - } - - [Test] - public async Task ShouldGetTokenFromInMemory() - { - // given - await TokenProvider.GetAccessTokenForRequestAsync(); - var files = Directory.GetFiles(TokenStoragePath); - var tokenFile = files[0]; - File.WriteAllText(tokenFile, "FILE_TOKEN"); - - // when - var token = await TokenProvider.GetAccessTokenForRequestAsync(); - - // then - Assert.AreEqual("REQUESTED_TOKEN", token); - Assert.AreEqual(1, MessageHandlerStub.RequestCount); - } - - [Test] - public async Task ShouldExpireInOneSecond() - { - // given - ExpiresIn = 1; - var firstToken = await TokenProvider.GetAccessTokenForRequestAsync(); - var files = Directory.GetFiles(TokenStoragePath); - var tokenFile = files[0]; - File.WriteAllText(tokenFile, "FILE_TOKEN"); - - // when - Token = "NEW_TOKEN"; - var secondToken = await TokenProvider.GetAccessTokenForRequestAsync(); - Thread.Sleep(1_000); - var thirdToken = await TokenProvider.GetAccessTokenForRequestAsync(); - - // then - Assert.AreEqual("REQUESTED_TOKEN", firstToken); - Assert.AreEqual(secondToken, firstToken); - Assert.AreEqual("NEW_TOKEN", thirdToken); - Assert.AreEqual(2, MessageHandlerStub.RequestCount); - } - - [Test] - public async Task ShouldRequestNewTokenWhenExpired() - { - // given - ExpiresIn = 0; - var firstToken = await TokenProvider.GetAccessTokenForRequestAsync(); - var files = Directory.GetFiles(TokenStoragePath); - var tokenFile = files[0]; - File.WriteAllText(tokenFile, "FILE_TOKEN"); - - // when - Token = "SECOND_TOKEN"; - var secondToken = await TokenProvider.GetAccessTokenForRequestAsync(); - - // then - Assert.AreEqual("REQUESTED_TOKEN", firstToken); - Assert.AreNotEqual(secondToken, firstToken); - Assert.AreEqual("SECOND_TOKEN", secondToken); - Assert.AreEqual(2, MessageHandlerStub.RequestCount); - } - - [Test] - public async Task ShouldUseCachedFile() - { - // given - Token = "STORED_TOKEN"; - await TokenProvider.GetAccessTokenForRequestAsync(); - // re-init the TokenProvider - Init(); - - // when - var token = await TokenProvider.GetAccessTokenForRequestAsync(); - - // then - Assert.AreEqual("STORED_TOKEN", token); - Assert.AreEqual(0, MessageHandlerStub.RequestCount); - } - - [Test] - public async Task ShouldNotUseCachedFileForOtherAudience() - { - // given - Token = "STORED_TOKEN"; - await TokenProvider.GetAccessTokenForRequestAsync(); - var otherProvider = new OAuth2TokenProviderBuilder() - .UseAuthServer(_requestUri) - .UseClientId(_clientId = "OTHERID") - .UseClientSecret(_clientSecret = "OTHERSECRET") - .UseAudience(_audience = "OTHER_AUDIENCE") - .Build(); - otherProvider.SetHttpMessageHandler(MessageHandlerStub); - otherProvider.TokenStoragePath = TokenStoragePath; - Token = "OTHER_TOKEN"; - - // when - var token = await otherProvider.GetAccessTokenForRequestAsync(); - - // then - Assert.AreEqual("OTHER_TOKEN", token); - } - - [Test] - public async Task ShouldRequestWhenCachedFileExpired() - { - // given - ExpiresIn = 0; - Token = "STORED_TOKEN"; - await TokenProvider.GetAccessTokenForRequestAsync(); - // re-init the TokenProvider - Init(); - - // when - var token = await TokenProvider.GetAccessTokenForRequestAsync(); - - // then - Assert.AreEqual("REQUESTED_TOKEN", token); - Assert.AreEqual(1, MessageHandlerStub.RequestCount); - } - - [Test] - public async Task ShouldUseCachedFileAndAfterwardsInMemory() - { - // given - Token = "STORED_TOKEN"; - await TokenProvider.GetAccessTokenForRequestAsync(); - // re-init the TokenProvider - Init(); - - // when - await TokenProvider.GetAccessTokenForRequestAsync(); - var files = Directory.GetFiles(TokenStoragePath); - var tokenFile = files[0]; - File.WriteAllText(tokenFile, "FILE_TOKEN"); - var token = await TokenProvider.GetAccessTokenForRequestAsync(); - - // then - Assert.AreEqual("STORED_TOKEN", token); - Assert.AreEqual(0, MessageHandlerStub.RequestCount); - } - - [Test] - public async Task ShouldNotThrowObjectDisposedExceptionWhenTokenExpires() - { - // given - ExpiresIn = 0; - await TokenProvider.GetAccessTokenForRequestAsync(); - - // when - Assert.DoesNotThrowAsync(async () => await TokenProvider.GetAccessTokenForRequestAsync()); - - // then - Assert.AreEqual(2, MessageHandlerStub.RequestCount); - } - - private static Dictionary GetFormFields(string content) - { - var formFields = new Dictionary(); - var keyValuePairs = content.Split('&'); - foreach (var keyValuePair in keyValuePairs) - { - var pair = keyValuePair.Split('='); - if (pair.Length == 2) - { - var key = Uri.UnescapeDataString(pair[0]); - var value = Uri.UnescapeDataString(pair[1]); - formFields.Add(key, value); - } - } - return formFields; - } - } -} \ No newline at end of file diff --git a/Client/Api/Builder/IOAuth2TokenProviderBuilder.cs b/Client/Api/Builder/IOAuth2TokenProviderBuilder.cs deleted file mode 100644 index 24c390d1..00000000 --- a/Client/Api/Builder/IOAuth2TokenProviderBuilder.cs +++ /dev/null @@ -1,63 +0,0 @@ -using Microsoft.Extensions.Logging; -using Zeebe.Client.Impl.Builder; - -namespace Zeebe.Client.Api.Builder; - -public interface IOAuth2TokenProviderBuilder -{ - /// - /// Defines the logger factory which should be used by the token provider - /// to log messages. - /// *This is optional and no messages are logged if this method is not called.* - /// - /// the factory to create an ILogger - /// the fluent IOAuth2TokenProviderBuilder - IOAuth2TokenProviderBuilder UseLoggerFactory(ILoggerFactory loggerFactory); - - /// - /// Defines the authorization server, from which the access token should be requested. - /// - /// an url, which points to the authorization server - /// the next step in building a OAuth2TokenProvider - IOAuth2TokenProviderBuilderStep2 UseAuthServer(string url); -} - -public interface IOAuth2TokenProviderBuilderStep2 -{ - /// - /// Defines the client id, which should be used to create the access token. - /// - /// the client id, which is supplied by OAuth2 - /// the next step in building a OAuth2TokenProvider - IOAuth2TokenProviderBuilderStep3 UseClientId(string clientId); -} - -public interface IOAuth2TokenProviderBuilderStep3 -{ - /// - /// Defines the client secret, which should be used to create the access token. - /// - /// the client secret, which is supplied by OAuth2 - /// the next step in building a OAuth2TokenProvider - IOAuth2TokenProviderBuilderStep4 UseClientSecret(string clientSecret); -} - -public interface IOAuth2TokenProviderBuilderStep4 -{ - /// - /// Defines the audience for which the token provider should create tokens. - /// - /// the audience, which is normally a domain name - /// the next step in building a OAuth2TokenProvider - IOAuth2TokenProviderBuilderFinalStep UseAudience(string audience); -} - -public interface IOAuth2TokenProviderBuilderFinalStep -{ - /// - /// Builds the OAuth2TokenProvider, which can be used by the ZeebeClient to - /// communicate with a Self-Hosted Zeebe gateway, which uses identity. - /// - /// the OAuth2TokenProvider - OAuth2TokenProvider Build(); -} \ No newline at end of file diff --git a/Client/Impl/Builder/OAuth2TokenProvider.cs b/Client/Impl/Builder/OAuth2TokenProvider.cs deleted file mode 100644 index 9290fdc8..00000000 --- a/Client/Impl/Builder/OAuth2TokenProvider.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Net.Http; -using System.Threading.Tasks; -using Microsoft.Extensions.Logging; -using Zeebe.Client.Impl.Misc; - -namespace Zeebe.Client.Impl.Builder -{ - public class OAuth2TokenProvider : BaseTokenProvider, IDisposable - { - private readonly ILogger logger; - private readonly string authServer; - private readonly string clientId; - private readonly string clientSecret; - private readonly string audience; - private HttpClient httpClient; - private HttpMessageHandler httpMessageHandler; - - public OAuth2TokenProvider( - string authServer, - string clientId, - string clientSecret, - string audience, - ILogger logger = null) : base("oauth2_credentials", audience) - { - this.logger = logger; - this.authServer = authServer; - this.clientId = clientId; - this.clientSecret = clientSecret; - this.audience = audience; - - // default client handler - httpClient = new HttpClient(new HttpClientHandler(), disposeHandler: false); - CachedCredentials = new Dictionary(); - } - - public static CamundaCloudTokenProviderBuilder Builder() - { - return new CamundaCloudTokenProviderBuilder(); - } - - internal void SetHttpMessageHandler(HttpMessageHandler handler) - { - httpMessageHandler = handler; - httpClient = new HttpClient(handler); - } - - protected override async Task RequestAccessTokenAsync() - { - var directoryInfo = Directory.CreateDirectory(TokenStoragePath); - if (!directoryInfo.Exists) - { - throw new IOException("Expected to create '~/.zeebe/' directory, but failed to do so."); - } - - var formContent = BuildRequestAccessTokenContent(); - - var httpResponseMessage = await httpClient.PostAsync(authServer, formContent); - - var result = await httpResponseMessage.Content.ReadAsStringAsync(); - var token = AccessToken.FromJson(result); - logger?.LogDebug("Received access token for {audience}", audience); - CachedCredentials[audience] = token; - WriteCredentials(); - - return token.Token; - } - - private FormUrlEncodedContent BuildRequestAccessTokenContent() - { - var formContent = new FormUrlEncodedContent(new[] - { - new KeyValuePair("client_id", clientId), - new KeyValuePair("client_secret", clientSecret), - new KeyValuePair("audience", audience), - new KeyValuePair("grant_type", "client_credentials") - }); - return formContent; - } - - public void Dispose() - { - httpClient.Dispose(); - httpMessageHandler.Dispose(); - } - } -} \ No newline at end of file diff --git a/Client/Impl/Builder/OAuth2TokenProviderBuilder.cs b/Client/Impl/Builder/OAuth2TokenProviderBuilder.cs deleted file mode 100644 index 288e83f6..00000000 --- a/Client/Impl/Builder/OAuth2TokenProviderBuilder.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using Microsoft.Extensions.Logging; -using Zeebe.Client.Api.Builder; - -namespace Zeebe.Client.Impl.Builder; - -public class OAuth2TokenProviderBuilder : IOAuth2TokenProviderBuilder, - IOAuth2TokenProviderBuilderStep2, - IOAuth2TokenProviderBuilderStep3, - IOAuth2TokenProviderBuilderStep4, - IOAuth2TokenProviderBuilderFinalStep -{ - private ILoggerFactory loggerFactory; - private string audience; - private string authServer = "https://login.cloud.camunda.io/oauth/token"; - private string clientId; - private string clientSecret; - - /// - public IOAuth2TokenProviderBuilder UseLoggerFactory(ILoggerFactory loggerFactory) - { - this.loggerFactory = loggerFactory; - return this; - } - - /// - public IOAuth2TokenProviderBuilderStep2 UseAuthServer(string url) - { - authServer = url ?? throw new ArgumentNullException(nameof(url)); - return this; - } - - /// - public IOAuth2TokenProviderBuilderStep3 UseClientId(string clientId) - { - this.clientId = clientId ?? throw new ArgumentNullException(nameof(clientId)); - return this; - } - - /// - public IOAuth2TokenProviderBuilderStep4 UseClientSecret(string clientSecret) - { - this.clientSecret = clientSecret ?? throw new ArgumentNullException(nameof(clientSecret)); - return this; - } - - /// - public IOAuth2TokenProviderBuilderFinalStep UseAudience(string audience) - { - this.audience = audience ?? throw new ArgumentNullException(nameof(audience)); - return this; - } - - /// - public OAuth2TokenProvider Build() - { - return new OAuth2TokenProvider( - authServer, - clientId, - clientSecret, - audience, - loggerFactory?.CreateLogger()); - } -} \ No newline at end of file