Compare commits

...

5 Commits

Author SHA1 Message Date
Developer 02
25a4b0752b refactor: Entfernen der right_group-Eigenschaft aus der Representation-Entität
- Die Spalte `right_group` aus der `Representation`-Entität entfernt, um die Zuordnung von Benutzern oder Gruppen zu spezifischen Gruppen zu entfernen.
- Stattdessen wurde die `group`-Eigenschaft hinzugefügt, um flexible Zuordnungen zu ermöglichen.
- Ermöglicht nun `user-user`, `user-group`, `group-user` und `group-group` Repräsentationen.
2024-09-09 17:25:12 +02:00
Developer 02
75e708d02d chore: Entfernen der standardmäßig zugewiesenen AD Sync- und Internal-Boxen 2024-09-09 13:34:03 +02:00
Developer 02
dfe848100a feat: Entfernen der EcmFkId-Eigenschaft aus GroupCreateDto und dem Formular zur Gruppenerstellung
- `EcmFkId`-Eigenschaft aus dem `GroupCreateDto` im Backend entfernt.
- Anpassungen im Frontend vorgenommen, um das `EcmFkId`-Feld im Formular zur Gruppenerstellung zu entfernen.
- `EcmFkId` wird im Entity standardmäßig auf `-1` gesetzt.
2024-09-09 13:23:45 +02:00
Developer 02
e6416f0d7f feat(security): Nur Benutzer-ID und Passwort im Connection String verschlüsseln
- Verschlüsselung des gesamten Connection Strings durch Verschlüsselung der Benutzer-ID und des Passworts ersetzt.
- Die `appsettings`-Datei wurde aktualisiert, um nur noch die Benutzer-ID und das Passwort verschlüsselt zu speichern.
- `program.cs` angepasst, um den Connection String zu entschlüsseln und die Benutzer-ID sowie das Passwort separat zu entschlüsseln.
2024-09-09 12:55:22 +02:00
Developer 02
15bc34ba95 chore(config): Verbindungsschlüssel umbenennen 2024-09-09 11:50:38 +02:00
22 changed files with 107 additions and 120 deletions

View File

@@ -11,15 +11,6 @@
} }
</mat-form-field> </mat-form-field>
</div> </div>
<div [ngClass]="formFieldBSClass">
<mat-form-field>
<mat-label>ECM FK ID</mat-label>
<input matInput type="number" [formControl]="ecmFkId" (blur)="updateErrorMessage()" required />
@if (groupname.invalid) {
<mat-error>{{errorMessage()}}</mat-error>
}
</mat-form-field>
</div>
<div [ngClass]="formFieldBSClass"> <div [ngClass]="formFieldBSClass">
<div [ngClass]="buttonBSClass"> <div [ngClass]="buttonBSClass">
<button mat-fab extended (click)="create()"> <button mat-fab extended (click)="create()">
@@ -30,16 +21,10 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div [ngClass]="checkBoxBSClass(3)"> <div [ngClass]="formFieldBSClass">
<mat-checkbox [disabled]="true">AD Sync</mat-checkbox>
</div>
<div [ngClass]="checkBoxBSClass(3)">
<mat-checkbox [(ngModel)]="checked" [disabled]="true">Internal</mat-checkbox>
</div>
<div [ngClass]="checkBoxBSClass(2)">
<mat-checkbox [formControl]="active" [disabled]="true">Active</mat-checkbox> <mat-checkbox [formControl]="active" [disabled]="true">Active</mat-checkbox>
</div> </div>
<div class="col d-flex justify-content-center me-4 my-2"> <div [ngClass]="formFieldBSClass">
<button mat-fab extended (click)="delete()"> <button mat-fab extended (click)="delete()">
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
Löschen Löschen

View File

