fix handling of relative roots
This commit is contained in:
parent
9098ac81b5
commit
381df5f38d
|
@ -68,36 +68,17 @@ public static class FolderMethods
|
||||||
|
|
||||||
public static Folder? Parent(this Folder folder)
|
public static Folder? Parent(this Folder folder)
|
||||||
{
|
{
|
||||||
return IsAbsoluteRoot(folder)
|
return IsRoot(folder)
|
||||||
? null
|
? null
|
||||||
: Db.GetFolderById(folder.ParentId);
|
: 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,21 +76,20 @@ public static class InstallationMethods
|
||||||
|
|
||||||
public static Folder? Parent(this Installation installation)
|
public static Folder? Parent(this Installation installation)
|
||||||
{
|
{
|
||||||
return installation.IsRelativeRoot()
|
if (installation.ParentId <= 0) // relative root
|
||||||
? null
|
{
|
||||||
: Db.GetFolderById(installation.ParentId);
|
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)
|
public static Boolean WasMoved(this Installation installation)
|
||||||
{
|
{
|
||||||
if (installation.IsRelativeRoot())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
var existingInstallation = Db.GetInstallationById(installation.Id);
|
var existingInstallation = Db.GetInstallationById(installation.Id);
|
||||||
|
|
||||||
return existingInstallation is not null
|
return existingInstallation is not null
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using InnovEnergy.App.Backend.Database;
|
using InnovEnergy.App.Backend.Database;
|
||||||
using InnovEnergy.App.Backend.Relations;
|
using InnovEnergy.App.Backend.Relations;
|
||||||
|
using InnovEnergy.Lib.Utils;
|
||||||
|
|
||||||
namespace InnovEnergy.App.Backend.DataTypes.Methods;
|
namespace InnovEnergy.App.Backend.DataTypes.Methods;
|
||||||
|
|
||||||
|
@ -13,20 +14,23 @@ public static class SessionMethods
|
||||||
&& folder is not null
|
&& folder is not null
|
||||||
&& user.HasWriteAccess
|
&& user.HasWriteAccess
|
||||||
&& user.HasAccessTo(folder.Parent())
|
&& 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 });
|
&& Db.Create(new FolderAccess { UserId = user.Id, FolderId = folder.Id });
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean Update(this Session? session, Folder? folder)
|
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
|
return user is not null
|
||||||
&& folder is not null
|
&& folder is not null
|
||||||
|
&& original is not null
|
||||||
&& user.HasWriteAccess
|
&& user.HasWriteAccess
|
||||||
&& user.HasAccessTo(folder)
|
&& user.HasAccessTo(folder)
|
||||||
&& (folder.IsRelativeRoot() || user.HasAccessTo(folder.Parent()))
|
&& folder
|
||||||
&& Db.Update(folder);
|
.WithParentOf(original) // prevent moving
|
||||||
|
.Apply(Db.Update);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean Delete(this Session? session, Folder? folder)
|
public static Boolean Delete(this Session? session, Folder? folder)
|
||||||
|
@ -49,24 +53,27 @@ public static class SessionMethods
|
||||||
&& installation is not null
|
&& installation is not null
|
||||||
&& user.HasWriteAccess
|
&& user.HasWriteAccess
|
||||||
&& user.HasAccessTo(installation.Parent())
|
&& 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 })
|
&& Db.Create(new InstallationAccess { UserId = user.Id, InstallationId = installation.Id })
|
||||||
&& await installation.CreateBucket()
|
&& await installation.CreateBucket()
|
||||||
&& await installation.RenewS3BucketUrl(); // generation of access _after_ generation of
|
&& 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)
|
public static Boolean Update(this Session? session, Installation? installation)
|
||||||
{
|
{
|
||||||
var user = session?.User;
|
var user = session?.User;
|
||||||
|
|
||||||
|
var original = Db.GetInstallationById(installation?.Id);
|
||||||
|
|
||||||
return user is not null
|
return user is not null
|
||||||
&& installation is not null
|
&& installation is not null
|
||||||
|
&& original is not null
|
||||||
&& user.HasWriteAccess
|
&& user.HasWriteAccess
|
||||||
&& installation.Exists()
|
|
||||||
&& user.HasAccessTo(installation)
|
&& user.HasAccessTo(installation)
|
||||||
&& (installation.IsRelativeRoot() || user.HasAccessTo(installation.Parent())) // TODO: triple check this
|
&& installation
|
||||||
&& Db.Update(installation);
|
.WithParentOf(original) // prevent moving
|
||||||
|
.Apply(Db.Update);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean Delete(this Session? session, Installation? installation)
|
public static Boolean Delete(this Session? session, Installation? installation)
|
||||||
|
@ -77,37 +84,37 @@ public static class SessionMethods
|
||||||
&& installation is not null
|
&& installation is not null
|
||||||
&& user.HasWriteAccess
|
&& user.HasWriteAccess
|
||||||
&& user.HasAccessTo(installation)
|
&& user.HasAccessTo(installation)
|
||||||
// && installation.DeleteBucket().Result // TODO: await?
|
// && installation.DeleteBucket().Result // TODO
|
||||||
&& Db.Delete(installation);
|
&& Db.Delete(installation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean Create(this Session? session, User? newUser)
|
public static Boolean Create(this Session? session, User? newUser)
|
||||||
{
|
{
|
||||||
var sessionUser = session?.User;
|
var sessionUser = session?.User;
|
||||||
|
|
||||||
if (sessionUser is null || newUser is null || !sessionUser.HasWriteAccess)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
newUser.ParentId = sessionUser.Id; // Important!
|
return sessionUser is not null
|
||||||
|
&& newUser is not null
|
||||||
return Db.Create(newUser);
|
&& sessionUser.HasWriteAccess
|
||||||
|
&& newUser
|
||||||
|
.WithParent(sessionUser)
|
||||||
|
.Do(() => newUser.Password = newUser.SaltAndHashPassword(newUser.Password))
|
||||||
|
.Apply(Db.Create);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean Update(this Session? session, User? editedUser)
|
public static Boolean Update(this Session? session, User? editedUser)
|
||||||
{
|
{
|
||||||
var sessionUser = session?.User;
|
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
|
return editedUser is not null
|
||||||
// Password change is only allowed for oneself
|
&& sessionUser is not null
|
||||||
editedUser.Password = editedUser.Id != sessionUser.Id
|
&& originalUser is not null
|
||||||
? sessionUser.Password
|
&& sessionUser.HasWriteAccess
|
||||||
: sessionUser.SaltAndHashPassword(editedUser.Password);
|
&& sessionUser.HasAccessTo(editedUser)
|
||||||
|
&& editedUser
|
||||||
return sessionUser.HasWriteAccess
|
.WithParentOf(originalUser) // prevent moving
|
||||||
&& sessionUser.HasAccessTo(editedUser)
|
.WithPasswordOf(originalUser)
|
||||||
&& (editedUser.IsRelativeRoot() || sessionUser.HasAccessTo(editedUser.Parent()) || editedUser.Id == sessionUser.Id) // TODO: triple check this
|
.Apply(Db.Update);
|
||||||
&& Db.Update(editedUser);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean Delete(this Session? session, User? userToDelete)
|
public static Boolean Delete(this Session? session, User? userToDelete)
|
||||||
|
@ -117,7 +124,7 @@ public static class SessionMethods
|
||||||
return sessionUser is not null
|
return sessionUser is not null
|
||||||
&& userToDelete is not null
|
&& userToDelete is not null
|
||||||
&& sessionUser.HasWriteAccess
|
&& sessionUser.HasWriteAccess
|
||||||
&& sessionUser.HasAccessTo(userToDelete) // TODO: && user.HasAccessTo(installation.Parent()) ???
|
&& sessionUser.HasAccessTo(userToDelete)
|
||||||
&& Db.Delete(userToDelete);
|
&& Db.Delete(userToDelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,8 +134,8 @@ public static class SessionMethods
|
||||||
var sessionUser = session?.User;
|
var sessionUser = session?.User;
|
||||||
|
|
||||||
return sessionUser is not null
|
return sessionUser is not null
|
||||||
&& user is not null
|
|
||||||
&& installation is not null
|
&& installation is not null
|
||||||
|
&& user is not null
|
||||||
&& user.IsDescendantOf(sessionUser)
|
&& user.IsDescendantOf(sessionUser)
|
||||||
&& sessionUser.HasAccessTo(installation)
|
&& sessionUser.HasAccessTo(installation)
|
||||||
&& !user.HasAccessTo(installation)
|
&& !user.HasAccessTo(installation)
|
||||||
|
@ -140,8 +147,8 @@ public static class SessionMethods
|
||||||
var sessionUser = session?.User;
|
var sessionUser = session?.User;
|
||||||
|
|
||||||
return sessionUser is not null
|
return sessionUser is not null
|
||||||
&& user is not null
|
|
||||||
&& folder is not null
|
&& folder is not null
|
||||||
|
&& user is not null
|
||||||
&& user.IsDescendantOf(sessionUser)
|
&& user.IsDescendantOf(sessionUser)
|
||||||
&& sessionUser.HasAccessTo(folder)
|
&& sessionUser.HasAccessTo(folder)
|
||||||
&& !user.HasAccessTo(folder)
|
&& !user.HasAccessTo(folder)
|
||||||
|
@ -153,8 +160,8 @@ public static class SessionMethods
|
||||||
var sessionUser = session?.User;
|
var sessionUser = session?.User;
|
||||||
|
|
||||||
return sessionUser is not null
|
return sessionUser is not null
|
||||||
&& user is not null
|
|
||||||
&& installation is not null
|
&& installation is not null
|
||||||
|
&& user is not null
|
||||||
&& user.IsDescendantOf(sessionUser)
|
&& user.IsDescendantOf(sessionUser)
|
||||||
&& sessionUser.HasAccessTo(installation)
|
&& sessionUser.HasAccessTo(installation)
|
||||||
&& user.HasAccessTo(installation)
|
&& user.HasAccessTo(installation)
|
||||||
|
@ -166,8 +173,8 @@ public static class SessionMethods
|
||||||
var sessionUser = session?.User;
|
var sessionUser = session?.User;
|
||||||
|
|
||||||
return sessionUser is not null
|
return sessionUser is not null
|
||||||
&& user is not null
|
|
||||||
&& folder is not null
|
&& folder is not null
|
||||||
|
&& user is not null
|
||||||
&& user.IsDescendantOf(sessionUser)
|
&& user.IsDescendantOf(sessionUser)
|
||||||
&& sessionUser.HasAccessTo(folder)
|
&& sessionUser.HasAccessTo(folder)
|
||||||
&& user.HasAccessTo(folder)
|
&& user.HasAccessTo(folder)
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -34,7 +34,7 @@ public static class UserMethods
|
||||||
// to a child folder of a folder he has already access to
|
// to a child folder of a folder he has already access to
|
||||||
// TODO shouldn't we prevent doubling permissions? -K"
|
// TODO shouldn't we prevent doubling permissions? -K"
|
||||||
// TODO yes we should -ig (still TODO)
|
// 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)
|
public static IEnumerable<TreeNode> AccessibleFoldersAndInstallations(this User user)
|
||||||
|
@ -51,9 +51,9 @@ public static class UserMethods
|
||||||
.InstallationAccess
|
.InstallationAccess
|
||||||
.Where(r => r.UserId == user.Id)
|
.Where(r => r.UserId == user.Id)
|
||||||
.Select(r => r.InstallationId)
|
.Select(r => r.InstallationId)
|
||||||
.Select(Db.GetInstallationById)
|
.Select(i => Db.GetInstallationById(i))
|
||||||
.NotNull()
|
.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)
|
public static IEnumerable<Folder> DirectlyAccessibleFolders(this User user)
|
||||||
|
@ -62,9 +62,9 @@ public static class UserMethods
|
||||||
.FolderAccess
|
.FolderAccess
|
||||||
.Where(r => r.UserId == user.Id)
|
.Where(r => r.UserId == user.Id)
|
||||||
.Select(r => r.FolderId)
|
.Select(r => r.FolderId)
|
||||||
.Select(Db.GetFolderById)
|
.Select(i => Db.GetFolderById(i))
|
||||||
.NotNull()
|
.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)
|
public static IEnumerable<User> ChildUsers(this User parent)
|
||||||
|
@ -112,21 +112,17 @@ public static class UserMethods
|
||||||
|
|
||||||
public static User? Parent(this User u)
|
public static User? Parent(this User u)
|
||||||
{
|
{
|
||||||
return u.IsAbsoluteRoot()
|
return u.IsRoot()
|
||||||
? null
|
? null
|
||||||
: Db.GetUserById(u.ParentId);
|
: Db.GetUserById(u.ParentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean IsAbsoluteRoot(this User u)
|
public static Boolean IsRoot(this User user)
|
||||||
{
|
{
|
||||||
return u.ParentId == 0;
|
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)
|
public static Boolean HasDirectAccessTo(this User user, Folder folder)
|
||||||
{
|
{
|
||||||
return Db
|
return Db
|
||||||
|
@ -174,12 +170,6 @@ public static class UserMethods
|
||||||
.Contains(user);
|
.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)
|
public static String Salt(this User user)
|
||||||
{
|
{
|
||||||
// + id => salt unique per user
|
// + id => salt unique per user
|
||||||
|
@ -188,6 +178,14 @@ public static class UserMethods
|
||||||
return $"{user.Id}InnovEnergy";
|
return $"{user.Id}InnovEnergy";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static User WithPasswordOf(this User user, User other)
|
||||||
|
{
|
||||||
|
user.Password = other.Password;
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO?
|
// TODO?
|
||||||
private static Boolean IsValidEmail(String email)
|
private static Boolean IsValidEmail(String email)
|
||||||
|
|
|
@ -4,6 +4,9 @@ namespace InnovEnergy.App.Backend;
|
||||||
|
|
||||||
public static class Program
|
public static class Program
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// TODO: Trash
|
||||||
|
|
||||||
public static void Main(String[] args)
|
public static void Main(String[] args)
|
||||||
{
|
{
|
||||||
//Db.CreateFakeRelations();
|
//Db.CreateFakeRelations();
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using InnovEnergy.App.Backend.Database;
|
using InnovEnergy.App.Backend.Database;
|
||||||
using InnovEnergy.App.Backend.DataTypes;
|
using InnovEnergy.App.Backend.DataTypes;
|
||||||
using InnovEnergy.Lib.Utils;
|
|
||||||
using SQLite;
|
using SQLite;
|
||||||
|
|
||||||
namespace InnovEnergy.App.Backend.Relations;
|
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 Int64 UserId { get => Right; init => Right = value;}
|
||||||
[Indexed] public DateTime LastSeen { get; set; }
|
[Indexed] public DateTime LastSeen { get; set; }
|
||||||
|
|
||||||
[Ignore] public Boolean Valid => DateTime.Now - LastSeen < MaxAge
|
[Ignore] public Boolean Valid => DateTime.Now - LastSeen < MaxAge
|
||||||
&& !User.Email.IsNullOrEmpty();
|
&& (User) is not null;
|
||||||
|
|
||||||
[Ignore] public User User => _User ??= Db.GetUserById(UserId)!;
|
[Ignore] public User User => _User ??= Db.GetUserById(UserId)!;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue