Changeset 395
- Timestamp:
- Aug 8, 2022, 8:09:28 PM (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
binary-improvements2/WebServer/src/WebPermissions.cs
r391 r395 6 6 namespace Webserver { 7 7 public class WebPermissions { 8 private const string permissionsFile = "webpermissions.xml";8 private const string permissionsFileName = "webpermissions.xml"; 9 9 private static WebPermissions instance; 10 11 private readonly FileSystemWatcher fileWatcher; 12 10 13 private readonly WebModulePermission defaultModulePermission = new WebModulePermission ("", 0); 11 14 12 private readonly Dictionary<string, WebModulePermission> knownModules = 15 /// <summary> 16 /// Registered user/pass admin tokens 17 /// </summary> 18 private readonly Dictionary<string, AdminToken> adminTokens = new CaseInsensitiveStringDictionary<AdminToken> (); 19 20 /// <summary> 21 /// Contains all registered modules and their default permission 22 /// </summary> 23 private readonly Dictionary<string, WebModulePermission> knownModules = new CaseInsensitiveStringDictionary<WebModulePermission> (); 24 25 /// <summary> 26 /// Manually defined module permissions 27 /// </summary> 28 private readonly Dictionary<string, WebModulePermission> modulePermissions = 13 29 new CaseInsensitiveStringDictionary<WebModulePermission> (); 14 30 15 private readonly Dictionary<string, AdminToken> admintokens = new CaseInsensitiveStringDictionary<AdminToken> (); 16 private FileSystemWatcher fileWatcher; 17 18 private readonly Dictionary<string, WebModulePermission> modules = new CaseInsensitiveStringDictionary<WebModulePermission> (); 31 /// <summary> 32 /// Public list of all modules, both those with custom permissions as well as those that do not with their default permission 33 /// </summary> 34 private readonly List<WebModulePermission> allModulesList = new List<WebModulePermission> (); 35 36 private readonly ReadOnlyCollection<WebModulePermission> allModulesListRo; 37 38 private static string SettingsFilePath => GamePrefs.GetString (EnumUtils.Parse<EnumGamePrefs> ("SaveGameFolder")); 39 private static string SettingsFileName => permissionsFileName; 40 private static string SettingsFullPath => SettingsFilePath + "/" + SettingsFileName; 19 41 20 42 private WebPermissions () { 21 allModulesList = new List<WebModulePermission> ();22 43 allModulesListRo = new ReadOnlyCollection<WebModulePermission> (allModulesList); 23 Directory.CreateDirectory (GetFilePath ()); 24 InitFileWatcher (); 44 45 Directory.CreateDirectory (SettingsFilePath); 46 25 47 Load (); 48 49 fileWatcher = new FileSystemWatcher (SettingsFilePath, SettingsFileName); 50 fileWatcher.Changed += OnFileChanged; 51 fileWatcher.Created += OnFileChanged; 52 fileWatcher.Deleted += OnFileChanged; 53 fileWatcher.EnableRaisingEvents = true; 26 54 } 27 55 … … 34 62 } 35 63 64 65 #region Admin Tokens 66 67 public void AddAdmin (string _name, string _token, int _permissionLevel, bool _save = true) { 68 AdminToken c = new AdminToken (_name, _token, _permissionLevel); 69 lock (this) { 70 adminTokens [_name] = c; 71 if (_save) { 72 Save (); 73 } 74 } 75 } 76 77 public void RemoveAdmin (string _name, bool _save = true) { 78 lock (this) { 79 adminTokens.Remove (_name); 80 if (_save) { 81 Save (); 82 } 83 } 84 } 85 86 public bool IsAdmin (string _name) { 87 return adminTokens.ContainsKey (_name); 88 } 89 90 public AdminToken[] GetAdmins () { 91 AdminToken[] result = new AdminToken[adminTokens.Count]; 92 adminTokens.CopyValuesTo (result); 93 return result; 94 } 95 96 public AdminToken GetWebAdmin (string _name, string _token) { 97 if (IsAdmin (_name) && adminTokens [_name].token == _token) { 98 return adminTokens [_name]; 99 } 100 101 return null; 102 } 103 104 #endregion 105 106 107 #region Modules 108 109 public void AddModulePermission (string _module, int _permissionLevel, bool _save = true) { 110 WebModulePermission p = new WebModulePermission (_module, _permissionLevel); 111 lock (this) { 112 allModulesList.Clear (); 113 modulePermissions [_module] = p; 114 if (_save) { 115 Save (); 116 } 117 } 118 } 119 120 public void AddKnownModule (string _module, int _defaultPermission) { 121 if (string.IsNullOrEmpty (_module)) { 122 return; 123 } 124 125 WebModulePermission p = new WebModulePermission (_module, _defaultPermission); 126 127 lock (this) { 128 allModulesList.Clear (); 129 knownModules [_module] = p; 130 } 131 } 132 133 public bool IsKnownModule (string _module) { 134 if (string.IsNullOrEmpty (_module)) { 135 return false; 136 } 137 138 lock (this) { 139 return knownModules.ContainsKey (_module); 140 } 141 } 142 143 public void RemoveModulePermission (string _module, bool _save = true) { 144 lock (this) { 145 allModulesList.Clear (); 146 modulePermissions.Remove (_module); 147 if (_save) { 148 Save (); 149 } 150 } 151 } 152 153 public IList<WebModulePermission> GetModules () { 154 if (allModulesList.Count != 0) { 155 return allModulesListRo; 156 } 157 158 foreach ((string moduleName, WebModulePermission moduleDefaultPerm) in knownModules) { 159 allModulesList.Add (modulePermissions.TryGetValue (moduleName, out WebModulePermission modulePermission) 160 ? modulePermission 161 : moduleDefaultPerm); 162 } 163 164 return allModulesListRo; 165 } 166 36 167 public bool ModuleAllowedWithLevel (string _module, int _level) { 37 168 WebModulePermission permInfo = GetModulePermission (_module); … … 39 170 } 40 171 41 public AdminToken GetWebAdmin (string _name, string _token) {42 if (IsAdmin (_name) && admintokens [_name].token == _token) {43 return admintokens [_name];44 }45 46 return null;47 }48 49 172 public WebModulePermission GetModulePermission (string _module) { 50 if (module s.TryGetValue (_module, out WebModulePermission result)) {173 if (modulePermissions.TryGetValue (_module, out WebModulePermission result)) { 51 174 return result; 52 175 } … … 55 178 } 56 179 57 58 // Admins 59 public void AddAdmin (string _name, string _token, int _permissionLevel, bool _save = true) { 60 AdminToken c = new AdminToken (_name, _token, _permissionLevel); 61 lock (this) { 62 admintokens [_name] = c; 63 if (_save) { 64 Save (); 65 } 66 } 67 } 68 69 public void RemoveAdmin (string _name, bool _save = true) { 70 lock (this) { 71 admintokens.Remove (_name); 72 if (_save) { 73 Save (); 74 } 75 } 76 } 77 78 public bool IsAdmin (string _name) { 79 return admintokens.ContainsKey (_name); 80 } 81 82 public AdminToken[] GetAdmins () { 83 AdminToken[] result = new AdminToken[admintokens.Count]; 84 admintokens.CopyValuesTo (result); 85 return result; 86 } 87 88 89 // Commands 90 public void AddModulePermission (string _module, int _permissionLevel, bool _save = true) { 91 WebModulePermission p = new WebModulePermission (_module, _permissionLevel); 92 lock (this) { 93 allModulesList.Clear (); 94 modules [_module] = p; 95 if (_save) { 96 Save (); 97 } 98 } 99 } 100 101 public void AddKnownModule (string _module, int _defaultPermission) { 102 if (string.IsNullOrEmpty (_module)) { 103 return; 104 } 105 106 WebModulePermission p = new WebModulePermission (_module, _defaultPermission); 107 108 lock (this) { 109 allModulesList.Clear (); 110 knownModules [_module] = p; 111 } 112 } 113 114 public bool IsKnownModule (string _module) { 115 if (string.IsNullOrEmpty (_module)) { 116 return false; 117 } 118 119 lock (this) { 120 return knownModules.ContainsKey (_module); 121 } 122 123 } 124 125 public void RemoveModulePermission (string _module, bool _save = true) { 126 lock (this) { 127 allModulesList.Clear (); 128 modules.Remove (_module); 129 if (_save) { 130 Save (); 131 } 132 } 133 } 134 135 private readonly List<WebModulePermission> allModulesList; 136 private readonly ReadOnlyCollection<WebModulePermission> allModulesListRo; 137 138 public IList<WebModulePermission> GetModules () { 139 if (allModulesList.Count != 0) { 140 return allModulesListRo; 141 } 142 143 foreach ((string moduleName, WebModulePermission moduleDefaultPerm) in knownModules) { 144 allModulesList.Add (modules.TryGetValue (moduleName, out WebModulePermission modulePermission) 145 ? modulePermission 146 : moduleDefaultPerm); 147 } 148 149 return allModulesListRo; 150 } 151 152 153 //IO Tasks 154 155 private void InitFileWatcher () { 156 fileWatcher = new FileSystemWatcher (GetFilePath (), GetFileName ()); 157 fileWatcher.Changed += OnFileChanged; 158 fileWatcher.Created += OnFileChanged; 159 fileWatcher.Deleted += OnFileChanged; 160 fileWatcher.EnableRaisingEvents = true; 161 } 180 #endregion 181 182 183 #region IO Tasks 162 184 163 185 private void OnFileChanged (object _source, FileSystemEventArgs _e) { 164 Log.Out ("Reloading " + permissionsFile);186 Log.Out ("Reloading " + SettingsFileName); 165 187 Load (); 166 188 } 167 189 168 private static string GetFilePath () {169 return GamePrefs.GetString (EnumUtils.Parse<EnumGamePrefs> ("SaveGameFolder"));170 }171 172 private static string GetFileName () {173 return permissionsFile;174 }175 176 private static string GetFullPath () {177 return GetFilePath () + "/" + GetFileName ();178 }179 180 190 public void Load () { 181 admin tokens.Clear ();182 module s.Clear ();183 184 if (!File.Exists ( GetFullPath ())) {185 Log.Out ($"Permissions file '{ GetFileName ()}' not found, creating.");191 adminTokens.Clear (); 192 modulePermissions.Clear (); 193 194 if (!File.Exists (SettingsFullPath)) { 195 Log.Out ($"Permissions file '{SettingsFileName}' not found, creating."); 186 196 Save (); 187 197 return; 188 198 } 189 199 190 Log.Out ($"Loading permissions file at '{ GetFullPath ()}'");200 Log.Out ($"Loading permissions file at '{SettingsFullPath}'"); 191 201 192 202 XmlDocument xmlDoc = new XmlDocument (); 193 203 194 204 try { 195 xmlDoc.Load ( GetFullPath ());205 xmlDoc.Load (SettingsFullPath); 196 206 } catch (XmlException e) { 197 207 Log.Error ("Failed loading permissions file: " + e.Message); … … 205 215 return; 206 216 } 217 218 foreach (XmlNode childNode in adminToolsNode.ChildNodes) { 219 switch (childNode.Name) { 220 case "admintokens": 221 ParseAdminTokens (childNode); 222 break; 223 case "permissions": 224 ParseModulePermissions (childNode); 225 break; 226 } 227 } 228 229 Log.Out ("Loading permissions file done."); 230 } 231 232 private void ParseAdminTokens (XmlNode _baseNode) { 233 foreach (XmlNode subChild in _baseNode.ChildNodes) { 234 if (subChild.NodeType == XmlNodeType.Comment) { 235 continue; 236 } 237 238 if (subChild.NodeType != XmlNodeType.Element) { 239 Log.Warning ($"Unexpected XML node found in 'admintokens' section: {subChild.OuterXml}"); 240 continue; 241 } 242 243 XmlElement lineItem = (XmlElement)subChild; 244 245 if (!lineItem.HasAttribute ("name")) { 246 Log.Warning ($"Ignoring admintoken-entry because of missing 'name' attribute: {subChild.OuterXml}"); 247 continue; 248 } 249 250 if (!lineItem.HasAttribute ("token")) { 251 Log.Warning ($"Ignoring admintoken-entry because of missing 'token' attribute: {subChild.OuterXml}"); 252 continue; 253 } 254 255 if (!lineItem.HasAttribute ("permission_level")) { 256 Log.Warning ($"Ignoring admintoken-entry because of missing 'permission_level' attribute: {subChild.OuterXml}"); 257 continue; 258 } 259 260 string name = lineItem.GetAttribute ("name"); 261 string token = lineItem.GetAttribute ("token"); 262 if (!int.TryParse (lineItem.GetAttribute ("permission_level"), out int permissionLevel)) { 263 Log.Warning ( 264 $"Ignoring admintoken-entry because of invalid (non-numeric) value for 'permission_level' attribute: {subChild.OuterXml}"); 265 continue; 266 } 267 268 AddAdmin (name, token, permissionLevel, false); 269 } 270 } 271 272 private void ParseModulePermissions (XmlNode _baseNode) { 273 foreach (XmlNode subChild in _baseNode.ChildNodes) { 274 if (subChild.NodeType == XmlNodeType.Comment) { 275 continue; 276 } 277 278 if (subChild.NodeType != XmlNodeType.Element) { 279 Log.Warning ($"Unexpected XML node found in 'permissions' section: {subChild.OuterXml}"); 280 continue; 281 } 282 283 XmlElement lineItem = (XmlElement)subChild; 284 285 if (!lineItem.HasAttribute ("module")) { 286 Log.Warning ($"Ignoring permission-entry because of missing 'module' attribute: {subChild.OuterXml}"); 287 continue; 288 } 289 290 if (!lineItem.HasAttribute ("permission_level")) { 291 Log.Warning ($"Ignoring permission-entry because of missing 'permission_level' attribute: {subChild.OuterXml}"); 292 continue; 293 } 294 295 if (!int.TryParse (lineItem.GetAttribute ("permission_level"), out int permissionLevel)) { 296 Log.Warning ( 297 $"Ignoring permission-entry because of invalid (non-numeric) value for 'permission_level' attribute: {subChild.OuterXml}"); 298 continue; 299 } 300 301 AddModulePermission (lineItem.GetAttribute ("module"), permissionLevel, false); 302 } 303 } 304 305 public void Save () { 306 XmlDocument xml = new XmlDocument (); 307 308 xml.CreateXmlDeclaration (); 309 310 // xml.AddXmlComment (XmlHeader); 311 312 XmlElement root = xml.AddXmlElement ("webpermissions"); 313 314 // AdminTokens 315 XmlElement adminTokensElem = root.AddXmlElement ("admintokens"); 316 adminTokensElem.AddXmlComment (" <token name=\"adminuser1\" token=\"supersecrettoken\" permission_level=\"0\" /> "); 317 foreach ((string _, AdminToken adminToken) in adminTokens) { 318 adminTokensElem.AddXmlElement ("token") 319 .SetAttrib ("name", adminToken.name) 320 .SetAttrib ("token", adminToken.token) 321 .SetAttrib ("permission_level", adminToken.permissionLevel.ToString ()); 322 } 323 324 XmlElement modulePermissionsElem = root.AddXmlElement ("permissions"); 325 foreach ((string _, WebModulePermission webModulePermission) in modulePermissions) { 326 modulePermissionsElem.AddXmlElement ("permission") 327 .SetAttrib ("module", webModulePermission.module) 328 .SetAttrib ("permission_level", webModulePermission.permissionLevel.ToString ()); 329 } 207 330 208 foreach (XmlNode childNode in adminToolsNode.ChildNodes) { 209 if (childNode.Name == "admintokens") { 210 foreach (XmlNode subChild in childNode.ChildNodes) { 211 if (subChild.NodeType == XmlNodeType.Comment) { 212 continue; 213 } 214 215 if (subChild.NodeType != XmlNodeType.Element) { 216 Log.Warning ("Unexpected XML node found in 'admintokens' section: " + subChild.OuterXml); 217 continue; 218 } 219 220 XmlElement lineItem = (XmlElement) subChild; 221 222 if (!lineItem.HasAttribute ("name")) { 223 Log.Warning ("Ignoring admintoken-entry because of missing 'name' attribute: " + 224 subChild.OuterXml); 225 continue; 226 } 227 228 if (!lineItem.HasAttribute ("token")) { 229 Log.Warning ("Ignoring admintoken-entry because of missing 'token' attribute: " + 230 subChild.OuterXml); 231 continue; 232 } 233 234 if (!lineItem.HasAttribute ("permission_level")) { 235 Log.Warning ("Ignoring admintoken-entry because of missing 'permission_level' attribute: " + 236 subChild.OuterXml); 237 continue; 238 } 239 240 string name = lineItem.GetAttribute ("name"); 241 string token = lineItem.GetAttribute ("token"); 242 if (!int.TryParse (lineItem.GetAttribute ("permission_level"), out int 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 if (!int.TryParse (lineItem.GetAttribute ("permission_level"), out int permissionLevel)) { 279 Log.Warning ( 280 "Ignoring permission-entry because of invalid (non-numeric) value for 'permission_level' attribute: " + 281 subChild.OuterXml); 282 continue; 283 } 284 285 AddModulePermission (lineItem.GetAttribute ("module"), permissionLevel, false); 286 } 287 } 288 } 289 290 Log.Out ("Loading permissions file done."); 291 } 292 293 public void Save () { 331 294 332 fileWatcher.EnableRaisingEvents = false; 295 296 using (StreamWriter sw = new StreamWriter (GetFullPath ())) { 297 sw.WriteLine ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); 298 sw.WriteLine ("<webpermissions>"); 299 sw.WriteLine (); 300 sw.WriteLine (" <admintokens>"); 301 sw.WriteLine ( 302 " <!-- <token name=\"adminuser1\" token=\"supersecrettoken\" permission_level=\"0\" /> -->"); 303 foreach ((var _, AdminToken adminToken) in admintokens) { 304 sw.WriteLine ($" <token name=\"{adminToken.name}\" token=\"{adminToken.token}\" permission_level=\"{adminToken.permissionLevel}\" />"); 305 } 306 307 sw.WriteLine (" </admintokens>"); 308 sw.WriteLine (); 309 sw.WriteLine (" <permissions>"); 310 foreach ((var _, WebModulePermission webModulePermission) in modules) { 311 sw.WriteLine ($" <permission module=\"{webModulePermission.module}\" permission_level=\"{webModulePermission.permissionLevel}\" />"); 312 } 313 314 sw.WriteLine (" <!-- <permission module=\"web.map\" permission_level=\"1000\" /> -->"); 315 sw.WriteLine (); 316 sw.WriteLine (" <!-- <permission module=\"webapi.getlog\" permission_level=\"0\" /> -->"); 317 sw.WriteLine ( 318 " <!-- <permission module=\"webapi.executeconsolecommand\" permission_level=\"0\" /> -->"); 319 sw.WriteLine (); 320 sw.WriteLine (" <!-- <permission module=\"webapi.getstats\" permission_level=\"1000\" /> -->"); 321 sw.WriteLine (" <!-- <permission module=\"webapi.getplayersonline\" permission_level=\"1000\" /> -->"); 322 sw.WriteLine (); 323 sw.WriteLine ( 324 " <!-- <permission module=\"webapi.getplayerslocation\" permission_level=\"1000\" /> -->"); 325 sw.WriteLine (" <!-- <permission module=\"webapi.viewallplayers\" permission_level=\"1\" /> -->"); 326 sw.WriteLine (); 327 sw.WriteLine (" <!-- <permission module=\"webapi.getlandclaims\" permission_level=\"1000\" /> -->"); 328 sw.WriteLine (" <!-- <permission module=\"webapi.viewallclaims\" permission_level=\"1\" /> -->"); 329 sw.WriteLine (); 330 sw.WriteLine (" <!-- <permission module=\"webapi.getplayerinventory\" permission_level=\"1\" /> -->"); 331 sw.WriteLine (); 332 sw.WriteLine (" <!-- <permission module=\"webapi.gethostilelocation\" permission_level=\"1\" /> -->"); 333 sw.WriteLine (" <!-- <permission module=\"webapi.getanimalslocation\" permission_level=\"1\" /> -->"); 334 sw.WriteLine (" </permissions>"); 335 sw.WriteLine (); 336 sw.WriteLine ("</webpermissions>"); 337 338 sw.Flush (); 339 sw.Close (); 340 } 341 333 xml.Save (SettingsFullPath); 342 334 fileWatcher.EnableRaisingEvents = true; 343 335 } 336 337 #endregion 344 338 345 339
Note:
See TracChangeset
for help on using the changeset viewer.