Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds support for editing the robots.txt on a website #4165

Merged
merged 3 commits into from
Oct 10, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information

namespace Dnn.PersonaBar.ConfigConsole.Components
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Xml;

using DotNetNuke.Application;
using DotNetNuke.Common;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Instrumentation;

public class ConfigConsoleController
{
private static readonly ILog Logger = LoggerSource.Instance.GetLogger(typeof(ConfigConsoleController));
private const string CONFIG_EXT = ".config";
private const string ROBOTS_EXT = "robots.txt"; // in multi-portal instances, there may be multiple robots.txt files (e.g., site1.com.robots.txt, site2.com.robots.txt, etc.)

public IEnumerable<string> GetConfigFilesList()
{
var files = Directory.GetFiles(Globals.ApplicationMapPath, "*.config");
var files = Directory
mitchelsellers marked this conversation as resolved.
Show resolved Hide resolved
.EnumerateFiles(Globals.ApplicationMapPath)
.Where(file => file.ToLower().EndsWith(CONFIG_EXT, StringComparison.InvariantCultureIgnoreCase) || file.ToLower().EndsWith(ROBOTS_EXT, StringComparison.InvariantCultureIgnoreCase))
.ToList();
IEnumerable<string> fileList = (from file in files select Path.GetFileName(file));
return fileList;
}
Expand All @@ -26,25 +36,41 @@ public string GetConfigFile(string configFile)
{
this.ValidateFilePath(configFile);

var configDoc = Config.Load(configFile);
using (var txtWriter = new StringWriter())
if (configFile.EndsWith(CONFIG_EXT, StringComparison.InvariantCultureIgnoreCase))
{
using (var writer = new XmlTextWriter(txtWriter))
var configDoc = Config.Load(configFile);
using (var txtWriter = new StringWriter())
{
writer.Formatting = Formatting.Indented;
configDoc.WriteTo(writer);
using (var writer = new XmlTextWriter(txtWriter))
{
writer.Formatting = Formatting.Indented;
configDoc.WriteTo(writer);
}

return txtWriter.ToString();
}
return txtWriter.ToString();
}
else
{
var doc = LoadNonConfig(configFile);
WillStrohl marked this conversation as resolved.
Show resolved Hide resolved
return doc;
}
}

public void UpdateConfigFile(string fileName, string fileContent)
{
this.ValidateFilePath(fileName);

var configDoc = new XmlDocument { XmlResolver = null };
configDoc.LoadXml(fileContent);
Config.Save(configDoc, fileName);
if (fileName.EndsWith(CONFIG_EXT, StringComparison.InvariantCultureIgnoreCase))
{
var configDoc = new XmlDocument {XmlResolver = null};
configDoc.LoadXml(fileContent);
Config.Save(configDoc, fileName);
}
else
{
SaveNonConfig(fileContent, fileName);
}
}

public void MergeConfigFile(string fileContent)
Expand Down Expand Up @@ -77,6 +103,69 @@ private void ValidateFilePath(string filePath)
{
throw new ArgumentException("Invalid File Path");
}
}

private static string LoadNonConfig(string filename)
{
// open the config file
var doc = File.ReadAllText(string.Concat(Globals.ApplicationMapPath, "\\", filename));

return doc;
}

private static string SaveNonConfig(string document, string filename)
{
var retMsg = string.Empty;
try
{
var strFilePath = string.Concat(Globals.ApplicationMapPath, "\\", filename);
WillStrohl marked this conversation as resolved.
Show resolved Hide resolved
var objFileAttributes = FileAttributes.Normal;
WillStrohl marked this conversation as resolved.
Show resolved Hide resolved
if (File.Exists(strFilePath))
{
// save current file attributes
objFileAttributes = File.GetAttributes(strFilePath);

// change to normal ( in case it is flagged as read-only )
File.SetAttributes(strFilePath, FileAttributes.Normal);
}

// Attempt a few times in case the file was locked; occurs during modules' installation due
// to application restarts where IIS can overlap old application shutdown and new one start.
const int maxRetires = 4;
mitchelsellers marked this conversation as resolved.
Show resolved Hide resolved
const double miltiplier = 2.5;
for (var retry = maxRetires; retry >= 0; retry--)
{
try
{
// save the config file
File.WriteAllText(strFilePath, document);

break;
}
catch (IOException exc)
{
if (retry == 0)
{
Logger.Error(exc);
retMsg = exc.Message;
}

// try incremental delay; maybe the file lock is released by then
Thread.Sleep((int)(miltiplier * (maxRetires - retry + 1)) * 1000);
}
}

// reset file attributes
File.SetAttributes(strFilePath, objFileAttributes);
}
catch (Exception exc)
{
// the file permissions may not be set properly
Logger.Error(exc);
retMsg = exc.Message;
}

return retMsg;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ define(['jquery',
configEditor.setValue('');
} else {
requestService('get', 'GetConfigFile', { 'fileName': curConfigName }, function (data) {
if (curConfigName.endsWith("config")) {
configEditor.setOption("mode", "xml");
}
else if (curConfigName.endsWith("txt")) {
configEditor.setOption("mode", "text");
}
configEditor.setValue(data.FileContent);
}, function () {
// failed
Expand Down