Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
b9eb495
Create draft PR for #1032
TomKovac Feb 17, 2026
0a2567a
Normalize line endings via .gitattributes
TomKovac Feb 17, 2026
69888c9
wip
TomKovac Feb 17, 2026
c9dbcd0
wip
TomKovac Feb 17, 2026
927d290
yml line endings
TomKovac Feb 17, 2026
595c5f2
abb cleanup
TomKovac Feb 17, 2026
16714aa
abb
TomKovac Feb 17, 2026
c6be8ab
abb
TomKovac Feb 17, 2026
acf9c2f
operonvars
TomKovac Feb 17, 2026
74c184d
shell_scripts
TomKovac Feb 17, 2026
c9921ec
data_test_files
TomKovac Feb 17, 2026
ecc87e4
add_css
TomKovac Feb 17, 2026
066f25a
gitattributes file renamed
TomKovac Feb 17, 2026
b1d915e
data tests renormalize
TomKovac Feb 18, 2026
e59bf98
update AXSharp package versions to 0.47.0-alpha.431
TomKovac Feb 19, 2026
0d29839
update Inxton.Operon package version to 0.3.0-alpha.113
TomKovac Feb 19, 2026
b9ea7b3
line endings normalized in the expected results of the integration tests
TomKovac Feb 19, 2026
ca0ca63
update AXSharp package versions to 0.47.0-alpha.435 and Inxton.Operon…
TomKovac Feb 19, 2026
d3206f4
wip
TomKovac Feb 19, 2026
cb6bf5f
update AXSharp package versions to 0.47.0-alpha.439
TomKovac Feb 19, 2026
370fc74
normalize line endings for PowerShell scripts and update JSON writing…
TomKovac Feb 19, 2026
fdd9d7c
add operon-variables.css to .gitignore
TomKovac Feb 19, 2026
2f46aea
Stop tracking operon-variables.css (ignore local changes)
TomKovac Feb 19, 2026
04b2704
sync_with_dev
TomKovac Feb 19, 2026
a2cd855
normalize line endings in script files using dos2unix
TomKovac Feb 20, 2026
0ff8c96
normalize line endings in Inputs.st, IoStructures.st, and Outputs.st
TomKovac Feb 20, 2026
9d55c66
remove commented-out line for HWC compiled files and add app\gsd\sour…
TomKovac Feb 20, 2026
58250b1
gitignore updated
TomKovac Feb 20, 2026
e69d312
normalize line endings for copy_hardware_ids.sh, copy_io_addresses.sh…
TomKovac Feb 20, 2026
7e1e89b
Add SecurityConfiguration.json for PLC line with PKI and access prote…
TomKovac Feb 20, 2026
ee44223
normalize line endings for hwc.gen files in copy_hardware_ids.sh, cop…
TomKovac Feb 20, 2026
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
9 changes: 5 additions & 4 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
{
"version": 1,
"isRoot": true,
"tools": {
"AXSharp.ixc": {
"version": "0.47.0-alpha.405",
"version": "0.47.0-alpha.439",
"commands": [
"ixc"
],
Expand All @@ -17,14 +17,14 @@
"rollForward": false
},
"AXSharp.ixd": {
"version": "0.47.0-alpha.405",
"version": "0.47.0-alpha.439",
"commands": [
"ixd"
],
"rollForward": false
},
"AXSharp.ixr": {
"version": "0.47.0-alpha.405",
"version": "0.47.0-alpha.439",
"commands": [
"ixr"
],
Expand Down Expand Up @@ -61,3 +61,4 @@




6 changes: 6 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
29 changes: 29 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Default: treat as text, normalize to LF in the repository
* text=auto eol=lf

# Typical source files (explicit, but the default already covers these)
*.c text eol=lf
*.cpp text eol=lf
*.h text eol=lf
*.py text eol=lf
*.js text eol=lf
*.ts text eol=lf
*.sh text eol=lf
*.yaml text eol=lf
*.yml text eol=lf
*.json text eol=lf
*.css text eol=lf
*.cs text eol=lf
*.ps1 text eol=lf


# Windows-native scripts that often *must* be CRLF in the working tree
# (repo still stores LF; checkout converts to CRLF)
*.bat text eol=crlf
*.cmd text eol=crlf

# Binary files (never touch line endings)
*.png -text
*.jpg -text
*.zip -text
*.pdf -text
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -420,9 +420,6 @@ import-cache
.ax/plcs
.ax/certificates

#AX HWC compiled
hwc.gen/

#AX HWC templates copied from library
library_templates

Expand All @@ -437,3 +434,6 @@ temp/
**/JSONREPOS/

.cursor
operon-variables.css

**/app/gsd/source/**
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"files.eol": "\n"
}
15 changes: 8 additions & 7 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project>
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<CentralPackageVersionOverrideEnabled>false</CentralPackageVersionOverrideEnabled>
Expand All @@ -11,12 +11,12 @@
<!-- Framework-Agnostic Packages -->
<ItemGroup>
<!-- AX# Libraries -->
<PackageVersion Include="AXSharp.Abstractions" Version="0.47.0-alpha.405" />
<PackageVersion Include="AXSharp.Connector" Version="0.47.0-alpha.405" />
<PackageVersion Include="AXSharp.Connector.S71500.WebAPI" Version="0.47.0-alpha.405" />
<PackageVersion Include="AXSharp.Presentation.Blazor" Version="0.47.0-alpha.405" />
<PackageVersion Include="AXSharp.Presentation.Blazor.Controls" Version="0.47.0-alpha.405" />
<PackageVersion Include="Inxton.Operon" Version="0.3.0-alpha.111" />
<PackageVersion Include="AXSharp.Abstractions" Version="0.47.0-alpha.439" />
<PackageVersion Include="AXSharp.Connector" Version="0.47.0-alpha.439" />
<PackageVersion Include="AXSharp.Connector.S71500.WebAPI" Version="0.47.0-alpha.439" />
<PackageVersion Include="AXSharp.Presentation.Blazor" Version="0.47.0-alpha.439" />
<PackageVersion Include="AXSharp.Presentation.Blazor.Controls" Version="0.47.0-alpha.439" />
<PackageVersion Include="Inxton.Operon" Version="0.3.0-alpha.114" />
<!-- Data & Serialization -->
<PackageVersion Include="ClosedXML" Version="0.105.0" />
<PackageVersion Include="Microsoft.Build" Version="18.0.2" />
Expand Down Expand Up @@ -98,3 +98,4 @@




16 changes: 0 additions & 16 deletions axopen.gitattributes

This file was deleted.

22 changes: 17 additions & 5 deletions scripts/update_axsharp_versions.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ $propsPath = Join-Path $repoRoot 'Directory.Packages.props'
if(-not (Test-Path $toolsJsonPath)){ Write-Err ".config/dotnet-tools.json not found at $toolsJsonPath"; exit 1 }
if(-not (Test-Path $propsPath)){ Write-Err "Directory.Packages.props not found at $propsPath"; exit 1 }

function Write-Utf8NoBom-LF {
param([string]$Path, [string]$Content)
$lf = ($Content -replace "`r`n", "`n") -replace "`r", "`n"
[System.IO.File]::WriteAllText($Path, $lf, [System.Text.UTF8Encoding]::new($false))
}

# Discover token from environment if not explicitly provided
if(-not $Token){
$envTokenCandidates = @('AXSHARP_FEED_TOKEN','GITHUB_PACKAGES_TOKEN','GITHUB_TOKEN','GH_TOKEN','NUGET_TOKEN')
Expand Down Expand Up @@ -254,10 +260,14 @@ foreach($k in $operonToolKeys){

if(-not $DryRun){
if($NormalizeJson){
$newJson = $toolsObj | ConvertTo-Json -Depth 10
#$newJson = $toolsObj | ConvertTo-Json -Depth 10
# Normalize spacing after colons to a single space
$newJson = ($newJson -split "`r?`n") | ForEach-Object { $_ -replace '":\s+','": ' } | Out-String
Set-Content -Path $toolsJsonPath -Value ($newJson.TrimEnd() + [Environment]::NewLine) -Encoding UTF8
#$newJson = ($newJson -split "`r?`n") | ForEach-Object { $_ -replace '":\s+','": ' } | Out-String
#Set-Content -Path $toolsJsonPath -Value ($newJson.TrimEnd() + [Environment]::NewLine) -Encoding UTF8
$newJson = $toolsObj | ConvertTo-Json -Depth 10
$newJson = (($newJson -split "`r?`n") | ForEach-Object { $_ -replace '":\s+','": ' }) -join "`n"
$newJson = $newJson.TrimEnd() + "`n"
Write-Utf8NoBom-LF -Path $toolsJsonPath -Content $newJson
} else {
# In-place substitution to preserve existing formatting (indentation, alignment, comments if any)
$updatedRaw = $toolsRaw
Expand Down Expand Up @@ -286,7 +296,8 @@ if(-not $DryRun){
)
}
if($updatedRaw -ne $toolsRaw){
Set-Content -Path $toolsJsonPath -Value $updatedRaw -Encoding UTF8
#Set-Content -Path $toolsJsonPath -Value $updatedRaw -Encoding UTF8
Write-Utf8NoBom-LF -Path $toolsJsonPath -Content $updatedRaw
}
}
}
Expand Down Expand Up @@ -331,7 +342,8 @@ $propsUpdated = [System.Text.RegularExpressions.Regex]::Replace($propsUpdated, $

if(-not $DryRun){
if($propsUpdated -ne $propsRaw){
Set-Content -Path $propsPath -Value $propsUpdated -Encoding UTF8
#Set-Content -Path $propsPath -Value $propsUpdated -Encoding UTF8
Write-Utf8NoBom-LF -Path $propsPath -Content $propsUpdated
} elseif($Detailed){
Write-Info 'No AXSharp.* or Inxton.Operon.* entries needed updating in Directory.Packages.props.'
}
Expand Down
102 changes: 102 additions & 0 deletions src/Security/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# AXOpen.Security

AxOpen.Security is library which provides authentication and authorization in Blazor AX applications. It is based on a default solution for authentication in Blazor, which is extended by using implemented repositories within Ax.Open.Data. As a result, multiple storage providers for security can be used.

## Installation

The security library is available in form of NuGet package. Detailed installation instructions of security into empty Blazor project is located in [security installation article](docs/INSTALLATION.md).

## Basic concepts

Each user is limited to having just a single group. A group is formed by a collection of multiple roles. When a user is assigned to a group, they possess all the roles associated with that group.
It is possible for a single role to be assigned to multiple groups.

## Security views

SecurityManagementView component serves for managing users. It is available only if user is logged in with administrator rights.

When user is logged in with administrator rights, it is possible to modify all available users and groups. Administrator can delete users or change group.

### User management

The SecurityManagementView component includes a tab dedicated to user management. Within this tab, users can be updated or newly created. When a user is selected, a card is displayed showing the current data for that user, there is an option to update or delete user.

![user management](assets/UserManagement.png)

### Group Management

The SecurityManagementView component includes a tab for group management. Within this tab, groups can be updated or newly created. When a group is selected, a card is displayed showing the assigned roles for that group. Users have the option assigned or unassign roles or delete group.

![group management](assets/GroupManagement.png)

### Account Management

In account management view is possible to change the your user data, like email address or password.

![account management](assets/AccountManagement.png)

### User Create

In user create view is possible to new user.

![Create user](assets/CreateUser.png)

## AuthorizeView and AuthenticationContext

There are two ways how to work with authentication and authorization.

- Use of the `AuthorizeView` component in Blazor component
- Use of the `AuthenticationStateProvider` within a C# class

### Use of AuthorizeView

The `AuthorizeView` is used to create a secure views within a Blazor application. It contains two child components `Authorized` and `NotAuthorized`, which serves for visualizing view in a corresponded views. In addition, the parameter `Roles` can be used to specified roles, based on which the authorized view is shown.

The `AuthorizeView` contain base class named `context`, which is used to access identity of currently logged in user.

The example of usage of `AuthorizeView` within a Blazor component is shown below:

```html
<AuthorizeView Roles="Administrator">
<Authorized>
<h4>You have role Administrator.</h4>
<h4>Your name is: @context.User.Identity.Name</h4>
</Authorized>
<NotAuthorized>
<h4>You dont have role Administrator.</h4>
</NotAuthorized>
</AuthorizeView>
```

If the user is authenticated and is also authorized with the `Administrator` role, the authorized view is shown. Otherwise, non-authorized view is displayed.

Also, there is a possibility to call method from `RoleGroupManager` called `GetRoles`, which takes as parameter name of the group and returns corresponded roles. `RoleGroupManager` is accessible from `IRepositoryService`.

```html
@inject IRepositoryService rs

<AuthorizeView Roles="@rs.RoleGroupManager.GetRoles("AdminGroup")">
```

### Use of AuthenticationStateProvider

The `AuthenticationStateProvider` serves for accessing current logged in user and his claims. This provider can be injected to any C# class (either from constructor injection (in ViewModel) or with `Inject` attribute in Blazor component), where user need to work with authentication context. The authentication context of current user can be accessed in following way:

```C#
@page "/mypage"
@inject AuthenticationStateProvider _asp

@code
{
protected override async Task OnInitializedAsync()
{
var context = await _asp.GetAuthenticationStateAsync();
var isAuth = context.User.Identity.IsAuthenticated;
if (isAuth)
{
Console.Writeline("I'm authenticated");
}
}
}

```
Loading
Loading