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

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

More cleanup, allocation improvements

File size: 10.7 KB
RevLine 
[253]1using System.Collections.Generic;
2using System.IO;
3using System.Xml;
4
[325]5namespace AllocsFixes.NetConnections.Servers.Web {
[253]6 public class WebPermissions {
[325]7 private const string PERMISSIONS_FILE = "webpermissions.xml";
8 private static WebPermissions instance;
9 private readonly WebModulePermission defaultModulePermission = new WebModulePermission ("", 0);
[253]10
[325]11 private readonly Dictionary<string, WebModulePermission> knownModules =
12 new Dictionary<string, WebModulePermission> ();
13
[326]14 private readonly Dictionary<string, AdminToken> admintokens = new CaseInsensitiveStringDictionary<AdminToken> ();
[325]15 private FileSystemWatcher fileWatcher;
16
[326]17 private readonly Dictionary<string, WebModulePermission> modules = new CaseInsensitiveStringDictionary<WebModulePermission> ();
[325]18
19 public WebPermissions () {
20 Directory.CreateDirectory (GetFilePath ());
21 InitFileWatcher ();
22 Load ();
23 }
24
[253]25 public static WebPermissions Instance {
26 get {
[325]27 lock (typeof (WebPermissions)) {
[253]28 if (instance == null) {
29 instance = new WebPermissions ();
30 }
[325]31
[253]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 }
[325]46
47 return null;
[253]48 }
49
50 public WebModulePermission GetModulePermission (string _module) {
[326]51 WebModulePermission result;
52 if (modules.TryGetValue (_module, out result)) {
53 return result;
[253]54 }
[325]55
[253]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];
[326]86 admintokens.CopyValuesTo (result);
[253]87 return result;
88 }
89
[325]90
[253]91 // Commands
92 public void AddModulePermission (string _module, int _permissionLevel, bool _save = true) {
[326]93 WebModulePermission p = new WebModulePermission (_module, _permissionLevel);
[253]94 lock (this) {
95 modules [_module] = p;
96 if (_save) {
97 Save ();
98 }
99 }
100 }
101
[279]102 public void AddKnownModule (string _module, int _defaultPermission) {
[326]103 if (string.IsNullOrEmpty (_module)) {
104 return;
105 }
[325]106
[326]107 lock (this) {
108 if (!IsKnownModule (_module)) {
109 knownModules.Add (_module, new WebModulePermission (_module, _defaultPermission));
[253]110 }
[326]111
112 if (_defaultPermission > 0 && !modules.ContainsKey (_module)) {
113 AddModulePermission (_module, _defaultPermission);
114 }
[253]115 }
116 }
117
118 public bool IsKnownModule (string _module) {
[326]119 if (string.IsNullOrEmpty (_module)) {
120 return false;
[253]121 }
[325]122
[326]123 lock (this) {
124 return knownModules.ContainsKey (_module);
125 }
126
[253]127 }
[325]128
[253]129 public void RemoveModulePermission (string _module, bool _save = true) {
130 lock (this) {
[326]131 modules.Remove (_module);
[253]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
[325]151
[253]152 //IO Tasks
153
154 private void InitFileWatcher () {
155 fileWatcher = new FileSystemWatcher (GetFilePath (), GetFileName ());
[325]156 fileWatcher.Changed += OnFileChanged;
157 fileWatcher.Created += OnFileChanged;
158 fileWatcher.Deleted += OnFileChanged;
[253]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 () {
[326]180 admintokens.Clear ();
181 modules.Clear ();
[253]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) {
[326]196 Log.Error ("Failed loading permissions file: " + e.Message);
[253]197 return;
198 }
199
200 XmlNode adminToolsNode = xmlDoc.DocumentElement;
201
[326]202 if (adminToolsNode == null) {
203 Log.Error ("Failed loading permissions file: No DocumentElement found");
204 return;
205 }
206
[253]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 }
[325]213
[253]214 if (subChild.NodeType != XmlNodeType.Element) {
215 Log.Warning ("Unexpected XML node found in 'admintokens' section: " + subChild.OuterXml);
216 continue;
217 }
218
[325]219 XmlElement lineItem = (XmlElement) subChild;
[253]220
221 if (!lineItem.HasAttribute ("name")) {
[325]222 Log.Warning ("Ignoring admintoken-entry because of missing 'name' attribute: " +
223 subChild.OuterXml);
[253]224 continue;
225 }
226
227 if (!lineItem.HasAttribute ("token")) {
[325]228 Log.Warning ("Ignoring admintoken-entry because of missing 'token' attribute: " +
229 subChild.OuterXml);
[253]230 continue;
231 }
232
233 if (!lineItem.HasAttribute ("permission_level")) {
[325]234 Log.Warning ("Ignoring admintoken-entry because of missing 'permission_level' attribute: " +
235 subChild.OuterXml);
[253]236 continue;
237 }
238
239 string name = lineItem.GetAttribute ("name");
240 string token = lineItem.GetAttribute ("token");
[326]241 int permissionLevel;
[253]242 if (!int.TryParse (lineItem.GetAttribute ("permission_level"), out permissionLevel)) {
[325]243 Log.Warning (
244 "Ignoring admintoken-entry because of invalid (non-numeric) value for 'permission_level' attribute: " +
245 subChild.OuterXml);
[253]246 continue;
247 }
248
[325]249 AddAdmin (name, token, permissionLevel, false);
[253]250 }
251 }
252
253 if (childNode.Name == "permissions") {
254 foreach (XmlNode subChild in childNode.ChildNodes) {
255 if (subChild.NodeType == XmlNodeType.Comment) {
256 continue;
257 }
[325]258
[253]259 if (subChild.NodeType != XmlNodeType.Element) {
260 Log.Warning ("Unexpected XML node found in 'permissions' section: " + subChild.OuterXml);
261 continue;
262 }
263
[325]264 XmlElement lineItem = (XmlElement) subChild;
[253]265
266 if (!lineItem.HasAttribute ("module")) {
[325]267 Log.Warning ("Ignoring permission-entry because of missing 'module' attribute: " +
268 subChild.OuterXml);
[253]269 continue;
270 }
[325]271
[253]272 if (!lineItem.HasAttribute ("permission_level")) {
[325]273 Log.Warning ("Ignoring permission-entry because of missing 'permission_level' attribute: " +
274 subChild.OuterXml);
[253]275 continue;
276 }
[325]277
[326]278 int permissionLevel;
[253]279 if (!int.TryParse (lineItem.GetAttribute ("permission_level"), out permissionLevel)) {
[325]280 Log.Warning (
281 "Ignoring permission-entry because of invalid (non-numeric) value for 'permission_level' attribute: " +
282 subChild.OuterXml);
[253]283 continue;
284 }
285
[326]286 AddModulePermission (lineItem.GetAttribute ("module"), permissionLevel, false);
[253]287 }
288 }
289 }
290
291 Log.Out ("Loading permissions file done.");
292 }
293
294 public void Save () {
295 fileWatcher.EnableRaisingEvents = false;
296
[325]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 }
[253]308
[325]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
[253]341 sw.Flush ();
342 sw.Close ();
343 }
344
345 fileWatcher.EnableRaisingEvents = true;
346 }
347
348
349 public class AdminToken {
350 public string name;
[325]351 public int permissionLevel;
[253]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 }
[325]371}
Note: See TracBrowser for help on using the repository browser.