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

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

*Latest optimizations

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