@@ -25,21 +25,19 @@ import Swal from 'sweetalert2';
}) })
export class GroupFormComponent { export class GroupFormComponent {
readonly groupname = new FormControl('', [Validators.required]); readonly groupname = new FormControl('', [Validators.required]);
readonly ecmFkId = new FormControl<number>(1, [Validators.required]);
readonly active = new FormControl<boolean>(true); readonly active = new FormControl<boolean>(true);
errorMessage = signal(''); errorMessage = signal('');
public readonly formFieldBSClass: string = "col d-flex justify-content-center mx-1 my-2" public readonly formFieldBSClass: string = "col d-flex justify-content-center mx-1 my-2"
public readonly buttonBSClass: string = "d-flex justify-content-center mx-1 my-2" public readonly buttonBSClass: string = "d-flex justify-content-center mx-1 my-2"
public readonly checkBoxBSClass: (colCount: number | undefined) => string = (colCount: number = 2) => `col-${colCount} d-flex justify-content-left mx-1 my-2` //public readonly checkBoxBSClass: (colCount: number | undefined) => string = (colCount: number = 2) => `col-${colCount} d-flex justify-content-left mx-1 my-2`
readonly checked = model(true); readonly checked = model(true);
constructor(private uService: UserService, private rService: RefreshService, private gService: GroupService) { constructor(private uService: UserService, private rService: RefreshService, private gService: GroupService) {
merge( merge(
this.groupname.statusChanges, this.groupname.valueChanges, this.groupname.statusChanges, this.groupname.valueChanges)
this.ecmFkId.statusChanges, this.ecmFkId.valueChanges)
.pipe(takeUntilDestroyed()) .pipe(takeUntilDestroyed())
.subscribe(() => this.updateErrorMessage()); .subscribe(() => this.updateErrorMessage());
} }
@@ -53,10 +51,9 @@ export class GroupFormComponent {
} }
create() { create() {
if (this.groupname.valid && this.ecmFkId.valid) { if (this.groupname.valid) {
this.gService.create({ this.gService.create({
name: this.groupname.value!, name: this.groupname.value!,
ecmFkId: (this.ecmFkId.value!),
adSync: false, adSync: false,
internal: true, internal: true,
active: this.active.value! active: this.active.value!
@@ -76,7 +73,6 @@ export class GroupFormComponent {
delete() { delete() {
this.groupname.setValue('') this.groupname.setValue('')
this.ecmFkId.setValue(1)
this.active.setValue(true) this.active.setValue(true)
} }
} }

View File

@@ -22,13 +22,13 @@ export class UserRepTableComponent extends BaseTableComponent<UserRep, UserRepSe
this.loading = false this.loading = false
} }
override fetchData(userId?: number): void { override fetchData(userId?: number, groupId?: number): void {
this.service.getAll(false, true, true, true, userId).subscribe({ this.service.getAll({ withUser: false, withRepGroup: true, withGroup: false, withRepUser: true, userId: userId, groupId: groupId }).subscribe({
next: (response: UserRep[]) => { next: (response: UserRep[]) => {
this.source = response; this.source = response;
this.loading = false; this.loading = false;
}, },
error: (error: any) => {} error: (error: any) => { }
}); });
} }
} }

View File

@@ -17,7 +17,6 @@ export interface User {
export interface Group { export interface Group {
id?: number; id?: number;
ecmFkId: number;
name?: string; name?: string;
adSync?: boolean; adSync?: boolean;
internal?: boolean; internal?: boolean;
@@ -59,12 +58,12 @@ export interface UserRep {
id?: number, id?: number,
userId: number, userId: number,
repGroupId?: number, repGroupId?: number,
rightGroupId: number, groupId?: number,
addedWho: string, addedWho: string,
repUserId?: number, repUserId?: number,
user?: User, user?: User,
repGroup?: Group, repGroup?: Group,
rightGroup?: Group, group?: Group,
repUser?: User repUser?: User
} }

View File

@@ -7,10 +7,13 @@
<mat-tab label="Benutzer"> <mat-tab label="Benutzer">
<app-user-table #users [onSelectedRows]="userOnSelectedRows"></app-user-table> <app-user-table #users [onSelectedRows]="userOnSelectedRows"></app-user-table>
</mat-tab> </mat-tab>
<mat-tab label="Gruppe">
<app-group-table #rightGroups [columns]="groupColumns" [onSelectedRows]="groupOnSelectedRows"></app-group-table>
</mat-tab>
</mat-tab-group> </mat-tab-group>
</div> </div>
<!-- (1, 2): representations --> <!-- (1, 2): representations -->
<div class="col-2"> <div class="col-4">
<mat-tab-group> <mat-tab-group>
<mat-tab label="Rep. Benutzer"> <mat-tab label="Rep. Benutzer">
<app-user-table #repUsers [onSelectedRows]="repUserOnSelectedRows"></app-user-table> <app-user-table #repUsers [onSelectedRows]="repUserOnSelectedRows"></app-user-table>
@@ -20,14 +23,6 @@
</mat-tab> </mat-tab>
</mat-tab-group> </mat-tab-group>
</div> </div>
<!-- (1, 3): right groups -->
<div class="col-2">
<mat-tab-group>
<mat-tab label="Rechte Gruppe">
<app-group-table #rightGroups] [columns]="groupRightColumns" [onSelectedRows]="rightGroupOnSelectedRows"></app-group-table>
</mat-tab>
</mat-tab-group>
</div>
<!-- (1, 4): assigned users --> <!-- (1, 4): assigned users -->
<div class="col-3"> <div class="col-3">
<mat-tab-group> <mat-tab-group>

View File

@@ -8,6 +8,7 @@ import Swal from 'sweetalert2';
import { MatTabsModule, MatTabGroup } from '@angular/material/tabs'; import { MatTabsModule, MatTabGroup } from '@angular/material/tabs';
import { env } from '../../../environments/environment'; import { env } from '../../../environments/environment';
import { BasePageComponent } from '../base-page/base-page.component'; import { BasePageComponent } from '../base-page/base-page.component';
import { UserRep } from '../../models/user-management.api.models';
@Component({ @Component({
standalone: true, standalone: true,
@@ -19,8 +20,8 @@ import { BasePageComponent } from '../base-page/base-page.component';
export class UserRepresentationComponent extends BasePageComponent implements AfterViewInit { export class UserRepresentationComponent extends BasePageComponent implements AfterViewInit {
useRepLabel: string = ""; useRepLabel: string = "";
groupColumns: Array<GuiColumn>;
groupRepCols: Array<GuiColumn>; groupRepCols: Array<GuiColumn>;
groupRightColumns: Array<GuiColumn>;
slUserId: null | number = null; slUserId: null | number = null;
slRepUserId: null | number = null; slRepUserId: null | number = null;
slRepGroupId: null | number = null; slRepGroupId: null | number = null;
@@ -32,7 +33,7 @@ export class UserRepresentationComponent extends BasePageComponent implements Af
constructor(private userRepService: UserRepService) { constructor(private userRepService: UserRepService) {
super() super()
this.groupRepCols = env.columnNames.group.representative; this.groupRepCols = env.columnNames.group.representative;
this.groupRightColumns = env.columnNames.group.right; this.groupColumns = env.columnNames.group.right;
this.userRepService = userRepService; this.userRepService = userRepService;
} }
@@ -43,7 +44,7 @@ export class UserRepresentationComponent extends BasePageComponent implements Af
this.users.fetchData(); this.users.fetchData();
this.repUsers.fetchData(); this.repUsers.fetchData();
this.repGroups.fetchData(); this.repGroups.fetchData();
this.rightGroups.fetchData(); this.groups.fetchData();
}) })
this.transferService.add(() => { this.transferService.add(() => {
this.repUsers.safelyUnselectAll(); this.repUsers.safelyUnselectAll();
@@ -53,26 +54,34 @@ export class UserRepresentationComponent extends BasePageComponent implements Af
} }
@ViewChild("users") users!: UserTableComponent; @ViewChild("users") users!: UserTableComponent;
@ViewChild("groups") groups!: GroupTableComponent;
@ViewChild("repUsers") repUsers!: UserTableComponent; @ViewChild("repUsers") repUsers!: UserTableComponent;
@ViewChild("repGroups") repGroups!: GroupTableComponent; @ViewChild("repGroups") repGroups!: GroupTableComponent;
@ViewChild("rightGroups") rightGroups!: GroupTableComponent;
@ViewChild("userReps") userReps!: UserRepTableComponent; @ViewChild("userReps") userReps!: UserRepTableComponent;
userOnSelectedRows = (rows: GuiSelectedRow[]) => { userGroupOnSelectedRows = (rows: GuiSelectedRow[], isUser: boolean = true) => {
if (rows.length > 0) { if (rows.length > 0) {
this.users.safelyUnselectAll(); this.users.safelyUnselectAll();
this.useRepLabel = `Vertretungen von ${rows[0].source?.username}`
this.userReps.fetchData(rows[0].source?.id) if (isUser) {
this.slUserId = rows[0].source?.id this.useRepLabel = `Vertretungen von ${rows[0].source?.username}`
this.userReps.fetchData(rows[0].source?.id)
this.slUserId = rows[0].source?.id
}
else {
this.useRepLabel = `Vertretungen von ${rows[0].source?.name}`
this.userReps.fetchData(undefined, rows[0].source?.id)
this.slUserId = rows[0].source?.id
}
} }
} }
rightGroupOnSelectedRows = (rows: GuiSelectedRow[]) => { userOnSelectedRows = (rows: GuiSelectedRow[]) => {
if (rows.length > 0) { this.userGroupOnSelectedRows(rows, true);
this.slRightGroupId = rows[0].source?.id }
} else {
this.slRightGroupId = null; groupOnSelectedRows = (rows: GuiSelectedRow[]) => {
} this.userGroupOnSelectedRows(rows, false);
} }
repUserOnSelectedRows = (rows: GuiSelectedRow[]) => { repUserOnSelectedRows = (rows: GuiSelectedRow[]) => {
@@ -91,17 +100,9 @@ export class UserRepresentationComponent extends BasePageComponent implements Af
text: "Bitte wählen Sie die Vertretungen Benutzer!", text: "Bitte wählen Sie die Vertretungen Benutzer!",
}); });
} }
else if (!this.slRightGroupId) {
Swal.fire({
icon: "error",
title: "Oops...",
text: "Bitte wählen Sie die Rechte Gruppe!",
});
}
else { else {
var newUserRep = { var newUserRep: UserRep = {
userId: this.slUserId, userId: this.slUserId,
rightGroupId: this.slRightGroupId,
repUserId: this.slRepUserId, repUserId: this.slRepUserId,
addedWho: 'DEFAULT' addedWho: 'DEFAULT'
} }
@@ -145,17 +146,9 @@ export class UserRepresentationComponent extends BasePageComponent implements Af
text: "Bitte wählen Sie die Vertretungen Gruppe!", text: "Bitte wählen Sie die Vertretungen Gruppe!",
}); });
} }
else if (!this.slRightGroupId) {
Swal.fire({
icon: "error",
title: "Oops...",
text: "Bitte wählen Sie die rechte Gruppe!",
});
}
else { else {
var newUserRep = { var newUserRep = {
userId: this.slUserId, userId: this.slUserId,
rightGroupId: this.slRightGroupId,
repGroupId: this.slRepGroupId, repGroupId: this.slRepGroupId,
addedWho: 'DEFAULT' addedWho: 'DEFAULT'
} }

View File

@@ -9,28 +9,42 @@ import { UrlService } from "./url.service";
providedIn: "root" providedIn: "root"
}) })
export class UserRepService extends ApiService<UserRep> { export class UserRepService extends ApiService<UserRep> {
constructor(http: HttpClient, urlService : UrlService) { constructor(http: HttpClient, urlService: UrlService) {
super(http, urlService.apiRoute.userRep) super(http, urlService.apiRoute.userRep)
} }
override getAll(withUser: boolean = false, withRepGroup: boolean = false, withRightGroup: boolean = false, withRepUser: boolean = false, userId?: number): Observable<UserRep[]> { override getAll(options?: Options): Observable<UserRep[]> {
let params = new HttpParams(); let params = new HttpParams();
if (withUser) { if (options) {
params = params.set('withUser', withUser); if (options.withUser) {
} params = params.set('withUser', options.withUser);
if (withRepGroup) { }
params = params.set('withRepGroup', withRepGroup); if (options.withRepGroup) {
} params = params.set('withRepGroup', options.withRepGroup);
if (withRightGroup) { }
params = params.set('withRightGroup', withRightGroup); if (options.withGroup) {
} params = params.set('withRightGroup', options.withGroup);
if (withRepUser) { }
params = params.set('withRepUser', withRepUser); if (options.withRepUser) {
} params = params.set('withRepUser', options.withRepUser);
if (userId) { }
params = params.set('userId', userId) if (options.userId) {
params = params.set('userId', options.userId)
}
if (options.groupId) {
params = params.set('groupId', options.groupId)
}
} }
return this.http.get<UserRep[]>(`${this.baseUrl}`, { params: params, withCredentials: true }); return this.http.get<UserRep[]>(`${this.baseUrl}`, { params: params, withCredentials: true });
} }
}
interface Options {
withUser: boolean;
withRepGroup: boolean;
withGroup: boolean;
withRepUser: boolean;
userId?: number;
groupId?: number;
} }

