Skip to content

Commit 3289b7e

Browse files
author
sam.gerene
committed
[Implement] login page in web app
1 parent 5b58d36 commit 3289b7e

23 files changed

+741
-73
lines changed

SySML2.NET.REST/RestClient.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public async Task<IEnumerable<Project>> Open(string username, string password, s
118118
var projects = await this.RequestProjects(null, null, cancellationToken);
119119
return projects;
120120
}
121-
catch (Exception)
121+
catch (Exception e)
122122
{
123123
this.baseUri = null;
124124
throw;
@@ -403,7 +403,9 @@ private async Task<IEnumerable<IData>> RequestData(Uri requestUri, CancellationT
403403
RequestUri = requestUri,
404404
};
405405

406-
var response = await this.httpClient.SendAsync(requestMessage, cancellationToken);
406+
using var response = await this.httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
407+
408+
response.EnsureSuccessStatusCode();
407409

408410
using var stream = await response.Content.ReadAsStreamAsync();
409411

SySML2.NET.REST/SySML2.NET.REST.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<PropertyGroup>
44
<TargetFramework>netstandard2.0</TargetFramework>
55
<LangVersion>8</LangVersion>
6-
<Version>0.3.0</Version>
6+
<Version>0.4.0</Version>
77
<Description>A .NET implementation of the OMG SysML v2 REST/HTTP PSM</Description>
88
<PackageId>SysML2.NET.REST</PackageId>
99
<Company>RHEA System S.A.</Company>

SysML2.NET.Serializer.Json/SysML2.NET.Serializer.Json.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFramework>netstandard2.0</TargetFramework>
5-
<Version>0.3.0</Version>
5+
<Version>0.4.0</Version>
66
<Description>A .NET implementation of the OMG SysML v2 JSON serializer.</Description>
77
<PackageId>SysML2.NET.Serializer.Json</PackageId>
88
<Company>RHEA System S.A.</Company>

SysML2.NET.Viewer/App.razor

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,23 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
------------------------------------------------------------------------------->
1616

17-
<Router AppAssembly="@typeof(App).Assembly" PreferExactMatches="@true">
18-
<Found Context="routeData">
19-
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
20-
</Found>
21-
<NotFound>
22-
<LayoutView Layout="@typeof(MainLayout)">
23-
<p>Sorry, there's nothing at this address.</p>
24-
</LayoutView>
25-
</NotFound>
26-
</Router>
17+
<CascadingAuthenticationState>
18+
<Router AppAssembly="@typeof(App).Assembly" PreferExactMatches="@true">
19+
<Found Context="routeData">
20+
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
21+
<Authorizing>
22+
<text>Please wait, we are authorizing the user.</text>
23+
</Authorizing>
24+
<NotAuthorized>
25+
<text> You are not authorized to access this page. </text>
26+
</NotAuthorized>
27+
</AuthorizeRouteView>
28+
</Found>
29+
<NotFound>
30+
<PageTitle>Not found</PageTitle>
31+
<LayoutView Layout="@typeof(MainLayout)">
32+
<p>Sorry, there's nothing at this address.</p>
33+
</LayoutView>
34+
</NotFound>
35+
</Router>
36+
</CascadingAuthenticationState>

SysML2.NET.Viewer/Components/LoginComponent.razor

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,44 +14,67 @@
1414
limitations under the License.
1515
------------------------------------------------------------------------------->
1616

17-
<!--
18-
<EditForm Model="this.ViewModel.Authentication" OnValidSubmit="this.ViewModel.ExecuteLogin">
17+
@using SySML2.NET.REST
18+
19+
<div class="text-center">Connect to a Model Server</div>
20+
21+
<EditForm Model="this.ViewModel.AuthenticationStatusKind" OnValidSubmit="this.ViewModel.ExecuteLogin">
22+
1923
<DataAnnotationsValidator/>
2024

2125
<div class="input-group row m-top-10px">
2226
<label for="username" class="text-align-start">Username:</label>
23-
<InputText id="username" class="form-control" @bind-Value="this.ViewModel.Authentication.UserName"/>
27+
<InputText disabled="true" id="username" class="form-control" @bind-Value="this.ViewModel.UserName"/>
2428
</div>
2529

2630
<div class="input-group row m-top-10px">
2731
<label for="password" class="text-align-start">Password:</label>
28-
<InputText id="password" type="password" class="form-control" @bind-Value="this.ViewModel.Authentication.Password"/>
32+
<InputText disabled="true" id="password" type="password" class="form-control" @bind-Value="this.ViewModel.Password"/>
2933
</div>
3034

35+
<div class="input-group row m-top-10px">
36+
<label for="password" class="text-align-start">Url:</label>
37+
<InputText id="url" type="form-control" class="form-control" @bind-Value="this.ViewModel.Url" />
38+
</div>
39+
3140
<ValidationSummary/>
3241

33-
@if (this.ViewModel.AuthenticationStatus == AuthenticationStatus.Fail)
42+
@if (this.ViewModel.AuthenticationStatusKind == AuthenticationStatusKind.Fail)
3443
{
3544
<div class="input-group row m-top-10px">
3645
<label class="text-danger">@this.ViewModel.ErrorMessage</label>
3746
</div>
3847
}
39-
40-
<div class="row">
41-
<div class="col-md-12 text-center">
42-
@switch (this.ViewModel.AuthenticationStatus)
43-
{
44-
case AuthenticationStatus.None:
45-
<button id="connectbtn" type="submit" class="btn btn-connect m-top-10px">Connect</button>
46-
break;
47-
case AuthenticationStatus.Authenticating:
48-
<button id="connectbtn" type="submit" class="btn btn-connect m-top-10px" disabled>Connecting</button>
49-
break;
50-
case AuthenticationStatus.Fail:
51-
<button id="connectbtn" type="submit" class="btn btn-connect m-top-10px">Retry</button>
52-
break;
53-
}
48+
49+
<div class="container">
50+
<div class="row justify-content-md-center">
51+
<div class="col col-lg-2"></div>
52+
<div class="col-md-auto">
53+
@switch (this.ViewModel.AuthenticationStatusKind)
54+
{
55+
case AuthenticationStatusKind.None:
56+
<button id="connectbtn" type="submit" class="btn btn-connect" style="margin: 5px">Connect</button>
57+
break;
58+
case AuthenticationStatusKind.Authenticating:
59+
<button id="connectbtn" type="submit" class="btn btn-connect" style="margin: 5px" disabled>Connecting</button>
60+
break;
61+
case AuthenticationStatusKind.Fail:
62+
<button id="connectbtn" type="submit" class="btn btn-connect" style="margin: 5px">Retry</button>
63+
break;
64+
}
65+
66+
@switch (this.ViewModel.AuthenticationStatusKind)
67+
{
68+
case AuthenticationStatusKind.Authenticating:
69+
<div id="cancelbtn" type="button" class="btn btn-secondary" style="margin: 5px" margin="5px" @onclick="this.ViewModel.ExecuteCancelLogin">Cancel</div>
70+
break;
71+
default:
72+
<div id="cancelbtn" type="label" class="btn btn-secondary" style="margin: 5px" disabled>Cancel</div>
73+
break;
74+
}
75+
</div>
76+
<div class="col col-lg-2"></div>
5477
</div>
5578
</div>
79+
5680
</EditForm>
57-
-->

SysML2.NET.Viewer/Components/LoginComponent.razor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,4 @@ public void Dispose()
7373
this.disposables.Clear();
7474
}
7575
}
76-
}
76+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!------------------------------------------------------------------------------
2+
Copyright 2022 RHEA System S.A.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
------------------------------------------------------------------------------->
16+
17+
<input type="submit" @onclick="this.ViewModel.ExecuteLogout" value="Logout" />
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// -------------------------------------------------------------------------------------------------
2+
// <copyright file="LogoutComponent.razor.cs" company="RHEA System S.A.">
3+
//
4+
// Copyright 2022 RHEA System S.A.
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// </copyright>
19+
// ------------------------------------------------------------------------------------------------
20+
21+
namespace SysML2.NET.Viewer.Components
22+
{
23+
using Microsoft.AspNetCore.Components;
24+
25+
using SysML2.NET.Viewer.ViewModels.Components;
26+
27+
/// <summary>
28+
/// A component used to logout from the SysML2 model server
29+
/// </summary>
30+
public partial class LogoutComponent
31+
{
32+
/// <summary>
33+
/// Gets or sets the (injected) <see cref="ILogoutViewModel" />
34+
/// </summary>
35+
[Inject]
36+
public ILogoutViewModel ViewModel { get; set; }
37+
}
38+
}

