Merge branch 'main' of https://git.innov.energy/Innovenergy/git_trunk
This commit is contained in:
commit
de96ce6f16
|
@ -2,388 +2,337 @@ using InnovEnergy.App.Backend.Database;
|
||||||
using InnovEnergy.App.Backend.DataTypes;
|
using InnovEnergy.App.Backend.DataTypes;
|
||||||
using InnovEnergy.App.Backend.DataTypes.Methods;
|
using InnovEnergy.App.Backend.DataTypes.Methods;
|
||||||
using InnovEnergy.App.Backend.Relations;
|
using InnovEnergy.App.Backend.Relations;
|
||||||
|
using InnovEnergy.Lib.Utils;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using static System.Net.HttpStatusCode;
|
|
||||||
using Folder = InnovEnergy.App.Backend.DataTypes.Folder;
|
|
||||||
using Installation = InnovEnergy.App.Backend.DataTypes.Installation;
|
|
||||||
using Object = System.Object;
|
|
||||||
using User = InnovEnergy.App.Backend.DataTypes.User;
|
|
||||||
|
|
||||||
namespace InnovEnergy.App.Backend.Controllers;
|
namespace InnovEnergy.App.Backend.Controllers;
|
||||||
|
|
||||||
|
using Token = String;
|
||||||
|
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/")]
|
[Route("api/")]
|
||||||
public class Controller
|
public class Controller : ControllerBase
|
||||||
{
|
{
|
||||||
private static readonly HttpResponseMessage _Unauthorized = new HttpResponseMessage(Unauthorized);
|
[HttpPost(nameof(Login))]
|
||||||
private static readonly HttpResponseMessage _Ok = new HttpResponseMessage(OK);
|
public ActionResult<Session> Login(String username, String password)
|
||||||
private static readonly HttpResponseMessage _BadRequest = new HttpResponseMessage(BadRequest);
|
|
||||||
|
|
||||||
[Returns<String>]
|
|
||||||
[Returns(Unauthorized)]
|
|
||||||
[Returns(BadRequest)]
|
|
||||||
[HttpPost($"{nameof(Login)}")]
|
|
||||||
public Object Login(Credentials credentials)
|
|
||||||
{
|
{
|
||||||
var session = credentials.Login();
|
var user = Db.GetUserByEmail(username);
|
||||||
|
|
||||||
return session is null
|
if (user is null || !user.VerifyPassword(password))
|
||||||
? _Unauthorized
|
return Unauthorized();
|
||||||
: session;
|
|
||||||
|
var session = new Session(user);
|
||||||
|
|
||||||
|
return Db.Create(session)
|
||||||
|
? session
|
||||||
|
: Unauthorized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Returns(OK)]
|
[HttpPost(nameof(Logout))]
|
||||||
[Returns(Unauthorized)]
|
public ActionResult Logout(Token authToken)
|
||||||
[HttpPost($"{nameof(Logout)}")]
|
|
||||||
public Object Logout()
|
|
||||||
{
|
{
|
||||||
var session = GetSession();
|
var session = Db.GetSession(authToken);
|
||||||
|
|
||||||
return session.Logout()
|
return session.Logout()
|
||||||
? _Ok
|
? Ok()
|
||||||
: _Unauthorized;
|
: Unauthorized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Returns<User>]
|
[HttpGet(nameof(GetUserById))]
|
||||||
[Returns(Unauthorized)]
|
public ActionResult<User> GetUserById(Int64 id, Token authToken)
|
||||||
[HttpGet($"{nameof(GetUserById)}")]
|
|
||||||
public Object GetUserById(Int64 id)
|
|
||||||
{
|
{
|
||||||
var caller = GetSession()?.User;
|
var session = Db.GetSession(authToken)?.User;
|
||||||
if (caller == null)
|
if (session == null)
|
||||||
return _Unauthorized;
|
return Unauthorized();
|
||||||
|
|
||||||
var user = Db.GetUserById(id);
|
var user = Db.GetUserById(id);
|
||||||
|
|
||||||
if (user is null || !caller.HasAccessTo(user))
|
if (user is null || !session.HasAccessTo(user))
|
||||||
return _Unauthorized;
|
return Unauthorized();
|
||||||
|
|
||||||
user.Password = "";
|
user.Password = "";
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Returns<Installation>]
|
[HttpGet(nameof(GetInstallationById))]
|
||||||
[Returns(Unauthorized)]
|
public ActionResult<Installation> GetInstallationById(Int64 id, Token authToken)
|
||||||
[HttpGet($"{nameof(GetInstallationById)}")]
|
|
||||||
public Object GetInstallationById(Int64 id)
|
|
||||||
{
|
{
|
||||||
var user = GetSession()?.User;
|
var user = Db.GetSession(authToken)?.User;
|
||||||
if (user == null)
|
if (user == null)
|
||||||
return _Unauthorized;
|
return Unauthorized();
|
||||||
|
|
||||||
var installation = Db.GetInstallationById(id);
|
var installation = Db.GetInstallationById(id);
|
||||||
|
|
||||||
if (installation is null || !user.HasAccessTo(installation))
|
if (installation is null || !user.HasAccessTo(installation))
|
||||||
return _Unauthorized;
|
return Unauthorized();
|
||||||
|
|
||||||
return installation;
|
return installation;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Returns<Installation>]
|
[HttpGet(nameof(GetUsersWithAccessToInstallation))]
|
||||||
[Returns(Unauthorized)]
|
public ActionResult<IEnumerable<Object>> GetUsersWithAccessToInstallation(Int64 id, Token authToken)
|
||||||
[HttpGet($"{nameof(GetUsersWithAccessToInstallation)}")]
|
|
||||||
public Object GetUsersWithAccessToInstallation(Int64 id)
|
|
||||||
{
|
{
|
||||||
var user = GetSession()?.User;
|
var user = Db.GetSession(authToken)?.User;
|
||||||
if (user == null)
|
if (user == null)
|
||||||
return _Unauthorized;
|
return Unauthorized();
|
||||||
|
|
||||||
var installation = Db.GetInstallationById(id);
|
var installation = Db.GetInstallationById(id);
|
||||||
|
|
||||||
if (installation is null || !user.HasAccessTo(installation))
|
if (installation is null || !user.HasAccessTo(installation))
|
||||||
return _Unauthorized;
|
return Unauthorized();
|
||||||
|
|
||||||
var usersWithInheritedAccess = installation
|
var directAccess = installation
|
||||||
|
.UsersWithDirectAccess()
|
||||||
|
.Where(u => u.IsDescendantOf(user));
|
||||||
|
|
||||||
|
var inheritedAccess = installation
|
||||||
.Ancestors()
|
.Ancestors()
|
||||||
.SelectMany(f => f.UsersWithDirectAccess()
|
|
||||||
.Where(u => u.IsDescendantOf(user))
|
|
||||||
.Select(u => new { folderId = f.Id, user = u }))
|
|
||||||
.OfType<Object>();
|
|
||||||
|
|
||||||
var usersWithDirectAccess = installation.UsersWithDirectAccess()
|
|
||||||
.Where(u => u.IsDescendantOf(user))
|
|
||||||
.Select(u => new { installationId = installation.Id, user = u })
|
|
||||||
.OfType<Object>();
|
|
||||||
|
|
||||||
return usersWithInheritedAccess.Concat(usersWithDirectAccess);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Returns<Installation>]
|
|
||||||
[Returns(Unauthorized)]
|
|
||||||
[HttpGet($"{nameof(GetUsersWithAccessToFolder)}")]
|
|
||||||
public Object GetUsersWithAccessToFolder(Int64 id)
|
|
||||||
{
|
|
||||||
var user = GetSession()?.User;
|
|
||||||
if (user == null)
|
|
||||||
return _Unauthorized;
|
|
||||||
|
|
||||||
var folder = Db.GetFolderById(id);
|
|
||||||
|
|
||||||
if (folder is null || !user.HasAccessTo(folder))
|
|
||||||
return _Unauthorized;
|
|
||||||
|
|
||||||
return folder
|
|
||||||
.Ancestors()
|
|
||||||
.Append(folder)
|
|
||||||
.SelectMany(f => f.UsersWithDirectAccess()
|
.SelectMany(f => f.UsersWithDirectAccess()
|
||||||
.Where(u => u.IsDescendantOf(user))
|
.Where(u => u.IsDescendantOf(user))
|
||||||
.Select(u => new { folderId = f.Id, user = u }));
|
.Select(u => new { folderId = f.Id, user = u }));
|
||||||
|
|
||||||
|
return directAccess
|
||||||
|
.Concat<Object>(inheritedAccess)
|
||||||
|
.Apply(Ok); // TODO: typing
|
||||||
}
|
}
|
||||||
|
|
||||||
[Returns<Folder>]
|
[HttpGet(nameof(GetUsersWithAccessToFolder))]
|
||||||
[Returns(Unauthorized)]
|
public ActionResult<IEnumerable<Object>> GetUsersWithAccessToFolder(Int64 id, Token authToken)
|
||||||
[HttpGet($"{nameof(GetFolderById)}")]
|
|
||||||
public Object GetFolderById(Int64 id)
|
|
||||||
{
|
{
|
||||||
var user = GetSession()?.User;
|
var user = Db.GetSession(authToken)?.User;
|
||||||
if (user == null)
|
if (user == null)
|
||||||
return _Unauthorized;
|
return Unauthorized();
|
||||||
|
|
||||||
var folder = Db.GetFolderById(id);
|
var folder = Db.GetFolderById(id);
|
||||||
|
|
||||||
if (folder is null || !user.HasAccessTo(folder))
|
if (folder is null || !user.HasAccessTo(folder))
|
||||||
return _Unauthorized;
|
return Unauthorized();
|
||||||
|
|
||||||
|
return folder
|
||||||
|
.Ancestors()
|
||||||
|
.Prepend(folder)
|
||||||
|
.SelectMany(f => f.UsersWithDirectAccess()
|
||||||
|
.Where(u => u.IsDescendantOf(user))
|
||||||
|
.Select(u => new { folderId = f.Id, user = u }))
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet(nameof(GetFolderById))]
|
||||||
|
public ActionResult<Folder> GetFolderById(Int64 id, Token authToken)
|
||||||
|
{
|
||||||
|
var user = Db.GetSession(authToken)?.User;
|
||||||
|
if (user == null)
|
||||||
|
return Unauthorized();
|
||||||
|
|
||||||
|
var folder = Db.GetFolderById(id);
|
||||||
|
|
||||||
|
if (folder is null || !user.HasAccessTo(folder))
|
||||||
|
return Unauthorized();
|
||||||
|
|
||||||
return folder;
|
return folder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Returns<Installation[]>] // assuming swagger knows about arrays but not lists (JSON)
|
[HttpGet(nameof(GetAllInstallations))]
|
||||||
[Returns(Unauthorized)]
|
public ActionResult<IEnumerable<Installation>> GetAllInstallations(Token authToken)
|
||||||
[HttpGet($"{nameof(GetAllInstallations)}/")]
|
|
||||||
public Object GetAllInstallations()
|
|
||||||
{
|
{
|
||||||
var user = GetSession()?.User;
|
var user = Db.GetSession(authToken)?.User;
|
||||||
|
|
||||||
return user is null
|
if (user is null)
|
||||||
? _Unauthorized
|
return Unauthorized();
|
||||||
: user.AccessibleInstallations();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return user.AccessibleInstallations().ToList();
|
||||||
[Returns<Folder[]>] // assuming swagger knows about arrays but not lists (JSON)
|
|
||||||
[Returns(Unauthorized)]
|
|
||||||
[HttpGet($"{nameof(GetAllFolders)}/")]
|
|
||||||
public Object GetAllFolders()
|
|
||||||
{
|
|
||||||
var user = GetSession()?.User;
|
|
||||||
|
|
||||||
return user is null
|
|
||||||
? _Unauthorized
|
|
||||||
: user.AccessibleFolders();
|
|
||||||
}
|
|
||||||
|
|
||||||
// [Returns<Folder[]>] // assuming swagger knows about arrays but not lists (JSON)
|
|
||||||
// [Returns(Unauthorized)]
|
|
||||||
// [HttpGet($"{nameof(GetUsersOfFolder)}/")]
|
|
||||||
// public Object GetUsersOfFolder(Int64 folderId)
|
|
||||||
// {
|
|
||||||
// var caller = GetCaller();
|
|
||||||
// if (caller == null)
|
|
||||||
// return new HttpResponseMessage(Unauthorized);
|
|
||||||
//
|
|
||||||
// var folder = Db.GetFolderById(folderId);
|
|
||||||
//
|
|
||||||
// if (folder is null || !caller.HasAccessTo(folder))
|
|
||||||
// return new HttpResponseMessage(Unauthorized);
|
|
||||||
//
|
|
||||||
// return descendantUsers;
|
|
||||||
// }
|
|
||||||
|
|
||||||
[Returns<TreeNode[]>] // assuming swagger knows about arrays but not lists (JSON)
|
|
||||||
[Returns(Unauthorized)]
|
|
||||||
[HttpGet($"{nameof(GetAllFoldersAndInstallations)}/")]
|
|
||||||
public Object GetAllFoldersAndInstallations()
|
|
||||||
{
|
|
||||||
var user = GetSession()?.User;
|
|
||||||
|
|
||||||
return user is null
|
|
||||||
? _Unauthorized
|
|
||||||
: user.AccessibleFoldersAndInstallations();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[Returns(OK)]
|
[HttpGet(nameof(GetAllFolders))]
|
||||||
[Returns(Unauthorized)]
|
public ActionResult<IEnumerable<Folder>> GetAllFolders(Token authToken)
|
||||||
[HttpPost($"{nameof(CreateUser)}/")]
|
|
||||||
public Object CreateUser(User newUser)
|
|
||||||
{
|
{
|
||||||
var session = GetSession();
|
var user = Db.GetSession(authToken)?.User;
|
||||||
|
|
||||||
return session.Create(newUser)
|
if (user is null)
|
||||||
|
return Unauthorized();
|
||||||
|
|
||||||
|
return new(user.AccessibleFolders());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpGet(nameof(GetAllFoldersAndInstallations))]
|
||||||
|
public ActionResult<IEnumerable<TreeNode>> GetAllFoldersAndInstallations(Token authToken)
|
||||||
|
{
|
||||||
|
var user = Db.GetSession(authToken)?.User;
|
||||||
|
|
||||||
|
if (user is null)
|
||||||
|
return Unauthorized();
|
||||||
|
|
||||||
|
return new (user.AccessibleFoldersAndInstallations());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost(nameof(CreateUser))]
|
||||||
|
public ActionResult<User> CreateUser(User newUser, Token authToken)
|
||||||
|
{
|
||||||
|
return Db.GetSession(authToken).Create(newUser)
|
||||||
? newUser
|
? newUser
|
||||||
: _Unauthorized ;
|
: Unauthorized() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Returns(OK)]
|
[HttpPost(nameof(CreateInstallation))]
|
||||||
[Returns(Unauthorized)]
|
public async Task<ActionResult<Installation>> CreateInstallation(Installation installation, Token authToken)
|
||||||
[HttpPost($"{nameof(CreateInstallation)}/")]
|
|
||||||
public Object CreateInstallation(Installation installation)
|
|
||||||
{
|
{
|
||||||
var session = GetSession();
|
if (!await Db.GetSession(authToken).Create(installation))
|
||||||
|
return Unauthorized();
|
||||||
|
|
||||||
return session.Create(installation)
|
return installation;
|
||||||
? installation
|
|
||||||
: _Unauthorized;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Returns(OK)]
|
[HttpPost(nameof(CreateFolder))]
|
||||||
[Returns(Unauthorized)]
|
public ActionResult<Folder> CreateFolder(Folder folder, Token authToken)
|
||||||
[Returns(InternalServerError)]
|
|
||||||
[HttpPost($"{nameof(CreateFolder)}/")]
|
|
||||||
public Object CreateFolder(Folder folder)
|
|
||||||
{
|
{
|
||||||
var session = GetSession();
|
var session = Db.GetSession(authToken);
|
||||||
|
|
||||||
return session.Create(folder)
|
if (!session.Create(folder))
|
||||||
? folder
|
return Unauthorized();
|
||||||
: _Unauthorized;
|
|
||||||
|
return folder;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Returns(OK)]
|
[HttpPost(nameof(GrantUserAccessToFolder))]
|
||||||
[Returns(Unauthorized)]
|
public ActionResult GrantUserAccessToFolder(FolderAccess folderAccess, Token authToken)
|
||||||
[HttpPost($"{nameof(GrantUserAccessToFolder)}/")]
|
|
||||||
public Object GrantUserAccessToFolder([FromQuery] Int64 folderId, [FromQuery] Int64? id)
|
|
||||||
{
|
{
|
||||||
var session = GetSession();
|
var session = Db.GetSession(authToken);
|
||||||
var user = id is not null ? Db.GetUserById(id) : session?.User;
|
|
||||||
|
|
||||||
return session.GrantUserAccessTo(user, Db.GetFolderById(folderId))
|
// TODO: automatic BadRequest when properties are null during deserialization
|
||||||
? _Ok
|
var folder = Db.GetFolderById(folderAccess.FolderId);
|
||||||
: _Unauthorized;
|
var user = Db.GetUserById(folderAccess.UserId);
|
||||||
|
|
||||||
|
return session.GrantUserAccessTo(user, folder)
|
||||||
|
? Ok()
|
||||||
|
: Unauthorized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Returns(OK)]
|
[HttpPost(nameof(RevokeUserAccessToFolder))]
|
||||||
[Returns(Unauthorized)]
|
public ActionResult RevokeUserAccessToFolder(FolderAccess folderAccess, Token authToken)
|
||||||
[HttpPost($"{nameof(GrantUserAccessToInstallation)}/")]
|
|
||||||
public Object GrantUserAccessToInstallation([FromQuery] Int64 installationId, [FromQuery] Int64? id)
|
|
||||||
{
|
{
|
||||||
var session = GetSession();
|
var session = Db.GetSession(authToken);
|
||||||
|
|
||||||
var user = id is not null ? Db.GetUserById(id) : session?.User;
|
// TODO: automatic BadRequest when properties are null during deserialization
|
||||||
|
var folder = Db.GetFolderById(folderAccess.FolderId);
|
||||||
|
var user = Db.GetUserById(folderAccess.UserId);
|
||||||
|
|
||||||
return session.GrantUserAccessTo(user, Db.GetInstallationById(installationId))
|
return session.RevokeUserAccessTo(user, folder)
|
||||||
? _Ok
|
? Ok()
|
||||||
: _Unauthorized;
|
: Unauthorized();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Returns(OK)]
|
|
||||||
[Returns(Unauthorized)]
|
[HttpPost(nameof(GrantUserAccessToInstallation))]
|
||||||
[HttpPost($"{nameof(RevokeUserAccessToInstallation)}/")]
|
public ActionResult GrantUserAccessToInstallation(InstallationAccess installationAccess, Token authToken)
|
||||||
public Object RevokeUserAccessToInstallation([FromQuery] Int64 installationId, [FromQuery] Int64? id)
|
|
||||||
{
|
{
|
||||||
var session = GetSession();
|
var session = Db.GetSession(authToken);
|
||||||
var user = id is not null ? Db.GetUserById(id) : session?.User;
|
|
||||||
|
|
||||||
|
// TODO: automatic BadRequest when properties are null during deserialization
|
||||||
|
var installation = Db.GetFolderById(installationAccess.InstallationId);
|
||||||
|
var user = Db.GetUserById(installationAccess.UserId);
|
||||||
|
|
||||||
return session.RevokeAccessTo(user, Db.GetInstallationById(installationId))
|
return session.GrantUserAccessTo(user, installation)
|
||||||
? _Ok
|
? Ok()
|
||||||
: _Unauthorized;
|
: Unauthorized();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Returns(OK)]
|
[HttpPost(nameof(RevokeUserAccessToInstallation))]
|
||||||
[Returns(Unauthorized)]
|
public ActionResult RevokeUserAccessToInstallation(InstallationAccess installationAccess, Token authToken)
|
||||||
[HttpPost($"{nameof(RevokeUserAccessToFolder)}/")]
|
|
||||||
public Object RevokeUserAccessToFolder([FromQuery] Int64 folderId, [FromQuery] Int64? id)
|
|
||||||
{
|
{
|
||||||
var session = GetSession();
|
var session = Db.GetSession(authToken);
|
||||||
var user = id is not null ? Db.GetUserById(id) : session?.User;
|
|
||||||
|
|
||||||
|
// TODO: automatic BadRequest when properties are null during deserialization
|
||||||
|
var installation = Db.GetFolderById(installationAccess.InstallationId);
|
||||||
|
var user = Db.GetUserById(installationAccess.UserId);
|
||||||
|
|
||||||
return session.RevokeAccessTo(user, Db.GetFolderById(folderId))
|
return session.RevokeUserAccessTo(user, installation)
|
||||||
? _Ok
|
? Ok()
|
||||||
: _Unauthorized;
|
: Unauthorized();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Returns(OK)]
|
|
||||||
[Returns(Unauthorized)]
|
|
||||||
[HttpPut($"{nameof(UpdateUser)}/")]
|
|
||||||
public Object UpdateUser(User updatedUser)
|
|
||||||
{
|
|
||||||
var session = GetSession();
|
|
||||||
|
|
||||||
if (!session.Update(updatedUser)) return _Unauthorized;
|
|
||||||
updatedUser.Password = "";
|
[HttpPut(nameof(UpdateUser))]
|
||||||
|
public ActionResult<User> UpdateUser(User updatedUser, Token authToken)
|
||||||
|
{
|
||||||
|
var session = Db.GetSession(authToken);
|
||||||
|
|
||||||
|
if (!session.Update(updatedUser))
|
||||||
|
return Unauthorized();
|
||||||
|
|
||||||
|
updatedUser.Password = ""; // TODO: generic sanitize return values
|
||||||
|
|
||||||
return updatedUser;
|
return updatedUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Returns(OK)]
|
[HttpPut(nameof(UpdateInstallation))]
|
||||||
[Returns(Unauthorized)]
|
public ActionResult<Installation> UpdateInstallation(Installation installation, Token authToken)
|
||||||
[HttpPut($"{nameof(UpdateInstallation)}/")]
|
|
||||||
public Object UpdateInstallation(Installation installation)
|
|
||||||
{
|
{
|
||||||
var session = GetSession();
|
var session = Db.GetSession(authToken);
|
||||||
|
|
||||||
return session.Update(installation)
|
if (!session.Update(installation))
|
||||||
? installation
|
return Unauthorized();
|
||||||
: _Unauthorized;
|
|
||||||
|
return installation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Returns(OK)]
|
[HttpPut(nameof(UpdateFolder))]
|
||||||
[Returns(Unauthorized)]
|
public ActionResult<Folder> UpdateFolder(Folder folder, Token authToken)
|
||||||
[HttpPut($"{nameof(UpdateFolder)}/")]
|
|
||||||
public Object UpdateFolder(Folder folder)
|
|
||||||
{
|
{
|
||||||
var session = GetSession();
|
var session = Db.GetSession(authToken);
|
||||||
|
|
||||||
return session.Update(folder)
|
if (!session.Update(folder))
|
||||||
? folder
|
return Unauthorized();
|
||||||
: _Unauthorized;
|
|
||||||
|
return folder;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Returns(OK)]
|
[HttpDelete(nameof(DeleteUser))]
|
||||||
[Returns(Unauthorized)]
|
public ActionResult DeleteUser(Int64 userId, Token authToken)
|
||||||
[HttpDelete($"{nameof(DeleteUser)}/")]
|
|
||||||
public Object DeleteUser(Int64 userId)
|
|
||||||
{
|
{
|
||||||
var session = GetSession();
|
var session = Db.GetSession(authToken);
|
||||||
var user = Db.GetUserById(userId);
|
var user = Db.GetUserById(userId);
|
||||||
|
|
||||||
return session.Delete(user)
|
return session.Delete(user)
|
||||||
? _Ok
|
? Ok()
|
||||||
: _Unauthorized;
|
: Unauthorized();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Returns(OK)]
|
[HttpDelete(nameof(DeleteInstallation))]
|
||||||
[Returns(Unauthorized)]
|
public ActionResult DeleteInstallation(Int64 installationId, Token authToken)
|
||||||
[HttpDelete($"{nameof(DeleteInstallation)}/")]
|
|
||||||
public Object DeleteInstallation(Int64 installationId)
|
|
||||||
{
|
{
|
||||||
var session = GetSession();
|
var session = Db.GetSession(authToken);
|
||||||
var installation = Db.GetInstallationById(installationId);
|
var installation = Db.GetInstallationById(installationId);
|
||||||
|
|
||||||
return session.Delete(installation)
|
return session.Delete(installation)
|
||||||
? _Ok
|
? Ok()
|
||||||
: _Unauthorized;
|
: Unauthorized();
|
||||||
}
|
}
|
||||||
|
|
||||||
[ProducesResponseType(200)]
|
[HttpDelete(nameof(DeleteFolder))]
|
||||||
[ProducesResponseType(401)]
|
public ActionResult DeleteFolder(Int64 folderId, Token authToken)
|
||||||
[HttpDelete($"{nameof(DeleteFolder)}/")]
|
|
||||||
public Object DeleteFolder(Int64 folderId)
|
|
||||||
{
|
{
|
||||||
var session = GetSession();
|
var session = Db.GetSession(authToken);
|
||||||
|
|
||||||
var folder = Db.GetFolderById(folderId);
|
var folder = Db.GetFolderById(folderId);
|
||||||
|
|
||||||
return session.Delete(folder)
|
return session.Delete(folder)
|
||||||
? _Ok
|
? Ok()
|
||||||
: _Unauthorized;
|
: Unauthorized();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Session? GetSession()
|
|
||||||
{
|
|
||||||
var ctxAccessor = new HttpContextAccessor();
|
|
||||||
return ctxAccessor.HttpContext?.Items["Session"] as Session;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
using System.Net;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
|
|
||||||
namespace InnovEnergy.App.Backend.Controllers;
|
|
||||||
|
|
||||||
public class ReturnsAttribute : ProducesResponseTypeAttribute
|
|
||||||
{
|
|
||||||
public ReturnsAttribute(HttpStatusCode statusCode) : base((Int32)statusCode)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ReturnsAttribute<T> : ProducesResponseTypeAttribute
|
|
||||||
{
|
|
||||||
public ReturnsAttribute(HttpStatusCode statusCode) : base(typeof(T), (Int32)statusCode)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public ReturnsAttribute() : base(typeof(T), (Int32)HttpStatusCode.OK)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
|
|
||||||
namespace InnovEnergy.App.Backend.DataTypes;
|
|
||||||
|
|
||||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
|
|
||||||
public record Credentials(String Username, String Password);
|
|
|
@ -1,27 +0,0 @@
|
||||||
using InnovEnergy.App.Backend.Database;
|
|
||||||
using InnovEnergy.App.Backend.Relations;
|
|
||||||
using InnovEnergy.Lib.Utils;
|
|
||||||
|
|
||||||
namespace InnovEnergy.App.Backend.DataTypes.Methods;
|
|
||||||
|
|
||||||
public static class CredentialsMethods
|
|
||||||
{
|
|
||||||
public static Session? Login(this Credentials credentials)
|
|
||||||
{
|
|
||||||
var (username, password) = credentials;
|
|
||||||
|
|
||||||
if (username.IsNullOrEmpty() || password.IsNullOrEmpty())
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var user = Db.GetUserByEmail(username);
|
|
||||||
|
|
||||||
if (user is null || !user.VerifyPassword(password))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var session = new Session(user);
|
|
||||||
|
|
||||||
return Db.Create(session)
|
|
||||||
? session
|
|
||||||
: null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,3 @@
|
||||||
using System.Collections;
|
|
||||||
using InnovEnergy.App.Backend.Database;
|
using InnovEnergy.App.Backend.Database;
|
||||||
using InnovEnergy.Lib.Utils;
|
using InnovEnergy.Lib.Utils;
|
||||||
|
|
||||||
|
@ -9,20 +8,27 @@ public static class FolderMethods
|
||||||
|
|
||||||
public static IEnumerable<User> UsersWithAccess(this Folder folder)
|
public static IEnumerable<User> UsersWithAccess(this Folder folder)
|
||||||
{
|
{
|
||||||
return UsersWithDirectAccess(folder).Concat(UsersWithInheritedAccess(folder));
|
var direct = folder.UsersWithDirectAccess();
|
||||||
|
var inherited = folder.UsersWithInheritedAccess();
|
||||||
|
|
||||||
|
return direct.Concat(inherited);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<User> UsersWithDirectAccess(this Folder folder)
|
public static IEnumerable<User> UsersWithDirectAccess(this Folder folder)
|
||||||
{
|
{
|
||||||
return Db.FolderAccess
|
return Db
|
||||||
.Where(access => access.FolderId == folder.Id)
|
.FolderAccess
|
||||||
.Select(access => Db.GetUserById(access.UserId))
|
.Where(a => a.FolderId == folder.Id)
|
||||||
|
.Select(a => Db.GetUserById(a.UserId))
|
||||||
.NotNull();
|
.NotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<User> UsersWithInheritedAccess(this Folder folder)
|
public static IEnumerable<User> UsersWithInheritedAccess(this Folder folder)
|
||||||
{
|
{
|
||||||
return folder.Ancestors().SelectMany(f => f.UsersWithDirectAccess()).NotNull();
|
return folder
|
||||||
|
.Ancestors()
|
||||||
|
.SelectMany(f => f.UsersWithDirectAccess())
|
||||||
|
.NotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<Folder> ChildFolders(this Folder parent)
|
public static IEnumerable<Folder> ChildFolders(this Folder parent)
|
||||||
|
@ -74,7 +80,7 @@ public static class FolderMethods
|
||||||
|
|
||||||
public static Boolean IsRelativeRoot(this Folder folder)
|
public static Boolean IsRelativeRoot(this Folder folder)
|
||||||
{
|
{
|
||||||
return folder.ParentId < 0;
|
return folder.ParentId < 0; // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean WasMoved(this Folder folder)
|
public static Boolean WasMoved(this Folder folder)
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using CliWrap;
|
|
||||||
using CliWrap.Buffered;
|
|
||||||
using InnovEnergy.App.Backend.Database;
|
using InnovEnergy.App.Backend.Database;
|
||||||
|
using InnovEnergy.App.Backend.S3;
|
||||||
using InnovEnergy.Lib.Utils;
|
using InnovEnergy.Lib.Utils;
|
||||||
|
|
||||||
namespace InnovEnergy.App.Backend.DataTypes.Methods;
|
namespace InnovEnergy.App.Backend.DataTypes.Methods;
|
||||||
|
@ -8,96 +7,59 @@ namespace InnovEnergy.App.Backend.DataTypes.Methods;
|
||||||
|
|
||||||
public static class InstallationMethods
|
public static class InstallationMethods
|
||||||
{
|
{
|
||||||
public static async Task RenewS3BucketUrl(this Installation installation)
|
private const String BucketNameSalt = "3e5b3069-214a-43ee-8d85-57d72000c19d";
|
||||||
|
|
||||||
|
public static String BucketName(this Installation installation)
|
||||||
{
|
{
|
||||||
await RenewS3BucketUrl(installation, TimeSpan.FromDays(1));
|
return $"s3://{installation.Id}-{BucketNameSalt}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task RenewS3BucketUrl(this Installation installation, TimeSpan validity)
|
public static async Task<Boolean> RenewS3BucketUrl(this Installation installation)
|
||||||
{
|
{
|
||||||
const String secret = "55MAqyO_FqUmh7O64VIO0egq50ERn_WIAWuc2QC44QU";
|
return await RenewS3BucketUrl(installation, TimeSpan.FromDays(1));
|
||||||
const String apiKey = "EXO44d2979c8e570eae81ead564";
|
|
||||||
const String salt = "3e5b3069-214a-43ee-8d85-57d72000c19d";
|
|
||||||
var cmd = Cli
|
|
||||||
.Wrap("python3")
|
|
||||||
.WithArguments(new[]
|
|
||||||
{
|
|
||||||
"Resources/s3cmd.py", "signurl", $"s3://{installation.Id}-{salt}", validity.TotalSeconds.ToString(), "--access_key",
|
|
||||||
apiKey, "--secret_key", secret
|
|
||||||
});
|
|
||||||
var x = await cmd.ExecuteBufferedAsync();
|
|
||||||
installation.S3Url = x.StandardOutput.Replace("\n", "").Replace(" ", "");
|
|
||||||
|
|
||||||
Db.Update(installation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task<Boolean> RenewS3BucketUrl(this Installation installation, TimeSpan validity)
|
||||||
public static async Task<Boolean> CreateBucket(this Installation installation)
|
|
||||||
{
|
{
|
||||||
const String secret = "-T9TAqy9a3-0-xj7HKsFFJOCcxfRpcnL6OW5oOrOcWU";
|
installation.S3Url = await S3Access.ReadOnly.SignUrl(installation.BucketName(), validity);
|
||||||
|
return Db.Update(installation);
|
||||||
const String apiKey = "EXO87ca85e29dd412f1238f1cf0";
|
|
||||||
const String salt = "3e5b3069-214a-43ee-8d85-57d72000c19d";
|
|
||||||
|
|
||||||
var cmd = Cli
|
|
||||||
.Wrap("python3")
|
|
||||||
.WithArguments(new[]
|
|
||||||
{
|
|
||||||
"Resources/s3cmd.py", "mb", $"s3://{installation.Id}-{salt}", "--access_key",
|
|
||||||
apiKey, "--secret_key", secret
|
|
||||||
});
|
|
||||||
var x = await cmd.ExecuteBufferedAsync();
|
|
||||||
|
|
||||||
//Updating the url in the db as not wait until the next bi-daily update
|
|
||||||
var cmd2 = Cli
|
|
||||||
.Wrap("python3")
|
|
||||||
.WithArguments(new[]
|
|
||||||
{
|
|
||||||
"Resources/s3cmd.py", "signurl", $"s3://{installation.Id}-{salt}",
|
|
||||||
TimeSpan.FromDays(1).TotalSeconds.ToString(), "--access_key",
|
|
||||||
apiKey, "--secret_key", secret
|
|
||||||
});
|
|
||||||
|
|
||||||
var y = await cmd2.ExecuteBufferedAsync();
|
|
||||||
installation.S3Url = y.StandardOutput.Replace("\n", "").Replace(" ", "");
|
|
||||||
|
|
||||||
Db.Update(installation);
|
|
||||||
|
|
||||||
return x.ExitCode == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<Boolean> DeleteBucket(this Installation installation)
|
public static Task<Boolean> CreateBucket(this Installation installation)
|
||||||
{
|
{
|
||||||
const String secret = "-T9TAqy9a3-0-xj7HKsFFJOCcxfRpcnL6OW5oOrOcWU";
|
return S3Access
|
||||||
const String apiKey = "EXO87ca85e29dd412f1238f1cf0";
|
.ReadWrite
|
||||||
const String salt = "3e5b3069-214a-43ee-8d85-57d72000c19d";
|
.CreateBucket(installation.BucketName());
|
||||||
var cmd = Cli
|
}
|
||||||
.Wrap("python3")
|
|
||||||
.WithArguments(new[]
|
public static Task<Boolean> DeleteBucket(this Installation installation)
|
||||||
{
|
{
|
||||||
"Resources/s3cmd.py", "rb", $"s3://{installation.Id}-{salt}", "--access_key",
|
return S3Access
|
||||||
apiKey, "--secret_key", secret
|
.ReadWrite
|
||||||
});
|
.DeleteBucket(installation.BucketName());
|
||||||
var x = await cmd.ExecuteBufferedAsync();
|
|
||||||
return x.ExitCode == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<User> UsersWithAccess(this Installation installation)
|
public static IEnumerable<User> UsersWithAccess(this Installation installation)
|
||||||
{
|
{
|
||||||
return UsersWithDirectAccess(installation).Concat(UsersWithInheritedAccess(installation));
|
return installation.UsersWithDirectAccess()
|
||||||
|
.Concat(installation.UsersWithInheritedAccess());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<User> UsersWithDirectAccess(this Installation installation)
|
public static IEnumerable<User> UsersWithDirectAccess(this Installation installation)
|
||||||
{
|
{
|
||||||
return Db.InstallationAccess
|
return Db
|
||||||
.Where(access => access.InstallationId == installation.Id)
|
.InstallationAccess
|
||||||
.Select(access => Db.GetUserById(access.UserId))
|
.Where(a => a.InstallationId == installation.Id)
|
||||||
|
.Select(a => Db.GetUserById(a.UserId))
|
||||||
.NotNull();
|
.NotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<User> UsersWithInheritedAccess(this Installation installation)
|
public static IEnumerable<User> UsersWithInheritedAccess(this Installation installation)
|
||||||
{
|
{
|
||||||
return installation.Ancestors().SelectMany(f => f.UsersWithDirectAccess()).NotNull();
|
return installation
|
||||||
|
.Ancestors()
|
||||||
|
.SelectMany(f => f.UsersWithDirectAccess())
|
||||||
|
.NotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<Folder> Ancestors(this Installation installation)
|
public static IEnumerable<Folder> Ancestors(this Installation installation)
|
||||||
|
|
|
@ -14,7 +14,7 @@ public static class SessionMethods
|
||||||
&& user.HasWriteAccess
|
&& user.HasWriteAccess
|
||||||
&& user.HasAccessTo(folder.Parent())
|
&& user.HasAccessTo(folder.Parent())
|
||||||
&& Db.Create(folder)
|
&& Db.Create(folder)
|
||||||
&& 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)
|
||||||
|
@ -41,19 +41,19 @@ public static class SessionMethods
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Boolean Create(this Session? session, Installation? installation)
|
public static async Task<Boolean> Create(this Session? session, Installation? installation)
|
||||||
{
|
{
|
||||||
var user = session?.User;
|
var user = session?.User;
|
||||||
|
|
||||||
//Note: keep generation of access _after_ generation of object to prevent "zombie" access-rights.
|
|
||||||
|
|
||||||
return user is not null
|
return user is not null
|
||||||
&& 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)
|
||||||
&& installation.CreateBucket().Result
|
&& 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.RenewS3BucketUrl(); // generation of access _after_ generation of
|
||||||
|
// bucket to prevent "zombie" access-rights.
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean Update(this Session? session, Installation? installation)
|
public static Boolean Update(this Session? session, Installation? installation)
|
||||||
|
@ -77,6 +77,7 @@ 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?
|
||||||
&& Db.Delete(installation);
|
&& Db.Delete(installation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,13 +98,11 @@ public static class SessionMethods
|
||||||
var sessionUser = session?.User;
|
var sessionUser = session?.User;
|
||||||
if (editedUser == null || sessionUser == null) return false;
|
if (editedUser == null || sessionUser == null) return false;
|
||||||
|
|
||||||
|
// TODO: make specific method for changing user account settings like pwd
|
||||||
// Password change is only allowed for oneself
|
// Password change is only allowed for oneself
|
||||||
if ( editedUser.Id != sessionUser.Id) editedUser.Password = sessionUser.Password;
|
editedUser.Password = editedUser.Id != sessionUser.Id
|
||||||
else
|
? sessionUser.Password
|
||||||
{
|
: sessionUser.SaltAndHashPassword(editedUser.Password);
|
||||||
editedUser.Password = sessionUser.SaltAndHashPassword(editedUser.Password);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sessionUser.HasWriteAccess
|
return sessionUser.HasWriteAccess
|
||||||
&& sessionUser.HasAccessTo(editedUser)
|
&& sessionUser.HasAccessTo(editedUser)
|
||||||
|
@ -149,7 +148,7 @@ public static class SessionMethods
|
||||||
&& Db.Create(new FolderAccess { UserId = user.Id, FolderId = folder.Id });
|
&& Db.Create(new FolderAccess { UserId = user.Id, FolderId = folder.Id });
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean RevokeAccessTo(this Session? session, User? user, Installation? installation)
|
public static Boolean RevokeUserAccessTo(this Session? session, User? user, Installation? installation)
|
||||||
{
|
{
|
||||||
var sessionUser = session?.User;
|
var sessionUser = session?.User;
|
||||||
|
|
||||||
|
@ -159,11 +158,10 @@ public static class SessionMethods
|
||||||
&& user.IsDescendantOf(sessionUser)
|
&& user.IsDescendantOf(sessionUser)
|
||||||
&& sessionUser.HasAccessTo(installation)
|
&& sessionUser.HasAccessTo(installation)
|
||||||
&& user.HasAccessTo(installation)
|
&& user.HasAccessTo(installation)
|
||||||
&& Db.InstallationAccess.Delete(access =>
|
&& Db.InstallationAccess.Delete(a => a.UserId == user.Id && a.InstallationId == installation.Id) > 0;
|
||||||
access.UserId == user.Id && access.InstallationId == installation.Id) > 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean RevokeAccessTo(this Session? session, User? user, Folder? folder)
|
public static Boolean RevokeUserAccessTo(this Session? session, User? user, Folder? folder)
|
||||||
{
|
{
|
||||||
var sessionUser = session?.User;
|
var sessionUser = session?.User;
|
||||||
|
|
||||||
|
@ -173,8 +171,7 @@ public static class SessionMethods
|
||||||
&& user.IsDescendantOf(sessionUser)
|
&& user.IsDescendantOf(sessionUser)
|
||||||
&& sessionUser.HasAccessTo(folder)
|
&& sessionUser.HasAccessTo(folder)
|
||||||
&& user.HasAccessTo(folder)
|
&& user.HasAccessTo(folder)
|
||||||
&& Db.FolderAccess.Delete(access =>
|
&& Db.FolderAccess.Delete(a => a.UserId == user.Id && a.FolderId == folder.Id) > 0;
|
||||||
access.UserId == user.Id && access.FolderId == folder.Id) > 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean Logout(this Session? session)
|
public static Boolean Logout(this Session? session)
|
||||||
|
|
|
@ -32,7 +32,9 @@ public static class UserMethods
|
||||||
|
|
||||||
// Distinct because the user might have direct access
|
// Distinct because the user might have direct access
|
||||||
// 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)
|
||||||
|
// however we should leave the distinct, defensive programming...
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<TreeNode> AccessibleFoldersAndInstallations(this User user)
|
public static IEnumerable<TreeNode> AccessibleFoldersAndInstallations(this User user)
|
||||||
|
@ -81,7 +83,6 @@ public static class UserMethods
|
||||||
|
|
||||||
public static Boolean IsDescendantOf(this User user, User ancestor)
|
public static Boolean IsDescendantOf(this User user, User ancestor)
|
||||||
{
|
{
|
||||||
// if (user.Id == ancestor.Id) return true;
|
|
||||||
return user
|
return user
|
||||||
.Ancestors()
|
.Ancestors()
|
||||||
.Any(u => u.Id == ancestor.Id);
|
.Any(u => u.Id == ancestor.Id);
|
||||||
|
|
|
@ -6,7 +6,6 @@ using InnovEnergy.Lib.Utils;
|
||||||
using SQLite;
|
using SQLite;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace InnovEnergy.App.Backend.Database;
|
namespace InnovEnergy.App.Backend.Database;
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,9 +37,6 @@ public static partial class Db
|
||||||
Connection.CreateTable<Session>();
|
Connection.CreateTable<Session>();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Observable.Interval(TimeSpan.FromDays(0.5))
|
Observable.Interval(TimeSpan.FromDays(0.5))
|
||||||
.StartWith(0) // Do it right away (on startup)
|
.StartWith(0) // Do it right away (on startup)
|
||||||
.SelectMany(Cleanup)
|
.SelectMany(Cleanup)
|
||||||
|
@ -85,7 +81,8 @@ public static partial class Db
|
||||||
|
|
||||||
private static Task UpdateS3Urls()
|
private static Task UpdateS3Urls()
|
||||||
{
|
{
|
||||||
var renewTasks = Installations.Select(i => i.RenewS3BucketUrl()).ToArray();
|
return Installations
|
||||||
return Task.WhenAll(renewTasks);
|
.Select(i => i.RenewS3BucketUrl())
|
||||||
|
.WhenAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
using InnovEnergy.App.Backend.Database;
|
|
||||||
using Microsoft.OpenApi.Models;
|
using Microsoft.OpenApi.Models;
|
||||||
|
|
||||||
namespace InnovEnergy.App.Backend;
|
namespace InnovEnergy.App.Backend;
|
||||||
|
@ -7,57 +6,50 @@ public static class Program
|
||||||
{
|
{
|
||||||
public static void Main(String[] args)
|
public static void Main(String[] args)
|
||||||
{
|
{
|
||||||
Db.CreateFakeRelations();
|
//Db.CreateFakeRelations();
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
builder.Services.AddControllers(); // TODO: remove magic, specify controllers explicitly
|
//builder.Services.AddHttpContextAccessor();
|
||||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
//builder.Services.AddEndpointsApiExplorer();
|
||||||
|
//builder.Services.AddCors(o => o.AddDefaultPolicy(p => p.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()));
|
||||||
|
|
||||||
builder.Services.AddHttpContextAccessor();
|
builder.Services.AddControllers();
|
||||||
builder.Services.AddEndpointsApiExplorer();
|
|
||||||
builder.Services.AddCors(o => o.AddDefaultPolicy(p => p.WithOrigins("*").AllowAnyHeader().AllowAnyMethod()));
|
|
||||||
builder.Services.AddSwaggerGen(c =>
|
builder.Services.AddSwaggerGen(c =>
|
||||||
{
|
{
|
||||||
c.SwaggerDoc("v1", new OpenApiInfo { Title = "InnovEnergy Backend API", Version = "v1" });
|
c.SwaggerDoc("v1", OpenApiInfo);
|
||||||
c.UseAllOfToExtendReferenceSchemas();
|
c.UseAllOfToExtendReferenceSchemas();
|
||||||
c.OperationFilter<HeaderFilter>(); //Todo testing throw me out
|
c.SupportNonNullableReferenceTypes();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
// Configure the HTTP request pipeline.
|
|
||||||
if (app.Environment.IsDevelopment())
|
if (app.Environment.IsDevelopment())
|
||||||
{
|
{
|
||||||
app.UseSwagger();
|
app.UseSwagger();
|
||||||
app.UseSwaggerUI(cfg => cfg.EnableFilter());
|
app.UseSwaggerUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
app.UseCors();
|
//app.UseCors(p => p.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()) ;
|
||||||
app.UseHttpsRedirection();
|
app.UseHttpsRedirection();
|
||||||
app.UseAuthorization();
|
//app.UseAuthorization();
|
||||||
app.Use(SetSessionUser);
|
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static OpenApiInfo OpenApiInfo { get; } = new OpenApiInfo
|
||||||
|
|
||||||
private static async Task SetSessionUser(HttpContext ctx, RequestDelegate next)
|
|
||||||
{
|
{
|
||||||
var headers = ctx.Request.Headers;
|
Title = "InnovEnergy Backend API",
|
||||||
var hasToken = headers.TryGetValue("auth", out var token) ;
|
Version = "v1"
|
||||||
|
};
|
||||||
|
|
||||||
if (hasToken)
|
|
||||||
{
|
|
||||||
var session = Db.GetSession(token);
|
|
||||||
|
|
||||||
if (session is not null)
|
|
||||||
ctx.Items["Session"] = session;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await next(ctx);
|
|
||||||
}
|
// var x = new CorsPolicy
|
||||||
}
|
// {
|
||||||
|
// Headers = { "*" },
|
||||||
|
// Origins = { "*" },
|
||||||
|
// Methods = { "*" }
|
||||||
|
// };
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
namespace InnovEnergy.App.Backend.S3;
|
||||||
|
|
||||||
|
public static class S3Access
|
||||||
|
{
|
||||||
|
// TODO: put these into Json files in /Resources and read them from
|
||||||
|
// there so they can be changed without recompiling
|
||||||
|
// they should be read from disk on each use,
|
||||||
|
// so the backend does not need to be restarted on change
|
||||||
|
|
||||||
|
public static S3Cmd ReadOnly { get; } = new S3Cmd
|
||||||
|
(
|
||||||
|
key : "EXO44d2979c8e570eae81ead564",
|
||||||
|
secret: "55MAqyO_FqUmh7O64VIO0egq50ERn_WIAWuc2QC44QU"
|
||||||
|
);
|
||||||
|
|
||||||
|
public static S3Cmd ReadWrite { get; } = new S3Cmd
|
||||||
|
(
|
||||||
|
key : "EXO87ca85e29dd412f1238f1cf0",
|
||||||
|
secret: "-T9TAqy9a3-0-xj7HKsFFJOCcxfRpcnL6OW5oOrOcWU"
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
using CliWrap;
|
||||||
|
using CliWrap.Buffered;
|
||||||
|
using InnovEnergy.Lib.Utils;
|
||||||
|
|
||||||
|
namespace InnovEnergy.App.Backend.S3;
|
||||||
|
|
||||||
|
public class S3Cmd
|
||||||
|
{
|
||||||
|
private static readonly Command Python = Cli.Wrap("python3");
|
||||||
|
|
||||||
|
private const String S3CmdPath = "Resources/s3cmd.py";
|
||||||
|
private const String S3Prefix = "s3://";
|
||||||
|
|
||||||
|
private String[] DefaultArgs { get; }
|
||||||
|
|
||||||
|
// ReSharper disable StringLiteralTypo
|
||||||
|
// ReSharper enable StringLiteralTypo
|
||||||
|
|
||||||
|
public S3Cmd(String key, String secret)
|
||||||
|
{
|
||||||
|
DefaultArgs = new[]
|
||||||
|
{
|
||||||
|
S3CmdPath,
|
||||||
|
"--access_key", key,
|
||||||
|
"--secret_key", secret,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<String> SignUrl(String bucketName, TimeSpan validity)
|
||||||
|
{
|
||||||
|
var result = await Run(bucketName, "signurl", $"+{validity.TotalSeconds}");
|
||||||
|
|
||||||
|
return result
|
||||||
|
.StandardOutput
|
||||||
|
.Replace("\n", "")
|
||||||
|
.Replace(" ", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Boolean> CreateBucket(String bucketName)
|
||||||
|
{
|
||||||
|
var result = await Run(bucketName, "mb");
|
||||||
|
return result.ExitCode == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Boolean> DeleteBucket(String bucketName)
|
||||||
|
{
|
||||||
|
var result = await Run(bucketName, "rb");
|
||||||
|
return result.ExitCode == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task<BufferedCommandResult> Run(String bucketName, String operation, params String[] optionalArgs)
|
||||||
|
{
|
||||||
|
var args = DefaultArgs
|
||||||
|
.Append(operation)
|
||||||
|
.Append(bucketName.EnsureStartsWith(S3Prefix))
|
||||||
|
.Concat(optionalArgs);
|
||||||
|
|
||||||
|
return Python
|
||||||
|
.WithArguments(args)
|
||||||
|
.ExecuteBufferedAsync();
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
|
@ -33,6 +33,7 @@
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=proxyport/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=proxyport/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=resultset/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=resultset/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Salimax/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Salimax/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=signurl/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Trumpf/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Trumpf/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=ttyusb/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=ttyusb/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=tupled/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=tupled/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
|
Loading…
Reference in New Issue