View File

@@ -189,10 +189,6 @@ export const env = {
header: "Repr. Gruppen", header: "Repr. Gruppen",
field: (ur: any) => ur.repGroup?.name field: (ur: any) => ur.repGroup?.name
}, },
{
header: "Rechte Gruppen",
field: (ur: any) => ur.rightGroup?.name
},
{ {
header: "Repr. Benutzer", header: "Repr. Benutzer",
field: (ur: any) => ur.repUser?.username field: (ur: any) => ur.repUser?.username

View File

@@ -8,11 +8,13 @@ using System.Security.Claims;
using DigitalData.UserManager.Application; using DigitalData.UserManager.Application;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using DigitalData.Core.DTO; using DigitalData.Core.DTO;
using Microsoft.AspNetCore.Authorization;
namespace DigitalData.UserManager.API.Controllers namespace DigitalData.UserManager.API.Controllers
{ {
[Route("api/[controller]")] [Route("api/[controller]")]
[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")] [SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")]
[Authorize]
public class DirectoryController : ControllerBase public class DirectoryController : ControllerBase
{ {
private readonly IUserService _userService; private readonly IUserService _userService;

View File

@@ -21,11 +21,11 @@ namespace DigitalData.UserManager.API.Controllers
} }
[HttpGet] [HttpGet]
public async Task<IActionResult> GetAll(bool withUser = false, bool withRepGroup = false, bool withRightGroup = false, bool withRepUser = false, int? userId = null) public async Task<IActionResult> GetAll(bool withUser = false, bool withRepGroup = false, bool withGroup = false, bool withRepUser = false, int? userId = null, int? groupId = null)
{ {
try try
{ {
return await _service.ReadAllAsync(withUser, withRepGroup, withRightGroup, withRepUser, userId).ThenAsync(Ok, IActionResult (m, n) => return await _service.ReadAllAsync(withUser, withRepGroup, withGroup, withRepUser, userId, groupId).ThenAsync(Ok, IActionResult (m, n) =>
{ {
_logger.LogNotice(n); _logger.LogNotice(n);
return NotFound(); return NotFound();

View File

@@ -6,9 +6,9 @@ using Microsoft.AspNetCore.Authentication.Cookies;
using NLog.Web; using NLog.Web;
using NLog; using NLog;
using DigitalData.Core.API; using DigitalData.Core.API;
using DigitalData.UserManager.API;
using DigitalData.UserManager.API.Controllers; using DigitalData.UserManager.API.Controllers;
using DigitalData.UserManager.Application.Services; using DigitalData.UserManager.Application.Services;
using Microsoft.Data.SqlClient;
var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger(); var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
logger.Debug("init main"); logger.Debug("init main");
@@ -72,7 +72,7 @@ try {
//builder.Services.AddAutoMapper(typeof(DirectoryMappingProfile).Assembly); //builder.Services.AddAutoMapper(typeof(DirectoryMappingProfile).Assembly);
builder.Services.AddUserManager<UserManagerDbContext>(); builder.Services.AddUserManager<UserManagerDbContext>();
builder.ConfigureBySection<DirectorySearchOptions>(); builder.ConfigureBySection<DirectorySearchOptions>();
builder.Services.AddDirectorySearchService(); builder.Services.AddDirectorySearchService();
@@ -83,9 +83,13 @@ try {
cnn_str = new(() => cnn_str = new(() =>
{ {
var encryptor = app.Services.GetRequiredService<Encryptor>(); var encryptor = app.Services.GetRequiredService<Encryptor>();
var eCnnStr = config.GetConnectionString("DD_ECM_Connection") ?? throw new InvalidOperationException("Connection string 'DD_ECM_Connection' is missing from the configuration."); var eCnnStr = config.GetConnectionString("UM_DEF") ?? throw new InvalidOperationException("Connection string 'DD_ECM_Connection' is missing from the configuration.");
var cnnStr = encryptor.Decrypt(eCnnStr);
return cnnStr; SqlConnectionStringBuilder cnnStrBuilder = new(eCnnStr);
cnnStrBuilder.UserID = encryptor.Decrypt(cnnStrBuilder.UserID);
cnnStrBuilder.Password = encryptor.Decrypt(cnnStrBuilder.Password);
var dCnnStr = cnnStrBuilder.ConnectionString;
return dCnnStr;
}); });
app.UseCors("DefaultCorsPolicy"); app.UseCors("DefaultCorsPolicy");

View File

@@ -6,7 +6,7 @@
} }
}, },
"ConnectionStrings": { "ConnectionStrings": {
"DD_ECM_Connection": "cIFSoeMqHel7SDkAj4MWjy1UHrNJgoHrLkBJ/I/1Y95MsV9vFQjJLn6Shm9qtAyymwSNrX9s+78mW2PX4KulSA/KAaRwNQteP6SHrX0nNOJptot8TcohuiT0m9K2M/GsJEnLyJ+3yb0nJHR5yzRaVvjl8ERhgntW47dFMni98YA=" "UM_DEF": "Server=SDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM;User Id=g+2edXEbMbujCUjh7INZRQ==;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" ], "AllowedOrigins": [ "https://localhost:7103", "http://172.24.12.39:85", "http://localhost:85", "http://localhost:4200", "http://localhost:5500", "https://localhost:7202" ],
"RunAsWindowsService": false, "RunAsWindowsService": false,

View File

@@ -6,6 +6,6 @@ namespace DigitalData.UserManager.Application.Contracts
{ {
public interface IUserRepService : IBaseService<UserRepCreateDto, UserRepReadDto, UserRepUpdateDto, UserRep> public interface IUserRepService : IBaseService<UserRepCreateDto, UserRepReadDto, UserRepUpdateDto, UserRep>
{ {
Task<DataResult<IEnumerable<UserRepReadDto>>> ReadAllAsync(bool withUser = false, bool withRepGroup = false, bool withRightGroup = false, bool withRepUser = false, int? userId = null); Task<DataResult<IEnumerable<UserRepReadDto>>> ReadAllAsync(bool withUser = false, bool withRepGroup = false, bool withGroup = false, bool withRepUser = false, int? userId = null, int? groupId = null);
} }
} }

View File

@@ -8,7 +8,6 @@ namespace DigitalData.UserManager.Application.DTOs.Group
bool? AdSync, bool? AdSync,
bool? Internal, bool? Internal,
bool? Active, bool? Active,
string? Comment, string? Comment
int EcmFkId
) : BaseCreateDto(); ) : BaseCreateDto();
} }

View File

@@ -5,8 +5,7 @@ namespace DigitalData.UserManager.Application.DTOs.UserRep
public record UserRepCreateDto( public record UserRepCreateDto(
int UserId, int UserId,
int? RepGroupId, int? RepGroupId,
int RightGroupId, int? GroupId,
string AddedWho,
int RepUserId int RepUserId
) : BaseCreateDto(); ) : BaseCreateDto();
} }

View File

@@ -8,13 +8,13 @@ namespace DigitalData.UserManager.Application.DTOs.UserRep
int Id, int Id,
int UserId, int UserId,
int? RepGroupId, int? RepGroupId,
int RightGroupId, int? GroupId,
string AddedWho, string AddedWho,
string ChangedWho, string ChangedWho,
int? RepUserId, int? RepUserId,
UserReadDto? User, UserReadDto? User,
GroupReadDto? RepGroup, GroupReadDto? RepGroup,
GroupReadDto? RightGroup, GroupReadDto? Group,
UserReadDto? RepUser, UserReadDto? RepUser,
DateTime? AddedWhen, DateTime? AddedWhen,
DateTime? ChangedWhen DateTime? ChangedWhen

View File

@@ -5,7 +5,7 @@ namespace DigitalData.UserManager.Application.DTOs.UserRep
public record UserRepUpdateDto( public record UserRepUpdateDto(
int UserId, int UserId,
int? RepGroupId, int? RepGroupId,
int RightGroupId, int? GroupId,
int RepUserId int RepUserId
) : BaseUpdateDto(); ) : BaseUpdateDto();
} }

View File

@@ -15,9 +15,9 @@ namespace DigitalData.UserManager.Application.Services
{ {
} }
public async Task<DataResult<IEnumerable<UserRepReadDto>>> ReadAllAsync(bool withUser = false, bool withRepGroup = false, bool withRightGroup = false, bool withRepUser = false, int? userId = null) public async Task<DataResult<IEnumerable<UserRepReadDto>>> ReadAllAsync(bool withUser = false, bool withRepGroup = false, bool withGroup = false, bool withRepUser = false, int? userId = null, int? groupId = null)
{ {
var urs = await _repository.ReadAllAsync(withUser, withRepGroup, withRightGroup, withRepUser, userId); var urs = await _repository.ReadAllAsync(withUser, withRepGroup, withGroup, withRepUser, userId, groupId);
var urReadDTOs = _mapper.MapOrThrow<IEnumerable<UserRepReadDto>>(urs); var urReadDTOs = _mapper.MapOrThrow<IEnumerable<UserRepReadDto>>(urs);
return Result.Success(urReadDTOs); return Result.Success(urReadDTOs);
} }

View File

@@ -26,9 +26,10 @@ namespace DigitalData.UserManager.Domain.Entities
[StringLength(200)] [StringLength(200)]
public string? Comment { get; set; } public string? Comment { get; set; }
// TODO: this column should be assigned by triggers. despite this it is not null and this is problem for creation. talk with others
[Required] [Required]
[Column("ECM_FK_ID")] [Column("ECM_FK_ID")]
[DefaultValue(0)] [DefaultValue(-1)]
public int EcmFkId { get; set; } public int EcmFkId { get; init; } = -1;
} }
} }