SysML2.NET.Viewer/Pages/Index.razor

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,27 @@ limitations under the License.
1515
------------------------------------------------------------------------------->
1616

1717
@page "/"
18+
@page "/index"
1819

19-
<div class="text-center">Connect to a Model Server</div>
20+
@using SysML2.NET.Viewer.Components
21+
22+
<div class="row text-align-start align-items-center justify-content-md-center">
23+
<div style="width: 70%">
24+
<AuthorizeView>
25+
<Authorized>
26+
<div class="container-fluid">
27+
<div class="row">
28+
<div class="col p-0 col-10">
29+
@context.User.Identity?.Name
30+
</div>
31+
</div>
32+
</div>
33+
</Authorized>
34+
<NotAuthorized>
35+
<div class="container">
36+
<LoginComponent/>
37+
</div>
38+
</NotAuthorized>
39+
</AuthorizeView>
40+
</div>
41+
</div>

SysML2.NET.Viewer/Program.cs

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,14 @@
2020

2121
namespace SysML2.NET.Viewer
2222
{
23+
using System.Linq;
2324
using System.Net.Http;
25+
using System.Reflection;
2426
using System.Threading.Tasks;
25-
27+
using Blazored.SessionStorage;
2628
using BlazorStrap;
2729

30+
using Microsoft.AspNetCore.Components.Authorization;
2831
using Microsoft.AspNetCore.Components.Web;
2932
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
3033

@@ -34,6 +37,10 @@ namespace SysML2.NET.Viewer
3437

3538
using Serilog;
3639
using Serilog.Events;
40+
41+
using SySML2.NET.REST;
42+
using SysML2.NET.Serializer.Json;
43+
using SysML2.NET.Viewer.Services.Authentication;
3744

3845
/// <summary>
3946
/// The purpose of the <see cref="Program"/> class is to provide the
@@ -63,17 +70,59 @@ public static async Task Main(string[] args)
6370

6471
builder.RootComponents.Add<App>("#app");
6572
builder.RootComponents.Add<HeadOutlet>("head::after");
73+
74+
AddServices(builder);
75+
AddViewModels(builder);
76+
77+
await builder.Build().RunAsync();
78+
}
6679

