From bfee073f4e972e23a2b25bfe3d0967f6e9f3b943 Mon Sep 17 00:00:00 2001 From: Antonio Zhu Date: Wed, 7 Dec 2022 16:51:56 +0100 Subject: [PATCH] Added rest client which will be needed for Attachments --- src/Rocket.Chat.Net/Driver/RestClient.cs | 119 ++++++++++++++++++ .../Driver/RocketChatDriver.cs | 9 ++ .../Driver/IRocketRestClientManagement.cs | 12 ++ src/Rocket.Chat.Net/Interfaces/IRestClient.cs | 18 +++ .../Interfaces/IRocketChatDriver.cs | 1 + src/Rocket.Chat.Net/Rocket.Chat.Net.csproj | 1 + 6 files changed, 160 insertions(+) create mode 100644 src/Rocket.Chat.Net/Driver/RestClient.cs create mode 100644 src/Rocket.Chat.Net/Interfaces/Driver/IRocketRestClientManagement.cs create mode 100644 src/Rocket.Chat.Net/Interfaces/IRestClient.cs diff --git a/src/Rocket.Chat.Net/Driver/RestClient.cs b/src/Rocket.Chat.Net/Driver/RestClient.cs new file mode 100644 index 0000000..a42c6be --- /dev/null +++ b/src/Rocket.Chat.Net/Driver/RestClient.cs @@ -0,0 +1,119 @@ +using Newtonsoft.Json.Linq; +using Rocket.Chat.Net.Interfaces; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +using RestSharp; +using NLog; +using WebSocketSharp; +using RestSharp.Authenticators; +using NLog.LayoutRenderers.Wrappers; + +namespace Rocket.Chat.Net.Driver +{ + public class RestClient : IRestClient + { + public RestSharp.RestClient _client; + private IAuthenticator _authenticator; + private bool _isLoggedIn; + ILogger _logger; + + public RestClient(string instanceUrl, ILogger logger) + { + _logger = logger; + _client = new RestSharp.RestClient(instanceUrl + "/api/v1/"); + } + + private bool disposedValue; + + public string Url => throw new NotImplementedException(); + + public bool IsDisposed => throw new NotImplementedException(); + + public bool IsLoggedIn { get => _isLoggedIn; } + + /// + /// + /// + /// HTTP method, such as GET, POST, PUT etc. + /// + /// + /// + /// + public async Task CallAsync(string method, string path, CancellationToken token, params object[] args) + { + var request = new RestRequest(path, (Method) Enum.Parse(typeof(Method), method)); + JObject data = JObject.FromObject(args); + if (data != null) + { + request.AddBody(data); + } + var response = await _client.ExecuteAsync(request).ConfigureAwait(false); + return JObject.FromObject(response.Content); + } + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // TODO: Verwalteten Zustand (verwaltete Objekte) bereinigen + _client.Dispose(); + } + + // TODO: Nicht verwaltete Ressourcen (nicht verwaltete Objekte) freigeben und Finalizer überschreiben + // TODO: Große Felder auf NULL setzen + disposedValue = true; + } + } + + // // TODO: Finalizer nur überschreiben, wenn "Dispose(bool disposing)" Code für die Freigabe nicht verwalteter Ressourcen enthält + // ~RestClient() + // { + // // Ändern Sie diesen Code nicht. Fügen Sie Bereinigungscode in der Methode "Dispose(bool disposing)" ein. + // Dispose(disposing: false); + // } + + public void Dispose() + { + // Ändern Sie diesen Code nicht. Fügen Sie Bereinigungscode in der Methode "Dispose(bool disposing)" ein. + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + + public async Task LoginAsync(object args) + { + JObject response = await CallAsync("POST", "login", CancellationToken.None, args).ConfigureAwait(false); + if (response["status"].ToObject() == "success") + { + string authToken = response["status"]["authToken"].ToObject(); + string userId = response["status"]["userId"].ToObject(); + _client.Authenticator = new RocketAuthenticator(userId, authToken); + _isLoggedIn = true; + } + } + } + + public class RocketAuthenticator : IAuthenticator + { + private string authToken; + private string userId; + + public RocketAuthenticator(string userId, string authToken) + { + this.authToken = authToken; + this.userId = userId; + } + + public ValueTask Authenticate(RestSharp.RestClient client, RestRequest request) + { + request.AddHeader("X-Auth-Token", authToken); + request.AddHeader("X-User-Id", userId); + return new ValueTask(); + } + } +} diff --git a/src/Rocket.Chat.Net/Driver/RocketChatDriver.cs b/src/Rocket.Chat.Net/Driver/RocketChatDriver.cs index a29a268..b740c94 100644 --- a/src/Rocket.Chat.Net/Driver/RocketChatDriver.cs +++ b/src/Rocket.Chat.Net/Driver/RocketChatDriver.cs @@ -30,6 +30,7 @@ public class RocketChatDriver : IRocketChatDriver private readonly IStreamCollectionDatabase _collectionDatabase; private readonly ILogger _logger; private readonly IDdpClient _client; + private readonly IRestClient _restClient; public event MessageReceived MessageReceived; public event DdpReconnect DdpReconnect; @@ -57,6 +58,8 @@ public RocketChatDriver(string url, bool useSsl, ILogger logger = null, bool isB _client.DataReceivedRaw += ClientOnDataReceivedRaw; _client.DdpReconnect += OnDdpReconnect; SetJsonOptions(jsonSerializerSettings); + + _restClient = new RestClient(url, logger); } public RocketChatDriver(ILogger logger, IDdpClient client, IStreamCollectionDatabase collectionDatabaseDatabase, bool isBot = true, @@ -250,6 +253,7 @@ public async Task PingAsync() await _client.PingAsync(TimeoutToken).ConfigureAwait(false); } + // TODO: Reuse login option for REST? public async Task> LoginAsync(ILoginOption loginOption) { var ldapLogin = loginOption as LdapLoginOption; @@ -695,5 +699,10 @@ private CancellationToken CreateTimeoutToken() return source.Token; } + + public async Task LoginRestApi(object args) + { + await _restClient.LoginAsync(args).ConfigureAwait(false); + } } } \ No newline at end of file diff --git a/src/Rocket.Chat.Net/Interfaces/Driver/IRocketRestClientManagement.cs b/src/Rocket.Chat.Net/Interfaces/Driver/IRocketRestClientManagement.cs new file mode 100644 index 0000000..35ad805 --- /dev/null +++ b/src/Rocket.Chat.Net/Interfaces/Driver/IRocketRestClientManagement.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace Rocket.Chat.Net.Interfaces.Driver +{ + public interface IRocketRestClientManagement + { + Task LoginRestApi(object loginArgs); + } +} diff --git a/src/Rocket.Chat.Net/Interfaces/IRestClient.cs b/src/Rocket.Chat.Net/Interfaces/IRestClient.cs new file mode 100644 index 0000000..19cfece --- /dev/null +++ b/src/Rocket.Chat.Net/Interfaces/IRestClient.cs @@ -0,0 +1,18 @@ +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using System.Threading; + +namespace Rocket.Chat.Net.Interfaces +{ + public interface IRestClient : IDisposable + { + string Url { get; } + bool IsDisposed { get; } + Task CallAsync(string method, string path, CancellationToken token, params object[] args); + Task LoginAsync(object args); + + } +} diff --git a/src/Rocket.Chat.Net/Interfaces/IRocketChatDriver.cs b/src/Rocket.Chat.Net/Interfaces/IRocketChatDriver.cs index 1ec9d42..cb68c9c 100644 --- a/src/Rocket.Chat.Net/Interfaces/IRocketChatDriver.cs +++ b/src/Rocket.Chat.Net/Interfaces/IRocketChatDriver.cs @@ -5,6 +5,7 @@ using Rocket.Chat.Net.Interfaces.Driver; public interface IRocketChatDriver : IDisposable, + IRocketRestClientManagement, IRocketClientManagement, IRocketUserManagement, IRocketMessagingManagement, diff --git a/src/Rocket.Chat.Net/Rocket.Chat.Net.csproj b/src/Rocket.Chat.Net/Rocket.Chat.Net.csproj index 986703d..8736b3f 100644 --- a/src/Rocket.Chat.Net/Rocket.Chat.Net.csproj +++ b/src/Rocket.Chat.Net/Rocket.Chat.Net.csproj @@ -16,6 +16,7 @@ +