259 lines
7.8 KiB
C#
259 lines
7.8 KiB
C#
using InnovEnergy.API.DataModel;
|
|
using static InnovEnergy.API.Result;
|
|
using Path = InnovEnergy.API.DataModel.Path;
|
|
|
|
namespace InnovEnergy.API;
|
|
|
|
public static class LoginStateExtensions
|
|
{
|
|
// TODO: sync VRM
|
|
|
|
public static Boolean CanEdit(this LoginState uc, Path path) => uc.CanEdit(path.Element);
|
|
|
|
public static Boolean CanEdit(this LoginState uc, DataElement de)
|
|
{
|
|
var user = uc.LoginUser;
|
|
|
|
return de is Folder && user.CanEditFolders() ||
|
|
de is User && user.CanEditUsers() ||
|
|
de is Installation && user.CanEditInstallations();
|
|
}
|
|
|
|
public static Result Move(this LoginState ctx, String sourcePath, String targetPath)
|
|
{
|
|
var source = ctx.ParsePath(sourcePath);
|
|
|
|
if (source is null)
|
|
return Failure($"cannot find {sourcePath}");
|
|
|
|
if (!ctx.CanEdit(source))
|
|
return Failure($"operation not allowed for {ctx.LoginUser}");
|
|
|
|
var target = ctx.ParsePath(targetPath);
|
|
|
|
if (target is null)
|
|
return Failure($"cannot find folder {targetPath}");
|
|
|
|
return source.MoveTo(target);
|
|
}
|
|
|
|
|
|
public static Result DeleteInstallation(this LoginState ctx, String? pathToDelete)
|
|
{
|
|
var path = ctx.ParsePath(pathToDelete);
|
|
|
|
if (path?.Installation() is null)
|
|
return Failure($"cannot find {pathToDelete}");
|
|
|
|
if (!ctx.CanEdit(path))
|
|
return Failure($"operation not allowed for {ctx.LoginUser}");
|
|
|
|
return path.Delete();
|
|
}
|
|
|
|
public static Result RenameInstallation(this LoginState ctx, String? installationPath, String? newName)
|
|
{
|
|
var path = ctx.ParsePath(installationPath);
|
|
|
|
var installation = path?.Installation();
|
|
|
|
if (path is null || installation is null)
|
|
return Failure($"cannot find {installationPath}");
|
|
|
|
if (newName is null)
|
|
return Failure("no name supplied");
|
|
|
|
if (!ctx.CanEdit(path))
|
|
return Failure($"operation not allowed for {ctx.LoginUser}");
|
|
|
|
|
|
installation.Name = newName;
|
|
|
|
return path.Delete();
|
|
}
|
|
|
|
|
|
public static Result DeleteFolder(this LoginState ctx, String? pathToDelete)
|
|
{
|
|
var path = ctx.ParsePath(pathToDelete);
|
|
|
|
if (path?.Folder() is null)
|
|
return Failure($"cannot find {pathToDelete}");
|
|
|
|
if (!ctx.CanEdit(path))
|
|
return Failure($"operation not allowed for {ctx.LoginUser}");
|
|
|
|
return path.Delete();
|
|
}
|
|
|
|
public static Result DeleteUser(this LoginState ctx, String? pathToDelete)
|
|
{
|
|
var path = ctx.ParsePath(pathToDelete);
|
|
|
|
if (path?.User() is null)
|
|
return Failure($"cannot find {pathToDelete}");
|
|
|
|
if (!ctx.CanEdit(path))
|
|
return Failure($"operation not allowed for {ctx.LoginUser}");
|
|
|
|
return path.Delete();
|
|
}
|
|
|
|
public static Result Rename(this LoginState ctx, String pathToRename, String newName)
|
|
{
|
|
var path = ctx.ParsePath(pathToRename);
|
|
|
|
if (path is null)
|
|
return Failure($"cannot find {pathToRename}");
|
|
|
|
if (!ctx.CanEdit(path) || path.IsUser())
|
|
return Failure("operation not permitted");
|
|
|
|
if (String.IsNullOrWhiteSpace(newName))
|
|
return Failure($"{newName} is not a valid name");
|
|
|
|
path.Element.Name = newName;
|
|
return Success($"renamed {pathToRename} to {newName}");
|
|
}
|
|
|
|
// TODO: prevent folder cycles!
|
|
|
|
// public Result AddNewFolder(String parentFolderPath, String folderName)
|
|
// {
|
|
// if (!User.CanEditFolders())
|
|
// return Failure($"operation not allowed for {User}");
|
|
//
|
|
// var parent = ParsePath(parentFolderPath);
|
|
//
|
|
// if (parent is null)
|
|
// return Failure($"cannot find folder {parentFolderPath}");
|
|
//
|
|
// return parent.AddChild(new Folder { Name = folderName });
|
|
// }
|
|
|
|
// TODO: VRM
|
|
// public Result AddNewInstallation(Int32 parentFolderId, String installationName)
|
|
// {
|
|
// if (!User.CanEditInstallations())
|
|
// throw new ApiException($"operation not allowed for {User}");
|
|
//
|
|
// var parentPath = HomeFolder.FindDescendantFolder(parentFolderId);
|
|
// var parentFolder = parentPath?.Folder();
|
|
//
|
|
// if (parentFolder is null)
|
|
// return new Failure($"cannot find folder {parentFolderId}");
|
|
//
|
|
// var newInstallation = new Installation { Name = installationName };
|
|
// parentFolder.Add(newInstallation);
|
|
//
|
|
// return new Success($"added new {newInstallation} to {parentPath}");
|
|
// }
|
|
|
|
|
|
public static Result CreateUser(this LoginState loginState, String? parentPath, String? userName, String? userType)
|
|
{
|
|
const String allowedSpecialChars = "_-.@";
|
|
|
|
if (!loginState.LoginUser.CanEditUsers())
|
|
return Failure($"operation not allowed for {loginState.LoginUser}");
|
|
|
|
if (userName is null || userName.Length < 3)
|
|
return Failure("username must consist of at least 3 characters");
|
|
|
|
if (!userName.All(c => Char.IsLetter(c) || Char.IsDigit(c) || allowedSpecialChars.Contains(c)))
|
|
{
|
|
return Failure("Illegal character in username.\n" +
|
|
"The username can contain letters, digits and the following the following characters:\n" +
|
|
allowedSpecialChars);
|
|
}
|
|
|
|
var path = loginState.ParsePath(parentPath);
|
|
|
|
if (path is null)
|
|
return Failure($"cannot find parent {parentPath}");
|
|
|
|
var type = ParseUserType(userType);
|
|
|
|
if (type == UserType.Unknown)
|
|
return Failure($"unknown user type {type}");
|
|
|
|
var newUser = new User
|
|
{
|
|
Name = userName,
|
|
UserType = type
|
|
};
|
|
|
|
return path.AddChild(newUser);
|
|
}
|
|
|
|
public static Result EditUser(this LoginState loginState, String? userPath, String? userType)
|
|
{
|
|
if (!loginState.LoginUser.CanEditUsers())
|
|
return Failure($"operation not permitted for {loginState.LoginUser}");
|
|
|
|
var user = loginState.ParsePath(userPath).User();
|
|
|
|
if (user == loginState.LoginUser)
|
|
return Failure($"operation not permitted for {loginState.LoginUser}");
|
|
|
|
if (user is null)
|
|
return Failure($"cannot find user {userPath}");
|
|
|
|
var oldType = user.UserType;
|
|
|
|
var newType = ParseUserType(userType);
|
|
|
|
if (newType == UserType.Unknown)
|
|
return Failure($"unknown user type {newType}");
|
|
|
|
user.UserType = newType;
|
|
|
|
return Success($"Changed user type of user {userPath} from {oldType} to {newType}");
|
|
}
|
|
|
|
private static UserType ParseUserType(String? userType)
|
|
{
|
|
return userType switch
|
|
{
|
|
"Viewer" => UserType.Viewer,
|
|
"Editor" => UserType.Editor,
|
|
"Admin" => UserType.Admin,
|
|
_ => UserType.Unknown
|
|
};
|
|
}
|
|
|
|
// public Result ChangeUserType(Int32 userId, UserType userType)
|
|
// {
|
|
// if (!User.CanEditUsers() || userId == User.Id)
|
|
// return Failure($"operation not allowed for {User}");
|
|
//
|
|
// var userToEdit = HomeFolder.FindDescendantUser(userId)?.User();
|
|
//
|
|
// if (userToEdit is null)
|
|
// return Failure($"cannot find user {userId}");
|
|
//
|
|
// var oldUserType = userToEdit.UserType;
|
|
// userToEdit.UserType = userType;
|
|
//
|
|
// return Success($"changed type of user {userToEdit} from {oldUserType} to {userType}");
|
|
// }
|
|
|
|
|
|
private static Path? ParsePath(this LoginState uc, String? path)
|
|
{
|
|
if (path == null)
|
|
return null;
|
|
|
|
var splitPath = path
|
|
.Split("|", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries)
|
|
.Skip(1);
|
|
|
|
return uc
|
|
.HomeFolder
|
|
.RelativePath()
|
|
.GetDescendant(splitPath);
|
|
}
|
|
|
|
|
|
|
|
} |