cleanup Rest API
This commit is contained in:
parent
d2006b52e1
commit
c7649dced2
|
@ -4,6 +4,8 @@
|
|||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<RootNamespace>Innovenergy.Backend</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using Backend.Database;
|
||||
using Backend.Model;
|
||||
using Backend.Model.Relations;
|
||||
using Backend.Utils;
|
||||
using Innovenergy.Backend.Database;
|
||||
using Innovenergy.Backend.Model;
|
||||
using Innovenergy.Backend.Model.Relations;
|
||||
using Innovenergy.Backend.Utils;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using HttpContextAccessor = Microsoft.AspNetCore.Http.HttpContextAccessor;
|
||||
|
||||
namespace Backend.Controllers;
|
||||
namespace Innovenergy.Backend.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/")]
|
||||
public class Controller
|
||||
{
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(401)]
|
||||
[Returns<String>]
|
||||
[Returns(HttpStatusCode.Unauthorized)]
|
||||
[Returns(HttpStatusCode.BadRequest)]
|
||||
[HttpPost($"{nameof(Login)}")]
|
||||
public Object Login(Credentials credentials)
|
||||
{
|
||||
|
@ -29,14 +29,282 @@ public class Controller
|
|||
if (user is null)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
// if (!VerifyPassword(password, user))
|
||||
// return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
#if !DEBUG
|
||||
if (!VerifyPassword(credentials.Password, user))
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
#endif
|
||||
|
||||
var ses = new Session(user);
|
||||
db.NewSession(ses);
|
||||
return ses.Token;
|
||||
}
|
||||
|
||||
|
||||
[Returns(HttpStatusCode.OK)]
|
||||
[Returns(HttpStatusCode.Unauthorized)]
|
||||
[HttpPost($"{nameof(Logout)}")]
|
||||
public Object Logout()
|
||||
{
|
||||
var caller = GetCaller();
|
||||
|
||||
if (caller is null)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
using var db = Db.Connect();
|
||||
return db.DeleteSession(caller.Id);
|
||||
}
|
||||
|
||||
|
||||
[Returns(HttpStatusCode.OK)]
|
||||
[Returns(HttpStatusCode.Unauthorized)]
|
||||
[HttpPost($"{nameof(UpdateS3Credentials)}")]
|
||||
public Object UpdateS3Credentials()
|
||||
{
|
||||
// TODO: S3Credentials should be per session, not per user
|
||||
|
||||
var caller = GetCaller();
|
||||
if (caller is null)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
using var db = Db.Connect();
|
||||
|
||||
return db.CreateAndSaveUserS3ApiKey(caller);
|
||||
}
|
||||
|
||||
|
||||
[Returns<User>]
|
||||
[Returns(HttpStatusCode.Unauthorized)]
|
||||
[HttpGet($"{nameof(GetUserById)}")]
|
||||
public Object GetUserById(Int64 id)
|
||||
{
|
||||
var caller = GetCaller();
|
||||
if (caller is null)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
using var db = Db.Connect();
|
||||
|
||||
var user = db
|
||||
.GetDescendantUsers(caller)
|
||||
.FirstOrDefault(u => u.Id == id);
|
||||
|
||||
return user as Object ?? new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
}
|
||||
|
||||
|
||||
[Returns<Installation>]
|
||||
[Returns(HttpStatusCode.Unauthorized)]
|
||||
[HttpGet($"{nameof(GetInstallationById)}")]
|
||||
public Object GetInstallationById(Int64 id)
|
||||
{
|
||||
var caller = GetCaller();
|
||||
if (caller == null)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
using var db = Db.Connect();
|
||||
|
||||
var installation = db
|
||||
.GetAllAccessibleInstallations(caller)
|
||||
.FirstOrDefault(i => i.Id == id);
|
||||
|
||||
return installation as Object ?? new HttpResponseMessage(HttpStatusCode.NotFound);
|
||||
}
|
||||
|
||||
|
||||
[Returns<Folder>]
|
||||
[Returns(HttpStatusCode.Unauthorized)]
|
||||
[HttpGet($"{nameof(GetFolderById)}")]
|
||||
public Object GetFolderById(Int64 id)
|
||||
{
|
||||
var caller = GetCaller();
|
||||
if (caller == null)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
using var db = Db.Connect();
|
||||
|
||||
var folder = db
|
||||
.GetAllAccessibleFolders(caller)
|
||||
.FirstOrDefault(f => f.Id == id);
|
||||
|
||||
return folder as Object ?? new HttpResponseMessage(HttpStatusCode.NotFound);
|
||||
}
|
||||
|
||||
|
||||
[Returns<Installation[]>] // assuming swagger knows about arrays but not lists (JSON)
|
||||
[Returns(HttpStatusCode.Unauthorized)]
|
||||
[HttpGet($"{nameof(GetAllInstallations)}/")]
|
||||
public Object GetAllInstallations()
|
||||
{
|
||||
var caller = GetCaller();
|
||||
if (caller == null)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
using var db = Db.Connect();
|
||||
|
||||
return db
|
||||
.GetAllAccessibleInstallations(caller)
|
||||
.ToList(); // important!
|
||||
}
|
||||
|
||||
|
||||
[Returns<Folder[]>] // assuming swagger knows about arrays but not lists (JSON)
|
||||
[Returns(HttpStatusCode.Unauthorized)]
|
||||
[HttpGet($"{nameof(GetAllFolders)}/")]
|
||||
public Object GetAllFolders()
|
||||
{
|
||||
var caller = GetCaller();
|
||||
if (caller == null)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
using var db = Db.Connect();
|
||||
return db
|
||||
.GetAllAccessibleFolders(caller)
|
||||
.ToList(); // important!
|
||||
}
|
||||
|
||||
|
||||
[Returns(HttpStatusCode.OK)]
|
||||
[Returns(HttpStatusCode.Unauthorized)]
|
||||
[HttpPut($"{nameof(UpdateUser)}/")]
|
||||
public Object UpdateUser(User updatedUser)
|
||||
{
|
||||
// TODO: distinguish between create and update
|
||||
|
||||
var caller = GetCaller();
|
||||
if (caller == null)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
using var db = Db.Connect();
|
||||
|
||||
return db.GetUserById(updatedUser.Id) != null
|
||||
? db.UpdateUser(updatedUser)
|
||||
: db.CreateUser(updatedUser);
|
||||
}
|
||||
|
||||
|
||||
[Returns(HttpStatusCode.OK)]
|
||||
[Returns(HttpStatusCode.Unauthorized)]
|
||||
[HttpPut($"{nameof(UpdateInstallation)}/")]
|
||||
public Object UpdateInstallation(Installation updatedInstallation)
|
||||
{
|
||||
var caller = GetCaller();
|
||||
|
||||
if (caller is null || !caller.HasWriteAccess)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
using var db = Db.Connect();
|
||||
|
||||
var hasAccessToInstallation = db
|
||||
.GetAllAccessibleInstallations(caller)
|
||||
.Any(i => i.Id == updatedInstallation.Id);
|
||||
|
||||
if (!hasAccessToInstallation)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
// TODO: accessibility by other users etc
|
||||
// TODO: sanity check changes
|
||||
|
||||
return db.UpdateInstallation(updatedInstallation);
|
||||
}
|
||||
|
||||
|
||||
[Returns(HttpStatusCode.OK)]
|
||||
[Returns(HttpStatusCode.Unauthorized)]
|
||||
[HttpPut($"{nameof(UpdateFolder)}/")]
|
||||
public Object UpdateFolder(Folder folder)
|
||||
{
|
||||
var caller = GetCaller();
|
||||
|
||||
if (caller is null || !caller.HasWriteAccess)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
using var db = Db.Connect();
|
||||
|
||||
var hasAccessToFolder = db
|
||||
.GetAllAccessibleFolders(caller)
|
||||
.Any(f => f.Id == folder.Id);
|
||||
|
||||
if (!hasAccessToFolder)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
// TODO: accessibility by other users etc
|
||||
// TODO: sanity check changes
|
||||
|
||||
return db.UpdateFolder(folder);
|
||||
}
|
||||
|
||||
[Returns(HttpStatusCode.OK)]
|
||||
[Returns(HttpStatusCode.Unauthorized)]
|
||||
[HttpDelete($"{nameof(DeleteUser)}/")]
|
||||
public Object DeleteUser(Int64 userId)
|
||||
{
|
||||
var caller = GetCaller();
|
||||
|
||||
if (caller is null || !caller.HasWriteAccess)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
using var db = Db.Connect();
|
||||
|
||||
var userToBeDeleted = db
|
||||
.GetDescendantUsers(caller)
|
||||
.FirstOrDefault(u => u.Id == userId);
|
||||
|
||||
if (userToBeDeleted is null)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
return db.DeleteUser(userToBeDeleted);
|
||||
}
|
||||
|
||||
[Returns(HttpStatusCode.OK)]
|
||||
[Returns(HttpStatusCode.Unauthorized)]
|
||||
[HttpDelete($"{nameof(DeleteInstallation)}/")]
|
||||
public Object DeleteInstallation(Int64 installationId)
|
||||
{
|
||||
var caller = GetCaller();
|
||||
|
||||
if (caller is null || !caller.HasWriteAccess)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
using var db = Db.Connect();
|
||||
|
||||
var installationToBeDeleted = db
|
||||
.GetAllAccessibleInstallations(caller)
|
||||
.FirstOrDefault(i => i.Id == installationId);
|
||||
|
||||
if (installationToBeDeleted is null)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
return db.DeleteInstallation(installationToBeDeleted);
|
||||
}
|
||||
|
||||
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(401)]
|
||||
[HttpDelete($"{nameof(DeleteFolder)}/")]
|
||||
public Object DeleteFolder(Int64 folderId)
|
||||
{
|
||||
var caller = GetCaller();
|
||||
if (caller == null)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
using var db = Db.Connect();
|
||||
|
||||
var folderToDelete = db
|
||||
.GetAllAccessibleFolders(caller)
|
||||
.FirstOrDefault(f => f.Id == folderId);
|
||||
|
||||
if (folderToDelete is null)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
return db.DeleteFolder(folderToDelete);
|
||||
}
|
||||
|
||||
|
||||
private static User? GetCaller()
|
||||
{
|
||||
var ctxAccessor = new HttpContextAccessor();
|
||||
return ctxAccessor.HttpContext?.Items["User"] as User;
|
||||
}
|
||||
|
||||
private static Boolean VerifyPassword(String password, User user)
|
||||
{
|
||||
var pwdBytes = Encoding.UTF8.GetBytes(password);
|
||||
|
@ -46,258 +314,7 @@ public class Controller
|
|||
return user.Password == pwdHash;
|
||||
}
|
||||
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(401)]
|
||||
[HttpPost($"{nameof(Logout)}")]
|
||||
public Object Logout()
|
||||
{
|
||||
var ctxAccessor = new HttpContextAccessor();
|
||||
var ctx = ctxAccessor.HttpContext;
|
||||
using var db = Db.Connect();
|
||||
var currentUser = (User)ctx.Items["User"];
|
||||
|
||||
if (currentUser is null)
|
||||
return new HttpResponseMessage(HttpStatusCode.Conflict);
|
||||
|
||||
return db.DeleteSession(currentUser.Id);
|
||||
}
|
||||
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(401)]
|
||||
[HttpPost($"{nameof(UpdateS3Creds)}")]
|
||||
public Object UpdateS3Creds()
|
||||
{
|
||||
var ctxAccessor = new HttpContextAccessor();
|
||||
var ctx = ctxAccessor.HttpContext;
|
||||
using var db = Db.Connect();
|
||||
var currentUser = (User)ctx!.Items["User"]!;
|
||||
|
||||
return db.CreateAndSaveUserS3ApiKey(currentUser);
|
||||
}
|
||||
|
||||
|
||||
[ProducesResponseType(typeof(User), 200)]
|
||||
[ProducesResponseType(401)]
|
||||
[HttpGet($"{nameof(GetUserById)}")]
|
||||
public Object GetUserById(Int64 id)
|
||||
{
|
||||
var ctxAccessor = new HttpContextAccessor();
|
||||
var ctx = ctxAccessor.HttpContext;
|
||||
using var db = Db.Connect();
|
||||
var currentUser = (User)ctx.Items["User"];
|
||||
var viewedUser = db.GetUserById(id);
|
||||
|
||||
//using the same error to prevent fishing for ids
|
||||
if (currentUser == null || viewedUser == null || !db.IsParentOfChild(currentUser, viewedUser))
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
return viewedUser;
|
||||
}
|
||||
|
||||
[ProducesResponseType(typeof(Installation), 200)]
|
||||
[ProducesResponseType(401)]
|
||||
[HttpGet($"{nameof(GetInstallationById)}")]
|
||||
public Object GetInstallationById(Int64 id)
|
||||
{
|
||||
var ctxAccessor = new HttpContextAccessor();
|
||||
var ctx = ctxAccessor.HttpContext;
|
||||
using var db = Db.Connect();
|
||||
var currentUser = (User)ctx.Items["User"];
|
||||
|
||||
if (currentUser == null)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
var installation = db
|
||||
.GetAllAccessibleInstallations(currentUser)
|
||||
.FirstOrDefault(i => i.Id == id);
|
||||
|
||||
if (installation is null)
|
||||
return new HttpResponseMessage(HttpStatusCode.NotFound);
|
||||
|
||||
return installation;
|
||||
}
|
||||
|
||||
[ProducesResponseType(typeof(Folder), 200)]
|
||||
[ProducesResponseType(401)]
|
||||
[HttpGet($"{nameof(GetFolderById)}")]
|
||||
public Object GetFolderById(Int64 id)
|
||||
{
|
||||
var ctxAccessor = new HttpContextAccessor();
|
||||
var ctx = ctxAccessor.HttpContext;
|
||||
using var db = Db.Connect();
|
||||
var currentUser = (User)ctx.Items["User"];
|
||||
|
||||
var folder = db
|
||||
.GetAllAccessibleFolders(currentUser!)
|
||||
.FirstOrDefault(f => f.Id == id);
|
||||
|
||||
if(folder is null)
|
||||
return new HttpResponseMessage(HttpStatusCode.NotFound);
|
||||
|
||||
return folder;
|
||||
}
|
||||
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(401)]
|
||||
[HttpGet($"{nameof(GetAllInstallations)}/")]
|
||||
public Object GetAllInstallations()
|
||||
{
|
||||
var ctxAccessor = new HttpContextAccessor();
|
||||
var ctx = ctxAccessor.HttpContext;
|
||||
using var db = Db.Connect();
|
||||
var user = (User)ctx.Items["User"];
|
||||
|
||||
if (user == null)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
return db.GetAllAccessibleInstallations(user).ToList();
|
||||
}
|
||||
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(401)]
|
||||
[HttpGet($"{nameof(GetAllFolders)}/")]
|
||||
public Object GetAllFolders()
|
||||
{
|
||||
var ctxAccessor = new HttpContextAccessor();
|
||||
var ctx = ctxAccessor.HttpContext;
|
||||
var user = (User)ctx.Items["User"];
|
||||
|
||||
using var db = Db.Connect();
|
||||
|
||||
if (user == null)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
return db.GetAllAccessibleFolders(user).ToList();
|
||||
}
|
||||
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(401)]
|
||||
[HttpPut($"{nameof(UpdateUser)}/")]
|
||||
public Object UpdateUser(User updatedUser)
|
||||
{
|
||||
var ctxAccessor = new HttpContextAccessor();
|
||||
var ctx = ctxAccessor.HttpContext;
|
||||
using var db = Db.Connect();
|
||||
var currentUser = (User)ctx.Items["User"];
|
||||
|
||||
if (currentUser == null || !currentUser.HasWriteAccess || !db.IsParentOfChild(currentUser, updatedUser))
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
return db.GetUserById(updatedUser.Id) != null ? db.UpdateUser(updatedUser) : db.CreateUser(updatedUser);
|
||||
}
|
||||
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(401)]
|
||||
[HttpPut($"{nameof(UpdateInstallation)}/")]
|
||||
public Object UpdateInstallation(Installation updatedInstallation)
|
||||
{
|
||||
var ctxAccessor = new HttpContextAccessor();
|
||||
var ctx = ctxAccessor.HttpContext;
|
||||
|
||||
var currentUser = (User)ctx.Items["User"];
|
||||
|
||||
if (currentUser == null || !currentUser.HasWriteAccess)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
using var db = Db.Connect();
|
||||
|
||||
var hasAccess = db.GetAllAccessibleInstallations(currentUser)
|
||||
.Any(i => i.Id == updatedInstallation.Id);
|
||||
if (!hasAccess)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
// TODO: accessibility by other users etc
|
||||
// TODO: sanity check changes
|
||||
|
||||
return db.UpdateInstallation(updatedInstallation);
|
||||
}
|
||||
|
||||
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(401)]
|
||||
[HttpPut($"{nameof(UpdateFolder)}/")]
|
||||
public Object UpdateFolder(Folder updatedFolder)
|
||||
{
|
||||
var ctxAccessor = new HttpContextAccessor();
|
||||
var ctx = ctxAccessor.HttpContext;
|
||||
using var db = Db.Connect();
|
||||
var currentUser = (User)ctx.Items["User"];
|
||||
|
||||
if (currentUser == null || !currentUser.HasWriteAccess)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
var hasAccess = db.GetAllAccessibleFolders(currentUser)
|
||||
.Any(f => f.Id == updatedFolder.Id);
|
||||
|
||||
if (!hasAccess)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
// TODO: accessibility by other users etc
|
||||
// TODO: sanity check changes
|
||||
|
||||
return db.UpdateFolder(updatedFolder);
|
||||
}
|
||||
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(401)]
|
||||
[HttpDelete($"{nameof(DeleteUser)}/")]
|
||||
public Object DeleteUser(Int64 userId)
|
||||
{
|
||||
var ctxAccessor = new HttpContextAccessor();
|
||||
var ctx = ctxAccessor.HttpContext;
|
||||
using var db = Db.Connect();
|
||||
var currentUser = (User)ctx.Items["User"];
|
||||
var userToBeDeleted = db.GetUserById(userId);
|
||||
|
||||
if (currentUser == null
|
||||
|| userToBeDeleted == null
|
||||
|| !currentUser.HasWriteAccess
|
||||
|| !db.IsParentOfChild(currentUser,userToBeDeleted))
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
return db.DeleteUser(userToBeDeleted);
|
||||
}
|
||||
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(401)]
|
||||
[HttpDelete($"{nameof(DeleteInstallation)}/")]
|
||||
public Object DeleteInstallation(Int64 idOfInstallationToBeDeleted)
|
||||
{
|
||||
var ctxAccessor = new HttpContextAccessor();
|
||||
var ctx = ctxAccessor.HttpContext;
|
||||
using var db = Db.Connect();
|
||||
var currentUser = (User)ctx.Items["User"];
|
||||
|
||||
var installationToBeDeleted = db
|
||||
.GetAllAccessibleInstallations(currentUser!)
|
||||
.FirstOrDefault(i => i.Id == idOfInstallationToBeDeleted);
|
||||
|
||||
if (installationToBeDeleted is null)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
return db.DeleteInstallation(installationToBeDeleted);
|
||||
}
|
||||
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(401)]
|
||||
[HttpDelete($"{nameof(DeleteFolder)}/")]
|
||||
public Object DeleteFolder(Int64 folderId)
|
||||
{
|
||||
var ctxAccessor = new HttpContextAccessor();
|
||||
var ctx = ctxAccessor.HttpContext;
|
||||
using var db = Db.Connect();
|
||||
var currentUser = (User)ctx.Items["User"];
|
||||
|
||||
var folderToDelete = db
|
||||
.GetAllAccessibleFolders(currentUser!)
|
||||
.FirstOrDefault(f => f.Id == folderId);
|
||||
|
||||
if (folderToDelete is null)
|
||||
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
|
||||
|
||||
return db.DeleteFolder(folderToDelete);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
namespace Backend.Controllers;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Innovenergy.Backend.Controllers;
|
||||
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
|
||||
public record Credentials(String Username, String Password);
|
|
@ -1,11 +1,11 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using Backend.Model;
|
||||
using Backend.Model.Relations;
|
||||
using Backend.Utils;
|
||||
using Innovenergy.Backend.Model;
|
||||
using Innovenergy.Backend.Model.Relations;
|
||||
using Innovenergy.Backend.Utils;
|
||||
using InnovEnergy.Lib.Utils;
|
||||
using SQLite;
|
||||
|
||||
namespace Backend.Database;
|
||||
namespace Innovenergy.Backend.Database;
|
||||
|
||||
public partial class Db : IDisposable
|
||||
{
|
||||
|
@ -98,6 +98,8 @@ public partial class Db : IDisposable
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public IEnumerable<Folder> GetAllAccessibleFolders(User user)
|
||||
{
|
||||
return GetDirectlyAccessibleFolders(user)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using Backend.Model.Relations;
|
||||
using Innovenergy.Backend.Model.Relations;
|
||||
|
||||
namespace Backend.Database;
|
||||
namespace Innovenergy.Backend.Database;
|
||||
|
||||
public partial class Db
|
||||
{
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
using Backend.Model;
|
||||
using Backend.Utils;
|
||||
using Innovenergy.Backend.Model;
|
||||
using Innovenergy.Backend.Utils;
|
||||
using InnovEnergy.Lib.Utils;
|
||||
using SQLite;
|
||||
|
||||
namespace Backend.Database;
|
||||
namespace Innovenergy.Backend.Database;
|
||||
|
||||
public partial class Db
|
||||
{
|
||||
|
@ -37,6 +37,15 @@ public partial class Db
|
|||
return Installations.Where(f => f.ParentId == parent.Id);
|
||||
}
|
||||
|
||||
public IEnumerable<User> GetChildUsers(User parent)
|
||||
{
|
||||
return Users.Where(f => f.ParentId == parent.Id);
|
||||
}
|
||||
|
||||
public IEnumerable<User> GetDescendantUsers(User parent)
|
||||
{
|
||||
return parent.Traverse(GetChildUsers);
|
||||
}
|
||||
|
||||
public Result CreateFolder(Folder folder)
|
||||
{
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
using Backend.Model;
|
||||
using Backend.Utils;
|
||||
using Innovenergy.Backend.Model;
|
||||
using Innovenergy.Backend.Utils;
|
||||
using SQLite;
|
||||
|
||||
namespace Backend.Database;
|
||||
namespace Innovenergy.Backend.Database;
|
||||
|
||||
public partial class Db
|
||||
{
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
using System.Net;
|
||||
using System.Net.Mail;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using Backend.Model;
|
||||
using Backend.Utils;
|
||||
using Flurl.Http;
|
||||
using Innovenergy.Backend.Model;
|
||||
using Innovenergy.Backend.Utils;
|
||||
using InnovEnergy.Lib.Utils;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using SQLite;
|
||||
|
||||
#pragma warning disable CS0472
|
||||
#pragma warning disable CS8602
|
||||
|
||||
namespace Backend.Database;
|
||||
namespace Innovenergy.Backend.Database;
|
||||
|
||||
public partial class Db
|
||||
{
|
||||
|
@ -22,7 +20,7 @@ public partial class Db
|
|||
|
||||
public User? GetUserById(Int64 id)
|
||||
{
|
||||
return Users.FirstOrDefault(u => u.Id == id);
|
||||
return Users.FirstOrDefault(u => u.Id == id);
|
||||
}
|
||||
|
||||
public Boolean IsParentOfChild(User parent, User child)
|
||||
|
@ -65,9 +63,11 @@ public partial class Db
|
|||
const String secret = "S2K1okphiCSNK4mzqr4swguFzngWAMb1OoSlZsJa9F0";
|
||||
const String apiKey = "EXOb98ec9008e3ec16e19d7b593";
|
||||
var payload = new
|
||||
{ name = user.Email,
|
||||
operations = new List<String> {"getObject", "listBucket"},
|
||||
content = new List<Object>{}};
|
||||
{
|
||||
name = user.Email,
|
||||
operations = new List<String> { "getObject", "listBucket" },
|
||||
content = new List<Object> { }
|
||||
};
|
||||
|
||||
var installationIdList = User2Installation
|
||||
.Where(i => i.UserId == user.Id)
|
||||
|
@ -76,7 +76,7 @@ public partial class Db
|
|||
|
||||
foreach (var installation in installationIdList)
|
||||
{
|
||||
payload.content.Add(new {domain = "sos", resource_type = "bucket", resource_name = installation.Name}); //TODO CHANGE NAME TO S3BUCKET
|
||||
payload.content.Add(new { domain = "sos", resource_type = "bucket", resource_name = installation.Name }); //TODO CHANGE NAME TO S3BUCKET
|
||||
}
|
||||
|
||||
using var hmacSha1 = new HMACSHA1(Encoding.UTF8.GetBytes(secret));
|
||||
|
@ -94,7 +94,7 @@ public partial class Db
|
|||
return SetUserS3ApiKey(user, keyJson.GetValue("key"));
|
||||
}
|
||||
|
||||
public Result SetUserS3ApiKey(User user,String key)
|
||||
public Result SetUserS3ApiKey(User user, String key)
|
||||
{
|
||||
user.S3Key = key;
|
||||
return Update(user);
|
||||
|
@ -109,16 +109,16 @@ public partial class Db
|
|||
//Checking for unchangeable things
|
||||
// TODO: depends on privileges of caller
|
||||
|
||||
user.Id = oldUser.Id;
|
||||
user.Id = oldUser.Id;
|
||||
user.ParentId = oldUser.ParentId;
|
||||
user.Email = oldUser.Email;
|
||||
user.Email = oldUser.Email;
|
||||
|
||||
return Update(user);
|
||||
}
|
||||
|
||||
public Result DeleteUser(User user)
|
||||
{
|
||||
User2Folder .Delete(u => u.UserId == user.Id);
|
||||
User2Folder.Delete(u => u.UserId == user.Id);
|
||||
User2Installation.Delete(u => u.UserId == user.Id);
|
||||
|
||||
//Todo check for orphaned Installations/Folders
|
||||
|
@ -140,10 +140,7 @@ public partial class Db
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using Backend.Model.Relations;
|
||||
using Innovenergy.Backend.Model.Relations;
|
||||
using SQLite;
|
||||
|
||||
namespace Backend.Database;
|
||||
namespace Innovenergy.Backend.Database;
|
||||
|
||||
public partial class Db
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using Backend.Model.Relations;
|
||||
using Innovenergy.Backend.Model.Relations;
|
||||
using SQLite;
|
||||
|
||||
namespace Backend.Database;
|
||||
namespace Innovenergy.Backend.Database;
|
||||
|
||||
public partial class Db
|
||||
{
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
using Microsoft.OpenApi.Models;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
|
||||
namespace Innovenergy.Backend;
|
||||
|
||||
/// <summary>
|
||||
/// This is for convenient testing! Todo throw me out?
|
||||
/// Operation filter to add the requirement of the custom header
|
||||
/// </summary>
|
||||
public class HeaderFilter : IOperationFilter
|
||||
{
|
||||
public void Apply(OpenApiOperation operation, OperationFilterContext context)
|
||||
{
|
||||
operation.Parameters ??= new List<OpenApiParameter>();
|
||||
|
||||
operation.Parameters.Add(new OpenApiParameter
|
||||
{
|
||||
Name = "auth",
|
||||
In = ParameterLocation.Header,
|
||||
Content = new Dictionary<String, OpenApiMediaType>(),
|
||||
Required = false
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,6 +1,4 @@
|
|||
using SQLite;
|
||||
|
||||
namespace Backend.Model;
|
||||
namespace Innovenergy.Backend.Model;
|
||||
|
||||
public class Folder : TreeNode
|
||||
{
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
using SQLite;
|
||||
|
||||
namespace Backend.Model;
|
||||
namespace Innovenergy.Backend.Model;
|
||||
|
||||
|
||||
public class Installation : TreeNode
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using SQLite;
|
||||
|
||||
namespace Backend.Model.Relations;
|
||||
namespace Innovenergy.Backend.Model.Relations;
|
||||
|
||||
public abstract class Relation<L,R>
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using SQLite;
|
||||
|
||||
namespace Backend.Model.Relations;
|
||||
namespace Innovenergy.Backend.Model.Relations;
|
||||
|
||||
public class Session : Relation<String, Int64>
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using SQLite;
|
||||
|
||||
namespace Backend.Model.Relations;
|
||||
namespace Innovenergy.Backend.Model.Relations;
|
||||
|
||||
internal class User2Folder : Relation<Int64, Int64>
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using SQLite;
|
||||
|
||||
namespace Backend.Model.Relations;
|
||||
namespace Innovenergy.Backend.Model.Relations;
|
||||
|
||||
internal class User2Installation : Relation<Int64, Int64>
|
||||
{
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using SQLite;
|
||||
|
||||
|
||||
namespace Backend.Model;
|
||||
namespace Innovenergy.Backend.Model;
|
||||
|
||||
public abstract class TreeNode
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using SQLite;
|
||||
|
||||
namespace Backend.Model;
|
||||
namespace Innovenergy.Backend.Model;
|
||||
|
||||
public class User : TreeNode
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using System.Security.Cryptography;
|
||||
|
||||
namespace Backend.Utils;
|
||||
namespace Innovenergy.Backend.Utils;
|
||||
|
||||
public static class Crypto
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace Backend.Utils;
|
||||
namespace Innovenergy.Backend.Utils;
|
||||
|
||||
public class Result
|
||||
{
|
||||
|
|
Binary file not shown.
|
@ -1,104 +1,59 @@
|
|||
using Backend.Controllers;
|
||||
using Backend.Database;
|
||||
using Innovenergy.Backend.Database;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
|
||||
namespace Innovenergy.Backend;
|
||||
|
||||
using (var db = Db.Connect())
|
||||
public class Program
|
||||
{
|
||||
db.CreateFakeRelations();
|
||||
}
|
||||
|
||||
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
builder.Services.AddControllers(); // TODO: remove magic, specify controllers explicitly
|
||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||
|
||||
builder.Services.AddHttpContextAccessor();
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddCors(o => o.AddDefaultPolicy(p => p.WithOrigins("*").AllowAnyHeader().AllowAnyMethod()));
|
||||
builder.Services.AddSwaggerGen(config =>
|
||||
{
|
||||
config.SwaggerDoc("v1", new OpenApiInfo{ Title = "My API", Version = "V1" });
|
||||
config.OperationFilter<MyHeaderFilter>(); //Todo testing throw me out
|
||||
});
|
||||
|
||||
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI(cfg => cfg.EnableFilter());
|
||||
}
|
||||
|
||||
app.UseCors();
|
||||
app.UseHttpsRedirection();
|
||||
app.UseAuthorization();
|
||||
app.Use(SetSessionUser);
|
||||
app.MapControllers();
|
||||
|
||||
app.Run();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//================= Functions for above ===================
|
||||
|
||||
//Setting User for current Session
|
||||
async Task SetSessionUser(HttpContext ctx, RequestDelegate next)
|
||||
{
|
||||
var headers = ctx.Request.Headers;
|
||||
var hasToken = headers.TryGetValue("auth", out var token);
|
||||
|
||||
if (!ctx.Request.Path.ToString().Contains(nameof(Controller.Login)))
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
if (!hasToken)
|
||||
using (var db = Db.Connect())
|
||||
db.CreateFakeRelations();
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
builder.Services.AddControllers(); // TODO: remove magic, specify controllers explicitly
|
||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||
|
||||
builder.Services.AddHttpContextAccessor();
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddCors(o => o.AddDefaultPolicy(p => p.WithOrigins("*").AllowAnyHeader().AllowAnyMethod()));
|
||||
builder.Services.AddSwaggerGen(config =>
|
||||
{
|
||||
ctx.Response.StatusCode = 403;
|
||||
return;
|
||||
}
|
||||
|
||||
using var db = Db.Connect();
|
||||
var user = db.GetUserByToken(token.ToString());
|
||||
|
||||
if (user is null)
|
||||
{
|
||||
ctx.Response.StatusCode = 403;
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.Items["User"] = user;
|
||||
}
|
||||
|
||||
await next(ctx);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This is for convenient testing! Todo throw me out?
|
||||
/// Operation filter to add the requirement of the custom header
|
||||
/// </summary>
|
||||
public class MyHeaderFilter : IOperationFilter
|
||||
{
|
||||
public void Apply(OpenApiOperation operation, OperationFilterContext context)
|
||||
{
|
||||
operation.Parameters ??= new List<OpenApiParameter>();
|
||||
|
||||
operation.Parameters.Add(new OpenApiParameter
|
||||
{
|
||||
Name = "auth",
|
||||
In = ParameterLocation.Header,
|
||||
Content = new Dictionary<String, OpenApiMediaType>(),
|
||||
Required = false
|
||||
config.SwaggerDoc("v1", new OpenApiInfo{ Title = "My API", Version = "V1" });
|
||||
config.OperationFilter<HeaderFilter>(); //Todo testing throw me out
|
||||
});
|
||||
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI(cfg => cfg.EnableFilter());
|
||||
}
|
||||
|
||||
app.UseCors();
|
||||
app.UseHttpsRedirection();
|
||||
app.UseAuthorization();
|
||||
app.Use(SetSessionUser);
|
||||
app.MapControllers();
|
||||
|
||||
app.Run();
|
||||
}
|
||||
|
||||
private static async Task SetSessionUser(HttpContext ctx, RequestDelegate next)
|
||||
{
|
||||
var headers = ctx.Request.Headers;
|
||||
var hasToken = headers.TryGetValue("auth", out var token);
|
||||
|
||||
if (hasToken)
|
||||
{
|
||||
using var db = Db.Connect();
|
||||
ctx.Items["User"] = db.GetUserByToken(token.ToString());
|
||||
}
|
||||
|
||||
await next(ctx);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue