Compare commits
27 Commits
ca214225ea
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 7ea89aa35e | |||
| 50f5289191 | |||
| f8dcd5ba41 | |||
| 8f5015f7d7 | |||
| efcd26fb29 | |||
| 2ee0f976fd | |||
| a3087a5e34 | |||
| 525a30b541 | |||
| f5471a8d01 | |||
| bcdcdd679a | |||
| 88cffc12a5 | |||
| 3bffdabc64 | |||
| 5b45bdfa6b | |||
| 4f5d034e53 | |||
| 17d4bc51f4 | |||
| fc4209eb40 | |||
| 545b629129 | |||
| eceace7e5e | |||
| cb9c7694db | |||
| 4c99e1cbee | |||
| 39c97e1e3c | |||
| 720c25bd5c | |||
| ae0301c5be | |||
| 8f31377b99 | |||
|
|
addf7585f2 | ||
|
|
dddabefc7d | ||
|
|
9c5cf2de30 |
@@ -117,5 +117,8 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cli": {
|
||||
"analytics": false
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "user-manager-ui",
|
||||
"version": "4.0.0",
|
||||
"version": "2.0.0",
|
||||
"minApiVersion":"6.1.3",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start:ssl": "ng serve --ssl -o",
|
||||
@@ -31,9 +32,12 @@
|
||||
"bootstrap": "^5.3.3",
|
||||
"bootstrap-icons": "^1.11.3",
|
||||
"express": "^4.18.2",
|
||||
"moment": "^2.30.1",
|
||||
"ng2-pdf-viewer": "^10.4.0",
|
||||
"rxjs": "~7.8.0",
|
||||
"sweetalert2": "^11.12.3",
|
||||
"tslib": "^2.3.0",
|
||||
"uuid": "^11.1.0",
|
||||
"zone.js": "~0.14.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
9384
src/DigitalData.UserManager.API/ClientApp/user_manager_ui/pnpm-lock.yaml
generated
Normal file
9384
src/DigitalData.UserManager.API/ClientApp/user_manager_ui/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,11 @@
|
||||
{
|
||||
"/api": {
|
||||
"target": "https://localhost:7052",
|
||||
"target": "https://localhost:7103",
|
||||
"secure": false,
|
||||
"changeOrigin": true
|
||||
},
|
||||
"/docs": {
|
||||
"target": "https://localhost:7103",
|
||||
"secure": false,
|
||||
"changeOrigin": true
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<app-nav-menu></app-nav-menu>
|
||||
<main class="container-fluid">
|
||||
<router-outlet></router-outlet>
|
||||
</main>
|
||||
</main>
|
||||
<app-footer></app-footer>
|
||||
@@ -5,11 +5,12 @@ import { TransferService } from './services/button/transfer.service';
|
||||
import { UpdateService } from './services/button/update.service';
|
||||
import { RefreshService } from './services/button/refresh.service';
|
||||
import { DeletionService } from './services/button/deletion.service';
|
||||
import { FooterComponent } from './components/footer/footer.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
standalone: true,
|
||||
imports: [RouterOutlet, NavMenuComponent],
|
||||
imports: [RouterOutlet, NavMenuComponent, FooterComponent],
|
||||
templateUrl: './app.component.html',
|
||||
styleUrl: './app.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.Default
|
||||
|
||||
@@ -6,6 +6,7 @@ import { GroupComponent } from './pages/group/group.component';
|
||||
import { ModuleComponent } from './pages/module/module.component';
|
||||
import { UserAssignmentComponent } from './pages/user-assignment/user-assignment.component';
|
||||
import { UserRepresentationComponent } from './pages/user-representation/user-representation.component';
|
||||
import { PrivacyPolicyComponent } from './pages/privacy-policy/privacy-policy.component';
|
||||
|
||||
export const routes: Routes = [
|
||||
{ path: '', component: HomeComponent },
|
||||
@@ -13,5 +14,6 @@ export const routes: Routes = [
|
||||
{ path: 'group-table', component: GroupComponent, canActivate: [AuthGuard] },
|
||||
{ path: 'module-table', component: ModuleComponent, canActivate: [AuthGuard] },
|
||||
{ path: 'user-assignment', component: UserAssignmentComponent, canActivate: [AuthGuard] },
|
||||
{ path: 'user-representation', component: UserRepresentationComponent, canActivate: [AuthGuard] }
|
||||
{ path: 'user-representation', component: UserRepresentationComponent, canActivate: [AuthGuard] },
|
||||
{ path: 'privacy-policy', component: PrivacyPolicyComponent }
|
||||
];
|
||||
@@ -0,0 +1,10 @@
|
||||
<footer>
|
||||
<mat-toolbar color="mat-h3" class="footer-toolbar">
|
||||
<a class="mat-h3 footer-brand-link" [routerLink]="['/']">© 2025 Digital Data</a>
|
||||
<div class="footer-links">
|
||||
<a mat-button class="mat-body-strong" [routerLink]="['/privacy-policy']">Datenschutz</a>
|
||||
<a mat-button class="mat-body-strong" href="https://digitaldata.works/#kontakt" target="_blank">Kontakt</a>
|
||||
<span mat-button class="mat-body-strong">{{appVersion}}</span>
|
||||
</div>
|
||||
</mat-toolbar>
|
||||
</footer>
|
||||
@@ -0,0 +1,23 @@
|
||||
.footer-toolbar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 2.2rem;
|
||||
z-index: 1000;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.footer-links{
|
||||
display: flex;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
justify-content: space-around;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
footer a {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
text-decoration: none;
|
||||
color: rgb(255, 255, 255);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { FooterComponent } from './footer.component';
|
||||
|
||||
describe('FooterComponent', () => {
|
||||
let component: FooterComponent;
|
||||
let fixture: ComponentFixture<FooterComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [FooterComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(FooterComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { name, version, minApiVersion } from '../../../../package.json';
|
||||
|
||||
@Component({
|
||||
selector: 'app-footer',
|
||||
standalone: true,
|
||||
imports: [
|
||||
MatToolbarModule, RouterModule
|
||||
],
|
||||
templateUrl: './footer.component.html',
|
||||
styleUrl: './footer.component.scss'
|
||||
})
|
||||
export class FooterComponent {
|
||||
appVersion: string = `${name} v${version} | ${minApiVersion}`;
|
||||
}
|
||||
@@ -42,7 +42,7 @@ export class GroupFormComponent {
|
||||
.subscribe(() => this.updateErrorMessage());
|
||||
}
|
||||
|
||||
updateErrorMessage() {
|
||||
public updateErrorMessage() {
|
||||
if (this.groupname.hasError('required')) {
|
||||
this.errorMessage.set('Wert eingeben');
|
||||
} else {
|
||||
|
||||
@@ -7,20 +7,20 @@
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w80p">
|
||||
<mat-label>Gruppe</mat-label>
|
||||
<input matInput [formControl]="name" />
|
||||
<input matInput [formControl]="name" [readonly] = 'group.internal' />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<!-- comment -->
|
||||
<div class="dd-row input-row">
|
||||
<mat-form-field>
|
||||
<mat-label>Kommentar</mat-label>
|
||||
<textarea matInput [formControl]="comment"></textarea>
|
||||
<textarea matInput [formControl]="comment" [readonly] = 'group.internal'></textarea>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<mat-divider></mat-divider>
|
||||
<!-- active, internal, async -->
|
||||
<div class="dd-row input-row">
|
||||
<mat-slide-toggle [(ngModel)]="group.active">
|
||||
<mat-slide-toggle [(ngModel)]="group.active" [disabled]='group.internal'>
|
||||
Aktiv
|
||||
</mat-slide-toggle>
|
||||
<mat-slide-toggle [(ngModel)]="group.internal" disabled>
|
||||
@@ -52,7 +52,7 @@
|
||||
<mat-divider></mat-divider>
|
||||
<!-- save-button, delete-button -->
|
||||
<div class="dd-row button-row">
|
||||
<button mat-fab extended (click)="update()">
|
||||
<button mat-fab extended (click)="update()" [disabled]='group.internal'>
|
||||
<mat-icon>save</mat-icon>
|
||||
Speichern
|
||||
</button>
|
||||
|
||||
@@ -46,6 +46,7 @@ export class GroupUpdateFormComponent {
|
||||
errorMessage = signal('');
|
||||
|
||||
constructor(private uService: GroupService, private rService: RefreshService) {
|
||||
console.log(this.group);
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<iframe src="docs/privacy-policy.pdf#toolbar=0&navpanes=0&scrollbar=1" ></iframe>
|
||||
@@ -0,0 +1,10 @@
|
||||
iframe {
|
||||
position : absolute;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
left : 0;
|
||||
top : 4rem;
|
||||
width : 100%;
|
||||
height : calc(100% - 6rem);
|
||||
z-index : 10;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { PrivacyPolicyComponent } from './privacy-policy.component';
|
||||
|
||||
describe('PrivacyPolicyComponent', () => {
|
||||
let component: PrivacyPolicyComponent;
|
||||
let fixture: ComponentFixture<PrivacyPolicyComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [PrivacyPolicyComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(PrivacyPolicyComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-privacy-policy',
|
||||
standalone: true,
|
||||
imports: [],
|
||||
templateUrl: './privacy-policy.component.html',
|
||||
styleUrl: './privacy-policy.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class PrivacyPolicyComponent {
|
||||
}
|
||||
@@ -23,7 +23,7 @@ export interface Group {
|
||||
id?: number;
|
||||
name?: string;
|
||||
adSync?: boolean;
|
||||
internal?: boolean;
|
||||
internal: boolean;
|
||||
active?: boolean;
|
||||
comment?: string;
|
||||
addedWho?: string;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Observable, tap } from 'rxjs';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { inject } from '@angular/core';
|
||||
|
||||
export class ApiService<Model> {
|
||||
constructor(http: HttpClient, baseUrl: string) {
|
||||
@@ -9,6 +11,7 @@ export class ApiService<Model> {
|
||||
|
||||
http: HttpClient;
|
||||
baseUrl: string;
|
||||
protected snackBar = inject(MatSnackBar);
|
||||
|
||||
getAll(): Observable<Model[]> {
|
||||
return this.http.get<Model[]>(this.baseUrl, { withCredentials: true });
|
||||
@@ -25,7 +28,12 @@ export class ApiService<Model> {
|
||||
|
||||
update(updateModel: Model): Observable<Model> {
|
||||
const url = `${this.baseUrl}`;
|
||||
return this.http.put<Model>(url, updateModel, { withCredentials: true });
|
||||
return this.http.put<Model>(url, updateModel, { withCredentials: true }).pipe(
|
||||
tap(() => {
|
||||
this.snackBar.open('Aktualisierung erfolgreich!', 'Schließen', {
|
||||
duration: 2000,
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
delete(id: number): Observable<any> {
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { Version } from "@angular/core";
|
||||
|
||||
export const env = {
|
||||
production: false,
|
||||
production: true,
|
||||
version: new Version("6.1.3"),
|
||||
default_api_url: "/api",
|
||||
routes: {
|
||||
user: "/user",
|
||||
|
||||
@@ -2,6 +2,13 @@
|
||||
@import '../node_modules/@angular/cdk/overlay-prebuilt.css';
|
||||
@import "../node_modules/bootstrap-icons/font/bootstrap-icons.css";
|
||||
|
||||
* {
|
||||
-webkit-user-select: none; /* Safari */
|
||||
-moz-user-select: none; /* Firefox */
|
||||
-ms-user-select: none; /* Internet Explorer/Edge */
|
||||
user-select: none; /* Standart */
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0366d6;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
"lib": [
|
||||
"ES2022",
|
||||
"dom"
|
||||
]
|
||||
],
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
|
||||
@@ -9,6 +9,8 @@ using Microsoft.Extensions.Localization;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using DigitalData.Core.Abstraction.Application;
|
||||
using DigitalData.Core.Abstraction.Application.DTO;
|
||||
using Microsoft.Extensions.Options;
|
||||
using DigitalData.UserManager.API.Models;
|
||||
|
||||
namespace DigitalData.UserManager.API.Controllers;
|
||||
|
||||
@@ -23,8 +25,9 @@ public class DirectoryController : ControllerBase
|
||||
private readonly Dictionary<string, string> _customSearchFilters;
|
||||
private readonly IStringLocalizer<Resource> _localizer;
|
||||
private readonly ILogger<DirectoryController> _logger;
|
||||
private readonly DirSearchRoot _dirSearchRoot;
|
||||
|
||||
public DirectoryController(IConfiguration configuration, IStringLocalizer<Resource> localizer, IUserService userService, IDirectorySearchService directorySearchService, ILogger<DirectoryController> logger)
|
||||
public DirectoryController(IConfiguration configuration, IStringLocalizer<Resource> localizer, IUserService userService, IDirectorySearchService directorySearchService, ILogger<DirectoryController> logger, IOptions<DirSearchRoot> dirSearchRootOptions)
|
||||
{
|
||||
_localizer = localizer;
|
||||
_userService = userService;
|
||||
@@ -33,23 +36,7 @@ public class DirectoryController : ControllerBase
|
||||
var customSearchFiltersSection = configuration.GetSection("DirectorySearch:CustomSearchFilters");
|
||||
_customSearchFilters = customSearchFiltersSection.Get<Dictionary<string, string>>() ?? new();
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpGet("Root/{username}")]
|
||||
public IActionResult GetRootOf(string username)
|
||||
{
|
||||
var root = _dirSearchService.GetSearchRootCache(username);
|
||||
|
||||
return root is null ? NotFound() : Ok(new
|
||||
{
|
||||
guid = root.Guid,
|
||||
nativeGuid = root.NativeGuid,
|
||||
name = root.Name,
|
||||
path = root.Path,
|
||||
parentPath = root.Parent?.Path,
|
||||
username = root.Username,
|
||||
schemaClassName = root.SchemaClassName
|
||||
});
|
||||
_dirSearchRoot = dirSearchRootOptions.Value;
|
||||
}
|
||||
|
||||
[HttpGet("CustomSearchFilter")]
|
||||
@@ -66,26 +53,6 @@ public class DirectoryController : ControllerBase
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> CreateSearchRoot([FromBody] SearchRootCreateDto searchRootCreateDto)
|
||||
{
|
||||
var dirEntryUsername = searchRootCreateDto.Username ?? CurrentUser;
|
||||
if (dirEntryUsername is null)
|
||||
return Unauthorized();
|
||||
|
||||
bool isValid = _dirSearchService.ValidateCredentials(dirEntryUsername, searchRootCreateDto.Password);
|
||||
|
||||
if (!isValid)
|
||||
return Unauthorized(Result.Fail().Message(_localizer[Key.UserNotFound]));
|
||||
|
||||
var userResult = await _userService.ReadByUsernameAsync(dirEntryUsername);
|
||||
if (!userResult.IsSuccess || userResult.Data is null)
|
||||
return Unauthorized(Result.Fail().Message(_localizer[Key.UserNotFoundInLocalDB]));
|
||||
|
||||
_dirSearchService.SetSearchRootCache(userResult.Data.Username, searchRootCreateDto.Password);
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpGet("SearchByFilter/{filter}")]
|
||||
public IActionResult SearchByFilter([FromRoute] string filter, string? dirEntryUsername, params string[] propName)
|
||||
{
|
||||
@@ -94,7 +61,9 @@ public class DirectoryController : ControllerBase
|
||||
if (dirEntryUsername is null)
|
||||
return Unauthorized();
|
||||
|
||||
return _dirSearchService.FindAllByUserCache(dirEntryUsername, filter, properties: propName).Then(Ok, IActionResult (m, n) =>
|
||||
using var sRoot = _dirSearchRoot.ToDirectoryEntry;
|
||||
|
||||
return _dirSearchService.FindAll(sRoot, filter, properties: propName).Then(Ok, IActionResult (m, n) =>
|
||||
{
|
||||
_logger.LogNotice(n);
|
||||
return StatusCode(StatusCodes.Status424FailedDependency);
|
||||
@@ -114,7 +83,9 @@ public class DirectoryController : ControllerBase
|
||||
if (filter is null)
|
||||
return NotFound($"The filter named {filterName} does not exist.");
|
||||
|
||||
return _dirSearchService.FindAllByUserCache(dirEntryUsername, filter, properties: propName).Then(Ok, IActionResult (m, n) =>
|
||||
using var sRoot = _dirSearchRoot.ToDirectoryEntry;
|
||||
|
||||
return _dirSearchService.FindAll(sRoot, filter, properties: propName).Then(Ok, IActionResult (m, n) =>
|
||||
{
|
||||
_logger.LogNotice(n);
|
||||
return StatusCode(StatusCodes.Status424FailedDependency);
|
||||
@@ -135,7 +106,9 @@ public class DirectoryController : ControllerBase
|
||||
if (filter is null)
|
||||
throw new InvalidOperationException("The LDAP Group Search filter configuration is missing in your appsettings. Please ensure it's added under DirectorySearch:CustomSearchFilters:Group to enable group searches.");
|
||||
|
||||
return _dirSearchService.FindAllByUserCache(username: dirEntryUsername, filter, properties: propName).Then(Ok, IActionResult (m, n) =>
|
||||
using var sRoot = _dirSearchRoot.ToDirectoryEntry;
|
||||
|
||||
return _dirSearchService.FindAll(_dirSearchRoot.ToDirectoryEntry, filter, properties: propName).Then(Ok, IActionResult (m, n) =>
|
||||
{
|
||||
_logger.LogNotice(n);
|
||||
return StatusCode(StatusCodes.Status424FailedDependency);
|
||||
@@ -156,7 +129,9 @@ public class DirectoryController : ControllerBase
|
||||
if (filter is null)
|
||||
throw new InvalidOperationException("The LDAP User Search filter configuration is missing in your appsettings. Please ensure it's added under DirectorySearch:CustomSearchFilters:User to enable group searches.");
|
||||
|
||||
return _dirSearchService.FindAllByUserCache(username: dirEntryUsername, filter, properties: propName).Then(
|
||||
using var sRoot = _dirSearchRoot.ToDirectoryEntry;
|
||||
|
||||
return _dirSearchService.FindAll(sRoot, filter, properties: propName).Then(
|
||||
Success: data =>
|
||||
{
|
||||
if (groupName is not null)
|
||||
|
||||
@@ -4,29 +4,12 @@
|
||||
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Version>6.1.2</Version>
|
||||
<AssemblyVersion>6.1.2</AssemblyVersion>
|
||||
<FileVersion>6.1.2</FileVersion>
|
||||
<Version>6.1.4</Version>
|
||||
<AssemblyVersion>6.1.4</AssemblyVersion>
|
||||
<FileVersion>6.1.4</FileVersion>
|
||||
<PackageIcon>icon.png</PackageIcon>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="wwwroot\assets\**" />
|
||||
<Compile Remove="wwwroot\media\**" />
|
||||
<Content Remove="wwwroot\assets\**" />
|
||||
<Content Remove="wwwroot\media\**" />
|
||||
<EmbeddedResource Remove="wwwroot\assets\**" />
|
||||
<EmbeddedResource Remove="wwwroot\media\**" />
|
||||
<None Remove="wwwroot\assets\**" />
|
||||
<None Remove="wwwroot\media\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Remove="wwwroot\chunk-A2L6DXQH.js" />
|
||||
<Content Remove="wwwroot\chunk-ZC35XWOR.js" />
|
||||
<Content Remove="wwwroot\main-QF3MRK45.js" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DigitalData.Auth.Client" Version="1.3.7" />
|
||||
<PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.0.0" />
|
||||
@@ -47,7 +30,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="ClientApp\" />
|
||||
<Folder Include="wwwroot\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -8,5 +8,5 @@ public class AuthTokenKeys
|
||||
|
||||
public string Issuer { get; init; } = "auth.digitaldata.works";
|
||||
|
||||
public string Audience { get; init; } = "user-manager.digitaldata.works";
|
||||
public string Audience { get; init; } = "usermanager.digitaldata.works";
|
||||
}
|
||||
|
||||
22
src/DigitalData.UserManager.API/Models/DirSearchRoot.cs
Normal file
22
src/DigitalData.UserManager.API/Models/DirSearchRoot.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using DigitalData.Core.Application;
|
||||
using System.DirectoryServices;
|
||||
|
||||
namespace DigitalData.UserManager.API.Models;
|
||||
|
||||
[Obsolete("Use ActiveDirectory.API")]
|
||||
public class DirSearchRoot : DirectorySearchOptions
|
||||
{
|
||||
public string Path => $"LDAP://{ServerName}/{Root}";
|
||||
|
||||
public string? Username { get; set; }
|
||||
|
||||
public string? Password { get; set; }
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")]
|
||||
public DirectoryEntry ToDirectoryEntry => new ()
|
||||
{
|
||||
Path = Path,
|
||||
Username = Username,
|
||||
Password = Password
|
||||
};
|
||||
}
|
||||
@@ -28,6 +28,12 @@ try {
|
||||
|
||||
var config = builder.Configuration;
|
||||
|
||||
Directory
|
||||
.GetFiles(builder.Environment.ContentRootPath, "appsettings.*.json", SearchOption.TopDirectoryOnly)
|
||||
.Where(file => Path.GetFileName(file) != $"appsettings.Development.json")
|
||||
.ToList()
|
||||
.ForEach(file => config.AddJsonFile(file, true, true));
|
||||
|
||||
builder.Services.AddEncryptor(builder.Configuration.GetSection("EncryptionParameters"));
|
||||
builder.Logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
|
||||
|
||||
@@ -76,6 +82,7 @@ try {
|
||||
|
||||
builder.ConfigureBySection<DirectorySearchOptions>();
|
||||
builder.Services.AddDirectorySearchService(config.GetSection("DirectorySearchOptions"));
|
||||
builder.Services.Configure<DirSearchRoot>(config.GetSection("DirectorySearchOptions"));
|
||||
builder.Services.AddJWTService<UserReadDto>(user => new SecurityTokenDescriptor()
|
||||
{
|
||||
Claims = user.ToClaimList().ToDictionary(claim => claim.Type, claim => claim.Value as object)
|
||||
@@ -165,7 +172,6 @@ try {
|
||||
var eCnnStr = config.GetConnectionString("UM_DEF") ?? throw new InvalidOperationException("Connection string 'DD_ECM_Connection' is missing from the configuration.");
|
||||
|
||||
SqlConnectionStringBuilder cnnStrBuilder = new(eCnnStr);
|
||||
cnnStrBuilder.UserID = encryptor.Decrypt(cnnStrBuilder.UserID);
|
||||
cnnStrBuilder.Password = encryptor.Decrypt(cnnStrBuilder.Password);
|
||||
var dCnnStr = cnnStrBuilder.ConnectionString;
|
||||
return dCnnStr;
|
||||
|
||||
12
src/DigitalData.UserManager.API/appsettings.Auth.json
Normal file
12
src/DigitalData.UserManager.API/appsettings.Auth.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"AuthClientParams": {
|
||||
"Url": "http://172.24.12.39:9090/auth-hub",
|
||||
"PublicKeys": [
|
||||
{
|
||||
"Issuer": "auth.digitaldata.works",
|
||||
"Audience": "usermanager.digitaldata.works"
|
||||
}
|
||||
],
|
||||
"RetryDelay": "00:00:05"
|
||||
}
|
||||
}
|
||||
45
src/DigitalData.UserManager.API/appsettings.Logging.json
Normal file
45
src/DigitalData.UserManager.API/appsettings.Logging.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"NLog": {
|
||||
"throwConfigExceptions": true,
|
||||
"variables": {
|
||||
"logDirectory": "E:\\LogFiles\\Digital Data\\WebUserManager",
|
||||
"logFileNamePrefix": "${shortdate}-ECM.WebUserManager.Web"
|
||||
},
|
||||
"targets": {
|
||||
"infoLogs": {
|
||||
"type": "File",
|
||||
"fileName": "${logDirectory}\\${logFileNamePrefix}-Info.log",
|
||||
"maxArchiveDays": 30
|
||||
},
|
||||
"errorLogs": {
|
||||
"type": "File",
|
||||
"fileName": "${logDirectory}\\${logFileNamePrefix}-Error.log",
|
||||
"maxArchiveDays": 30
|
||||
},
|
||||
"criticalLogs": {
|
||||
"type": "File",
|
||||
"fileName": "${logDirectory}\\${logFileNamePrefix}-Critical.log",
|
||||
"maxArchiveDays": 30
|
||||
}
|
||||
},
|
||||
// Trace, Debug, Info, Warn, Error and *Fatal*
|
||||
"rules": [
|
||||
{
|
||||
"logger": "*",
|
||||
"minLevel": "Info",
|
||||
"maxLevel": "Warn",
|
||||
"writeTo": "infoLogs"
|
||||
},
|
||||
{
|
||||
"logger": "*",
|
||||
"level": "Error",
|
||||
"writeTo": "errorLogs"
|
||||
},
|
||||
{
|
||||
"logger": "*",
|
||||
"level": "Fatal",
|
||||
"writeTo": "criticalLogs"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -6,67 +6,20 @@
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"UM_DEF": "Server=SDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM;User Id=g+2edXEbMbujCUjh7INZRQ==;Password=Bz/n9pu8EyzlVqicaMRQGQ==;Encrypt=false;TrustServerCertificate=True;"
|
||||
"UM_DEF": "Server=SDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=Bz/n9pu8EyzlVqicaMRQGQ==;Encrypt=false;TrustServerCertificate=True;"
|
||||
},
|
||||
"AllowedOrigins": [ "https://localhost:7103", "http://172.24.12.39:85", "http://localhost:85", "http://localhost:4200", "http://localhost:5500", "https://localhost:7202" ],
|
||||
"RunAsWindowsService": false,
|
||||
"DirectorySearchOptions": {
|
||||
"ServerName": "DD-VMP01-DC01",
|
||||
"Root": "DC=dd-gan,DC=local,DC=digitaldata,DC=works",
|
||||
"UserCacheExpirationDays": 1,
|
||||
"Username": "FABRIK19-User01",
|
||||
"Password": "9bWOr0UGuHn_7VkC",
|
||||
"CustomSearchFilters": {
|
||||
"User": "(&(objectClass=user)(sAMAccountName=*))",
|
||||
"Group": "(&(objectClass=group) (samAccountName=*))"
|
||||
}
|
||||
},
|
||||
"Jwt": {
|
||||
"Key": "pJBcBWZSjsWlhi1OlCcw6ERTMRNb7qsdvsfvdfbagdfbdfsSDGSDMhsjkfdhsdfbgkHKSDF",
|
||||
"Issuer": "http://localhost:44316",
|
||||
"Audience": "http://localhost:44316"
|
||||
},
|
||||
"NLog": {
|
||||
"throwConfigExceptions": true,
|
||||
"variables": {
|
||||
"logDirectory": "E:\\LogFiles\\Digital Data\\WebUserManager",
|
||||
"logFileNamePrefix": "${shortdate}-ECM.WebUserManager.Web"
|
||||
},
|
||||
"targets": {
|
||||
"infoLogs": {
|
||||
"type": "File",
|
||||
"fileName": "${logDirectory}\\${logFileNamePrefix}-Info.log",
|
||||
"maxArchiveDays": 30
|
||||
},
|
||||
"errorLogs": {
|
||||
"type": "File",
|
||||
"fileName": "${logDirectory}\\${logFileNamePrefix}-Error.log",
|
||||
"maxArchiveDays": 30
|
||||
},
|
||||
"criticalLogs": {
|
||||
"type": "File",
|
||||
"fileName": "${logDirectory}\\${logFileNamePrefix}-Critical.log",
|
||||
"maxArchiveDays": 30
|
||||
}
|
||||
},
|
||||
// Trace, Debug, Info, Warn, Error and *Fatal*
|
||||
"rules": [
|
||||
{
|
||||
"logger": "*",
|
||||
"minLevel": "Info",
|
||||
"maxLevel": "Warn",
|
||||
"writeTo": "infoLogs"
|
||||
},
|
||||
{
|
||||
"logger": "*",
|
||||
"level": "Error",
|
||||
"writeTo": "errorLogs"
|
||||
},
|
||||
{
|
||||
"logger": "*",
|
||||
"level": "Fatal",
|
||||
"writeTo": "criticalLogs"
|
||||
}
|
||||
]
|
||||
},
|
||||
"EncryptionParameters": {
|
||||
"Key": "JGPwHVD0BQmC7upi5OV11PzzIk47ugTJoqBV/et5w40=",
|
||||
"IV": "gMuetIjlPvJnSzu+i7I3xg=="
|
||||
@@ -75,15 +28,5 @@
|
||||
"DateTimeZoneHandling": "Local",
|
||||
// Delete below in production
|
||||
"UseEncryptor": true,
|
||||
"UseSwagger": true,
|
||||
"AuthClientParams": {
|
||||
"Url": "http://172.24.12.39:9090/auth-hub",
|
||||
"PublicKeys": [
|
||||
{
|
||||
"Issuer": "auth.digitaldata.works",
|
||||
"Audience": "user-manager.digitaldata.works"
|
||||
}
|
||||
],
|
||||
"RetryDelay": "00:00:05"
|
||||
}
|
||||
"UseSwagger": true
|
||||
}
|
||||
BIN
src/DigitalData.UserManager.API/wwwroot/docs/privacy-policy.pdf
Normal file
BIN
src/DigitalData.UserManager.API/wwwroot/docs/privacy-policy.pdf
Normal file
Binary file not shown.
@@ -43,7 +43,7 @@ namespace DigitalData.UserManager.Application.Services
|
||||
var group = await _repository.ReadByIdAsync(gId);
|
||||
if (group is null)
|
||||
throw new ForbiddenException("Group not found.");
|
||||
else if (!group.Internal)
|
||||
else if (group.Internal)
|
||||
throw new ForbiddenException("Updates are not allowed for system groups.");
|
||||
return await base.UpdateAsync(updateDto);
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
<PackageIcon>icon.png</PackageIcon>
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/WebUserManager.git</RepositoryUrl>
|
||||
<PackageTags>digital data user maanger</PackageTags>
|
||||
<Version>1.1.2</Version>
|
||||
<AssemblyVersion>1.1.2</AssemblyVersion>
|
||||
<FileVersion>1.1.2</FileVersion>
|
||||
<Version>1.1.3</Version>
|
||||
<AssemblyVersion>1.1.3</AssemblyVersion>
|
||||
<FileVersion>1.1.3</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -6,36 +6,44 @@ using System;
|
||||
#endif
|
||||
|
||||
namespace DigitalData.UserManager.Domain.Entities
|
||||
{
|
||||
public class BaseEntity
|
||||
#if NET
|
||||
;
|
||||
#elif NETFRAMEWORK
|
||||
{
|
||||
[Column("GUID")]
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[StringLength(50)]
|
||||
[Column("ADDED_WHO")]
|
||||
public string
|
||||
#if NET7_0_OR_GREATER
|
||||
?
|
||||
#endif
|
||||
AddedWho { get; set; }
|
||||
|
||||
[StringLength(50)]
|
||||
[Column("CHANGED_WHO")]
|
||||
public string
|
||||
#if NET7_0_OR_GREATER
|
||||
?
|
||||
public class BaseEntity
|
||||
{
|
||||
[Column("GUID")]
|
||||
[Key]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[StringLength(50)]
|
||||
[Column("ADDED_WHO")]
|
||||
public string
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
ChangedWho { get; set; }
|
||||
AddedWho { get; set; }
|
||||
|
||||
//TODO: assign it to default value in create dto, not here!
|
||||
[Column("ADDED_WHEN", TypeName = "datetime")]
|
||||
[DefaultValue("GETDATE()")]
|
||||
public DateTime AddedWhen { get; set; } = DateTime.Now;
|
||||
[StringLength(50)]
|
||||
[Column("CHANGED_WHO")]
|
||||
public string
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
ChangedWho { get; set; }
|
||||
|
||||
[Column("CHANGED_WHEN", TypeName = "datetime")]
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
//TODO: assign it to default value in create dto, not here!
|
||||
[Column("ADDED_WHEN", TypeName = "datetime")]
|
||||
[DefaultValue("GETDATE()")]
|
||||
public DateTime AddedWhen { get; set; } = DateTime.Now;
|
||||
|
||||
[Column("CHANGED_WHEN", TypeName = "datetime")]
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
}
|
||||
|
||||
#if NETFRAMEWORK
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -25,7 +25,7 @@ namespace DigitalData.UserManager.Domain.Entities
|
||||
|
||||
[Column("COMMENT")]
|
||||
public string
|
||||
#if NET7_0_OR_GREATER
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
Comment { get; set; }
|
||||
@@ -33,7 +33,7 @@ namespace DigitalData.UserManager.Domain.Entities
|
||||
[StringLength(50)]
|
||||
[Column("ADDED_WHO")]
|
||||
public string
|
||||
#if NET7_0_OR_GREATER
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
AddedWho { get; set; }
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace DigitalData.UserManager.Domain.Entities
|
||||
{
|
||||
[StringLength(50)]
|
||||
public string
|
||||
#if NET7_0_OR_GREATER
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
Name { get; set; }
|
||||
@@ -29,7 +29,7 @@ namespace DigitalData.UserManager.Domain.Entities
|
||||
|
||||
[StringLength(200)]
|
||||
public string
|
||||
#if NET7_0_OR_GREATER
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
Comment { get; set; }
|
||||
|
||||
@@ -16,21 +16,21 @@ namespace DigitalData.UserManager.Domain.Entities
|
||||
|
||||
[StringLength(200)]
|
||||
public string
|
||||
#if NET7_0_OR_GREATER
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
Comment { get; set; }
|
||||
|
||||
[ForeignKey("UserId")]
|
||||
public virtual User
|
||||
#if NET7_0_OR_GREATER
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
User { get; set; }
|
||||
|
||||
[ForeignKey("GroupId")]
|
||||
public virtual Group
|
||||
#if NET7_0_OR_GREATER
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
Group { get; set; }
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace DigitalData.UserManager.Domain.Entities
|
||||
|
||||
[StringLength(50)]
|
||||
public string
|
||||
#if NET7_0_OR_GREATER
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
Name { get; set; }
|
||||
@@ -21,7 +21,7 @@ namespace DigitalData.UserManager.Domain.Entities
|
||||
[StringLength(20)]
|
||||
[Column("SHORT_NAME")]
|
||||
public string
|
||||
#if NET7_0_OR_GREATER
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
ShortName { get; set; }
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace DigitalData.UserManager.Domain.Entities
|
||||
[Column("COMMENT")]
|
||||
[StringLength(200)]
|
||||
public string
|
||||
#if NET7_0_OR_GREATER
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
Comment { get; set; }
|
||||
@@ -30,7 +30,7 @@ namespace DigitalData.UserManager.Domain.Entities
|
||||
[Column("ADDED_WHO")]
|
||||
[StringLength(50)]
|
||||
public string
|
||||
#if NET7_0_OR_GREATER
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
AddedWho { get; set; } = "DEFAULT";
|
||||
@@ -38,21 +38,21 @@ namespace DigitalData.UserManager.Domain.Entities
|
||||
[Column("CHANGED_WHO")]
|
||||
[StringLength(50)]
|
||||
public string
|
||||
#if NET7_0_OR_GREATER
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
ChangedWho { get; set; }
|
||||
|
||||
[ForeignKey("UserId")]
|
||||
public virtual User
|
||||
#if NET7_0_OR_GREATER
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
User { get; set; }
|
||||
|
||||
[ForeignKey("ModuleId")]
|
||||
public virtual Module
|
||||
#if NET7_0_OR_GREATER
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
Module { get; set; }
|
||||
|
||||
@@ -6,122 +6,130 @@ using System;
|
||||
#endif
|
||||
|
||||
namespace DigitalData.UserManager.Domain.Entities
|
||||
{
|
||||
[Table("TBDD_USER", Schema = "dbo")]
|
||||
public partial class User : BaseEntity
|
||||
#if NET
|
||||
;
|
||||
#elif NETFRAMEWORK
|
||||
{
|
||||
[Column("PRENAME")]
|
||||
[StringLength(50)]
|
||||
public string
|
||||
#if NET7_0_OR_GREATER
|
||||
?
|
||||
#endif
|
||||
Prename { get; set; }
|
||||
|
||||
[Column("NAME")]
|
||||
[StringLength(50)]
|
||||
public string
|
||||
#if NET7_0_OR_GREATER
|
||||
?
|
||||
[Table("TBDD_USER", Schema = "dbo")]
|
||||
public partial class User : BaseEntity
|
||||
{
|
||||
[Column("PRENAME")]
|
||||
[StringLength(50)]
|
||||
public string
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
Name { get; set; }
|
||||
Prename { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("USERNAME")]
|
||||
[StringLength(50)]
|
||||
public
|
||||
#if NET7_0_OR_GREATER
|
||||
required
|
||||
[Column("NAME")]
|
||||
[StringLength(50)]
|
||||
public string
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
string Username { get; set; }
|
||||
Name { get; set; }
|
||||
|
||||
[Column("SHORTNAME")]
|
||||
[StringLength(30)]
|
||||
public string
|
||||
#if NET7_0_OR_GREATER
|
||||
?
|
||||
[Required]
|
||||
[Column("USERNAME")]
|
||||
[StringLength(50)]
|
||||
public
|
||||
#if NET
|
||||
required
|
||||
#endif
|
||||
Shortname
|
||||
{ get; set; }
|
||||
string Username { get; set; }
|
||||
|
||||
[Column("EMAIL")]
|
||||
[StringLength(100)]
|
||||
public string
|
||||
#if NET7_0_OR_GREATER
|
||||
?
|
||||
[Column("SHORTNAME")]
|
||||
[StringLength(30)]
|
||||
public string
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
Email { get; set; }
|
||||
Shortname
|
||||
{ get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("LANGUAGE")]
|
||||
[StringLength(5)]
|
||||
[DefaultValue("de-DE")]
|
||||
public string
|
||||
#if NET7_0_OR_GREATER
|
||||
?
|
||||
[Column("EMAIL")]
|
||||
[StringLength(100)]
|
||||
public string
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
Language { get; set; }
|
||||
Email { get; set; }
|
||||
|
||||
[Column("COMMENT")]
|
||||
[StringLength(500)]
|
||||
public string
|
||||
#if NET7_0_OR_GREATER
|
||||
?
|
||||
[Required]
|
||||
[Column("LANGUAGE")]
|
||||
[StringLength(5)]
|
||||
[DefaultValue("de-DE")]
|
||||
public string
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
Comment { get; set; }
|
||||
Language { get; set; }
|
||||
|
||||
[Column("DELETED")]
|
||||
public bool Deleted { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("DATE_FORMAT")]
|
||||
[StringLength(10)]
|
||||
[DefaultValue("dd.MM.yyyy")]
|
||||
public
|
||||
#if NET7_0_OR_GREATER
|
||||
required
|
||||
[Column("COMMENT")]
|
||||
[StringLength(500)]
|
||||
public string
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
string DateFormat { get; set; }
|
||||
Comment { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("ACTIVE")]
|
||||
public bool Active { get; set; }
|
||||
[Column("DELETED")]
|
||||
public bool Deleted { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("GENERAL_VIEWER")]
|
||||
[StringLength(30)]
|
||||
[DefaultValue("NONE")]
|
||||
public
|
||||
#if NET7_0_OR_GREATER
|
||||
required
|
||||
[Required]
|
||||
[Column("DATE_FORMAT")]
|
||||
[StringLength(10)]
|
||||
[DefaultValue("dd.MM.yyyy")]
|
||||
public
|
||||
#if NET
|
||||
required
|
||||
#endif
|
||||
string GeneralViewer { get; set; }
|
||||
string DateFormat { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("WAN_ENVIRONMENT")]
|
||||
public bool WanEnvironment { get; set; }
|
||||
[Required]
|
||||
[Column("ACTIVE")]
|
||||
public bool Active { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("USERID_FK_INT_ECM")]
|
||||
public int UserIdFkIntEcm { get; set; }
|
||||
|
||||
[Column("DELETED_WHEN")]
|
||||
public DateTime
|
||||
#if NET7_0_OR_GREATER
|
||||
?
|
||||
[Required]
|
||||
[Column("GENERAL_VIEWER")]
|
||||
[StringLength(30)]
|
||||
[DefaultValue("NONE")]
|
||||
public
|
||||
#if NET
|
||||
required
|
||||
#endif
|
||||
DeletedWhen { get; set; }
|
||||
string GeneralViewer { get; set; }
|
||||
|
||||
[Column("DELETED_WHO")]
|
||||
[StringLength(50)]
|
||||
public
|
||||
#if NET7_0_OR_GREATER
|
||||
required
|
||||
[Required]
|
||||
[Column("WAN_ENVIRONMENT")]
|
||||
public bool WanEnvironment { get; set; }
|
||||
|
||||
[Required]
|
||||
[Column("USERID_FK_INT_ECM")]
|
||||
public int UserIdFkIntEcm { get; set; }
|
||||
|
||||
[Column("DELETED_WHEN")]
|
||||
public DateTime
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
string
|
||||
#if NET7_0_OR_GREATER
|
||||
?
|
||||
# endif
|
||||
DeletedWho { get; set; }
|
||||
DeletedWhen { get; set; }
|
||||
|
||||
[Column("DELETED_WHO")]
|
||||
[StringLength(50)]
|
||||
public
|
||||
#if NET
|
||||
required
|
||||
#endif
|
||||
string
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
DeletedWho { get; set; }
|
||||
}
|
||||
|
||||
#if NETFRAMEWORK
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -28,28 +28,28 @@ namespace DigitalData.UserManager.Domain.Entities
|
||||
|
||||
[ForeignKey("UserId")]
|
||||
public virtual User
|
||||
#if NET7_0_OR_GREATER
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
User { get; set; }
|
||||
|
||||
[ForeignKey("RepGroupId")]
|
||||
public virtual Group
|
||||
#if NET7_0_OR_GREATER
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
RepGroup { get; set; }
|
||||
|
||||
[ForeignKey("GroupId")]
|
||||
public virtual Group
|
||||
#if NET7_0_OR_GREATER
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
Group { get; set; }
|
||||
|
||||
[ForeignKey("RepUserId")]
|
||||
public virtual User
|
||||
#if NET7_0_OR_GREATER
|
||||
#if NET
|
||||
?
|
||||
#endif
|
||||
RepUser { get; set; }
|
||||
|
||||
Reference in New Issue
Block a user