using System; using System.Collections.Generic; using System.IO; using System.Text; using ScrewTurn.Wiki.AclEngine; namespace ScrewTurn.Wiki { /// /// Implements a file-based ACL Storer. /// public class AclStorer : AclStorerBase { private string file; /// /// Initializes a new instance of the class. /// /// The instance of the ACL Manager to handle. /// The storage file. public AclStorer(IAclManager aclManager, string file) : base(aclManager) { if(file == null) throw new ArgumentNullException("file"); if(file.Length == 0) throw new ArgumentException("File cannot be empty", "file"); this.file = file; } /// /// Loads data from storage. /// /// The loaded ACL entries. protected override AclEntry[] LoadDataInternal() { lock(this) { if(!File.Exists(file)) { File.Create(file).Close(); return new AclEntry[0]; } // Format // Resource|Action|Subject|(1|0) string[] lines = File.ReadAllLines(file); AclEntry[] result = new AclEntry[lines.Length]; string[] fields; for(int i = 0; i < lines.Length; i++) { fields = lines[i].Split('|'); result[i] = new AclEntry(fields[0], fields[1], fields[2], (fields[3] == "1" ? Value.Grant : Value.Deny)); } return result; } } /// /// Dumps a into a string. /// /// The entry to dump. /// The resulting string. private static string DumpAclEntry(AclEntry entry) { return string.Format("{0}|{1}|{2}|{3}", entry.Resource, entry.Action, entry.Subject, (entry.Value == Value.Grant ? "1" : "0")); } /// /// Deletes some entries. /// /// The entries to delete. protected override void DeleteEntries(AclEntry[] entries) { lock(this) { AclEntry[] allEntries = LoadDataInternal(); StringBuilder sb = new StringBuilder(10000); foreach(AclEntry originalEntry in allEntries) { // If the current entry is not contained in the entries array, then preserve it bool delete = false; foreach(AclEntry entryToDelete in entries) { if(AclEntry.Equals(originalEntry, entryToDelete)) { delete = true; break; } } if(!delete) { sb.Append(DumpAclEntry(originalEntry)); sb.Append("\r\n"); } } File.WriteAllText(file, sb.ToString()); } } /// /// Stores some entries. /// /// The entries to store. protected override void StoreEntries(AclEntry[] entries) { lock(this) { StringBuilder sb = new StringBuilder(100); foreach(AclEntry entry in entries) { sb.Append(DumpAclEntry(entry)); sb.Append("\r\n"); } File.AppendAllText(file, sb.ToString()); } } } }