using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using Pilz.Networking.CloudProviders.Nextcloud.Client; using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud; using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Model; using Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2.Ocs; using Pilz.Networking.CloudProviders.Nextcloud.Ocs; namespace Pilz.Networking.CloudProviders.Nextcloud { public class NextcloudClient : IDisposable { private readonly List clients = new(); private NextcloudLogin? currentLogin; public OcsApi Ocs { get; init; } = new(); public NextcloudLogin? CurrentLogin { get => currentLogin; private set { currentLogin = value; Ocs.BaseUrl = value?.Server ?? string.Empty; } } public CloudClient Cloud => GetClient(); public NextcloudClient() { Ocs.GetOcsApiAuthCredentails += Ocs_GetOcsApiAuthCredentails; } private void Ocs_GetOcsApiAuthCredentails(object sender, GetOcsApiAuthCredentailsEventArgs eventArgs) { if (sender == Ocs) eventArgs.Credentials = CurrentLogin.ToOcsApiAuthCredentials(); } 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 UserInfo? Login(NextcloudLogin login) { return Login(login, true); } public UserInfo? Login(NextcloudLogin login, bool checkUser) { // Ensure we are logged out Logout(false); // Temporary set user login CurrentLogin = login; if (checkUser) { // Try get user info & check if user is enabled var userInfo = Cloud.GetUserInfo(); var isValid = userInfo != null /*&& userInfo.Enabled*/; // Enabled is false for some (new) users but they still are able to login?? // If invalid, reset login credentials if (!isValid) CurrentLogin = null; return userInfo; } return null; } public NextcloudLogin? Login(string baseUrl, CancellationToken cancellationToken) { // Ensure we are logged out Logout(false); // Init the login process var initResponse = Ocs.LoginFlowV2.Init(baseUrl); if (!string.IsNullOrEmpty(initResponse?.LoginUrl) && initResponse.Poll != null) { // Open the browser Process.Start(new ProcessStartInfo { FileName = initResponse.LoginUrl, UseShellExecute = true }); // Poll for credentails in intervals OcsResponseLoginFlowV2Credentials? pollResponse = null; while (!cancellationToken.IsCancellationRequested && pollResponse is null) { // Wait 5 seconds Thread.Sleep(5000); // Poll the credentials if (!cancellationToken.IsCancellationRequested) pollResponse = Ocs.LoginFlowV2.Poll(initResponse.Poll); } // Check login credentials if (pollResponse is not null) CurrentLogin = new(pollResponse); } return CurrentLogin; } public void Logout() { Logout(false); } public void Logout(bool logoutOnServer) { if (CurrentLogin != null) { // Delete currently used app password if (logoutOnServer) Ocs.Core.DeleteAppPassword(); // Reset current login infos CurrentLogin = null; } } public void Dispose() { Ocs.Dispose(); GC.SuppressFinalize(this); } } }