Innovenergy_trunk/csharp/App/Backend/Controllers/Controller.cs

444 lines
14 KiB
C#
Raw Normal View History

2023-02-16 12:57:06 +00:00
using System.Net;
2023-02-16 14:08:50 +00:00
using System.Text;
2023-03-08 12:20:33 +00:00
using InnovEnergy.App.Backend.Database;
using InnovEnergy.App.Backend.Model;
using InnovEnergy.App.Backend.Model.Relations;
using InnovEnergy.App.Backend.Utils;
2023-02-16 12:57:06 +00:00
using Microsoft.AspNetCore.Mvc;
using HttpContextAccessor = Microsoft.AspNetCore.Http.HttpContextAccessor;
2023-02-16 12:57:06 +00:00
2023-03-08 12:20:33 +00:00
namespace InnovEnergy.App.Backend.Controllers;
2023-02-16 12:57:06 +00:00
[ApiController]
[Route("api/")]
public class Controller
{
2023-02-24 11:58:47 +00:00
[Returns<String>]
[Returns(HttpStatusCode.Unauthorized)]
[Returns(HttpStatusCode.BadRequest)]
2023-02-16 12:57:06 +00:00
[HttpPost($"{nameof(Login)}")]
public Object Login(Credentials credentials)
2023-02-16 12:57:06 +00:00
{
if (String.IsNullOrWhiteSpace(credentials.Username) ||
String.IsNullOrWhiteSpace(credentials.Password))
2023-02-16 12:57:06 +00:00
return new HttpResponseMessage(HttpStatusCode.BadRequest);
2023-02-16 14:08:50 +00:00
2023-02-16 12:57:06 +00:00
using var db = Db.Connect();
var user = db.GetUserByEmail(credentials.Username);
2023-02-16 14:08:50 +00:00
if (user is null)
2023-02-16 12:57:06 +00:00
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
2023-02-24 11:58:47 +00:00
#if !DEBUG
if (!VerifyPassword(credentials.Password, user))
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
#endif
2023-02-16 12:57:06 +00:00
var ses = new Session(user);
db.NewSession(ses);
return ses.Token;
}
2023-02-24 11:58:47 +00:00
[Returns(HttpStatusCode.OK)]
[Returns(HttpStatusCode.Unauthorized)]
[HttpPost($"{nameof(Logout)}")]
public Object Logout()
{
2023-02-24 11:58:47 +00:00
var caller = GetCaller();
2023-02-24 11:58:47 +00:00
if (caller is null)
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
2023-02-24 11:58:47 +00:00
using var db = Db.Connect();
return db.DeleteSession(caller.Id);
}
2023-02-24 11:58:47 +00:00
[Returns(HttpStatusCode.OK)]
[Returns(HttpStatusCode.Unauthorized)]
2023-03-09 11:50:21 +00:00
[HttpGet($"{nameof(GetInstallationS3Key)}")]
public Object GetInstallationS3Key(Int64 installationId)
2023-02-22 13:46:36 +00:00
{
2023-02-24 11:58:47 +00:00
var caller = GetCaller();
if (caller is null)
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
2023-02-22 13:46:36 +00:00
using var db = Db.Connect();
2023-03-09 11:50:21 +00:00
var installation = db
.GetAllAccessibleInstallations(caller)
.FirstOrDefault(i => i.Id == installationId);
2023-02-22 13:46:36 +00:00
2023-03-09 11:50:21 +00:00
if(installation == null)
{
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
}
var key = db.GetInstallationS3Key(installationId);
return key ?? db.CreateAndSaveInstallationS3ApiKey(installation);
2023-02-22 13:46:36 +00:00
}
2023-02-16 14:08:50 +00:00
2023-02-24 11:58:47 +00:00
[Returns<User>]
[Returns(HttpStatusCode.Unauthorized)]
2023-02-16 14:08:50 +00:00
[HttpGet($"{nameof(GetUserById)}")]
public Object GetUserById(Int64 id)
{
2023-02-24 11:58:47 +00:00
var caller = GetCaller();
if (caller is null)
2023-02-16 14:08:50 +00:00
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
2023-02-24 11:58:47 +00:00
using var db = Db.Connect();
2023-02-16 14:08:50 +00:00
2023-02-24 11:58:47 +00:00
var user = db
.GetDescendantUsers(caller)
.FirstOrDefault(u => u.Id == id);
return user as Object ?? new HttpResponseMessage(HttpStatusCode.Unauthorized);
}
2023-02-24 11:58:47 +00:00
[Returns<Installation>]
[Returns(HttpStatusCode.Unauthorized)]
2023-02-16 14:08:50 +00:00
[HttpGet($"{nameof(GetInstallationById)}")]
public Object GetInstallationById(Int64 id)
{
2023-02-24 11:58:47 +00:00
var caller = GetCaller();
if (caller == null)
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
2023-02-24 11:58:47 +00:00
using var db = Db.Connect();
var installation = db
2023-02-24 11:58:47 +00:00
.GetAllAccessibleInstallations(caller)
.FirstOrDefault(i => i.Id == id);
2023-02-24 11:58:47 +00:00
return installation as Object ?? new HttpResponseMessage(HttpStatusCode.NotFound);
2023-02-16 14:08:50 +00:00
}
2023-02-24 11:58:47 +00:00
[Returns<Folder>]
[Returns(HttpStatusCode.Unauthorized)]
2023-02-16 14:08:50 +00:00
[HttpGet($"{nameof(GetFolderById)}")]
public Object GetFolderById(Int64 id)
{
2023-02-24 11:58:47 +00:00
var caller = GetCaller();
if (caller == null)
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
2023-02-16 14:08:50 +00:00
using var db = Db.Connect();
2023-02-24 11:58:47 +00:00
var folder = db
2023-02-24 11:58:47 +00:00
.GetAllAccessibleFolders(caller)
.FirstOrDefault(f => f.Id == id);
2023-02-24 11:58:47 +00:00
return folder as Object ?? new HttpResponseMessage(HttpStatusCode.NotFound);
2023-02-16 14:08:50 +00:00
}
2023-02-24 11:58:47 +00:00
[Returns<Installation[]>] // assuming swagger knows about arrays but not lists (JSON)
[Returns(HttpStatusCode.Unauthorized)]
2023-02-16 12:57:06 +00:00
[HttpGet($"{nameof(GetAllInstallations)}/")]
public Object GetAllInstallations()
{
2023-02-24 11:58:47 +00:00
var caller = GetCaller();
if (caller == null)
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
2023-02-24 11:58:47 +00:00
using var db = Db.Connect();
2023-02-16 12:57:06 +00:00
2023-02-24 11:58:47 +00:00
return db
.GetAllAccessibleInstallations(caller)
.ToList(); // important!
2023-02-16 12:57:06 +00:00
}
2023-02-24 11:58:47 +00:00
[Returns<Folder[]>] // assuming swagger knows about arrays but not lists (JSON)
[Returns(HttpStatusCode.Unauthorized)]
2023-02-16 12:57:06 +00:00
[HttpGet($"{nameof(GetAllFolders)}/")]
public Object GetAllFolders()
{
2023-02-24 11:58:47 +00:00
var caller = GetCaller();
if (caller == null)
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
2023-02-24 11:58:47 +00:00
using var db = Db.Connect();
return db
.GetAllAccessibleFolders(caller)
.ToList(); // important!
2023-02-16 12:57:06 +00:00
}
2023-02-24 12:59:56 +00:00
[Returns<TreeNode[]>] // assuming swagger knows about arrays but not lists (JSON)
[Returns(HttpStatusCode.Unauthorized)]
[HttpGet($"{nameof(GetTree)}/")]
public Object GetTree()
{
var caller = GetCaller();
if (caller == null)
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
using var db = Db.Connect();
var folders = db
.GetDirectlyAccessibleFolders(caller) // ReSharper disable once AccessToDisposedClosure
2023-02-24 12:59:56 +00:00
.Select(f => PopulateChildren(db, f));
var installations = db.GetDirectlyAccessibleInstallations(caller);
return folders
.Concat<TreeNode>(installations)
.ToList(); // important!
}
[Returns<TreeNode[]>] // assuming swagger knows about arrays but not lists (JSON)
[Returns(HttpStatusCode.Unauthorized)]
[HttpGet($"{nameof(GetAllFoldersAndInstallations)}/")]
public Object GetAllFoldersAndInstallations()
{
var caller = GetCaller();
if (caller == null)
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
using var db = Db.Connect();
var folders = db.GetAllAccessibleFolders(caller) as IEnumerable<TreeNode>;
var installations = db.GetAllAccessibleInstallations(caller);
return folders
.Concat(installations)
.ToList(); // important!
}
2023-02-24 12:59:56 +00:00
private static Folder PopulateChildren(Db db, Folder folder, HashSet<Int64>? hs = null)
{
// TODO: remove cycle detector
hs ??= new HashSet<Int64>();
if (!hs.Add(folder.Id))
throw new Exception("Cycle detected: folder " + folder.Id);
var installations = db.GetChildInstallations(folder);
var folders = db
.GetChildFolders(folder)
.Select(c => PopulateChildren(db, c, hs));
folder.Children = folders.Concat<TreeNode>(installations).ToList();
return folder;
}
2023-03-09 15:33:14 +00:00
[Returns(HttpStatusCode.OK)]
[Returns(HttpStatusCode.Unauthorized)]
[HttpPost($"{nameof(CreateUser)}/")]
public Object CreateUser(User newUser)
{
var caller = GetCaller();
using var db = Db.Connect();
if (caller == null || !caller.HasWriteAccess)
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
2023-02-24 12:59:56 +00:00
2023-03-09 15:33:14 +00:00
newUser.ParentId = caller.Id;
return db.CreateUser(newUser);
}
[Returns(HttpStatusCode.OK)]
[Returns(HttpStatusCode.Unauthorized)]
[HttpPost($"{nameof(CreateInstallation)}/")]
public Object CreateInstallation(Installation installation)
{
var caller = GetCaller();
using var db = Db.Connect();
if (caller == null || !caller.HasWriteAccess)
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
db.CreateInstallation(installation);
if (db.GetInstallationById(1)!.Name != installation.Name)
{
return new HttpResponseMessage(HttpStatusCode.BadRequest);
}
return db.AddToAccessibleInstallations(caller.Id, 1);
}
[Returns(HttpStatusCode.OK)]
[Returns(HttpStatusCode.Unauthorized)]
[HttpPost($"{nameof(CreateFolder)}/")]
public Object CreateFolder(Folder folder)
{
var caller = GetCaller();
using var db = Db.Connect();
if (caller == null || !caller.HasWriteAccess || db.GetInstallationByName(folder.Name) != null)
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
db.CreateFolder(folder);
return db.AddToAccessibleInstallations(caller.Id, db.GetInstallationByName(folder.Name)!.Id);
}
2023-02-24 12:59:56 +00:00
2023-02-24 11:58:47 +00:00
[Returns(HttpStatusCode.OK)]
[Returns(HttpStatusCode.Unauthorized)]
2023-02-16 12:57:06 +00:00
[HttpPut($"{nameof(UpdateUser)}/")]
public Object UpdateUser(User updatedUser)
{
2023-02-24 11:58:47 +00:00
var caller = GetCaller();
using var db = Db.Connect();
2023-03-09 15:33:14 +00:00
if (caller == null || !db.IsParentOfChild(caller.Id, updatedUser) || !caller.HasWriteAccess)
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
2023-02-24 11:58:47 +00:00
2023-03-09 15:33:14 +00:00
return db.UpdateUser(updatedUser);
2023-02-16 12:57:06 +00:00
}
2023-02-24 11:58:47 +00:00
[Returns(HttpStatusCode.OK)]
[Returns(HttpStatusCode.Unauthorized)]
2023-02-16 12:57:06 +00:00
[HttpPut($"{nameof(UpdateInstallation)}/")]
2023-02-24 12:59:56 +00:00
public Object UpdateInstallation(Installation installation)
2023-02-16 12:57:06 +00:00
{
2023-02-24 11:58:47 +00:00
var caller = GetCaller();
2023-02-24 11:58:47 +00:00
if (caller is null || !caller.HasWriteAccess)
2023-02-16 12:57:06 +00:00
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
2023-02-24 11:58:47 +00:00
using var db = Db.Connect();
2023-02-16 12:57:06 +00:00
2023-03-09 11:50:21 +00:00
var installationFromAccessibleInstallations = db
2023-02-24 11:58:47 +00:00
.GetAllAccessibleInstallations(caller)
2023-03-09 11:50:21 +00:00
.FirstOrDefault(i => i.Id == installation.Id);
2023-02-24 11:58:47 +00:00
2023-03-09 11:50:21 +00:00
if (installationFromAccessibleInstallations == null)
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
// TODO: accessibility by other users etc
// TODO: sanity check changes
2023-03-09 11:50:21 +00:00
// foreach(var property in installationFromAccessibleInstallations.GetType().GetProperties()){
// if(installation.GetType().GetProperties().Contains(property))
// {
// property.SetValue(installationFromAccessibleInstallations, property.GetValue(installation));
// }
// }
2023-02-16 12:57:06 +00:00
2023-02-24 12:59:56 +00:00
return db.UpdateInstallation(installation);
2023-02-16 12:57:06 +00:00
}
2023-02-24 11:58:47 +00:00
[Returns(HttpStatusCode.OK)]
[Returns(HttpStatusCode.Unauthorized)]
2023-02-16 12:57:06 +00:00
[HttpPut($"{nameof(UpdateFolder)}/")]
2023-02-24 11:58:47 +00:00
public Object UpdateFolder(Folder folder)
2023-02-16 12:57:06 +00:00
{
2023-02-24 11:58:47 +00:00
var caller = GetCaller();
if (caller is null || !caller.HasWriteAccess)
2023-02-16 12:57:06 +00:00
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
2023-02-24 11:58:47 +00:00
using var db = Db.Connect();
2023-03-09 11:50:21 +00:00
var installationFromAccessibleFolders = db
2023-02-24 11:58:47 +00:00
.GetAllAccessibleFolders(caller)
2023-03-09 11:50:21 +00:00
.FirstOrDefault(f => f.Id == folder.Id);
2023-03-09 11:50:21 +00:00
if (installationFromAccessibleFolders == null)
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
2023-02-16 12:57:06 +00:00
// TODO: accessibility by other users etc
// TODO: sanity check changes
2023-03-09 11:50:21 +00:00
// foreach(var property in installationFromAccessibleFolders.GetType().GetProperties()){
// if(folder.GetType().GetProperties().Contains(property))
// {
// property.SetValue(installationFromAccessibleFolders, property.GetValue(folder));
// }
// }
return db.UpdateFolder(installationFromAccessibleFolders);
2023-02-16 12:57:06 +00:00
}
2023-02-24 11:58:47 +00:00
[Returns(HttpStatusCode.OK)]
[Returns(HttpStatusCode.Unauthorized)]
2023-02-16 12:57:06 +00:00
[HttpDelete($"{nameof(DeleteUser)}/")]
public Object DeleteUser(Int64 userId)
{
2023-02-24 11:58:47 +00:00
var caller = GetCaller();
if (caller is null || !caller.HasWriteAccess)
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
2023-02-16 12:57:06 +00:00
using var db = Db.Connect();
2023-02-24 11:58:47 +00:00
var userToBeDeleted = db
.GetDescendantUsers(caller)
.FirstOrDefault(u => u.Id == userId);
if (userToBeDeleted is null)
2023-02-16 12:57:06 +00:00
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
return db.DeleteUser(userToBeDeleted);
}
2023-02-24 11:58:47 +00:00
[Returns(HttpStatusCode.OK)]
[Returns(HttpStatusCode.Unauthorized)]
2023-02-16 12:57:06 +00:00
[HttpDelete($"{nameof(DeleteInstallation)}/")]
2023-02-24 11:58:47 +00:00
public Object DeleteInstallation(Int64 installationId)
2023-02-16 12:57:06 +00:00
{
2023-02-24 11:58:47 +00:00
var caller = GetCaller();
if (caller is null || !caller.HasWriteAccess)
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
2023-02-16 12:57:06 +00:00
using var db = Db.Connect();
var installationToBeDeleted = db
2023-02-24 11:58:47 +00:00
.GetAllAccessibleInstallations(caller)
.FirstOrDefault(i => i.Id == installationId);
2023-02-16 12:57:06 +00:00
if (installationToBeDeleted is null)
2023-02-16 12:57:06 +00:00
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
return db.DeleteInstallation(installationToBeDeleted);
}
2023-02-24 11:58:47 +00:00
2023-02-16 12:57:06 +00:00
[ProducesResponseType(200)]
[ProducesResponseType(401)]
[HttpDelete($"{nameof(DeleteFolder)}/")]
public Object DeleteFolder(Int64 folderId)
{
2023-02-24 11:58:47 +00:00
var caller = GetCaller();
if (caller == null)
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
2023-02-16 12:57:06 +00:00
using var db = Db.Connect();
var folderToDelete = db
2023-02-24 11:58:47 +00:00
.GetAllAccessibleFolders(caller)
.FirstOrDefault(f => f.Id == folderId);
2023-02-16 12:57:06 +00:00
if (folderToDelete is null)
2023-02-16 12:57:06 +00:00
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
return db.DeleteFolder(folderToDelete);
2023-02-16 12:57:06 +00:00
}
2023-02-24 11:58:47 +00:00
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);
var saltBytes = Encoding.UTF8.GetBytes(user.Salt + "innovEnergy");
var pwdHash = Crypto.ComputeHash(pwdBytes, saltBytes);
return user.Password == pwdHash;
}
2023-02-16 12:57:06 +00:00
}
2023-02-24 11:58:47 +00:00