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

Last change on this file since 365 was 351, checked in by alloc, 6 years ago

Fixed game version compatibility of GamePrefs
Code style cleanup (mostly argument names)

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