67-
builder.Services.AddScoped(sp => new HttpClient());
80+
/// <summary>
81+
/// Register all services into the <see cref="WebAssemblyHostBuilder.Services" />
82+
/// </summary>
83+
/// <param name="builder">The <see cref="WebAssemblyHostBuilder" /></param>
84+
private static void AddServices(WebAssemblyHostBuilder builder)
85+
{
86+
builder.Services.AddBlazoredSessionStorage();
87+
builder.Services.AddAuthorizationCore();
6888

6989
builder.Services.AddScoped<DialogService>();
7090
builder.Services.AddScoped<NotificationService>();
7191
builder.Services.AddScoped<TooltipService>();
7292
builder.Services.AddScoped<ContextMenuService>();
73-
93+
7494
builder.Services.AddBlazorStrap();
7595

76-
await builder.Build().RunAsync();
96+
builder.Services.AddScoped(sp => new HttpClient());
97+
98+
builder.Services.AddScoped<AuthenticationStateProvider, AnonymousAuthenticationStateProvider>();
99+
builder.Services.AddScoped<IAuthenticationService, AuthenticationService>();
100+
builder.Services.AddScoped<IRestClient, RestClient>();
101+
builder.Services.AddScoped<IDeSerializer, DeSerializer>();
102+
builder.Services.AddScoped<ISerializer, Serializer>();
103+
}
104+
105+
/// <summary>
106+
/// Register all ViewModels into the <see cref="WebAssemblyHostBuilder" />
107+
/// </summary>
108+
/// <param name="builder">The <see cref="WebAssemblyHostBuilder" /></param>
109+
private static void AddViewModels(WebAssemblyHostBuilder builder)
110+
{
111+
var viewModelInterfaces = Assembly.GetCallingAssembly().GetExportedTypes()
112+
.Where(x => x.IsInterface && x.Name.EndsWith("ViewModel")).ToList();
113+
114+
foreach (var viewModelInterface in viewModelInterfaces)
115+
{
116+
var viewModel = Assembly.GetCallingAssembly().GetExportedTypes()
117+
.FirstOrDefault(x => x.IsClass
118+
&& x.Name == viewModelInterface.Name.Remove(0, 1)
119+
&& x.GetInterface(viewModelInterface.Name) == viewModelInterface);
120+
121+
if (viewModel != null)
122+
{
123+
builder.Services.AddTransient(viewModelInterface, viewModel);
124+
}
125+
}
77126
}
78127
}
79128
}

0 commit comments

Comments
 (0)