source: binary-improvements/MapRendering/Web/WebPermissions.cs @ 326

Last change on this file since 326 was 326, checked in by alloc, 5 years ago

More cleanup, allocation improvements

File size: 10.7 KB
Line 
1using System.Collections.Generic;
2using System.IO;
3using System.Xml;
4
5namespace AllocsFixes.NetConnections.Servers.Web {
6        public class WebPermissions {
7                private const string PERMISSIONS_FILE = "webpermissions.xml";
8                private static WebPermissions instance;
9                private readonly WebModulePermission defaultModulePermission = new WebModulePermission ("", 0);
10
11                private readonly Dictionary<string, WebModulePermission> knownModules =
12                        new Dictionary<string, WebModulePermission> ();
13
14                private readonly Dictionary<string, AdminToken> admintokens = new CaseInsensitiveStringDictionary<AdminToken> ();
15                private FileSystemWatcher fileWatcher;
16
17                private readonly Dictionary<string, WebModulePermission> modules = new CaseInsensitiveStringDictionary<WebModulePermission> ();
18
19                public WebPermissions () {
20                        Directory.CreateDirectory (GetFilePath ());
21                        InitFileWatcher ();
22                        Load ();
23                }
24
25                public static WebPermissions Instance {
26                        get {
27                                lock (typeof (WebPermissions)) {
28                                        if (instance == null) {
29                                                instance = new WebPermissions ();
30                                        }
31
32                                        return instance;
33                                }
34                        }
35                }
36
37                public bool ModuleAllowedWithLevel (string _module, int _level) {
38                        WebModulePermission permInfo = GetModulePermission (_module);
39                        return permInfo.permissionLevel >= _level;
40                }
41
42                public AdminToken GetWebAdmin (string _name, string _token) {
43                        if (IsAdmin (_name) && admintokens [_name].token == _token) {
44                                return admintokens [_name];
45                        }
46
47                        return null;
48                }
49
50                public WebModulePermission GetModulePermission (string _module) {
51                        WebModulePermission result;
52                        if (modules.TryGetValue (_module, out result)) {
53                                return result;
54                        }
55
56                        return defaultModulePermission;
57                }
58
59
60                // Admins
61                public void AddAdmin (string _name, string _token, int _permissionLevel, bool _save = true) {
62                        AdminToken c = new AdminToken (_name, _token, _permissionLevel);
63                        lock (this) {
64                                admintokens [_name] = c;
65                                if (_save) {
66                                        Save ();
67                                }
68                        }
69                }
70
71                public void RemoveAdmin (string _name, bool _save = true) {
72                        lock (this) {
73                                admintokens.Remove (_name);
74                                if (_save) {
75                                        Save ();
76                                }
77                        }
78                }
79
80                public bool IsAdmin (string _name) {
81                        return admintokens.ContainsKey (_name);
82                }
83
84                public AdminToken[] GetAdmins () {
85                        AdminToken[] result = new AdminToken[admintokens.Count];
86                        admintokens.CopyValuesTo (result);
87                        return result;
88                }
89
90
91                // Commands
92                public void AddModulePermission (string _module, int _permissionLevel, bool _save = true) {
93                        WebModulePermission p = new WebModulePermission (_module, _permissionLevel);
94                        lock (this) {
95                                modules [_module] = p;
96                                if (_save) {
97                                        Save ();
98                                }
99                        }
100                }
101
102                public void AddKnownModule (string _module, int _defaultPermission) {
103                        if (string.IsNullOrEmpty (_module)) {
104                                return;
105                        }
106
107                        lock (this) {
108                                if (!IsKnownModule (_module)) {
109                                        knownModules.Add (_module, new WebModulePermission (_module, _defaultPermission));
110                                }
111
112                                if (_defaultPermission > 0 && !modules.ContainsKey (_module)) {
113                                        AddModulePermission (_module, _defaultPermission);
114                                }
115                        }
116                }
117
118                public bool IsKnownModule (string _module) {
119                        if (string.IsNullOrEmpty (_module)) {
120                                return false;
121                        }
122
123                        lock (this) {
124                                return knownModules.ContainsKey (_module);
125                        }
126
127                }
128
129                public void RemoveModulePermission (string _module, bool _save = true) {
130                        lock (this) {
131                                modules.Remove (_module);
132                                if (_save) {
133                                        Save ();
134                                }
135                        }
136                }
137
138                public List<WebModulePermission> GetModules () {
139                        List<WebModulePermission> result = new List<WebModulePermission> ();
140                        foreach (string module in knownModules.Keys) {
141                                if (modules.ContainsKey (module)) {
142                                        result.Add (modules [module]);
143                                } else {
144                                        result.Add (knownModules [module]);
145                                }
146                        }
147
148                        return result;
149                }
150
151
152                //IO Tasks
153
154                private void InitFileWatcher () {
155                        fileWatcher = new FileSystemWatcher (GetFilePath (), GetFileName ());
156                        fileWatcher.Changed += OnFileChanged;
157                        fileWatcher.Created += OnFileChanged;
158                        fileWatcher.Deleted += OnFileChanged;
159                        fileWatcher.EnableRaisingEvents = true;
160                }
161
162                private void OnFileChanged (object source, FileSystemEventArgs e) {
163                        Log.Out ("Reloading " + PERMISSIONS_FILE);
164                        Load ();
165                }
166
167                private string GetFilePath () {
168                        return GamePrefs.GetString (EnumGamePrefs.SaveGameFolder);
169                }
170
171                private string GetFileName () {
172                        return PERMISSIONS_FILE;
173                }
174
175                private string GetFullPath () {
176                        return GetFilePath () + "/" + GetFileName ();
177                }
178
179                public void Load () {
180                        admintokens.Clear ();
181                        modules.Clear ();
182
183                        if (!Utils.FileExists (GetFullPath ())) {
184                                Log.Out (string.Format ("Permissions file '{0}' not found, creating.", GetFileName ()));
185                                Save ();
186                                return;
187                        }
188
189                        Log.Out (string.Format ("Loading permissions file at '{0}'", GetFullPath ()));
190
191                        XmlDocument xmlDoc = new XmlDocument ();
192
193                        try {
194                                xmlDoc.Load (GetFullPath ());
195                        } catch (XmlException e) {
196                                Log.Error ("Failed loading permissions file: " + e.Message);
197                                return;
198                        }
199
200                        XmlNode adminToolsNode = xmlDoc.DocumentElement;
201
202                        if (adminToolsNode == null) {
203                                Log.Error ("Failed loading permissions file: No DocumentElement found");
204                                return;
205                        }
206                       
207                        foreach (XmlNode childNode in adminToolsNode.ChildNodes) {
208                                if (childNode.Name == "admintokens") {
209                                        foreach (XmlNode subChild in childNode.ChildNodes) {
210                                                if (subChild.NodeType == XmlNodeType.Comment) {
211                                                        continue;
212                                                }
213
214                                                if (subChild.NodeType != XmlNodeType.Element) {
215                                                        Log.Warning ("Unexpected XML node found in 'admintokens' section: " + subChild.OuterXml);
216                                                        continue;
217                                                }
218
219                                                XmlElement lineItem = (XmlElement) subChild;
220
221                                                if (!lineItem.HasAttribute ("name")) {
222                                                        Log.Warning ("Ignoring admintoken-entry because of missing 'name' attribute: " +
223                                                                     subChild.OuterXml);
224                                                        continue;
225                                                }
226
227                                                if (!lineItem.HasAttribute ("token")) {
228                                                        Log.Warning ("Ignoring admintoken-entry because of missing 'token' attribute: " +
229                                                                     subChild.OuterXml);
230                                                        continue;
231                                                }
232
233                                                if (!lineItem.HasAttribute ("permission_level")) {
234                                                        Log.Warning ("Ignoring admintoken-entry because of missing 'permission_level' attribute: " +
235                                                                     subChild.OuterXml);
236                                                        continue;
237                                                }
238
239                                                string name = lineItem.GetAttribute ("name");
240                                                string token = lineItem.GetAttribute ("token");
241                                                int permissionLevel;
242                                                if (!int.TryParse (lineItem.GetAttribute ("permission_level"), out permissionLevel)) {
243                                                        Log.Warning (
244                                                                "Ignoring admintoken-entry because of invalid (non-numeric) value for 'permission_level' attribute: " +
245                                                                subChild.OuterXml);
246                                                        continue;
247                                                }
248
249                                                AddAdmin (name, token, permissionLevel, false);
250                                        }
251                                }
252
253                                if (childNode.Name == "permissions") {
254                                        foreach (XmlNode subChild in childNode.ChildNodes) {
255                                                if (subChild.NodeType == XmlNodeType.Comment) {
256                                                        continue;
257                                                }
258
259                                                if (subChild.NodeType != XmlNodeType.Element) {
260                                                        Log.Warning ("Unexpected XML node found in 'permissions' section: " + subChild.OuterXml);
261                                                        continue;
262                                                }
263
264                                                XmlElement lineItem = (XmlElement) subChild;
265
266                                                if (!lineItem.HasAttribute ("module")) {
267                                                        Log.Warning ("Ignoring permission-entry because of missing 'module' attribute: " +
268                                                                     subChild.OuterXml);
269                                                        continue;
270                                                }
271
272                                                if (!lineItem.HasAttribute ("permission_level")) {
273                                                        Log.Warning ("Ignoring permission-entry because of missing 'permission_level' attribute: " +
274                                                                     subChild.OuterXml);
275                                                        continue;
276                                                }
277
278                                                int permissionLevel;
279                                                if (!int.TryParse (lineItem.GetAttribute ("permission_level"), out permissionLevel)) {
280                                                        Log.Warning (
281                                                                "Ignoring permission-entry because of invalid (non-numeric) value for 'permission_level' attribute: " +
282                                                                subChild.OuterXml);
283                                                        continue;
284                                                }
285
286                                                AddModulePermission (lineItem.GetAttribute ("module"), permissionLevel, false);
287                                        }
288                                }
289                        }
290
291                        Log.Out ("Loading permissions file done.");
292                }
293
294                public void Save () {
295                        fileWatcher.EnableRaisingEvents = false;
296
297                        using (StreamWriter sw = new StreamWriter (GetFullPath ())) {
298                                sw.WriteLine ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
299                                sw.WriteLine ("<webpermissions>");
300                                sw.WriteLine ();
301                                sw.WriteLine (" <admintokens>");
302                                sw.WriteLine (
303                                        "               <!-- <token name=\"adminuser1\" token=\"supersecrettoken\" permission_level=\"0\" /> -->");
304                                foreach (AdminToken at in admintokens.Values) {
305                                        sw.WriteLine ("         <token name=\"{0}\" token=\"{1}\" permission_level=\"{2}\" />", at.name, at.token,
306                                                at.permissionLevel);
307                                }
308
309                                sw.WriteLine (" </admintokens>");
310                                sw.WriteLine ();
311                                sw.WriteLine (" <permissions>");
312                                foreach (WebModulePermission wap in modules.Values) {
313                                        sw.WriteLine ("         <permission module=\"{0}\" permission_level=\"{1}\" />", wap.module,
314                                                wap.permissionLevel);
315                                }
316
317                                sw.WriteLine ("         <!-- <permission module=\"web.map\" permission_level=\"1000\" /> -->");
318                                sw.WriteLine ();
319                                sw.WriteLine ("         <!-- <permission module=\"webapi.getlog\" permission_level=\"0\" /> -->");
320                                sw.WriteLine (
321                                        "               <!-- <permission module=\"webapi.executeconsolecommand\" permission_level=\"0\" /> -->");
322                                sw.WriteLine ();
323                                sw.WriteLine ("         <!-- <permission module=\"webapi.getstats\" permission_level=\"1000\" /> -->");
324                                sw.WriteLine ("         <!-- <permission module=\"webapi.getplayersonline\" permission_level=\"1000\" /> -->");
325                                sw.WriteLine ();
326                                sw.WriteLine (
327                                        "               <!-- <permission module=\"webapi.getplayerslocation\" permission_level=\"1000\" /> -->");
328                                sw.WriteLine ("         <!-- <permission module=\"webapi.viewallplayers\" permission_level=\"1\" /> -->");
329                                sw.WriteLine ();
330                                sw.WriteLine ("         <!-- <permission module=\"webapi.getlandclaims\" permission_level=\"1000\" /> -->");
331                                sw.WriteLine ("         <!-- <permission module=\"webapi.viewallclaims\" permission_level=\"1\" /> -->");
332                                sw.WriteLine ();
333                                sw.WriteLine ("         <!-- <permission module=\"webapi.getplayerinventory\" permission_level=\"1\" /> -->");
334                                sw.WriteLine ();
335                                sw.WriteLine ("         <!-- <permission module=\"webapi.gethostilelocation\" permission_level=\"1\" /> -->");
336                                sw.WriteLine ("         <!-- <permission module=\"webapi.getanimalslocation\" permission_level=\"1\" /> -->");
337                                sw.WriteLine (" </permissions>");
338                                sw.WriteLine ();
339                                sw.WriteLine ("</webpermissions>");
340
341                                sw.Flush ();
342                                sw.Close ();
343                        }
344
345                        fileWatcher.EnableRaisingEvents = true;
346                }
347
348
349                public class AdminToken {
350                        public string name;
351                        public int permissionLevel;
352                        public string token;
353
354                        public AdminToken (string _name, string _token, int _permissionLevel) {
355                                name = _name;
356                                token = _token;
357                                permissionLevel = _permissionLevel;
358                        }
359                }
360
361                public struct WebModulePermission {
362                        public string module;
363                        public int permissionLevel;
364
365                        public WebModulePermission (string _module, int _permissionLevel) {
366                                module = _module;
367                                permissionLevel = _permissionLevel;
368                        }
369                }
370        }
371}
Note: See TracBrowser for help on using the repository browser.