fix handling of relative roots

This commit is contained in:
ig 2023-03-21 11:49:17 +01:00
parent 9098ac81b5
commit 381df5f38d
7 changed files with 100 additions and 89 deletions

View File

@ -68,36 +68,17 @@ public static class FolderMethods
public static Folder? Parent(this Folder folder)
{
return IsAbsoluteRoot(folder)
return IsRoot(folder)
? null
: Db.GetFolderById(folder.ParentId);
}
public static Boolean IsAbsoluteRoot(this Folder folder)
public static Boolean IsRoot(this Folder folder)
{
return folder.ParentId == 0; // root has ParentId 0 by definition
return folder.ParentId <= 0
&& Db.GetFolderById(folder.Id)?.Id == 0; // might have been 0 because it is a relative root
}
public static Boolean IsRelativeRoot(this Folder folder)
{
return folder.ParentId < 0; // TODO
}
public static Boolean WasMoved(this Folder folder)
{
if (folder.IsRelativeRoot())
return false;
var existingFolder = Db.GetFolderById(folder.Id);
return existingFolder is not null
&& existingFolder.ParentId != folder.ParentId;
}
public static Boolean Exists(this Folder folder)
{
return Db.Folders.Any(f => f.Id == folder.Id);
}
}

View File

@ -76,21 +76,20 @@ public static class InstallationMethods
public static Folder? Parent(this Installation installation)
{
return installation.IsRelativeRoot()
? null
: Db.GetFolderById(installation.ParentId);
if (installation.ParentId <= 0) // relative root
{
var i = Db.GetInstallationById(installation.Id);
if (i is null)
return null;
installation = i;
}
return Db.GetFolderById(installation.ParentId);
}
public static Boolean IsRelativeRoot(this Installation i)
{
return i.ParentId < 0;
}
public static Boolean WasMoved(this Installation installation)
{
if (installation.IsRelativeRoot())
return false;
var existingInstallation = Db.GetInstallationById(installation.Id);
return existingInstallation is not null

View File

@ -1,5 +1,6 @@
using InnovEnergy.App.Backend.Database;
using InnovEnergy.App.Backend.Relations;
using InnovEnergy.Lib.Utils;
namespace InnovEnergy.App.Backend.DataTypes.Methods;
@ -13,20 +14,23 @@ public static class SessionMethods
&& folder is not null
&& user.HasWriteAccess
&& user.HasAccessTo(folder.Parent())
&& Db.Create(folder)
&& Db.Create(folder) // TODO: these two in a transaction
&& Db.Create(new FolderAccess { UserId = user.Id, FolderId = folder.Id });
}
public static Boolean Update(this Session? session, Folder? folder)
{
var user = session?.User;
var user = session?.User;
var original = Db.GetFolderById(folder?.Id);
return user is not null
&& folder is not null
&& original is not null
&& user.HasWriteAccess
&& user.HasAccessTo(folder)
&& (folder.IsRelativeRoot() || user.HasAccessTo(folder.Parent()))
&& Db.Update(folder);
&& folder
.WithParentOf(original) // prevent moving
.Apply(Db.Update);
}
public static Boolean Delete(this Session? session, Folder? folder)
@ -49,24 +53,27 @@ public static class SessionMethods
&& installation is not null
&& user.HasWriteAccess
&& user.HasAccessTo(installation.Parent())
&& Db.Create(installation)
&& Db.Create(installation) // TODO: these two in a transaction
&& Db.Create(new InstallationAccess { UserId = user.Id, InstallationId = installation.Id })
&& await installation.CreateBucket()
&& await installation.RenewS3BucketUrl(); // generation of access _after_ generation of
// bucket to prevent "zombie" access-rights.
// bucket to prevent "zombie" access-rights.
}
public static Boolean Update(this Session? session, Installation? installation)
{
var user = session?.User;
var original = Db.GetInstallationById(installation?.Id);
return user is not null
&& installation is not null
&& original is not null
&& user.HasWriteAccess
&& installation.Exists()
&& user.HasAccessTo(installation)
&& (installation.IsRelativeRoot() || user.HasAccessTo(installation.Parent())) // TODO: triple check this
&& Db.Update(installation);
&& installation
.WithParentOf(original) // prevent moving
.Apply(Db.Update);
}
public static Boolean Delete(this Session? session, Installation? installation)
@ -77,37 +84,37 @@ public static class SessionMethods
&& installation is not null
&& user.HasWriteAccess
&& user.HasAccessTo(installation)
// && installation.DeleteBucket().Result // TODO: await?
// && installation.DeleteBucket().Result // TODO
&& Db.Delete(installation);
}
public static Boolean Create(this Session? session, User? newUser)
{
var sessionUser = session?.User;
if (sessionUser is null || newUser is null || !sessionUser.HasWriteAccess)
return false;
newUser.ParentId = sessionUser.Id; // Important!
return Db.Create(newUser);
return sessionUser is not null
&& newUser is not null
&& sessionUser.HasWriteAccess
&& newUser
.WithParent(sessionUser)
.Do(() => newUser.Password = newUser.SaltAndHashPassword(newUser.Password))
.Apply(Db.Create);
}
public static Boolean Update(this Session? session, User? editedUser)
{
var sessionUser = session?.User;
if (editedUser == null || sessionUser == null) return false;
var originalUser = Db.GetUserById(editedUser?.Id);
// TODO: make specific method for changing user account settings like pwd
// Password change is only allowed for oneself
editedUser.Password = editedUser.Id != sessionUser.Id
? sessionUser.Password
: sessionUser.SaltAndHashPassword(editedUser.Password);
return sessionUser.HasWriteAccess
&& sessionUser.HasAccessTo(editedUser)
&& (editedUser.IsRelativeRoot() || sessionUser.HasAccessTo(editedUser.Parent()) || editedUser.Id == sessionUser.Id) // TODO: triple check this
&& Db.Update(editedUser);
return editedUser is not null
&& sessionUser is not null
&& originalUser is not null
&& sessionUser.HasWriteAccess
&& sessionUser.HasAccessTo(editedUser)
&& editedUser
.WithParentOf(originalUser) // prevent moving
.WithPasswordOf(originalUser)
.Apply(Db.Update);
}
public static Boolean Delete(this Session? session, User? userToDelete)
@ -117,7 +124,7 @@ public static class SessionMethods
return sessionUser is not null
&& userToDelete is not null
&& sessionUser.HasWriteAccess
&& sessionUser.HasAccessTo(userToDelete) // TODO: && user.HasAccessTo(installation.Parent()) ???
&& sessionUser.HasAccessTo(userToDelete)
&& Db.Delete(userToDelete);
}
@ -127,8 +134,8 @@ public static class SessionMethods
var sessionUser = session?.User;
return sessionUser is not null
&& user is not null
&& installation is not null
&& user is not null
&& user.IsDescendantOf(sessionUser)
&& sessionUser.HasAccessTo(installation)
&& !user.HasAccessTo(installation)
@ -140,8 +147,8 @@ public static class SessionMethods
var sessionUser = session?.User;
return sessionUser is not null
&& user is not null
&& folder is not null
&& user is not null
&& user.IsDescendantOf(sessionUser)
&& sessionUser.HasAccessTo(folder)
&& !user.HasAccessTo(folder)
@ -153,8 +160,8 @@ public static class SessionMethods
var sessionUser = session?.User;
return sessionUser is not null
&& user is not null
&& installation is not null
&& user is not null
&& user.IsDescendantOf(sessionUser)
&& sessionUser.HasAccessTo(installation)
&& user.HasAccessTo(installation)
@ -166,8 +173,8 @@ public static class SessionMethods
var sessionUser = session?.User;
return sessionUser is not null
&& user is not null
&& folder is not null
&& user is not null
&& user.IsDescendantOf(sessionUser)
&& sessionUser.HasAccessTo(folder)
&& user.HasAccessTo(folder)

