Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GDS: add Users Database as SQL Database & allow to specifiy own User #582

Merged
merged 5 commits into from
Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 78 additions & 2 deletions Samples/GDS/ConsoleServer/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,18 @@

using Mono.Options;
using Opc.Ua.Configuration;
using Opc.Ua.Gds.Server.Database;
using Opc.Ua.Gds.Server.Database.Linq;
using Opc.Ua.Server;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace Opc.Ua.Gds.Server
{
Expand Down Expand Up @@ -236,14 +241,19 @@ private async Task ConsoleGlobalDiscoveryServer()
string databaseStorePath = Utils.ReplaceSpecialFolderNames(gdsConfiguration.DatabaseStorePath);
string userdatabaseStorePath = Utils.ReplaceSpecialFolderNames(gdsConfiguration.UsersDatabaseStorePath);

// start the server.
var database = JsonApplicationsDatabase.Load(databaseStorePath);
var userDatabase = JsonUsersDatabase.Load(userdatabaseStorePath);

bool createStandardUsers = ConfigureUsers(userDatabase);

// start the server.
server = new GlobalDiscoverySampleServer(
database,
database,
new CertificateGroup(),
userDatabase);
userDatabase,
true,
createStandardUsers);
await application.Start(server).ConfigureAwait(false);

// print endpoint info
Expand All @@ -263,6 +273,39 @@ private async Task ConsoleGlobalDiscoveryServer()

}

private bool ConfigureUsers(JsonUsersDatabase userDatabase)
{
ApplicationInstance.MessageDlg.Message("Use default users?", true);
bool createStandardUsers = ApplicationInstance.MessageDlg.ShowAsync().Result;

if (!createStandardUsers)
{
//delete existing standard users
userDatabase.DeleteUser("appadmin");
userDatabase.DeleteUser("appuser");
userDatabase.DeleteUser("sysadmin");

//Create new admin user
Console.Write("Please specify user name of the application admin user:");
string username = Console.ReadLine();
_ = username ?? throw new ArgumentNullException("User name is not allowed to be empty");

Console.Write($"Please specify the password of {username}:");

//string password = Console.ReadLine();
string password = GetPassword();
_ = password ?? throw new ArgumentNullException("Password is not allowed to be empty");

//create User, if User exists delete & recreate
if (!userDatabase.CreateUser(username, password, GdsRole.ApplicationAdmin))
{
userDatabase.DeleteUser(username);
userDatabase.CreateUser(username, password, GdsRole.ApplicationAdmin);
}
}
return createStandardUsers;
}

private void EventStatus(Session session, SessionEventReason reason)
{
lastEventTime = DateTime.UtcNow;
Expand Down Expand Up @@ -307,5 +350,38 @@ private async void StatusThread()
await Task.Delay(1000).ConfigureAwait(false);
}
}

private static string GetPassword()
{
StringBuilder input = new StringBuilder();
while (true)
{
int x = Console.CursorLeft;
int y = Console.CursorTop;
ConsoleKeyInfo key = Console.ReadKey(true);
if (key.Key == ConsoleKey.Enter)
{
Console.WriteLine();
break;
}
if (key.Key == ConsoleKey.Backspace && input.Length > 0)
{
input.Remove(input.Length - 1, 1);
Console.SetCursorPosition(x - 1, y);
Console.Write(" ");
Console.SetCursorPosition(x - 1, y);
}
else if (key.KeyChar < 32 || key.KeyChar > 126)
{
Trace.WriteLine("Output suppressed: no key char"); //catch non-printable chars, e.g F1, CursorUp and so ...
}
else if (key.Key != ConsoleKey.Backspace)
{
input.Append(key.KeyChar);
Console.Write("*");
}
}
return input.ToString();
}
}
}
25 changes: 11 additions & 14 deletions Samples/GDS/Server/App.config
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="Opc.Ua.ServerConfiguration" type="Opc.Ua.ApplicationConfigurationSection,Opc.Ua.Core"/>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
<section name="Opc.Ua.ServerConfiguration" type="Opc.Ua.ApplicationConfigurationSection,Opc.Ua.Core" />
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />

