/* * * (c) Copyright Ascensio System Limited 2010-2018 * * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. * * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html * * You can contact Ascensio System SIA by email at sales@onlyoffice.com * * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. * * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains * relevant author attributions when distributing the software. If the display of the logo in its graphic * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" * in every copy of the program you distribute. * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. * */ using System; using System.Diagnostics; using System.Linq; using ASC.Common.Threading; using ASC.Core; using ASC.Core.Billing; using ASC.Web.Studio.Core; using ASC.Web.Studio.Utility; using Newtonsoft.Json; using ASC.Notify.Cron; using ASC.Web.Api.Routing; using ASC.Web.Core.PublicResources; namespace ASC.Api.Settings { public partial class SettingsApi { /// /// Returns current portal LDAP settings /// /// /// Get LDAP settings /// /// LDAPSupportSettings object [Read("ldap")] public LdapSettings GetLdapSettings() { CheckLdapPermissions(); var settings = LdapSettings.Load(); settings = settings.Clone() as LdapSettings; // clone LdapSettings object for clear password (potencial AscCache.Memory issue) if (settings == null) return new LdapSettings().GetDefault() as LdapSettings; settings.Password = null; settings.PasswordBytes = null; if (settings.IsDefault) return settings; var defaultSettings = settings.GetDefault(); if (settings.Equals(defaultSettings)) settings.IsDefault = true; return settings; } /// /// Returns current portal LDAP AutoSync cron expression if any /// /// /// Get LDAP AutoSync Cron expression /// /// string or null [Read("ldap/cron")] public string GetLdapCronSettings() { CheckLdapPermissions(); var settings = LdapCronSettings.Load(); if (settings == null) settings = new LdapCronSettings().GetDefault() as LdapCronSettings; if (string.IsNullOrEmpty(settings.Cron)) return null; return settings.Cron; } /// /// Sets current portal LDAP AutoSync cron expression /// /// /// Sets LDAP AutoSync Cron expression /// [Create("ldap/cron")] public void SetLdapCronSettings(string cron) { CheckLdapPermissions(); if (!string.IsNullOrEmpty(cron)) { new CronExpression(cron); // validate if (!LdapSettings.Load().EnableLdapAuthentication) { throw new Exception(Resource.LdapSettingsErrorCantSaveLdapSettings); } } var settings = LdapCronSettings.Load(); if (settings == null) settings = new LdapCronSettings(); settings.Cron = cron; settings.Save(); var t = CoreContext.TenantManager.GetCurrentTenant(); if (!string.IsNullOrEmpty(cron)) { LdapNotifyHelper.UnregisterAutoSync(t); LdapNotifyHelper.RegisterAutoSync(t, cron); } else { LdapNotifyHelper.UnregisterAutoSync(t); } } /// /// Start sync users and groups process by LDAP /// /// /// Sync LDAP /// [Read("ldap/sync")] public LdapOperationStatus SyncLdap() { CheckLdapPermissions(); var operations = LDAPTasks.GetTasks() .Where(t => t.GetProperty(LdapOperation.OWNER) == TenantProvider.CurrentTenantID) .ToList(); var hasStarted = operations.Any(o => { var opType = o.GetProperty(LdapOperation.OPERATION_TYPE); return o.Status <= DistributedTaskStatus.Running && (opType == LdapOperationType.Sync || opType == LdapOperationType.Save); }); if (hasStarted) { return GetLdapOperationStatus(); } if (operations.Any(o => o.Status <= DistributedTaskStatus.Running)) { return GetStartProcessError(); } var ldapSettings = LdapSettings.Load(); var ldapLocalization = new LdapLocalization(Resource.ResourceManager); var tenant = CoreContext.TenantManager.GetCurrentTenant(); var op = new LdapSaveSyncOperation(ldapSettings, tenant, LdapOperationType.Sync, ldapLocalization); return QueueTask(op); } /// /// Starts the process of collecting preliminary changes on the portal according to the selected LDAP settings /// /// /// Sync LDAP /// [Read("ldap/sync/test")] public LdapOperationStatus TestLdapSync() { CheckLdapPermissions(); var operations = LDAPTasks.GetTasks() .Where(t => t.GetProperty(LdapOperation.OWNER) == TenantProvider.CurrentTenantID) .ToList(); var hasStarted = operations.Any(o => { var opType = o.GetProperty(LdapOperation.OPERATION_TYPE); return o.Status <= DistributedTaskStatus.Running && (opType == LdapOperationType.SyncTest || opType == LdapOperationType.SaveTest); }); if (hasStarted) { return GetLdapOperationStatus(); } if (operations.Any(o => o.Status <= DistributedTaskStatus.Running)) { return GetStartProcessError(); } var ldapSettings = LdapSettings.Load(); var ldapLocalization = new LdapLocalization(Resource.ResourceManager); var tenant = CoreContext.TenantManager.GetCurrentTenant(); var op = new LdapSaveSyncOperation(ldapSettings, tenant, LdapOperationType.SyncTest, ldapLocalization); return QueueTask(op); } /// /// Save LDAP settings and start import/sync users and groups process by LDAP /// /// /// Save LDAP settings /// /// LDAPSupportSettings serialized string /// Flag permits errors of checking certificates [Create("ldap")] public LdapOperationStatus SaveLdapSettings(string settings, bool acceptCertificate) { CheckLdapPermissions(); var operations = LDAPTasks.GetTasks() .Where(t => t.GetProperty(LdapOperation.OWNER) == TenantProvider.CurrentTenantID).ToList(); if (operations.Any(o => o.Status <= DistributedTaskStatus.Running)) { return GetStartProcessError(); } var ldapSettings = JsonConvert.DeserializeObject(settings); ldapSettings.AcceptCertificate = acceptCertificate; if (!ldapSettings.EnableLdapAuthentication) { SetLdapCronSettings(null); } //ToDo ldapSettings.AccessRights.Clear(); var ldapLocalization = new LdapLocalization(Resource.ResourceManager); var tenant = CoreContext.TenantManager.GetCurrentTenant(); var op = new LdapSaveSyncOperation(ldapSettings, tenant, LdapOperationType.Save, ldapLocalization, CurrentUser.ToString()); return QueueTask(op); } /// /// Starts the process of collecting preliminary changes on the portal according to the LDAP settings /// /// /// Save LDAP settings /// [Create("ldap/save/test")] public LdapOperationStatus TestLdapSave(string settings, bool acceptCertificate) { CheckLdapPermissions(); var operations = LDAPTasks.GetTasks() .Where(t => t.GetProperty(LdapOperation.OWNER) == TenantProvider.CurrentTenantID) .ToList(); var hasStarted = operations.Any(o => { var opType = o.GetProperty(LdapOperation.OPERATION_TYPE); return o.Status <= DistributedTaskStatus.Running && (opType == LdapOperationType.SyncTest || opType == LdapOperationType.SaveTest); }); if (hasStarted) { return GetLdapOperationStatus(); } if (operations.Any(o => o.Status <= DistributedTaskStatus.Running)) { return GetStartProcessError(); } var ldapSettings = JsonConvert.DeserializeObject(settings); ldapSettings.AcceptCertificate = acceptCertificate; var ldapLocalization = new LdapLocalization(Resource.ResourceManager); var tenant = CoreContext.TenantManager.GetCurrentTenant(); var op = new LdapSaveSyncOperation(ldapSettings, tenant, LdapOperationType.SaveTest, ldapLocalization, CurrentUser.ToString()); return QueueTask(op); } /// /// Returns LDAP sync process status /// /// /// Get LDAP sync process status /// /// LDAPSupportSettingsResult object [Read("ldap/status")] public LdapOperationStatus GetLdapOperationStatus() { CheckLdapPermissions(); return ToLdapOperationStatus(); } /// /// Returns LDAP default settings /// /// /// Get LDAP default settings /// /// LDAPSupportSettings object [Read("ldap/default")] public LdapSettings GetDefaultLdapSettings() { CheckLdapPermissions(); return new LdapSettings().GetDefault() as LdapSettings; } private static LdapOperationStatus ToLdapOperationStatus() { var operations = LDAPTasks.GetTasks().ToList(); foreach (var o in operations) { if (!string.IsNullOrEmpty(o.InstanseId) && Process.GetProcesses().Any(p => p.Id == int.Parse(o.InstanseId))) continue; o.SetProperty(LdapOperation.PROGRESS, 100); LDAPTasks.RemoveTask(o.Id); } var operation = operations .FirstOrDefault(t => t.GetProperty(LdapOperation.OWNER) == TenantProvider.CurrentTenantID); if (operation == null) { return null; } if (DistributedTaskStatus.Running < operation.Status) { operation.SetProperty(LdapOperation.PROGRESS, 100); LDAPTasks.RemoveTask(operation.Id); } var certificateConfirmRequest = operation.GetProperty(LdapOperation.CERT_REQUEST); var result = new LdapOperationStatus { Id = operation.Id, Completed = operation.GetProperty(LdapOperation.FINISHED), Percents = operation.GetProperty(LdapOperation.PROGRESS), Status = operation.GetProperty(LdapOperation.RESULT), Error = operation.GetProperty(LdapOperation.ERROR), CertificateConfirmRequest = certificateConfirmRequest, Source = operation.GetProperty(LdapOperation.SOURCE), OperationType = Enum.GetName(typeof(LdapOperationType), (LdapOperationType)Convert.ToInt32(operation.GetProperty(LdapOperation.OPERATION_TYPE))), Warning = operation.GetProperty(LdapOperation.WARNING) }; if (!(string.IsNullOrEmpty(result.Warning))) { operation.SetProperty(LdapOperation.WARNING, ""); // "mark" as read } return result; } private static void CheckLdapPermissions() { SecurityContext.DemandPermissions(SecutiryConstants.EditPortalSettings); if (!SetupInfo.IsVisibleSettings(ManagementType.LdapSettings.ToString()) || (CoreContext.Configuration.Standalone && !CoreContext.TenantManager.GetTenantQuota(TenantProvider.CurrentTenantID).Ldap)) { throw new BillingException(Resource.ErrorNotAllowedOption, "Ldap"); } } private LdapOperationStatus QueueTask(LdapOperation op) { LDAPTasks.QueueTask(op.RunJob, op.GetDistributedTask()); return ToLdapOperationStatus(); } private LdapOperationStatus GetStartProcessError() { var result = new LdapOperationStatus { Id = null, Completed = true, Percents = 0, Status = "", Error = Resource.LdapSettingsTooManyOperations, CertificateConfirmRequest = null, Source = "" }; return result; } } }