Innovenergy_trunk/csharp/App/Backend/Controller.cs

749 lines
24 KiB
C#

using System.Net;
using InnovEnergy.App.Backend.Database;
using InnovEnergy.App.Backend.DataTypes;
using InnovEnergy.App.Backend.DataTypes.Methods;
using InnovEnergy.App.Backend.Relations;
using InnovEnergy.App.Backend.Websockets;
using InnovEnergy.Lib.Utils;
using Microsoft.AspNetCore.Mvc;
namespace InnovEnergy.App.Backend;
using Token = String;
[Controller]
[Route("api/")]
public class Controller : ControllerBase
{
[HttpPost(nameof(Login))]
public ActionResult<Session> Login(String username, String? password)
{
var user = Db.GetUserByEmail(username);
if (user is null)
throw new Exceptions(400, "Null User Exception", "Must provide a user to log in as.", Request.Path.Value!);
if (!(user.Password.IsNullOrEmpty() && user.MustResetPassword) && !user.VerifyPassword(password))
{
//return Unauthorized("No Password set");
throw new Exceptions(401, "Wrong Password Exception", "Please try again.", Request.Path.Value!);
}
var session = new Session(user.HidePassword().HideParentIfUserHasNoAccessToParent(user));
//TODO The Frontend should check for the MustResetPassword Flag
return Db.Create(session)
? session
: throw new Exceptions(401,"Session Creation Exception", "Not allowed to log in.", Request.Path.Value!);
}
[HttpPost(nameof(Logout))]
public ActionResult Logout(Token authToken)
{
var session = Db.GetSession(authToken);
return session.Logout()
? Ok()
: Unauthorized();
}
[HttpGet(nameof(CreateWebSocket))]
public async Task CreateWebSocket(Token authToken)
{
var session = Db.GetSession(authToken)?.User;
if (session is null)
{
Console.WriteLine("------------------------------------Unauthorized user----------------------------------------------");
HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
HttpContext.Abort();
return;
}
if (!HttpContext.WebSockets.IsWebSocketRequest)
{
Console.WriteLine("------------------------------------Not a websocket request ----------------------------------------------");
HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
HttpContext.Abort();
return;
}
var webSocketContext = await HttpContext.WebSockets.AcceptWebSocketAsync();
var webSocket = webSocketContext;
//Handle the WebSocket connection
await WebsocketManager.HandleWebSocketConnection(webSocket);
}
[HttpGet(nameof(GetAllErrorsForInstallation))]
public ActionResult<IEnumerable<Error>> GetAllErrorsForInstallation(Int64 id, Token authToken)
{
var user = Db.GetSession(authToken)?.User;
if (user == null)
return Unauthorized();
var installation = Db.GetInstallationById(id);
if (installation is null || !user.HasAccessTo(installation))
return Unauthorized();
return Db.Errors
.Where(error => error.InstallationId == id)
.OrderByDescending(error => error.Date)
.ThenByDescending(error => error.Time)
.ToList();
}
[HttpGet(nameof(GetHistoryForInstallation))]
public ActionResult<IEnumerable<UserAction>> GetHistoryForInstallation(Int64 id, Token authToken)
{
var user = Db.GetSession(authToken)?.User;
if (user == null)
return Unauthorized();
var installation = Db.GetInstallationById(id);
if (installation is null || !user.HasAccessTo(installation))
return Unauthorized();
return Db.UserActions
.Where(action =>action.InstallationId == id)
.OrderByDescending(action => action.Timestamp)
.ToList();
}
[HttpGet(nameof(GetAllWarningsForInstallation))]
public ActionResult<IEnumerable<Warning>> GetAllWarningsForInstallation(Int64 id, Token authToken)
{
var user = Db.GetSession(authToken)?.User;
if (user == null)
return Unauthorized();
var installation = Db.GetInstallationById(id);
if (installation is null || !user.HasAccessTo(installation))
return Unauthorized();
return Db.Warnings
.Where(error => error.InstallationId == id)
.OrderByDescending(error => error.Date)
.ThenByDescending(error => error.Time)
.ToList();
}
[HttpGet(nameof(GetCsvTimestampsForInstallation))]
public ActionResult<IEnumerable<CsvTimestamp>> GetCsvTimestampsForInstallation(Int64 id, Int32 start, Int32 end, Token authToken)
{
var user = Db.GetSession(authToken)?.User;
if (user == null)
return Unauthorized();
var installation = Db.GetInstallationById(id);
if (installation is null || !user.HasAccessTo(installation))
return Unauthorized();
var sampleSize = 100;
var allTimestamps = new List<CsvTimestamp>();
if (start != 0 && end != 0)
{
allTimestamps = Db.CsvTimestamps
.Where(csvTimestamp => csvTimestamp.InstallationId == id && csvTimestamp.Timestamp > start && csvTimestamp.Timestamp < end)
.OrderBy(csvTimestamp => csvTimestamp.Timestamp).ToList();
}
else
{
allTimestamps = Db.CsvTimestamps
.Where(csvTimestamp => csvTimestamp.InstallationId == id)
.OrderBy(csvTimestamp => csvTimestamp.Timestamp).ToList();
}
int totalRecords = allTimestamps.Count;
if (totalRecords <= sampleSize)
{
// If the total records are less than or equal to the sample size, return all records
Console.WriteLine("Start timestamp = "+start +" end timestamp = "+end);
Console.WriteLine("SampledTimestamps = " + allTimestamps.Count);
return allTimestamps;
}
int interval = totalRecords / sampleSize;
var sampledTimestamps = new List<CsvTimestamp>();
for (int i = 0; i < totalRecords; i += interval)
{
sampledTimestamps.Add(allTimestamps[i]);
}
// If we haven't picked enough records (due to rounding), add the latest record to ensure completeness
if (sampledTimestamps.Count < sampleSize)
{
sampledTimestamps.Add(allTimestamps.Last());
}
Console.WriteLine("Start timestamp = "+start +" end timestamp = "+end);
Console.WriteLine("TotalRecords = "+totalRecords + " interval = "+ interval);
Console.WriteLine("SampledTimestamps = " + sampledTimestamps.Count);
return sampledTimestamps;
// return Db.CsvTimestamps
// .Where(csvTimestamp => csvTimestamp.InstallationId == id)
// .OrderByDescending(csvTimestamp => csvTimestamp.Timestamp)
// .ToList();
}
[HttpGet(nameof(GetUserById))]
public ActionResult<User> GetUserById(Int64 id, Token authToken)
{
var session = Db.GetSession(authToken)?.User;
if (session == null)
return Unauthorized();
var user = Db.GetUserById(id);
if (user is null || !session.HasAccessTo(user))
return Unauthorized();
return user
.HidePassword()
.HideParentIfUserHasNoAccessToParent(session);
}
[HttpGet(nameof(GetInstallationById))]
public ActionResult<Installation> GetInstallationById(Int64 id, Token authToken)
{
var user = Db.GetSession(authToken)?.User;
if (user == null)
return Unauthorized();
var installation = Db.GetInstallationById(id);
if (installation is null || !user.HasAccessTo(installation))
return Unauthorized();
return installation
.FillOrderNumbers()
.HideParentIfUserHasNoAccessToParent(user)
.HideWriteKeyIfUserIsNotAdmin(user.UserType);
}
[HttpGet(nameof(GetUsersWithDirectAccessToInstallation))]
public ActionResult<IEnumerable<Object>> GetUsersWithDirectAccessToInstallation(Int64 id, Token authToken)
{
var user = Db.GetSession(authToken)?.User;
if (user == null)
return Unauthorized();
var installation = Db.GetInstallationById(id);
if (installation is null || !user.HasAccessTo(installation))
return Unauthorized();
return installation
.UsersWithDirectAccess()
.Where(u => u.IsDescendantOf(user))
.Select(u => u.HidePassword())
.ToList();
}
[HttpGet(nameof(GetUsersWithInheritedAccessToInstallation))]
public ActionResult<IEnumerable<Object>> GetUsersWithInheritedAccessToInstallation(Int64 id, Token authToken)
{
var user = Db.GetSession(authToken)?.User;
if (user == null)
return Unauthorized();
var installation = Db.GetInstallationById(id);
if (installation is null || !user.HasAccessTo(installation))
return Unauthorized();
return installation
.Ancestors()
.SelectMany(f => f.UsersWithDirectAccess()
.Where(u => u.IsDescendantOf(user))
.Select(u => new { folderId = f.Id, folderName = f.Name, user = u.HidePassword() }))
.ToList();
}
[HttpGet(nameof(GetUsersWithDirectAccessToFolder))]
public ActionResult<IEnumerable<Object>> GetUsersWithDirectAccessToFolder(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
.UsersWithDirectAccess()
.Where(u => u.IsDescendantOf(user))
.Select(u => u.HidePassword())
.ToList();
}
[HttpGet(nameof(GetUsersWithInheritedAccessToFolder))]
public ActionResult<IEnumerable<Object>> GetUsersWithInheritedAccessToFolder(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
.Ancestors()
.SelectMany(f => f.UsersWithDirectAccess()
.Where(u => u.IsDescendantOf(user))
.Select(u => new { folderId = f.Id, folderName = f.Name, user = u.HidePassword() }))
.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.HideParentIfUserHasNoAccessToParent(user);
}
[HttpGet(nameof(GetAllDirectChildUsers))]
public ActionResult<IEnumerable<User>> GetAllDirectChildUsers(Token authToken)
{
var user = Db.GetSession(authToken)?.User;
if (user == null)
return Unauthorized();
return user.ChildUsers().Select(u => u.HidePassword()).ToList();
}
[HttpGet(nameof(GetAllChildUsers))]
public ActionResult<IEnumerable<User>> GetAllChildUsers(Token authToken)
{
var user = Db.GetSession(authToken)?.User;
if (user == null)
return Unauthorized();
return user
.DescendantUsers()
.Select(u => u.HidePassword())
.ToList();
}
[HttpGet(nameof(GetAllInstallations))]
public ActionResult<IEnumerable<Installation>> GetAllInstallations(Token authToken)
{
var user = Db.GetSession(authToken)?.User;
if (user is null)
return Unauthorized();
return user
.AccessibleInstallations(product:0)
.Select(i => i.FillOrderNumbers().HideParentIfUserHasNoAccessToParent(user).HideWriteKeyIfUserIsNotAdmin(user.UserType))
.ToList();
}
[HttpGet(nameof(GetAllSalidomoInstallations))]
public ActionResult<IEnumerable<Installation>> GetAllSalidomoInstallations(Token authToken)
{
var user = Db.GetSession(authToken)?.User;
if (user is null)
return Unauthorized();
return user
.AccessibleInstallations(product:1)
.ToList();
}
[HttpGet(nameof(GetAllFolders))]
public ActionResult<IEnumerable<Folder>> GetAllFolders(Token authToken)
{
var user = Db.GetSession(authToken)?.User;
if (user is null)
return Unauthorized();
return new(user.AccessibleFolders().HideParentIfUserHasNoAccessToParent(user));
}
[HttpGet(nameof(GetAllFoldersAndInstallations))]
public ActionResult<IEnumerable<Object>> GetAllFoldersAndInstallations(Token authToken)
{
var user = Db.GetSession(authToken)?.User;
if (user is null)
return Unauthorized();
var foldersAndInstallations = user
.AccessibleFoldersAndInstallations(product:0)
.Do(o => o.FillOrderNumbers())
.Select(o => o.HideParentIfUserHasNoAccessToParent(user))
.OfType<Object>(); // Important! JSON serializer must see Objects otherwise
// it will just serialize the members of TreeNode %&@#!!!
// TODO Filter out write keys
return new (foldersAndInstallations);
}
[HttpPost(nameof(CreateUser))]
public async Task<ActionResult<User>> CreateUser([FromBody] User newUser, Token authToken)
{
var create = Db.GetSession(authToken).Create(newUser);
if (create)
{
var mail_success= await Db.SendNewUserEmail(newUser);
if (!mail_success)
{
Db.GetSession(authToken).Delete(newUser);
}
return mail_success ? newUser.HidePassword():Unauthorized();
}
return Unauthorized() ;
}
[HttpPost(nameof(CreateInstallation))]
public async Task<ActionResult<Installation>> CreateInstallation([FromBody] Installation installation, Token authToken)
{
var session = Db.GetSession(authToken);
if (! await session.Create(installation))
return Unauthorized();
return installation;
}
[HttpPost(nameof(CreateFolder))]
public ActionResult<Folder> CreateFolder([FromBody] Folder folder, Token authToken)
{
var session = Db.GetSession(authToken);
if (!session.Create(folder))
return Unauthorized();
return folder.HideParentIfUserHasNoAccessToParent(session!.User);
}
[HttpPost(nameof(GrantUserAccessToFolder))]
public ActionResult GrantUserAccessToFolder(FolderAccess folderAccess, Token authToken)
{
var session = Db.GetSession(authToken);
// 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, folder)
? Ok()
: Unauthorized();
}
[HttpPost(nameof(RevokeUserAccessToFolder))]
public ActionResult RevokeUserAccessToFolder(FolderAccess folderAccess, Token authToken)
{
var session = Db.GetSession(authToken);
// TODO: automatic BadRequest when properties are null during deserialization
var folder = Db.GetFolderById(folderAccess.FolderId);
var user = Db.GetUserById(folderAccess.UserId);
return session.RevokeUserAccessTo(user, folder)
? Ok()
: Unauthorized();
}
[HttpPost(nameof(GrantUserAccessToInstallation))]
public ActionResult GrantUserAccessToInstallation(InstallationAccess installationAccess, Token authToken)
{
var session = Db.GetSession(authToken);
// TODO: automatic BadRequest when properties are null during deserialization
var installation = Db.GetInstallationById(installationAccess.InstallationId);
var user = Db.GetUserById(installationAccess.UserId);
return session.GrantUserAccessTo(user, installation)
? Ok()
: Unauthorized();
}
[HttpPost(nameof(RevokeUserAccessToInstallation))]
public ActionResult RevokeUserAccessToInstallation(InstallationAccess installationAccess, Token authToken)
{
var session = Db.GetSession(authToken);
// TODO: automatic BadRequest when properties are null during deserialization
var installation = Db.GetInstallationById(installationAccess.InstallationId);
var user = Db.GetUserById(installationAccess.UserId);
return session.RevokeUserAccessTo(user, installation)
? Ok()
: Unauthorized();
}
[HttpPut(nameof(UpdateUser))]
public ActionResult<User> UpdateUser([FromBody] User updatedUser, Token authToken)
{
var session = Db.GetSession(authToken);
if (!session.Update(updatedUser))
return Unauthorized();
return updatedUser.HidePassword();
}
[HttpPut(nameof(UpdatePassword))]
public ActionResult<User> UpdatePassword(String newPassword, Token authToken)
{
var session = Db.GetSession(authToken);
return session.UpdatePassword(newPassword)
? Ok()
: Unauthorized();
}
[HttpPut(nameof(UpdateInstallation))]
public ActionResult<Installation> UpdateInstallation([FromBody] Installation installation, Token authToken)
{
var session = Db.GetSession(authToken);
if (!session.Update(installation))
return Unauthorized();
if (installation.Product == 0)
{
return installation.FillOrderNumbers().HideParentIfUserHasNoAccessToParent(session!.User).HideWriteKeyIfUserIsNotAdmin(session.User.UserType);
}
return installation.HideParentIfUserHasNoAccessToParent(session!.User);
}
[HttpPost(nameof(AcknowledgeError))]
public ActionResult AcknowledgeError(Int64 id, Token authToken)
{
var session = Db.GetSession(authToken);
if (session == null)
return Unauthorized();
var error=Db.Errors
.FirstOrDefault(error => error.Id == id);
error.Seen = true;
return Db.Update(error)
? Ok()
: Unauthorized();
}
[HttpPost(nameof(AcknowledgeWarning))]
public ActionResult AcknowledgeWarning(Int64 id, Token authToken)
{
var session = Db.GetSession(authToken);
if (session == null)
return Unauthorized();
var warning=Db.Warnings
.FirstOrDefault(warning => warning.Id == id);
warning.Seen = true;
return Db.Update(warning)
? Ok()
: Unauthorized();
}
[HttpPut(nameof(UpdateFolder))]
public ActionResult<Folder> UpdateFolder([FromBody] Folder folder, Token authToken)
{
var session = Db.GetSession(authToken);
if (!session.Update(folder))
return Unauthorized();
return folder.HideParentIfUserHasNoAccessToParent(session!.User);
}
[HttpPut(nameof(MoveInstallation))]
public ActionResult MoveInstallation(Int64 installationId,Int64 parentId, Token authToken)
{
var session = Db.GetSession(authToken);
return session.MoveInstallation(installationId, parentId)
? Ok()
: Unauthorized();
}
[HttpPost(nameof(UpdateFirmware))]
public async Task<ActionResult> UpdateFirmware(Int64 batteryNode, Int64 installationId,String version,Token authToken)
{
var session = Db.GetSession(authToken);
var installationToUpdate = Db.GetInstallationById(installationId);
if (installationToUpdate != null)
{
_ = session.RunScriptInBackground(installationToUpdate.VpnIp, batteryNode,version,installationToUpdate.Product);
}
return Ok();
}
[HttpPost(nameof(InsertNewAction))]
public async Task<ActionResult<IEnumerable<Object>>> InsertNewAction([FromBody] UserAction action, Token authToken)
{
var session = Db.GetSession(authToken);
var actionSuccess = await session.RecordUserAction(action);
return actionSuccess ? Ok() : Unauthorized();
}
[HttpPost(nameof(EditInstallationConfig))]
public async Task<ActionResult<IEnumerable<Object>>> EditInstallationConfig([FromBody] Configuration config, Int64 installationId,Token authToken)
{
var session = Db.GetSession(authToken);
// Send configuration changes
var success = await session.SendInstallationConfig(installationId, config);
// Record configuration change
if (success)
{
// Create a new UserAction object
var action = new UserAction
{
InstallationId = installationId,
Timestamp = DateTime.Now,
Description = config.GetConfigurationString()
};
var actionSuccess = await session.RecordUserAction(action);
return actionSuccess?Ok():Unauthorized();
}
return Unauthorized();
}
[HttpPut(nameof(MoveFolder))]
public ActionResult MoveFolder(Int64 folderId,Int64 parentId, Token authToken)
{
var session = Db.GetSession(authToken);
return session.MoveFolder(folderId, parentId)
? Ok()
: Unauthorized();
}
[HttpDelete(nameof(DeleteUser))]
public ActionResult DeleteUser(Int64 userId, Token authToken)
{
var session = Db.GetSession(authToken);
var user = Db.GetUserById(userId);
return session.Delete(user)
? Ok()
: Unauthorized();
}
[HttpDelete(nameof(DeleteInstallation))]
public async Task<ActionResult> DeleteInstallation(Int64 installationId, Token authToken)
{
var session = Db.GetSession(authToken);
var installation = Db.GetInstallationById(installationId);
return await session.Delete(installation)
? Ok()
: Unauthorized();
}
[HttpDelete(nameof(DeleteFolder))]
public ActionResult DeleteFolder(Int64 folderId, Token authToken)
{
var session = Db.GetSession(authToken);
var folder = Db.GetFolderById(folderId);
return session.Delete(folder)
? Ok()
: Unauthorized();
}
[HttpPost(nameof(ResetPasswordRequest))]
public async Task<ActionResult<IEnumerable<Object>>> ResetPasswordRequest(String username)
{
var user = Db.GetUserByEmail(username);
if (user is null)
return Unauthorized();
var session = new Session(user.HidePassword().HideParentIfUserHasNoAccessToParent(user));
var success = Db.Create(session);
return success && await Db.SendPasswordResetEmail(user, session.Token)
? Ok()
: Unauthorized();
}
[HttpGet(nameof(ResetPassword))]
public ActionResult<Object> ResetPassword(Token token)
{
var user = Db.GetSession(token)?.User;
if (user is null)
return Unauthorized();
Db.DeleteUserPassword(user);
return Redirect($"https://monitor.innov.energy/?username={user.Email}&reset=true"); // TODO: move to settings file
}
}