static ApplicationPartManagerExtensions() { //we use the default file provider, since the DI isn't initialized yet _fileProvider = CommonHelper.DefaultFileProvider; _baseAppLibraries = new List <string>(); //get all libraries from /bin/{version}/ directory _baseAppLibraries.AddRange(_fileProvider.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll") .Select(fileName => _fileProvider.GetFileName(fileName))); //get all libraries from base site directory if (!AppDomain.CurrentDomain.BaseDirectory.Equals(Environment.CurrentDirectory, StringComparison.InvariantCultureIgnoreCase)) { _baseAppLibraries.AddRange(_fileProvider.GetFiles(Environment.CurrentDirectory, "*.dll") .Select(fileName => _fileProvider.GetFileName(fileName))); } //get all libraries from refs directory var refsPathName = _fileProvider.Combine(Environment.CurrentDirectory, NopPluginDefaults.RefsPathName); if (_fileProvider.DirectoryExists(refsPathName)) { _baseAppLibraries.AddRange(_fileProvider.GetFiles(refsPathName, "*.dll") .Select(fileName => _fileProvider.GetFileName(fileName))); } }
/// <summary> /// Makes sure matching assemblies in the supplied folder are loaded in the app domain. /// </summary> /// <param name="directoryPath"> /// The physical path to a directory containing dlls to load in the app domain. /// </param> protected virtual void LoadMatchingAssemblies(string directoryPath) { var loadedAssemblyNames = new List <string>(); foreach (var a in GetAssemblies()) { loadedAssemblyNames.Add(a.FullName); } if (!_fileProvider.DirectoryExists(directoryPath)) { return; } foreach (var dllPath in _fileProvider.GetFiles(directoryPath, "*.dll")) { try { var an = AssemblyName.GetAssemblyName(dllPath); if (Matches(an.FullName) && !loadedAssemblyNames.Contains(an.FullName)) { App.Load(an); } } catch (BadImageFormatException ex) { Trace.TraceError(ex.ToString()); } } }
/// <summary> /// Gets all backup files /// </summary> /// <returns>Backup file collection</returns> public virtual IList <string> GetAllBackupFiles() { var path = GetBackupDirectoryPath(); if (!_fileProvider.DirectoryExists(path)) { throw new NopException("Backup directory not exists"); } return(_fileProvider.GetFiles(path, $"*.{NopCommonDefaults.DbBackupFileExtension}") .OrderByDescending(p => _fileProvider.GetLastWriteTime(p)).ToList()); }
/// <summary> /// Gets all backup files /// </summary> /// <returns>Backup file collection</returns> public virtual IList <string> GetAllBackupFiles() { var path = GetBackupDirectoryPath(); if (!_fileProvider.DirectoryExists(path)) { throw new IOException("Backup directory not exists"); } return(_fileProvider.GetFiles(path, "*.bak") .OrderByDescending(p => _fileProvider.GetLastWriteTime(p)).ToList()); }
/// <summary> /// Delete plugins /// </summary> public virtual void DeletePlugins() { //get all uninstalled plugins (delete plugin only previously uninstalled) var pluginDescriptors = _pluginsInfo.PluginDescriptors.Where(descriptor => !descriptor.Installed).ToList(); //filter plugins need to delete pluginDescriptors = pluginDescriptors .Where(descriptor => _pluginsInfo.PluginNamesToDelete.Contains(descriptor.SystemName)).ToList(); if (!pluginDescriptors.Any()) { return; } //do not inject services via constructor because it'll cause circular references var localizationService = EngineContext.Current.Resolve <ILocalizationService>(); var customerActivityService = EngineContext.Current.Resolve <ICustomerActivityService>(); //delete plugins foreach (var descriptor in pluginDescriptors) { try { //try to delete a plugin directory from disk storage var pluginDirectory = _fileProvider.GetDirectoryName(descriptor.OriginalAssemblyFile); if (_fileProvider.DirectoryExists(pluginDirectory)) { _fileProvider.DeleteDirectory(pluginDirectory); } //remove plugin system name from the appropriate list _pluginsInfo.PluginNamesToDelete.Remove(descriptor.SystemName); //activity log customerActivityService.InsertActivity("DeletePlugin", string.Format(localizationService.GetResource("ActivityLog.DeletePlugin"), descriptor.SystemName)); } catch (Exception exception) { //log error var message = string.Format(localizationService.GetResource("Admin.Plugins.Errors.NotDeleted"), descriptor.SystemName); _logger.Error(message, exception); } } //save changes _pluginsInfo.Save(); }
/// <summary> /// Delete plugin directory from disk storage /// </summary> /// <param name="pluginDescriptor">Plugin descriptor</param> /// <returns>True if plugin directory is deleted, false if not</returns> public static bool DeletePlugin(PluginDescriptor pluginDescriptor) { //no plugin descriptor set if (pluginDescriptor == null) { return(false); } //check whether plugin is installed if (pluginDescriptor.Installed) { return(false); } var directoryName = _fileProvider.GetDirectoryName(pluginDescriptor.OriginalAssemblyFile); if (_fileProvider.DirectoryExists(directoryName)) { _fileProvider.DeleteDirectory(directoryName); } return(true); }
/// <summary> /// Get all available directories as a directory tree /// </summary> /// <param name="type">Type of the file</param> /// <returns>A task that represents the completion of the operation</returns> protected virtual async Task GetDirectoriesAsync(string type) { var rootDirectoryPath = GetFullPath(GetVirtualPath(null)); if (!_fileProvider.DirectoryExists(rootDirectoryPath)) { throw new Exception("Invalid files root directory. Check your configuration."); } var allDirectories = GetDirectories(rootDirectoryPath); allDirectories.Insert(0, rootDirectoryPath); var localPath = GetFullPath(null); await HttpContext.Response.WriteAsync("["); for (var i = 0; i < allDirectories.Count; i++) { var directoryPath = (string)allDirectories[i]; await HttpContext.Response.WriteAsync($"{{\"p\":\"/{directoryPath.Replace(localPath, string.Empty).Replace("\\", "/").TrimStart('/')}\",\"f\":\"{GetFiles(directoryPath, type).Count}\",\"d\":\"{_fileProvider.GetDirectories(directoryPath).Length}\"}}"); if (i < allDirectories.Count - 1) { await HttpContext.Response.WriteAsync(","); } } await HttpContext.Response.WriteAsync("]"); }
/// <summary> /// Upload single item from the archive into the physical directory /// </summary> /// <param name="archivePath">Path to the archive</param> /// <returns>Uploaded item descriptor</returns> protected virtual IDescriptor UploadSingleItem(string archivePath) { //get path to the plugins directory var pluginsDirectory = _fileProvider.MapPath(NopPluginDefaults.Path); //get path to the themes directory var themesDirectory = string.Empty; if (!string.IsNullOrEmpty(NopPluginDefaults.ThemesPath)) { themesDirectory = _fileProvider.MapPath(NopPluginDefaults.ThemesPath); } IDescriptor descriptor = null; string uploadedItemDirectoryName; using (var archive = ZipFile.OpenRead(archivePath)) { //the archive should contain only one root directory (the plugin one or the theme one) var rootDirectories = archive.Entries.Select(p => p.FullName.Split('/')[0]).Distinct().ToList(); if (rootDirectories.Count != 1) { throw new Exception("The archive should contain only one root plugin or theme directory. " + "For example, Payments.PayPalDirect or DefaultClean. " + $"To upload multiple items, the archive should have the '{NopPluginDefaults.UploadedItemsFileName}' file in the root"); } //get directory name (remove the ending /) uploadedItemDirectoryName = rootDirectories.First(); //try to get descriptor of the uploaded item foreach (var entry in archive.Entries) { //whether it's a plugin descriptor var isPluginDescriptor = entry.FullName .Equals($"{uploadedItemDirectoryName}/{NopPluginDefaults.DescriptionFileName}", StringComparison.InvariantCultureIgnoreCase); //or whether it's a theme descriptor var isThemeDescriptor = entry.FullName .Equals($"{uploadedItemDirectoryName}/{NopPluginDefaults.ThemeDescriptionFileName}", StringComparison.InvariantCultureIgnoreCase); if (!isPluginDescriptor && !isThemeDescriptor) { continue; } using var unzippedEntryStream = entry.Open(); using var reader = new StreamReader(unzippedEntryStream); //whether a plugin is upload if (isPluginDescriptor) { descriptor = PluginDescriptor.GetPluginDescriptorFromText(reader.ReadToEnd()); //ensure that the plugin current version is supported if (!((PluginDescriptor)descriptor).SupportedVersions.Contains(NopVersion.CURRENT_VERSION)) { throw new Exception($"This plugin doesn't support the current version - {NopVersion.CURRENT_VERSION}"); } } //or whether a theme is upload if (isThemeDescriptor) { descriptor = _themeProvider.GetThemeDescriptorFromText(reader.ReadToEnd()); } break; } } if (descriptor == null) { throw new Exception("No descriptor file is found. It should be in the root of the archive."); } if (string.IsNullOrEmpty(uploadedItemDirectoryName)) { throw new Exception($"Cannot get the {(descriptor is PluginDescriptor ? "plugin" : "theme")} directory name"); } //get path to upload var directoryPath = descriptor is PluginDescriptor ? pluginsDirectory : themesDirectory; var pathToUpload = _fileProvider.Combine(directoryPath, uploadedItemDirectoryName); //ensure it's a new directory (e.g. some old files are not required when re-uploading a plugin) //furthermore, zip extract functionality cannot override existing files //but there could deletion issues (related to file locking, etc). In such cases the directory should be deleted manually if (_fileProvider.DirectoryExists(pathToUpload)) { _fileProvider.DeleteDirectory(pathToUpload); } //unzip archive ZipFile.ExtractToDirectory(archivePath, directoryPath); return(descriptor); }
private static bool CheckPermissionsInWindows(INopFileProvider fileProvider, string path, bool checkRead, bool checkWrite, bool checkModify, bool checkDelete) { var permissionsAreGranted = true; try { if (!(fileProvider.FileExists(path) || fileProvider.DirectoryExists(path))) { return(true); } var current = WindowsIdentity.GetCurrent(); var readIsDeny = false; var writeIsDeny = false; var modifyIsDeny = false; var deleteIsDeny = false; var readIsAllow = false; var writeIsAllow = false; var modifyIsAllow = false; var deleteIsAllow = false; var rules = fileProvider.GetAccessControl(path).GetAccessRules(true, true, typeof(SecurityIdentifier)) .Cast <FileSystemAccessRule>() .ToList(); foreach (var rule in rules.Where(rule => current.User?.Equals(rule.IdentityReference) ?? false)) { CheckAccessRule(rule, ref deleteIsDeny, ref modifyIsDeny, ref readIsDeny, ref writeIsDeny, ref deleteIsAllow, ref modifyIsAllow, ref readIsAllow, ref writeIsAllow); } if (current.Groups != null) { foreach (var reference in current.Groups) { foreach (var rule in rules.Where(rule => reference.Equals(rule.IdentityReference))) { CheckAccessRule(rule, ref deleteIsDeny, ref modifyIsDeny, ref readIsDeny, ref writeIsDeny, ref deleteIsAllow, ref modifyIsAllow, ref readIsAllow, ref writeIsAllow); } } } deleteIsAllow = !deleteIsDeny && deleteIsAllow; modifyIsAllow = !modifyIsDeny && modifyIsAllow; readIsAllow = !readIsDeny && readIsAllow; writeIsAllow = !writeIsDeny && writeIsAllow; if (checkRead) { permissionsAreGranted = readIsAllow; } if (checkWrite) { permissionsAreGranted = permissionsAreGranted && writeIsAllow; } if (checkModify) { permissionsAreGranted = permissionsAreGranted && modifyIsAllow; } if (checkDelete) { permissionsAreGranted = permissionsAreGranted && deleteIsAllow; } } catch (IOException) { return(false); } catch { return(true); } return(permissionsAreGranted); }