<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections>
<connectionStrings>
<!-- creates gdsdb in user folder -->
<add name="gdsdbEntities" connectionString="metadata=res://*/gdsdb.csdl|res://*/gdsdb.ssdl|res://*/gdsdb.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=gdsdb;MultipleActiveResultSets=true;Integrated Security=True;Pooling=False&quot;" providerName="System.Data.EntityClient"/>
<!-- opens existing gdsdb.mdl in project folder -->
<!--add name="gdsdbEntities" connectionString="metadata=res://*/gdsdb.csdl|res://*/gdsdb.ssdl|res://*/gdsdb.msl;provider=System.Data.SqlClient;provider connection string=&quot;Server=(localdb)\MSSQLLocalDB;MultipleActiveResultSets=true;Integrated Security=true;AttachDbFileName=|DataDirectory|\gdsdb.mdf;&quot;" providerName="System.Data.EntityClient"/-->
</connectionStrings>
<!-- creates gdsdb in user folder --><!-- opens existing gdsdb.mdl in project folder -->
<!--add name="gdsdbEntities" connectionString="metadata=res://*/gdsdb.csdl|res://*/gdsdb.ssdl|res://*/gdsdb.msl;provider=System.Data.SqlClient;provider connection string=&quot;Server=(localdb)\MSSQLLocalDB;MultipleActiveResultSets=true;Integrated Security=true;AttachDbFileName=|DataDirectory|\gdsdb.mdf;&quot;" providerName="System.Data.EntityClient"/--><add name="gdsdbEntities" connectionString="metadata=res://*/gdsdb.csdl|res://*/gdsdb.ssdl|res://*/gdsdb.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=gdsdb;MultipleActiveResultSets=true;Integrated Security=True;Pooling=False&quot;" providerName="System.Data.EntityClient" /><add name="usersdbEntities" connectionString="metadata=res://*/usersdb.csdl|res://*/usersdb.ssdl|res://*/usersdb.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=(localdb)\MSSQLLocalDB;initial catalog=usersdb;integrated security=True;encrypt=False;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" /></connectionStrings>

<system.serviceModel>
<!--
Expand All @@ -20,15 +17,15 @@
-->
<services>
<service name="Opc.Ua.SessionEndpoint" behaviorConfiguration="Opc.Ua.SessionEndpoint.Behavior">
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<!-- Servers deployed in production environments should turn the httpGetEnabled and includeExceptionDetailInFaults options off -->
<behaviors>
<serviceBehaviors>
<behavior name="Opc.Ua.SessionEndpoint.Behavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
Expand Down Expand Up @@ -69,16 +66,16 @@
</ConfigurationLocation>
</Opc.Ua.ServerConfiguration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v11.0"/>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer"/>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<runtime>
Expand Down
55 changes: 55 additions & 0 deletions Samples/GDS/Server/DB/usersdb.edmx.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@

-- --------------------------------------------------
-- Entity Designer DDL Script for SQL Server 2005, 2008, 2012 and Azure
-- --------------------------------------------------
-- Date Created: 12/22/2023 22:14:49
-- Generated from EDMX file: C:\Users\roman\source\repos\UA-.NETStandard-Samples\Samples\GDS\Server\usersdb.edmx
-- --------------------------------------------------

SET QUOTED_IDENTIFIER OFF;
GO
USE [usersdb];
GO
IF SCHEMA_ID(N'dbo') IS NULL EXECUTE(N'CREATE SCHEMA [dbo]');
GO

-- --------------------------------------------------
-- Dropping existing FOREIGN KEY constraints
-- --------------------------------------------------


