From 16ca4ecbb6dc013c7a6dc37165718d9ad38e3290 Mon Sep 17 00:00:00 2001 From: Pilzinsel64 Date: Sun, 1 Oct 2023 16:51:10 +0200 Subject: [PATCH] huge work for nextcloud api --- NuGet.Config | 1 + .../Client/Apps/FilesRetentionClient.cs | 46 ++++++++++++ .../Client/ClientBase.cs | 18 +++++ .../Client/CloudClient.cs | 34 +++++++++ .../Apps/FilesRetention/RetentionRule.cs | 73 ++++++++++++++++++ .../Apps/FilesRetention/RetentionTimeAfter.cs | 14 ++++ .../Apps/FilesRetention/RetentionTimeUnit.cs | 16 ++++ .../{ => Cloud}/UserBackendCapabilities.cs | 2 +- .../Model/{ => Cloud}/UserInfo.cs | 32 ++++---- .../Model/{ => Cloud}/UserQuota.cs | 2 +- .../NextcloudClient.cs | 74 ++++++++++--------- .../OCS/APIs/Apps/OcsApiFilesRetention.cs | 39 ++++++++++ .../OCS/APIs/OcsApiCloud.cs | 2 +- .../OCS/APIs/OcsApiLoginFlowV2.cs | 4 +- .../FileRetention/OcsDataRetentionRule.cs | 25 +++++++ .../OCS/Data/OcsData.cs | 12 +++ .../OCS/OcsApi.cs | 56 ++++++++++---- .../OcsResponseDataEntryRetention.cs | 30 ++++++++ .../FilesRetention/OcsResponseRetention.cs | 13 ++++ .../OCS/Responses/IOcsResponseData.cs | 12 +++ .../OCS/Responses/OcsResponse.cs | 6 +- .../OCS/Responses/OcsResponseData.cs | 2 +- .../OCS/Responses/OcsResponseDataArray.cs | 12 +++ .../OCS/Responses/OcsResponseDataEntry.cs | 12 +++ ...Networking.CloudProviders.Nextcloud.csproj | 2 +- .../Pilz.UI.Telerik.SymbolFactory.csproj | 10 +-- Pilz.UI.Telerik/Pilz.UI.Telerik.csproj | 10 +-- 27 files changed, 472 insertions(+), 87 deletions(-) create mode 100644 Pilz.Networking.CloudProviders.Nextcloud/Client/Apps/FilesRetentionClient.cs create mode 100644 Pilz.Networking.CloudProviders.Nextcloud/Client/ClientBase.cs create mode 100644 Pilz.Networking.CloudProviders.Nextcloud/Client/CloudClient.cs create mode 100644 Pilz.Networking.CloudProviders.Nextcloud/Model/Apps/FilesRetention/RetentionRule.cs create mode 100644 Pilz.Networking.CloudProviders.Nextcloud/Model/Apps/FilesRetention/RetentionTimeAfter.cs create mode 100644 Pilz.Networking.CloudProviders.Nextcloud/Model/Apps/FilesRetention/RetentionTimeUnit.cs rename Pilz.Networking.CloudProviders.Nextcloud/Model/{ => Cloud}/UserBackendCapabilities.cs (88%) rename Pilz.Networking.CloudProviders.Nextcloud/Model/{ => Cloud}/UserInfo.cs (82%) rename Pilz.Networking.CloudProviders.Nextcloud/Model/{ => Cloud}/UserQuota.cs (93%) create mode 100644 Pilz.Networking.CloudProviders.Nextcloud/OCS/APIs/Apps/OcsApiFilesRetention.cs create mode 100644 Pilz.Networking.CloudProviders.Nextcloud/OCS/Data/Apps/FileRetention/OcsDataRetentionRule.cs create mode 100644 Pilz.Networking.CloudProviders.Nextcloud/OCS/Data/OcsData.cs create mode 100644 Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/Apps/FilesRetention/OcsResponseDataEntryRetention.cs create mode 100644 Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/Apps/FilesRetention/OcsResponseRetention.cs create mode 100644 Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/IOcsResponseData.cs create mode 100644 Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/OcsResponseDataArray.cs create mode 100644 Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/OcsResponseDataEntry.cs diff --git a/NuGet.Config b/NuGet.Config index e5056d3..99feee0 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -2,5 +2,6 @@ + \ No newline at end of file diff --git a/Pilz.Networking.CloudProviders.Nextcloud/Client/Apps/FilesRetentionClient.cs b/Pilz.Networking.CloudProviders.Nextcloud/Client/Apps/FilesRetentionClient.cs new file mode 100644 index 0000000..e258a45 --- /dev/null +++ b/Pilz.Networking.CloudProviders.Nextcloud/Client/Apps/FilesRetentionClient.cs @@ -0,0 +1,46 @@ +using Pilz.Networking.CloudProviders.Nextcloud.Model.Apps.FilesRetention; +using Pilz.Networking.CloudProviders.Nextcloud.OCS.APIs.Apps; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps +{ + public class FilesRetentionClient : ClientBase + { + public FilesRetentionClient(NextcloudClient client) : base(client) + { + } + + public Task CreateRetentionRule(RetentionRule rule) + { + var entry = rule.ToOcsData(); + return Client.Ocs.GetApi().CreateRetentionRule(entry); + } + + public Task DeleteRetentionRule(int ruleID) + { + return Client.Ocs.GetApi().DeleteRetentionRule(ruleID); + } + + public async Task GetRetentionRules() + { + var api = Client.Ocs.GetApi(); + var response = await api.GetRetentionRules(); + + if (response?.Data is not null) + { + var rules = new List(); + + foreach (var entry in response.Data) + rules.Add(new RetentionRule(entry)); + + return rules.ToArray(); + } + + return null; + } + } +} diff --git a/Pilz.Networking.CloudProviders.Nextcloud/Client/ClientBase.cs b/Pilz.Networking.CloudProviders.Nextcloud/Client/ClientBase.cs new file mode 100644 index 0000000..94eb24d --- /dev/null +++ b/Pilz.Networking.CloudProviders.Nextcloud/Client/ClientBase.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Pilz.Networking.CloudProviders.Nextcloud.Client +{ + public abstract class ClientBase + { + public NextcloudClient Client { get; init; } + + public ClientBase(NextcloudClient client) + { + Client = client; + } + } +} diff --git a/Pilz.Networking.CloudProviders.Nextcloud/Client/CloudClient.cs b/Pilz.Networking.CloudProviders.Nextcloud/Client/CloudClient.cs new file mode 100644 index 0000000..361e8c7 --- /dev/null +++ b/Pilz.Networking.CloudProviders.Nextcloud/Client/CloudClient.cs @@ -0,0 +1,34 @@ +using Pilz.Networking.CloudProviders.Nextcloud.Model.Cloud; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Pilz.Networking.CloudProviders.Nextcloud.Client +{ + public class CloudClient : ClientBase + { + public CloudClient(NextcloudClient client) : base(client) + { + } + + public Task GetUserInfo() + { + if (!string.IsNullOrEmpty(Client.CurrentLogin?.LoginName)) + return GetUserInfo(Client.CurrentLogin.LoginName); + else + return Task.FromResult(null); + } + + public async Task GetUserInfo(string username) + { + var result = await Client.Ocs.Cloud.GetUserMeta(username); + + if (result?.Data != null) + return new UserInfo(result.Data); + + return null; + } + } +} diff --git a/Pilz.Networking.CloudProviders.Nextcloud/Model/Apps/FilesRetention/RetentionRule.cs b/Pilz.Networking.CloudProviders.Nextcloud/Model/Apps/FilesRetention/RetentionRule.cs new file mode 100644 index 0000000..088b760 --- /dev/null +++ b/Pilz.Networking.CloudProviders.Nextcloud/Model/Apps/FilesRetention/RetentionRule.cs @@ -0,0 +1,73 @@ +using Pilz.Networking.CloudProviders.Nextcloud.OCS.Data.Apps.FileRetention; +using Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses.Apps.FilesRetention; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Pilz.Networking.CloudProviders.Nextcloud.Model.Apps.FilesRetention +{ + public class RetentionRule + { + /// + /// The ID for the retention rule. + /// + public int ID { get; init; } + + /// + /// The ID for the tag that is used for this rule. + /// + public int TagID { get; init; } + + /// + /// The unit used for the time. + /// + public RetentionTimeUnit TimeUnit { get; init; } + + /// + /// Represents numer of days/weeks/months/years. + /// + public int TimeAmount { get; init; } + + /// + /// The time used for the rule. + /// + public RetentionTimeAfter TimeAfter { get; init; } + + /// + /// Defines if a background job has been generated + /// + public bool HasJob { get; init; } + + public RetentionRule(int iD, int tagID, RetentionTimeUnit timeUnit, int timeAmount, RetentionTimeAfter timeAfter, bool hasJob) + { + ID = iD; + TagID = tagID; + TimeUnit = timeUnit; + TimeAmount = timeAmount; + TimeAfter = timeAfter; + HasJob = hasJob; + } + + public RetentionRule(OcsResponseDataEntryRetention data) + { + ID = data.ID ?? -1; + TagID = data.TagID ?? -1; + TimeUnit = (RetentionTimeUnit)(data.TimeUnit ?? 0); + TimeAmount = data.TimeAmount ?? -1; + TimeAfter = (RetentionTimeAfter)(data.TimeAfter ?? 0); + } + + public OcsDataRetentionRule ToOcsData() + { + return new OcsDataRetentionRule + { + TagID = TagID, + TimeUnit = (int)TimeUnit, + TimeAmount = TimeAmount, + TimeAfter = (int)TimeAfter + }; + } + } +} diff --git a/Pilz.Networking.CloudProviders.Nextcloud/Model/Apps/FilesRetention/RetentionTimeAfter.cs b/Pilz.Networking.CloudProviders.Nextcloud/Model/Apps/FilesRetention/RetentionTimeAfter.cs new file mode 100644 index 0000000..09a02eb --- /dev/null +++ b/Pilz.Networking.CloudProviders.Nextcloud/Model/Apps/FilesRetention/RetentionTimeAfter.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Pilz.Networking.CloudProviders.Nextcloud.Model.Apps.FilesRetention +{ + public enum RetentionTimeAfter + { + CreationDate, + LastAccess + } +} diff --git a/Pilz.Networking.CloudProviders.Nextcloud/Model/Apps/FilesRetention/RetentionTimeUnit.cs b/Pilz.Networking.CloudProviders.Nextcloud/Model/Apps/FilesRetention/RetentionTimeUnit.cs new file mode 100644 index 0000000..95d381a --- /dev/null +++ b/Pilz.Networking.CloudProviders.Nextcloud/Model/Apps/FilesRetention/RetentionTimeUnit.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Pilz.Networking.CloudProviders.Nextcloud.Model.Apps.FilesRetention +{ + public enum RetentionTimeUnit + { + Day, + Week, + Month, + Year + } +} diff --git a/Pilz.Networking.CloudProviders.Nextcloud/Model/UserBackendCapabilities.cs b/Pilz.Networking.CloudProviders.Nextcloud/Model/Cloud/UserBackendCapabilities.cs similarity index 88% rename from Pilz.Networking.CloudProviders.Nextcloud/Model/UserBackendCapabilities.cs rename to Pilz.Networking.CloudProviders.Nextcloud/Model/Cloud/UserBackendCapabilities.cs index b234ac4..e0dc646 100644 --- a/Pilz.Networking.CloudProviders.Nextcloud/Model/UserBackendCapabilities.cs +++ b/Pilz.Networking.CloudProviders.Nextcloud/Model/Cloud/UserBackendCapabilities.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Pilz.Networking.CloudProviders.Nextcloud.Model +namespace Pilz.Networking.CloudProviders.Nextcloud.Model.Cloud { public class UserBackendCapabilities { diff --git a/Pilz.Networking.CloudProviders.Nextcloud/Model/UserInfo.cs b/Pilz.Networking.CloudProviders.Nextcloud/Model/Cloud/UserInfo.cs similarity index 82% rename from Pilz.Networking.CloudProviders.Nextcloud/Model/UserInfo.cs rename to Pilz.Networking.CloudProviders.Nextcloud/Model/Cloud/UserInfo.cs index e46205a..30d2e3d 100644 --- a/Pilz.Networking.CloudProviders.Nextcloud/Model/UserInfo.cs +++ b/Pilz.Networking.CloudProviders.Nextcloud/Model/Cloud/UserInfo.cs @@ -5,84 +5,84 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Pilz.Networking.CloudProviders.Nextcloud.Model +namespace Pilz.Networking.CloudProviders.Nextcloud.Model.Cloud { public class UserInfo { /// /// Defines if the user is enabled. /// - public bool Enabled { get; set; } + public bool Enabled { get; init; } /// /// The location of the user's storage directory. /// - public string? StorageLocation { get; set; } + public string? StorageLocation { get; init; } /// /// The uniquie user id that infos are for. /// - public string? ID { get; set; } + public string? ID { get; init; } /// /// The last time when the user has logged in to its account. /// - public DateTime LastLogin { get; set; } + public DateTime LastLogin { get; init; } /// /// The backend of the user. Common values are "Database" or "LDAP". /// - public string? Backend { get; set; } + public string? Backend { get; init; } /// /// The Email address of the user. /// - public string? Email { get; set; } + public string? Email { get; init; } /// /// The displayname of the user. /// - public string? Displayname { get; set; } + public string? Displayname { get; init; } /// /// The displayname of the user. /// - public string? Displayname2 { get; set; } + public string? Displayname2 { get; init; } /// /// The phone number of the user. /// - public string? Phone { get; set; } + public string? Phone { get; init; } /// /// The address of the user. /// - public string? Address { get; set; } + public string? Address { get; init; } /// /// The Website of the user. /// - public string? Website { get; set; } + public string? Website { get; init; } /// /// The twitter profile name of the user. /// - public string? Twitter { get; set; } + public string? Twitter { get; init; } /// /// Defines the groups the user is member of. /// - public string[] Groups { get; set; } + public string[] Groups { get; init; } /// /// The configured language of the user. /// - public string? Language { get; set; } + public string? Language { get; init; } /// /// The configured location of the user. /// - public string? Locale { get; set; } + public string? Locale { get; init; } /// /// Quota informations for the user. diff --git a/Pilz.Networking.CloudProviders.Nextcloud/Model/UserQuota.cs b/Pilz.Networking.CloudProviders.Nextcloud/Model/Cloud/UserQuota.cs similarity index 93% rename from Pilz.Networking.CloudProviders.Nextcloud/Model/UserQuota.cs rename to Pilz.Networking.CloudProviders.Nextcloud/Model/Cloud/UserQuota.cs index dcbef3c..921092a 100644 --- a/Pilz.Networking.CloudProviders.Nextcloud/Model/UserQuota.cs +++ b/Pilz.Networking.CloudProviders.Nextcloud/Model/Cloud/UserQuota.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Pilz.Networking.CloudProviders.Nextcloud.Model +namespace Pilz.Networking.CloudProviders.Nextcloud.Model.Cloud { public class UserQuota { diff --git a/Pilz.Networking.CloudProviders.Nextcloud/NextcloudClient.cs b/Pilz.Networking.CloudProviders.Nextcloud/NextcloudClient.cs index 874f68f..dae0f21 100644 --- a/Pilz.Networking.CloudProviders.Nextcloud/NextcloudClient.cs +++ b/Pilz.Networking.CloudProviders.Nextcloud/NextcloudClient.cs @@ -6,39 +6,62 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Pilz.Networking.CloudProviders.Nextcloud; +using Pilz.Networking.CloudProviders.Nextcloud.Client; using Pilz.Networking.CloudProviders.Nextcloud.Model; +using Pilz.Networking.CloudProviders.Nextcloud.Model.Cloud; using Pilz.Networking.CloudProviders.Nextcloud.OCS; using Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses.LoginFlowV2; -namespace ConsoleApp9 +namespace Pilz.Networking.CloudProviders.Nextcloud { public class NextcloudClient : IDisposable { - private readonly OcsApi ocs = new(); + private readonly List clients = new(); + public OcsApi Ocs { get; init; } = new(); public NextcloudLogin? CurrentLogin { get; private set; } + public CloudClient Cloud => GetClient(); + public NextcloudClient() { - ocs.GetOcsApiAuthCredentails += Ocs_GetOcsApiAuthCredentails; + Ocs.GetOcsApiAuthCredentails += Ocs_GetOcsApiAuthCredentails; } private void Ocs_GetOcsApiAuthCredentails(object sender, GetOcsApiAuthCredentailsEventArgs eventArgs) { - if (sender == ocs) + if (sender == Ocs) eventArgs.Credentials = CurrentLogin.ToOcsApiAuthCredentials(); } - public async Task LoginAsync(NextcloudLogin login) + public TClient GetClient() where TClient : ClientBase + { + var instance = TryGetClient(); + return instance is null ? throw new NullReferenceException() : instance; + } + + public TClient? TryGetClient() where TClient : ClientBase + { + TClient? instance = (TClient?)clients.FirstOrDefault(n => n is TClient); + + instance ??= (TClient?)Activator.CreateInstance(typeof(TClient), new object[] { this }); + + if (instance is not null) + clients.Add(instance); + + return instance; + } + + public async Task Login(NextcloudLogin login) { // Ensure we are logged out - await LogoutAsync(); + await Logout(); // Temporary set user login CurrentLogin = login; // Try get user info & check if user is enabled - var userInfo = await GetUserInfoAsync(); + var userInfo = await Cloud.GetUserInfo(); var isValid = userInfo != null && userInfo.Enabled; // If invalid, reset login credentials @@ -48,13 +71,13 @@ namespace ConsoleApp9 return userInfo; } - public async Task LoginAsync(string baseUrl, CancellationToken cancellationToken) + public async Task Login(string baseUrl, CancellationToken cancellationToken) { // Ensure we are logged out - await LogoutAsync(); + await Logout(); // Init the login process - var initResponse = await ocs.LoginFlowV2.Init(baseUrl); + var initResponse = await Ocs.LoginFlowV2.Init(baseUrl); if (!string.IsNullOrEmpty(initResponse?.LoginUrl) && initResponse.Poll != null) { @@ -74,7 +97,7 @@ namespace ConsoleApp9 // Poll the credentials if (!cancellationToken.IsCancellationRequested) - pollResponse = await ocs.LoginFlowV2.Poll(initResponse.Poll); + pollResponse = await Ocs.LoginFlowV2.Poll(initResponse.Poll); } // Check login credentials @@ -85,35 +108,18 @@ namespace ConsoleApp9 return CurrentLogin; } - public Task GetUserInfoAsync() + public Task Logout() { - if (!string.IsNullOrEmpty(CurrentLogin?.LoginName)) - return GetUserInfoAsync(CurrentLogin.LoginName); - else - return Task.FromResult(null); + return Logout(true); } - public async Task GetUserInfoAsync(string username) - { - var result = await ocs.Cloud.GetUserMeta(username); - - if (result?.Data != null) - return new UserInfo(result.Data); - - return null; - } - - public Task LogoutAsync() - { - return LogoutAsync(true); - } - - public async Task LogoutAsync(bool logoutOnServer) + public async Task Logout(bool logoutOnServer) { if (CurrentLogin != null) { // Delete currently used app password - await ocs.Core.DeleteAppPassword(); + if (logoutOnServer) + await Ocs.Core.DeleteAppPassword(); // Reset current login infos CurrentLogin = null; @@ -122,7 +128,7 @@ namespace ConsoleApp9 public void Dispose() { - ocs.Dispose(); + Ocs.Dispose(); GC.SuppressFinalize(this); } } diff --git a/Pilz.Networking.CloudProviders.Nextcloud/OCS/APIs/Apps/OcsApiFilesRetention.cs b/Pilz.Networking.CloudProviders.Nextcloud/OCS/APIs/Apps/OcsApiFilesRetention.cs new file mode 100644 index 0000000..e7a7e18 --- /dev/null +++ b/Pilz.Networking.CloudProviders.Nextcloud/OCS/APIs/Apps/OcsApiFilesRetention.cs @@ -0,0 +1,39 @@ +using Pilz.Networking.CloudProviders.Nextcloud.OCS.Data.Apps.FileRetention; +using Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses; +using Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses.Apps.FilesRetention; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.APIs.Apps +{ + public class OcsApiFilesRetention : OcsApiBase + { + public static readonly OcsApiUrlPath OCS_FILE_RETENTION_RULES = new("/ocs/v2.php/apps/files_retention/api/v1/retentions"); + public static readonly OcsApiUrlPath OCS_FILE_RETENTION_RULE = new("/ocs/v2.php/apps/files_retention/api/v1/retentions/{0}"); + + public OcsApiFilesRetention(OcsApi manager) : base(manager) + { + } + + public async Task CreateRetentionRule(OcsDataRetentionRule rule) + { + var response = await Manager.MakeRequest(HttpMethod.Put, OCS_FILE_RETENTION_RULES, content: rule); + return response.IsSuccessStatusCode; + } + + public async Task DeleteRetentionRule(int ruleID) + { + var response = await Manager.MakeRequest(HttpMethod.Delete, OCS_FILE_RETENTION_RULE.FillParameters(ruleID)); + return response.IsSuccessStatusCode; + } + + public Task GetRetentionRules() + { + return Manager.MakeRequest(HttpMethod.Get, OCS_FILE_RETENTION_RULES); + } + } +} diff --git a/Pilz.Networking.CloudProviders.Nextcloud/OCS/APIs/OcsApiCloud.cs b/Pilz.Networking.CloudProviders.Nextcloud/OCS/APIs/OcsApiCloud.cs index 21e4d95..1f32186 100644 --- a/Pilz.Networking.CloudProviders.Nextcloud/OCS/APIs/OcsApiCloud.cs +++ b/Pilz.Networking.CloudProviders.Nextcloud/OCS/APIs/OcsApiCloud.cs @@ -17,7 +17,7 @@ namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.APIs public Task GetUserMeta(string username) { - return Manager.MakeRequestJson(HttpMethod.Get, OCS_CLOUD_USER_METADATA.FillParameters(username)); + return Manager.MakeRequest(HttpMethod.Get, OCS_CLOUD_USER_METADATA.FillParameters(username)); } } } diff --git a/Pilz.Networking.CloudProviders.Nextcloud/OCS/APIs/OcsApiLoginFlowV2.cs b/Pilz.Networking.CloudProviders.Nextcloud/OCS/APIs/OcsApiLoginFlowV2.cs index 357aeaa..824dc4b 100644 --- a/Pilz.Networking.CloudProviders.Nextcloud/OCS/APIs/OcsApiLoginFlowV2.cs +++ b/Pilz.Networking.CloudProviders.Nextcloud/OCS/APIs/OcsApiLoginFlowV2.cs @@ -17,7 +17,7 @@ namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.APIs public Task Init(string url) { - return Manager.MakeRequestJson(HttpMethod.Get, url + OCS_LOGIN_INIT); + return Manager.MakeRequest(HttpMethod.Get, url + OCS_LOGIN_INIT); } public Task Poll(OcsResponseLoginFlowV2.PollData poll) @@ -25,7 +25,7 @@ namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.APIs ArgumentNullException.ThrowIfNull(poll?.Endpoint); ArgumentNullException.ThrowIfNull(poll?.Token); - return Manager.MakeRequestJson(HttpMethod.Get, poll.Endpoint, + return Manager.MakeRequest(HttpMethod.Get, poll.Endpoint, parameters: new Dictionary { { "token", poll.Token } diff --git a/Pilz.Networking.CloudProviders.Nextcloud/OCS/Data/Apps/FileRetention/OcsDataRetentionRule.cs b/Pilz.Networking.CloudProviders.Nextcloud/OCS/Data/Apps/FileRetention/OcsDataRetentionRule.cs new file mode 100644 index 0000000..7a6a2fc --- /dev/null +++ b/Pilz.Networking.CloudProviders.Nextcloud/OCS/Data/Apps/FileRetention/OcsDataRetentionRule.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.Data.Apps.FileRetention +{ + public class OcsDataRetentionRule : OcsData + { + + [JsonProperty("tagid")] + public int? TagID { get; set; } + + [JsonProperty("timeunit")] + public int? TimeUnit { get; set; } + + [JsonProperty("timeamount")] + public int? TimeAmount { get; set; } + + [JsonProperty("timeafter")] + public int? TimeAfter { get; set; } + } +} diff --git a/Pilz.Networking.CloudProviders.Nextcloud/OCS/Data/OcsData.cs b/Pilz.Networking.CloudProviders.Nextcloud/OCS/Data/OcsData.cs new file mode 100644 index 0000000..749615c --- /dev/null +++ b/Pilz.Networking.CloudProviders.Nextcloud/OCS/Data/OcsData.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.Data +{ + public class OcsData + { + } +} diff --git a/Pilz.Networking.CloudProviders.Nextcloud/OCS/OcsApi.cs b/Pilz.Networking.CloudProviders.Nextcloud/OCS/OcsApi.cs index 96761a8..43091a0 100644 --- a/Pilz.Networking.CloudProviders.Nextcloud/OCS/OcsApi.cs +++ b/Pilz.Networking.CloudProviders.Nextcloud/OCS/OcsApi.cs @@ -8,26 +8,42 @@ using Newtonsoft.Json; using System.Diagnostics; using System.Net; using Pilz.Networking.CloudProviders.Nextcloud.OCS.APIs; +using System.Net.Sockets; +using Pilz.Networking.CloudProviders.Nextcloud.OCS.Data; namespace Pilz.Networking.CloudProviders.Nextcloud.OCS { public class OcsApi : IDisposable { + public const string CONTENT_TYPE_JSON = "application/json"; + public event GetOcsApiAuthCredentailsEventHandler? GetOcsApiAuthCredentails; private readonly HttpClient client = new(); + private readonly List apis = new(); public string BaseUrl { get; set; } = string.Empty; - public OcsApiLoginFlowV2 LoginFlowV2 { get; init; } - public OcsApiCore Core { get; init; } - public OcsApiCloud Cloud { get; init; } + public OcsApiLoginFlowV2 LoginFlowV2 => GetApi(); + public OcsApiCore Core => GetApi(); + public OcsApiCloud Cloud => GetApi(); - public OcsApi() + public TApi GetApi() where TApi : OcsApiBase { - LoginFlowV2 = new(this); - Core = new(this); - Cloud = new(this); + var instance = TryGetApi(); + return instance is null ? throw new NullReferenceException() : instance; + } + + public TApi? TryGetApi() where TApi : OcsApiBase + { + TApi? instance = (TApi?)apis.FirstOrDefault(n => n is TApi); + + instance ??= (TApi?)Activator.CreateInstance(typeof(TApi), new object[] { this }); + + if (instance is not null) + apis.Add(instance); + + return instance; } public string BuildFullUrl(OcsApiUrlPath path) @@ -35,19 +51,19 @@ namespace Pilz.Networking.CloudProviders.Nextcloud.OCS return BaseUrl + path; } - public Task MakeRequestJson(HttpMethod httpMethod, OcsApiUrlPath url, bool useAuthentication = true, Dictionary? parameters = null) + public Task MakeRequest(HttpMethod httpMethod, OcsApiUrlPath url, bool useAuthentication = true, Dictionary? parameters = null, object? content = null) { - return MakeRequestJson(httpMethod, BuildFullUrl(url), useAuthentication: useAuthentication, parameters: parameters); + return MakeRequest(httpMethod, BuildFullUrl(url), useAuthentication: useAuthentication, parameters: parameters, content: content); } - public Task MakeRequest(HttpMethod httpMethod, OcsApiUrlPath url, bool useAuthentication = true, Dictionary? parameters = null) + public Task MakeRequest(HttpMethod httpMethod, OcsApiUrlPath url, bool useAuthentication = true, Dictionary? parameters = null, object? content = null) { - return MakeRequest(httpMethod, BuildFullUrl(url), useAuthentication: useAuthentication, parameters: parameters); + return MakeRequest(httpMethod, BuildFullUrl(url), useAuthentication: useAuthentication, parameters: parameters, content: content); } - public async Task MakeRequestJson(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary? parameters = null) + public async Task MakeRequest(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary? parameters = null, object? content = null) { - using var responseInit = await MakeRequest(httpMethod, url, useAuthentication: useAuthentication, parameters: parameters); + using var responseInit = await MakeRequest(httpMethod, url, useAuthentication: useAuthentication, parameters: parameters, content: content); if (responseInit != null) { @@ -58,10 +74,11 @@ namespace Pilz.Networking.CloudProviders.Nextcloud.OCS return default; } - public async Task MakeRequest(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary? parameters = null) + public async Task MakeRequest(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary? parameters = null, object? content = null) { OcsApiAuthCredentials? authentication; string @params; + HttpContent? httpContent; // Get authentication if (useAuthentication) @@ -79,6 +96,14 @@ namespace Pilz.Networking.CloudProviders.Nextcloud.OCS else @params = string.Empty; + // Create content + if (content is HttpContent contentHttp) + httpContent = contentHttp; + else if (content is OcsData) + httpContent = new StringContent(JsonConvert.SerializeObject(content), null, CONTENT_TYPE_JSON); + else + httpContent = null; + // Send request var request = new HttpRequestMessage { @@ -86,10 +111,11 @@ namespace Pilz.Networking.CloudProviders.Nextcloud.OCS RequestUri = new Uri(url + @params), Headers = { - { "Accept", "application/json" }, + { "Accept", CONTENT_TYPE_JSON }, { "OCS-APIREQUEST", "true" }, { "Authorization", authentication.ToBasicAuth() } }, + Content = httpContent }; return await client.SendAsync(request); diff --git a/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/Apps/FilesRetention/OcsResponseDataEntryRetention.cs b/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/Apps/FilesRetention/OcsResponseDataEntryRetention.cs new file mode 100644 index 0000000..0ea024d --- /dev/null +++ b/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/Apps/FilesRetention/OcsResponseDataEntryRetention.cs @@ -0,0 +1,30 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses.Apps.FilesRetention +{ + public class OcsResponseDataEntryRetention : OcsResponseDataEntry + { + [JsonProperty("id")] + public int? ID { get; set; } + + [JsonProperty("tagid")] + public int? TagID { get; set; } + + [JsonProperty("timeunit")] + public int? TimeUnit { get; set; } + + [JsonProperty("timeamount")] + public int? TimeAmount { get; set; } + + [JsonProperty("timeafter")] + public int? TimeAfter { get; set; } + + [JsonProperty("hasJob")] + public bool? HasJob { get; set; } + } +} diff --git a/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/Apps/FilesRetention/OcsResponseRetention.cs b/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/Apps/FilesRetention/OcsResponseRetention.cs new file mode 100644 index 0000000..ad65dc7 --- /dev/null +++ b/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/Apps/FilesRetention/OcsResponseRetention.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses.Apps.FilesRetention +{ + public class OcsResponseRetention : OcsResponse> + { + } +} diff --git a/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/IOcsResponseData.cs b/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/IOcsResponseData.cs new file mode 100644 index 0000000..6822652 --- /dev/null +++ b/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/IOcsResponseData.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses +{ + public interface IOcsResponseData + { + } +} diff --git a/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/OcsResponse.cs b/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/OcsResponse.cs index c21a6a4..2003436 100644 --- a/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/OcsResponse.cs +++ b/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/OcsResponse.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses { - public class OcsResponse where TMeta : OcsResponseMeta where TData : OcsResponseData + public class OcsResponse where TMeta : OcsResponseMeta where TData : IOcsResponseData { [JsonProperty("meta")] public TMeta? Meta { get; set; } @@ -16,11 +16,11 @@ namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses public TData? Data { get; set; } } - public class OcsResponse : OcsResponse where TData : OcsResponseData + public class OcsResponse : OcsResponse where TData : IOcsResponseData { } - public class OcsResponse : OcsResponse + public class OcsResponse : OcsResponse { } } diff --git a/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/OcsResponseData.cs b/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/OcsResponseData.cs index cc3a1ac..0cdbb80 100644 --- a/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/OcsResponseData.cs +++ b/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/OcsResponseData.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses { - public class OcsResponseData + public class OcsResponseData : IOcsResponseData { } } diff --git a/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/OcsResponseDataArray.cs b/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/OcsResponseDataArray.cs new file mode 100644 index 0000000..6f5d399 --- /dev/null +++ b/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/OcsResponseDataArray.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses +{ + public class OcsResponseDataArray : List, IOcsResponseData where TEntry : OcsResponseDataEntry + { + } +} diff --git a/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/OcsResponseDataEntry.cs b/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/OcsResponseDataEntry.cs new file mode 100644 index 0000000..796f889 --- /dev/null +++ b/Pilz.Networking.CloudProviders.Nextcloud/OCS/Responses/OcsResponseDataEntry.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses +{ + public class OcsResponseDataEntry + { + } +} diff --git a/Pilz.Networking.CloudProviders.Nextcloud/Pilz.Networking.CloudProviders.Nextcloud.csproj b/Pilz.Networking.CloudProviders.Nextcloud/Pilz.Networking.CloudProviders.Nextcloud.csproj index c07d969..b280cb9 100644 --- a/Pilz.Networking.CloudProviders.Nextcloud/Pilz.Networking.CloudProviders.Nextcloud.csproj +++ b/Pilz.Networking.CloudProviders.Nextcloud/Pilz.Networking.CloudProviders.Nextcloud.csproj @@ -9,7 +9,7 @@ True 1.yyyy.Mdd.Hmm - 1.2023.927.1412 + 1.2023.1001.1650 diff --git a/Pilz.UI.Telerik.SymbolFactory/Pilz.UI.Telerik.SymbolFactory.csproj b/Pilz.UI.Telerik.SymbolFactory/Pilz.UI.Telerik.SymbolFactory.csproj index b5732c2..fb06f3d 100644 --- a/Pilz.UI.Telerik.SymbolFactory/Pilz.UI.Telerik.SymbolFactory.csproj +++ b/Pilz.UI.Telerik.SymbolFactory/Pilz.UI.Telerik.SymbolFactory.csproj @@ -1,21 +1,19 @@  - net6.0-windows enable enable Pilz.UI.Telerik - True 1.yyyy.Mdd.Hmm 1.2023.914.1955 - - + + 2023.2.718 + - - + \ No newline at end of file diff --git a/Pilz.UI.Telerik/Pilz.UI.Telerik.csproj b/Pilz.UI.Telerik/Pilz.UI.Telerik.csproj index e6dfa26..5da11f4 100644 --- a/Pilz.UI.Telerik/Pilz.UI.Telerik.csproj +++ b/Pilz.UI.Telerik/Pilz.UI.Telerik.csproj @@ -1,20 +1,18 @@  - net6.0-windows enable enable true - True 1.yyyy.Mdd.Hmm 1.2023.914.856 - - + + 2023.2.718 + - - + \ No newline at end of file