View File

@@ -14,9 +14,8 @@ namespace DigitalData.UserManager.Domain.Entities
[Column("REPR_GROUP")] [Column("REPR_GROUP")]
public int? RepGroupId { get; set; } public int? RepGroupId { get; set; }
[Required] [Column("GROUP_ID")]
[Column("RIGHT_GROUP")] public int? GroupId { get; set; } = null;
public int RightGroupId { get; set; }
[Column("REPR_USER")] [Column("REPR_USER")]
public int? RepUserId { get; set; } public int? RepUserId { get; set; }
@@ -27,8 +26,8 @@ namespace DigitalData.UserManager.Domain.Entities
[ForeignKey("RepGroupId")] [ForeignKey("RepGroupId")]
public virtual Group? RepGroup { get; set; } public virtual Group? RepGroup { get; set; }
[ForeignKey("RightGroupId")] [ForeignKey("GroupId")]
public virtual Group? RightGroup { get; set; } public virtual Group? Group { get; set; }
[ForeignKey("RepUserId")] [ForeignKey("RepUserId")]
public virtual User? RepUser { get; set; } public virtual User? RepUser { get; set; }

View File

@@ -5,6 +5,6 @@ namespace DigitalData.UserManager.Infrastructure.Contracts
{ {
public interface IUserRepRepository : ICRUDRepository<UserRep, int> public interface IUserRepRepository : ICRUDRepository<UserRep, int>
{ {
Task<IEnumerable<UserRep>> ReadAllAsync(bool withUser = false, bool withRepGroup = false, bool withRightGroup = false, bool withRepUser = false, int? userId = null); Task<IEnumerable<UserRep>> ReadAllAsync(bool withUser = false, bool withRepGroup = false, bool withGroup = false, bool withRepUser = false, int? userId = null, int? groupId = null);
} }
} }

