This commit is contained in:
Sina Blattmann 2023-04-14 07:53:18 +02:00
commit dcab3ab4d1
15 changed files with 80 additions and 39 deletions

View File

@ -3,6 +3,7 @@
<ItemGroup>
<PackageReference Include="Flurl.Http" Version="3.2.4" />
<PackageReference Include="Hellang.Middleware.ProblemDetails" Version="6.5.1" />
<PackageReference Include="MailKit" Version="3.6.0" />
<PackageReference Include="Microsoft.AspNet.Identity.Core" Version="2.2.3" />
<PackageReference Include="Microsoft.AspNet.Identity.Owin" Version="2.2.3" />

View File

@ -19,12 +19,17 @@ public class Controller : ControllerBase
var user = Db.GetUserByName(username);
if (user is null)
return Unauthorized();
{
throw new Exceptions(400,"Null User Exception", "Must provide a user to log in as.", Request.Path.Value!);
}
if (!(user.Password is null && user.MustResetPassword))
{
if (!user.VerifyPassword(password))
return Unauthorized();
{
//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));
@ -33,7 +38,7 @@ public class Controller : ControllerBase
return Db.Create(session)
? session
: Unauthorized();
: throw new Exceptions(401,"Session Creation Exception", "Not allowed to log in.", Request.Path.Value!);
}
@ -427,8 +432,6 @@ public class Controller : ControllerBase
: Unauthorized();
}
}

View File

@ -187,6 +187,7 @@ public static class SessionMethods
return sessionUser is not null
&& sessionUser
.Do(() => sessionUser.Password = sessionUser.SaltAndHashPassword(newPassword))
.Do(() => sessionUser.MustResetPassword = false)
.Apply(Db.Update);
}

View File

@ -0,0 +1,16 @@
namespace InnovEnergy.App.Backend;
public class Exceptions : Exception
{
public String Type { get; set; }
public String Detail { get; set; }
public String Instance { get; set; }
public Int32? Status { get; set; }
public Exceptions(Int32? status, String type, String detail, String instance)
{
Type = type;
Detail = detail;
Instance = instance;
Status = status;
}
}

View File

@ -1,4 +1,6 @@
using Hellang.Middleware.ProblemDetails;
using InnovEnergy.App.Backend.Database;
using Microsoft.AspNetCore.Mvc;
using Microsoft.OpenApi.Models;
namespace InnovEnergy.App.Backend;
@ -16,6 +18,21 @@ public static class Program
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails(setup =>
{
//This includes the stacktrace in Development Env
setup.IncludeExceptionDetails = (ctx, env) => builder.Environment.IsDevelopment() || builder.Environment.IsStaging();
//This handles our Exceptions
setup.Map<Exceptions>(exception => new ProblemDetails()
{
Detail = exception.Detail,
Status = exception.Status,
Type = exception.Type,
Instance = exception.Instance
});
});
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", OpenApiInfo);
@ -34,6 +51,7 @@ public static class Program
app.UseCors(p => p.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()) ;
app.UseHttpsRedirection();
app.MapControllers();
app.UseProblemDetails();
app.Run();
}

Binary file not shown.

View File

@ -38,7 +38,7 @@ public readonly struct BatteryConnection
var ttys = await fs.GetFiles("/dev", FileType.CharacterDevice);
var candidateTtys = ttys
.Where(f => f.StartsWith("ttyUSB"))
.Where(f => f.Contains("ttyUSB"))
.Select(t => t.Split("/").LastOrDefault())
.NotNull()
.ToList();

View File