View File

@ -0,0 +1,24 @@
namespace InnovEnergy.App.Backend.DataTypes.Methods;
public static class TreeNodeMethods
{
public static T WithParentOf<T>(this T treeNode, T other) where T: TreeNode
{
treeNode.ParentId = other.ParentId;
return treeNode;
}
public static T WithParent<T>(this T treeNode, T other) where T: TreeNode
{
treeNode.ParentId = other.Id;
return treeNode;
}
public static T HideParent<T>(this T treeNode) where T: TreeNode
{
treeNode.ParentId = 0;
return treeNode;
}
}

View File

@ -34,7 +34,7 @@ public static class UserMethods
// to a child folder of a folder he has already access to
// TODO shouldn't we prevent doubling permissions? -K"
// TODO yes we should -ig (still TODO)
// however we should leave the distinct, defensive programming...
// however we should still leave the distinct, defensive programming...
}
public static IEnumerable<TreeNode> AccessibleFoldersAndInstallations(this User user)
@ -51,9 +51,9 @@ public static class UserMethods
.InstallationAccess
.Where(r => r.UserId == user.Id)
.Select(r => r.InstallationId)
.Select(Db.GetInstallationById)
.Select(i => Db.GetInstallationById(i))
.NotNull()
.Do(i => i.ParentId = 0); // hide inaccessible parents from calling user
.Do(i => i.HideParent()); // hide inaccessible parents from calling user
}
public static IEnumerable<Folder> DirectlyAccessibleFolders(this User user)
@ -62,9 +62,9 @@ public static class UserMethods
.FolderAccess
.Where(r => r.UserId == user.Id)
.Select(r => r.FolderId)
.Select(Db.GetFolderById)
.Select(i => Db.GetFolderById(i))
.NotNull()
.Do(i => i.ParentId = 0); // hide inaccessible parents from calling user;
.Do(f => f.HideParent()); // hide inaccessible parents from calling user;
}
public static IEnumerable<User> ChildUsers(this User parent)
@ -112,21 +112,17 @@ public static class UserMethods
public static User? Parent(this User u)
{
return u.IsAbsoluteRoot()
return u.IsRoot()
? null
: Db.GetUserById(u.ParentId);
}
public static Boolean IsAbsoluteRoot(this User u)
{
return u.ParentId == 0;
public static Boolean IsRoot(this User user)
{
return user.ParentId <= 0
&& Db.GetUserById(user.Id)?.Id == 0; // might have been 0 because it is a relative root
}
public static Boolean IsRelativeRoot(this User u)
{
return u.ParentId < 0;
}
public static Boolean HasDirectAccessTo(this User user, Folder folder)
{
return Db
@ -174,12 +170,6 @@ public static class UserMethods
.Contains(user);
}
public static Boolean IsRelativeRoot(this User user, Installation i)
{
// TODO: determine not by id but by accessibility
return i.ParentId < 0;
}
public static String Salt(this User user)
{
// + id => salt unique per user
@ -188,6 +178,14 @@ public static class UserMethods
return $"{user.Id}InnovEnergy";
}
public static User WithPasswordOf(this User user, User other)
{
user.Password = other.Password;
return user;
}
// TODO?
private static Boolean IsValidEmail(String email)

View File

@ -4,6 +4,9 @@ namespace InnovEnergy.App.Backend;
public static class Program
{
// TODO: Trash
public static void Main(String[] args)
{
//Db.CreateFakeRelations();

View File

@ -1,6 +1,5 @@
using InnovEnergy.App.Backend.Database;
using InnovEnergy.App.Backend.DataTypes;
using InnovEnergy.Lib.Utils;
using SQLite;
namespace InnovEnergy.App.Backend.Relations;
@ -13,8 +12,8 @@ public class Session : Relation<String, Int64>
[Indexed] public Int64 UserId { get => Right; init => Right = value;}
[Indexed] public DateTime LastSeen { get; set; }
[Ignore] public Boolean Valid => DateTime.Now - LastSeen < MaxAge
&& !User.Email.IsNullOrEmpty();
[Ignore] public Boolean Valid => DateTime.Now - LastSeen < MaxAge
&& (User) is not null;
[Ignore] public User User => _User ??= Db.GetUserById(UserId)!;