summaryrefslogtreecommitdiffstats
path: root/src/main.lib/Services/Legacy/LegacySettingsService.cs
blob: 45d711b3dc1c11061b85eab2f0725a6207c90261 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
using PKISharp.WACS.Configuration;
using PKISharp.WACS.Services;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;
using static PKISharp.WACS.Services.SettingsService;

namespace PKISharp.WACS.Host.Services.Legacy
{
    public class LegacySettingsService : ISettingsService
    {
        private readonly ILogService _log;

        public ClientSettings Client { get; private set; } = new ClientSettings();
        public UiSettings UI { get; private set; } = new UiSettings();
        public AcmeSettings Acme { get; private set; } = new AcmeSettings();
        public ProxySettings Proxy { get; private set; } = new ProxySettings();
        public CacheSettings Cache { get; private set; } = new CacheSettings();
        public ScheduledTaskSettings ScheduledTask { get; private set; } = new ScheduledTaskSettings();
        public NotificationSettings Notification { get; private set; } = new NotificationSettings();
        public SecuritySettings Security { get; private set; } = new SecuritySettings();
        public ScriptSettings Script { get; private set; } = new ScriptSettings();
        public TargetSettings Target { get; private set; } = new TargetSettings();
        public ValidationSettings Validation { get; private set; } = new ValidationSettings();
        public OrderSettings Order { get; private set; } = new OrderSettings();
        public CsrSettings Csr { get; private set; } = new CsrSettings();
        public StoreSettings Store { get; private set; } = new StoreSettings();
        public InstallationSettings Installation { get; private set; } = new InstallationSettings();
        public string ExePath { get; private set; }

        public List<string> ClientNames { get; private set; }
        public Uri BaseUri { get; private set; } 

        public LegacySettingsService(ILogService log, MainArguments main, ISettingsService settings)
        {
            _log = log;
            UI = settings.UI;
            Acme = settings.Acme;
            ScheduledTask = settings.ScheduledTask;
            Notification = settings.Notification;
            Security = settings.Security;
            Script = settings.Script;
            // Copy so that the "ConfigurationPath" setting is not modified
            // from outside anymore
            Client = new ClientSettings()
            {
                ClientName = settings.Client.ClientName,
                ConfigurationPath = settings.Client.ConfigurationPath,
                LogPath = settings.Client.LogPath
            };
            Validation = settings.Validation;
            Store = settings.Store;
            ExePath = settings.ExePath;

            ClientNames = new List<string>() { 
                settings.Client.ClientName,
                "win-acme", 
                "letsencrypt-win-simple"
            };

            // Read legacy configuration file
            var installDir = new FileInfo(ExePath).DirectoryName;
            var legacyConfig = new FileInfo(Path.Combine(installDir, "settings.config"));
            var userRoot = default(string);
            if (legacyConfig.Exists)
            {
                var configXml = new XmlDocument();
                configXml.LoadXml(File.ReadAllText(legacyConfig.FullName));

                // Get custom configuration path:
                var configPath = configXml.SelectSingleNode("//setting[@name='ConfigurationPath']/value")?.InnerText ?? "";
                if (!string.IsNullOrEmpty(configPath))
                {
                    userRoot = configPath;
                }

                // Get custom client name: 
                var customName = configXml.SelectSingleNode("//setting[@name='ClientName']/value")?.InnerText ?? "";
                if (!string.IsNullOrEmpty(customName))
                {
                    ClientNames.Insert(0, customName);
                }
            }
            BaseUri = new Uri(main.BaseUri);
            CreateConfigPath(main, userRoot);
        }

        private void CreateConfigPath(MainArguments options, string? userRoot)
        {
            var configRoot = "";
            if (!string.IsNullOrEmpty(userRoot))
            {
                configRoot = userRoot;

                // Path configured in settings always wins, but
                // check for possible sub directories with client name
                // to keep bug-compatible with older releases that
                // created a subfolder inside of the users chosen config path
                foreach (var clientName in ClientNames)
                {
                    var configRootWithClient = Path.Combine(userRoot, clientName);
                    if (Directory.Exists(configRootWithClient))
                    {
                        configRoot = configRootWithClient;
                        Client.ClientName = clientName;
                        break;
                    }
                }
            }
            else
            {
                // When using a system folder, we have to create a sub folder
                // with the most preferred client name, but we should check first
                // if there is an older folder with an less preferred (older)
                // client name.
                var roots = new List<string>
                {
                    Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
                    Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)
                };
                foreach (var root in roots)
                {
                    // Stop looking if the directory has been found
                    if (!Directory.Exists(configRoot))
                    {
                        foreach (var clientName in ClientNames.ToArray().Reverse())
                        {
                            Client.ClientName = clientName;
                            configRoot = Path.Combine(root, clientName);
                            if (Directory.Exists(configRoot))
                            {
                                // Stop looking if the directory has been found
                                break;
                            }
                        }
                    }
                }
            }

            Client.ConfigurationPath = Path.Combine(configRoot, CleanFileName(options.BaseUri));
            _log.Debug("Legacy config folder: {_configPath}", Client.ConfigurationPath);
        }

        public string CleanFileName(string fileName) => Path.GetInvalidFileNameChars().Aggregate(fileName, (current, c) => current.Replace(c.ToString(), string.Empty));
    }
}