@ -23,15 +23,16 @@ public class BmsTunnel : IDisposable
private const Byte TunnelCode = 0x41;
private const String CrcError = "?? CRC FAILED";
public BmsTunnel(String tty, Byte node)
public BmsTunnel(String tty, Byte node, SshHost? host)
{
Tty = tty;
Node = node;
StopSerialStarter();
StopSerialStarter(host);
SerialPort = new SerialPort(Tty, BaudRate, Parity, DataBits, StopBits);
SerialPort.ReadTimeout = 100;
SerialPort.Open();
}
@ -164,10 +165,11 @@ public class BmsTunnel : IDisposable
.Concat(NewLine);
}
private void StopSerialStarter()
private void StopSerialStarter(SshHost? host)
{
CliPrograms.StopTty
.WithArguments(Tty)
.OnHost(host)
.ExecuteBufferedAsync()
.Task
.Wait(3000);

View File

@ -13,16 +13,19 @@ public static class Program
public static async Task<Int32> Main(String[] args)
{
var connection = await ConnectToBms(args.FirstOrDefault());
var hostName = args.FirstOrDefault();
BatteryConnection? connection = hostName is not null ? await ConnectToBms(hostName, new SshHost(hostName)): new BatteryConnection();
if (connection is null)
return 2;
// connection.Tty;
Console.WriteLine("\nstarting BMS tunnel\n");
// var path = $"/dev/{tty}";
// if (host != null)
// path = $"root@{host}" + path;
var path = $"/dev/{connection.Value.Tty}";
// if (hostName != null)
// path = $"root@{hostName}:" + path;
//
// var node = connection.Nodes.Any()
// ? connection.Nodes.First()
@ -30,13 +33,13 @@ public static class Program
//
// TODO: Fixme
var path = "";
// var path = "";
Byte node = 2;
var nodes = new Byte[] { 1, 2, 3 };
// TODO: Fixme
using var tunnel = new BmsTunnel(path, node);
using var tunnel = new BmsTunnel(path, node, hostName is not null ? new SshHost(hostName): null);
ExplainNode();
ExplainNodes();
@ -117,12 +120,8 @@ public static class Program
}
}
private static async Task<BatteryConnection?> ConnectToBms(String? hostName)
private static async Task<BatteryConnection?> ConnectToBms(String? hostName, SshHost host)
{
if (hostName is null)
return new BatteryConnection();
var host = new SshHost(hostName);
if (await host.Ping())
return await BatteryConnection.Connect(host);

View File

@ -41,7 +41,7 @@ public class FileSystem
public async Task<IReadOnlyList<String>> GetFiles(String path, FileType fileType, Int32 maxDepth = 1)
{
var result = await Find
.WithArguments($"find {path} -maxdepth {maxDepth} -type {(Char)fileType}")
.WithArguments($"{path} -maxdepth {maxDepth} -type {(Char)fileType}")
.OnHost(Host)
.ExecuteBufferedAsync();

View File

@ -8,6 +8,7 @@ const resolution = TimeSpan.fromSeconds(2);
const cache = new DataCache(x => (Promise.resolve({foo: 0})), resolution)
// @ts-ignore
const sampleTimes = [1, 2, 3, 4, 5, 6].select(e => UnixTime.fromTicks(e)).toArray();
const series = cache.getSeries(sampleTimes)

View File

@ -115,6 +115,7 @@ export default class DataCache<T extends Record<string, number>>
let interpolated: Partial<Record<string, number>> = {}
//What about string nodes? like Alarms
for (const k of Object.keys(dataBefore))
{
interpolated[k] = (dataBefore[k] * n + dataAfter[k] * p) / pn

View File

@ -59,7 +59,7 @@ const AvailableUserDialog = () => {
scroll="paper"
>
<DialogTitle id="available-user-dialog-title">
Create new folder
Grant access
</DialogTitle>
<DialogContent id="available-user-dialog-content">
<Autocomplete

View File

@ -27,7 +27,7 @@ const AddUser = () => {
sx={{ my: 1 }}
onClick={() => setOpen(true)}
>
<FormattedMessage id="addUser" defaultMessage="Add user" />
<FormattedMessage id="addUser" defaultMessage="Create user" />
</InnovenergyButton>
<Dialog
onClose={() => setOpen(false)}

View File

@ -1,4 +1,5 @@
import { Selector } from 'testcafe';
import { login, logout } from "./helper.js";
fixture('Login testing')
.page('http://localhost:3000/'); //Todo write me in a config file
@ -8,33 +9,31 @@ fixture('Login testing')
test('Lulu login', async t => {
// await t
// .debug();
await t
.login('lulu', '1233') //Todo write me in a config file
.expect(Selector('#demo-simple-select').visible).ok();
login('lulu', '1233'); //Todo write me in a config file
await t.expect(Selector('#demo-simple-select').visible).ok();
});
test('Wrong PW', async t => {
await t
.login('lulu', '12334') //Todo write me in a config file
.expect(Selector('#demo-simple-select').visible).notOk(); //Todo check for feedback
login('lulu', '12334'); //Todo write me in a config file
await t.expect(Selector('#demo-simple-select').visible).notOk(); //Todo check for feedback
});
test('Invalid Username', async t => {
login('Not Agent Smith', '12334')
await t
.login('Not Agent Smith', '12334') //Todo write me in a config file
.expect(Selector('#demo-simple-select').visible).notOk(); //Todo check for feedback
});
test('Logout', async t => {
login('lulu', '1233');
logout();
await t
.login('lulu', '1233') //Todo write me in a config file
.logout()
.expect(Selector('#username-textfield').visible).Ok();
});
test('Installation List Loads', async t => {
login('lulu', '1233');
await t
.login('lulu', '1233') //Todo write me in a config file
.expect(Selector('').visible).Ok();
});