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

Last change on this file since 245 was 244, checked in by alloc, 9 years ago

Fixes intermediate state

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