diff --git a/csharp/App/Backend/Controllers/Controller.cs b/csharp/App/Backend/Controllers/Controller.cs index db58b240b..269a5e736 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.FillOrderNumbers().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.FillOrderNumbers().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.FillOrderNumbers().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); diff --git a/csharp/App/OpenVpnCertificatesServer/AccToken.cs b/csharp/App/OpenVpnCertificatesServer/AccToken.cs index a12ee720c..bd8ea28e6 100644 --- a/csharp/App/OpenVpnCertificatesServer/AccToken.cs +++ b/csharp/App/OpenVpnCertificatesServer/AccToken.cs @@ -1,17 +1,17 @@ using System.Diagnostics.CodeAnalysis; -#pragma warning disable CS8618 namespace InnovEnergy.App.OpenVpnCertificatesServer; -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] + [SuppressMessage("ReSharper", "InconsistentNaming")] +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] internal class AccToken { - public String token { get; init; } - public String bearer { get; init; } + public String bearer { get; init; } = ""; public UInt64 idUser { get; init; } - public String verification_mode { get; init; } - public String idAccessToken { get; init; } - public Boolean verification_sent { get; init; } - public Boolean success { get; init; } + public String verification_mode { get; init; } = "password"; + public Boolean verification_sent { get; init; } = false; + public Boolean success { get; init; } = false; + public String token { get; init; } = ""; + public String idAccessToken { get; init; } = ""; } \ No newline at end of file diff --git a/csharp/App/OpenVpnCertificatesServer/OpenVpnCertificatesServer.csproj b/csharp/App/OpenVpnCertificatesServer/OpenVpnCertificatesServer.csproj index 96abef819..de611520f 100644 --- a/csharp/App/OpenVpnCertificatesServer/OpenVpnCertificatesServer.csproj +++ b/csharp/App/OpenVpnCertificatesServer/OpenVpnCertificatesServer.csproj @@ -19,4 +19,8 @@ + + false + + diff --git a/csharp/App/OpenVpnCertificatesServer/Program.cs b/csharp/App/OpenVpnCertificatesServer/Program.cs index a3e035fbe..581699d5f 100644 --- a/csharp/App/OpenVpnCertificatesServer/Program.cs +++ b/csharp/App/OpenVpnCertificatesServer/Program.cs @@ -36,10 +36,11 @@ public static class Program private const String CertsDir = VpnDir + "/certs"; private const String Endpoint = "http://localhost:4000/"; - private static AccToken ReadAccessToken() + private static AccToken? ReadAccessToken() { var content = File.ReadAllText("./token.json"); - return JsonSerializer.Deserialize(content)!; + + return JsonSerializer.Deserialize(content); } @@ -146,9 +147,14 @@ public static class Program //var installationName = await LookupInstallationNameByUniqueId(ccdName); var token = ReadAccessToken(); - using var vrm = VrmAccount.Token(token.idUser, token.token); - var installations = await vrm.GetInstallations(); + var vrm = VrmAccount.Token(token.idUser, token.token); + + + var installations = await vrm.GetInstallations(); + + + var installationName = installations .Where(i => i.UniqueId == uniqueId) .Select(i => i.Name) @@ -163,7 +169,9 @@ public static class Program { Console.WriteLine($"looking up {ccdName} on VRM"); var token = ReadAccessToken(); + using var vrm = VrmAccount.Token(token.idUser, token.token); + var installations = await vrm.GetInstallations(); foreach (var installation in installations) @@ -176,6 +184,7 @@ public static class Program return (ccdName, installation.Name); } + Console.WriteLine($"not found"); return null; }