From e1305126ee61ee8741cb48e40e8998ef632904b2 Mon Sep 17 00:00:00 2001 From: Kim Date: Thu, 30 Mar 2023 09:27:18 +0200 Subject: [PATCH] Shifted sanitizing outputs into Controller.cs Now Hiding Parents --- csharp/App/Backend/Controllers/Controller.cs | 49 ++++++++++--------- .../App/Backend/DataTypes/Methods/Session.cs | 1 + .../App/Backend/DataTypes/Methods/TreeNode.cs | 28 ++++++++++- csharp/App/Backend/DataTypes/Methods/User.cs | 43 ++++++++++++---- csharp/App/Backend/Database/Read.cs | 14 +----- 5 files changed, 88 insertions(+), 47 deletions(-) diff --git a/csharp/App/Backend/Controllers/Controller.cs b/csharp/App/Backend/Controllers/Controller.cs index db58b240b..f4dd895d3 100644 --- a/csharp/App/Backend/Controllers/Controller.cs +++ b/csharp/App/Backend/Controllers/Controller.cs @@ -27,7 +27,7 @@ public class Controller : ControllerBase return Unauthorized(); } - var session = new Session(user); + var session = new Session(user.HidePassword().HideParentIfUserHasNoAccessToParent(user)); //TODO The Frontend should check for the MustResetPassword Flag @@ -60,8 +60,7 @@ public class Controller : ControllerBase if (user is null || !session.HasAccessTo(user)) return Unauthorized(); - user.Password = ""; - return user; + return user.HidePassword().HideParentIfUserHasNoAccessToParent(session); } @@ -77,7 +76,7 @@ public class Controller : ControllerBase if (installation is null || !user.HasAccessTo(installation)) return Unauthorized(); - return installation; + return installation.HideParentIfUserHasNoAccessToParent(user); } [HttpGet(nameof(GetUsersWithDirectAccessToInstallation))] @@ -95,6 +94,7 @@ public class Controller : ControllerBase return installation .UsersWithDirectAccess() .Where(u => u.IsDescendantOf(user)) + .Select(u => u.HidePassword()) .ToList(); } @@ -133,6 +133,7 @@ public class Controller : ControllerBase return folder .UsersWithDirectAccess() .Where(u => u.IsDescendantOf(user)) + .Select(u => u.HidePassword()) .ToList(); } @@ -167,8 +168,8 @@ public class Controller : ControllerBase if (folder is null || !user.HasAccessTo(folder)) return Unauthorized(); - - return folder; + + return folder.HideParentIfUserHasNoAccessToParent(user); } [HttpGet(nameof(GetAllDirectChildUsers))] @@ -178,7 +179,7 @@ public class Controller : ControllerBase if (user == null) return Unauthorized(); - return user.ChildUsers().ToList(); + return user.ChildUsers().Select(u => u.HidePassword()).ToList(); } [HttpGet(nameof(GetAllChildUsers))] @@ -188,7 +189,7 @@ public class Controller : ControllerBase if (user == null) return Unauthorized(); - return user.DescendantUsers().ToList(); + return user.DescendantUsers().Select(u => u.HidePassword()).ToList(); } @@ -199,10 +200,8 @@ public class Controller : ControllerBase if (user is null) return Unauthorized(); - - user.AccessibleInstallations().ForEach(i => i.FillOrderNumbers()); - - return user.AccessibleInstallations().ToList(); + + return user.AccessibleInstallations().Select(i => i.FillOrderNumbers().HideParentIfUserHasNoAccessToParent(user)).ToList(); } @@ -215,7 +214,7 @@ public class Controller : ControllerBase if (user is null) return Unauthorized(); - return new(user.AccessibleFolders()); + return new(user.AccessibleFolders().HideParentIfUserHasNoAccessToParent(user)); } @@ -228,9 +227,11 @@ public class Controller : ControllerBase return Unauthorized(); var foldersAndInstallations = user - .AccessibleFoldersAndInstallations() - .OfType(); // Important! JSON serializer must see Objects otherwise - // it will just serialize the members of TreeNode %&@#!!! + .AccessibleFoldersAndInstallations() + .Do(o => o.FillOrderNumbers()) + .Select(o => o.HideParentIfUserHasNoAccessToParent(user)) + .OfType(); // Important! JSON serializer must see Objects otherwise + // it will just serialize the members of TreeNode %&@#!!! return new (foldersAndInstallations); } @@ -240,17 +241,19 @@ public class Controller : ControllerBase public ActionResult CreateUser(User newUser, Token authToken) { return Db.GetSession(authToken).Create(newUser) - ? newUser + ? newUser.HidePassword() : Unauthorized() ; } [HttpPost(nameof(CreateInstallation))] public async Task> CreateInstallation(Installation installation, Token authToken) { - if (!await Db.GetSession(authToken).Create(installation)) + var session = Db.GetSession(authToken); + + if (! await session.Create(installation)) return Unauthorized(); - return installation; + return installation.HideParentIfUserHasNoAccessToParent(session!.User); } [HttpPost(nameof(CreateFolder))] @@ -261,7 +264,7 @@ public class Controller : ControllerBase if (!session.Create(folder)) return Unauthorized(); - return folder; + return folder.HideParentIfUserHasNoAccessToParent(session!.User); } [HttpPost(nameof(GrantUserAccessToFolder))] @@ -332,7 +335,7 @@ public class Controller : ControllerBase if (!session.Update(updatedUser)) return Unauthorized(); - return updatedUser; + return updatedUser.HidePassword(); } @@ -356,7 +359,7 @@ public class Controller : ControllerBase if (!session.Update(installation)) return Unauthorized(); - return installation; + return installation.HideParentIfUserHasNoAccessToParent(session.User); } @@ -368,7 +371,7 @@ public class Controller : ControllerBase if (!session.Update(folder)) return Unauthorized(); - return folder; + return folder.HideParentIfUserHasNoAccessToParent(session.User); } [HttpPut(nameof(MoveInstallation))] diff --git a/csharp/App/Backend/DataTypes/Methods/Session.cs b/csharp/App/Backend/DataTypes/Methods/Session.cs index e29e9e769..d3e599ebc 100644 --- a/csharp/App/Backend/DataTypes/Methods/Session.cs +++ b/csharp/App/Backend/DataTypes/Methods/Session.cs @@ -175,6 +175,7 @@ public static class SessionMethods && sessionUser.HasAccessTo(editedUser) && editedUser .WithParentOf(originalUser) // prevent moving + .WithNameOf(originalUser) .WithPasswordOf(originalUser) .Apply(Db.Update); } diff --git a/csharp/App/Backend/DataTypes/Methods/TreeNode.cs b/csharp/App/Backend/DataTypes/Methods/TreeNode.cs index 3c8a530bc..cb88be7d8 100644 --- a/csharp/App/Backend/DataTypes/Methods/TreeNode.cs +++ b/csharp/App/Backend/DataTypes/Methods/TreeNode.cs @@ -1,3 +1,5 @@ +using InnovEnergy.App.Backend.Database; + namespace InnovEnergy.App.Backend.DataTypes.Methods; public static class TreeNodeMethods @@ -9,16 +11,38 @@ public static class TreeNodeMethods return treeNode; } + public static T WithNameOf(this T treeNode, T other) where T: TreeNode + { + treeNode.Name = other.Name; + return treeNode; + } + public static T WithParent(this T treeNode, T other) where T: TreeNode { treeNode.ParentId = other.Id; return treeNode; } - public static T HideParent(this T treeNode) where T: TreeNode + public static T HideParentIfUserHasNoAccessToParent(this T node, User? accessingUser) { - treeNode.ParentId = 0; + if (accessingUser is not null && node is TreeNode treeNode && !accessingUser.HasAccessToParentOf(treeNode)) + { + treeNode.ParentId = 0; + } + + return node; + } + + public static TreeNode FillOrderNumbers(this TreeNode treeNode) + { + if (treeNode is Installation installation) + { + installation.FillOrderNumbers(); + } + return treeNode; } + + } \ No newline at end of file diff --git a/csharp/App/Backend/DataTypes/Methods/User.cs b/csharp/App/Backend/DataTypes/Methods/User.cs index c56b2c62b..f20ae6b87 100644 --- a/csharp/App/Backend/DataTypes/Methods/User.cs +++ b/csharp/App/Backend/DataTypes/Methods/User.cs @@ -35,7 +35,7 @@ public static class UserMethods { var folders = user.AccessibleFolders() as IEnumerable; - user.AccessibleInstallations().ForEach(i => i.FillOrderNumbers()); + // user.AccessibleInstallations().ForEach(i => i.FillOrderNumbers()); var installations = user.AccessibleInstallations(); return folders.Concat(installations); @@ -49,7 +49,7 @@ public static class UserMethods .Select(r => r.InstallationId) .Select(i => Db.GetInstallationById(i)) .NotNull() - .Do(i => i.HideParent()); // hide inaccessible parents from calling user + .Do(i => i.HideParentIfUserHasNoAccessToParent(user)); // hide inaccessible parents from calling user } public static IEnumerable DirectlyAccessibleFolders(this User user) @@ -60,7 +60,7 @@ public static class UserMethods .Select(r => r.FolderId) .Select(i => Db.GetFolderById(i)) .NotNull() - .Do(f => f.HideParent()); // hide inaccessible parents from calling user; + .Do(f => f.HideParentIfUserHasNoAccessToParent(user)); // hide inaccessible parents from calling user; } public static IEnumerable ChildUsers(this User parent) @@ -93,7 +93,7 @@ public static class UserMethods public static Boolean VerifyPassword(this User user, String password) { - return Db.GetUserWithPasswordByName(user.Name)?.Password == user.SaltAndHashPassword(password); + return Db.GetUserByName(user.Name)?.Password == user.SaltAndHashPassword(password); } @@ -166,8 +166,32 @@ public static class UserMethods .Ancestors() .Contains(user); } + + public static Boolean HasAccessTo(this User user, TreeNode? other) + { + return other?.Type switch + { + "installation" => user.HasAccessTo((Installation)other), + "user" => user.HasAccessTo((User)other), + "folder" => user.HasAccessTo((Folder)other), + _ => false + }; + } - public static String Salt(this User user) + public static Boolean HasAccessToParentOf(this User user, TreeNode? other) + { + return other?.Type switch + { + "installation" => user.HasAccessTo(Db.GetInstallationById(other.ParentId)), + "user" => user.HasAccessTo(Db.GetUserById(other.ParentId)), + "folder" => user.HasAccessTo(Db.GetFolderById(other.ParentId)), + _ => false + }; + } + + + + private static String Salt(this User user) { // + id => salt unique per user // + InnovEnergy => globally unique @@ -192,11 +216,10 @@ public static class UserMethods return deletedUser; } - public static User? HidePassword(this User? user) - { - if(user is not null) - user.Password = ""; - + public static User HidePassword(this User user) + { + user.Password = ""; return user; } + } \ No newline at end of file diff --git a/csharp/App/Backend/Database/Read.cs b/csharp/App/Backend/Database/Read.cs index 91e94bf7a..5d4341d0b 100644 --- a/csharp/App/Backend/Database/Read.cs +++ b/csharp/App/Backend/Database/Read.cs @@ -1,7 +1,6 @@ using InnovEnergy.App.Backend.DataTypes; using InnovEnergy.App.Backend.DataTypes.Methods; using InnovEnergy.App.Backend.Relations; -using InnovEnergy.Lib.Utils; namespace InnovEnergy.App.Backend.Database; @@ -18,25 +17,16 @@ public static partial class Db public static Installation? GetInstallationById(Int64? id) { return Installations - .FirstOrDefault(i => i.Id == id) - .FillOrderNumbers(); + .FirstOrDefault(i => i.Id == id); } public static User? GetUserById(Int64? id) { return Users - .FirstOrDefault(u => u.Id == id) - .HidePassword(); + .FirstOrDefault(u => u.Id == id); } public static User? GetUserByName(String userName) - { - return Users - .FirstOrDefault(u => u.Name == userName) - .HidePassword(); - } - - public static User? GetUserWithPasswordByName(String userName) { return Users .FirstOrDefault(u => u.Name == userName);