View File

@@ -12,9 +12,9 @@ namespace DigitalData.UserManager.Infrastructure.Repositories
{ {
} }
public async Task<IEnumerable<UserRep>> ReadAllAsync(bool withUser = false, bool withRepGroup = false, bool withRightGroup = false, bool withRepUser = false, int? userId = null) public async Task<IEnumerable<UserRep>> ReadAllAsync(bool withUser = false, bool withRepGroup = false, bool withGroup = false, bool withRepUser = false, int? userId = null, int? groupId = null)
{ {
var query = _dbSet.AsQueryable(); var query = _dbSet.AsNoTracking();
if (withUser) if (withUser)
query = query.Include(ur => ur.User); query = query.Include(ur => ur.User);
@@ -22,8 +22,8 @@ namespace DigitalData.UserManager.Infrastructure.Repositories
if (withRepGroup) if (withRepGroup)
query = query.Include(ur => ur.RepGroup); query = query.Include(ur => ur.RepGroup);
if (withRightGroup) if (withGroup)
query = query.Include(ur => ur.RightGroup); query = query.Include(ur => ur.Group);
if (withRepUser) if (withRepUser)
query = query.Include(ur => ur.RepUser); query = query.Include(ur => ur.RepUser);
@@ -33,6 +33,11 @@ namespace DigitalData.UserManager.Infrastructure.Repositories
query = query.Where(ur => ur.UserId == userId); query = query.Where(ur => ur.UserId == userId);
} }
if (groupId is not null)
{
query = query.Where(ur => ur.GroupId == groupId);
}
return await query.ToListAsync(); return await query.ToListAsync();
} }
} }