-- --------------------------------------------------
-- Dropping existing tables
-- --------------------------------------------------


-- --------------------------------------------------
-- Creating all tables
-- --------------------------------------------------

-- Creating table 'UserSet'
CREATE TABLE [dbo].[UserSet] (
[ID] uniqueidentifier NOT NULL,
[UserName] nvarchar(max) NOT NULL,
[Hash] nvarchar(max) NOT NULL,
[GdsRole] int NOT NULL
);
GO

-- --------------------------------------------------
-- Creating all PRIMARY KEY constraints
-- --------------------------------------------------

-- Creating primary key on [ID] in table 'UserSet'
ALTER TABLE [dbo].[UserSet]
ADD CONSTRAINT [PK_UserSet]
PRIMARY KEY CLUSTERED ([ID] ASC);
GO

-- --------------------------------------------------
-- Creating all FOREIGN KEY constraints
-- --------------------------------------------------

-- --------------------------------------------------
-- Script has ended
-- --------------------------------------------------
41 changes: 41 additions & 0 deletions Samples/GDS/Server/GlobalDiscoveryServer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,16 @@
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Data.Entity" />
<Reference Include="System.Deployment" />
<Reference Include="System.IdentityModel">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Security" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Application.cs">
Expand All @@ -82,6 +85,24 @@
<Compile Include="ApplicationName.cs">
<DependentUpon>gdsdb.tt</DependentUpon>
</Compile>
<Compile Include="User.cs">
<DependentUpon>usersdb.tt</DependentUpon>
</Compile>
<Compile Include="usersdb.Context.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>usersdb.Context.tt</DependentUpon>
</Compile>
<Compile Include="usersdb.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>usersdb.tt</DependentUpon>
</Compile>
<Compile Include="usersdb.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>usersdb.edmx</DependentUpon>
</Compile>
<Compile Include="SqlApplicationsDatabase.cs" />
<Compile Include="CertificateRequest.cs">
<DependentUpon>gdsdb.tt</DependentUpon>
Expand Down Expand Up @@ -110,6 +131,19 @@
<Compile Include="ServerEndpoint.cs">
<DependentUpon>gdsdb.tt</DependentUpon>
</Compile>
<Compile Include="SqlUsersDatabase.cs" />
<Content Include="usersdb.Context.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>usersdb.Context.cs</LastGenOutput>
<DependentUpon>usersdb.edmx</DependentUpon>
</Content>
<EmbeddedResource Include="DB\usersdb.edmx.sql" />
<Content Include="usersdb.edmx.sql" />
<Content Include="usersdb.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>usersdb.cs</LastGenOutput>
<DependentUpon>usersdb.edmx</DependentUpon>
</Content>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
Expand Down Expand Up @@ -146,6 +180,13 @@
<Generator>EntityModelCodeGenerator</Generator>
<LastGenOutput>gdsdb.Designer.cs</LastGenOutput>
</EntityDeploy>
<EntityDeploy Include="usersdb.edmx">
<Generator>EntityModelCodeGenerator</Generator>
<LastGenOutput>usersdb.Designer.cs</LastGenOutput>
</EntityDeploy>
<None Include="usersdb.edmx.diagram">
<DependentUpon>usersdb.edmx</DependentUpon>
</None>
<None Include="gdsdb.edmx.diagram">
<DependentUpon>gdsdb.edmx</DependentUpon>
</None>
Expand Down
1 change: 0 additions & 1 deletion Samples/GDS/Server/Opc.Ua.GlobalDiscoveryServer.Config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@
</CertificateGroups>
<KnownHostNames/>
<ShutdownDelay>5</ShutdownDelay>
<UsersDatabaseStorePath>%LocalApplicationData%/OPC Foundation/GDS/gdsuserdb.json</UsersDatabaseStorePath>
</GlobalDiscoveryServerConfiguration>
</ua:XmlElement>
</Extensions>
Expand Down
Loading
Loading