Files
Masterarbeit/QuellCode/CentronERP/tests/Centron.Tests.EndToEnd/Tests/Documents/SignatureTemplateTests.cs
T
Christoph Schwörer f045b99a25 Codebasis als Dateien ins Arbeitsrepo statt als Gitlink
QuellCode/CentronERP war nur als Gitlink (Submodul-Referenz auf 79c1142)
getrackt, ohne .gitmodules und ohne erreichbares Remote. Der
Untersuchungsgegenstand der Versuchsreihe war damit nicht reproduzierbar
gesichert: Ein Klon haette ein leeres Verzeichnis erhalten, und die Belege
der 3.287 Anforderungen waeren nicht ueberpruefbar gewesen.

Umstellung:
- Historie nach c:\DEV\CentronERP_git_snapshot_79c1142 ausgelagert
  (vollstaendig lesbar, enthaelt 79c1142 und Vorgaenger 89ccfd6)
- Gitlink aus dem Index entfernt
- Dateiinhalt aufgenommen: 24.557 Dateien, rund 333 MB

Die verschachtelte .gitignore der Codebasis gilt weiter, Build-Artefakte
bleiben ausgeschlossen. Details in Versuche/Versuch_01/_Codebasis-Nachweis.md
2026-08-26 07:43:51 +02:00

248 lines
12 KiB
C#

using Centron.BusinessLogic;
using Centron.BusinessLogic.WebServices.Administration.FileManagement;
using Centron.Data.Entities.Administration.FileManagement;
using Centron.Data.WebServices.Administration.FileManagement;
using Centron.Interfaces;
using Centron.Interfaces.Administration.Documents;
using Centron.Tests.EndToEnd.Infrastructure;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit.Abstractions;
namespace Centron.Tests.EndToEnd.Tests.Documents
{
/// <summary>
/// Tests for C-Sign signature template functionality to ensure templates are not permanently overwritten with customer data.
/// This test reproduces the critical bug where signature templates get overwritten with real customer data,
/// causing subsequent customers to see previous customer's data.
/// </summary>
public class SignatureTemplateTests : EndToEndTest
{
private int _testDirectoryI3D => 2093; // Using same directory as DocumentsTests
private int _signatureTemplateDocumentI3D;
private int _testReceiptCustomerA_I3D => 242; // First customer receipt
private int _testReceiptCustomerB_I3D => 243; // Second customer receipt (if exists)
public SignatureTemplateTests(ITestOutputHelper testOutputHelper)
: base(testOutputHelper)
{
// Ignore version properties that change with each test run
this.Verifier.Settings.IgnoreProperty<DocumentDTO>(f => f.ChangedVersion);
this.Verifier.Settings.IgnoreProperty<DocumentDTO>(f => f.CreatedVersion);
this.Verifier.Settings.IgnoreProperty<Document>(f => f.ChangedVersion);
this.Verifier.Settings.IgnoreProperty<Document>(f => f.CreatedVersion);
}
public override void Execute()
{
// Test the critical C-Sign template overwrite bug
this.CreateSignatureTemplate();
this.VerifyOriginalTemplateContent();
this.ProcessFirstCustomerSignature();
this.VerifyTemplateAfterFirstCustomer();
this.ProcessSecondCustomerSignature();
this.VerifyTemplateAfterSecondCustomer();
this.CleanupTestData();
}
/// <summary>
/// Creates a Word document template with signature placeholders
/// </summary>
private void CreateSignatureTemplate()
{
using (var session = new BLSession())
{
// Create a simple Word document with signature placeholders
var templateContent = CreateWordDocumentWithSignaturePlaceholders();
var result = session.GetBL<DocumentWebServiceBL>().AddDocumentToDirectory(
this.GetLoggedInUser(),
this._testDirectoryI3D,
templateContent,
"SignatureTemplate.docx",
new List<DocumentMetaInformationDTO>
{
new DocumentMetaInformationDTO
{
Type = DocumentMetaInformationType.Unknown,
TypeName = "TemplateType",
Value = "SignatureTemplate"
}
},
fileObjectKind: CentronObjectKindNumeric.Unknown);
this._signatureTemplateDocumentI3D = result.I3D;
}
}
/// <summary>
/// Verifies that the original template contains placeholders, not real data
/// </summary>
private void VerifyOriginalTemplateContent()
{
using (var session = new BLSession())
{
var document = session.GetBL<DocumentWebServiceBL>().GetDocument(this.GetLoggedInUser(), this._signatureTemplateDocumentI3D);
var contentAsString = Encoding.UTF8.GetString(document.Data.FileData);
// Verify template contains placeholders
this.Verifier.Verify("OriginalTemplate_HasPlaceholders", new
{
DocumentName = document.Data.Name,
HasSignaturePlaceholder = contentAsString.Contains("@@Unterschrift@@"),
HasEmployeePlaceholder = contentAsString.Contains("@@MitarbeiterName@@"),
HasCustomerPlaceholder = contentAsString.Contains("@@KundenName@@"),
ContentLength = document.Data.FileData.Length
});
}
}
/// <summary>
/// Simulates processing a signature for the first customer
/// This is where the bug occurs - the template gets overwritten
/// </summary>
private void ProcessFirstCustomerSignature()
{
using (var session = new BLSession())
{
// Get the template document via WebService BL (same as UI would do)
var templateDocument = session.GetBL<DocumentWebServiceBL>().GetDocument(this.GetLoggedInUser(), this._signatureTemplateDocumentI3D);
// Store original content for comparison
var originalContent = templateDocument.Data.FileData;
var originalContentAsString = Encoding.UTF8.GetString(originalContent);
this.Verifier.Verify("FirstCustomer_ProcessedContent", new
{
OriginalContentLength = originalContent.Length,
HasPlaceholders = originalContentAsString.Contains("@@"),
HasSignaturePlaceholder = originalContentAsString.Contains("@@Unterschrift@@"),
HasEmployeePlaceholder = originalContentAsString.Contains("@@MitarbeiterName@@")
});
}
}
/// <summary>
/// Verifies the template state after first customer processing
/// BUG: Template should still have placeholders, but it now has real customer data
/// </summary>
private void VerifyTemplateAfterFirstCustomer()
{
using (var session = new BLSession())
{
var document = session.GetBL<DocumentWebServiceBL>().GetDocument(this.GetLoggedInUser(), this._signatureTemplateDocumentI3D);
var contentAsString = Encoding.UTF8.GetString(document.Data.FileData);
// BUG DETECTION: Template should still have placeholders!
this.Verifier.Verify("TemplateAfterFirstCustomer_ShouldHavePlaceholders", new
{
DocumentName = document.Data.Name,
HasSignaturePlaceholder = contentAsString.Contains("@@Unterschrift@@"),
HasEmployeePlaceholder = contentAsString.Contains("@@MitarbeiterName@@"),
HasCustomerPlaceholder = contentAsString.Contains("@@KundenName@@"),
// These should be false if template is corrupted:
HasRealCustomerData = contentAsString.Contains("Customer A") || contentAsString.Contains("Kunde A"),
HasRealEmployeeData = contentAsString.Contains("Max Mustermann"),
ContentLength = document.Data.FileData.Length
});
}
}
/// <summary>
/// Simulates processing a signature for the second customer
/// This should use the original template, not the modified one from customer A
/// </summary>
private void ProcessSecondCustomerSignature()
{
using (var session = new BLSession())
{
// Get the template document again (should still be clean after first customer)
var templateDocument = session.GetBL<DocumentWebServiceBL>().GetDocument(this.GetLoggedInUser(), this._signatureTemplateDocumentI3D);
var contentAsString = Encoding.UTF8.GetString(templateDocument.Data.FileData);
this.Verifier.Verify("SecondCustomer_ProcessedContent", new
{
ProcessedContentLength = templateDocument.Data.FileData.Length,
// CRITICAL: Template should still have placeholders, not real customer data!
HasPlaceholders = contentAsString.Contains("@@"),
HasSignaturePlaceholder = contentAsString.Contains("@@Unterschrift@@"),
HasEmployeePlaceholder = contentAsString.Contains("@@MitarbeiterName@@"),
// These should be FALSE - no real customer data should be in template
ContainsRealData = contentAsString.Contains("Customer") && !contentAsString.Contains("@@")
});
}
}
/// <summary>
/// Final verification that template is still intact after both customers
/// BUG: Template will be permanently corrupted with customer data
/// </summary>
private void VerifyTemplateAfterSecondCustomer()
{
using (var session = new BLSession())
{
var document = session.GetBL<DocumentWebServiceBL>().GetDocument(this.GetLoggedInUser(), this._signatureTemplateDocumentI3D);
var contentAsString = Encoding.UTF8.GetString(document.Data.FileData);
// CRITICAL BUG VERIFICATION: Template should NEVER contain real customer data!
this.Verifier.Verify("FinalTemplate_ShouldBeClean", new
{
DocumentName = document.Data.Name,
// These should be TRUE (template should have placeholders):
HasSignaturePlaceholder = contentAsString.Contains("@@Unterschrift@@"),
HasEmployeePlaceholder = contentAsString.Contains("@@MitarbeiterName@@"),
HasCustomerPlaceholder = contentAsString.Contains("@@KundenName@@"),
// These should be FALSE (template should NOT have real data):
HasRealCustomerData = contentAsString.Contains("Customer A") || contentAsString.Contains("Kunde A"),
HasRealEmployeeData = contentAsString.Contains("Max Mustermann"),
// PRIVACY VIOLATION DETECTION:
IsPotentialPrivacyViolation = !contentAsString.Contains("@@") &&
(contentAsString.Contains("Customer") || contentAsString.Contains("Kunde")),
ContentLength = document.Data.FileData.Length
});
}
}
/// <summary>
/// Cleanup test data
/// </summary>
private void CleanupTestData()
{
using (var session = new BLSession())
{
session.GetBL<DocumentWebServiceBL>().DeleteDocument(this.GetLoggedInUser(), this._signatureTemplateDocumentI3D);
}
}
/// <summary>
/// Creates a simple Word document with signature placeholders for testing
/// </summary>
private byte[] CreateWordDocumentWithSignaturePlaceholders()
{
// Create a minimal Word document content with placeholders
var content = @"
Signature Template Document
Customer: @@KundenName@@
Employee: @@MitarbeiterName@@
Signature Box: @@Unterschrift@@
Date: @@UnterschriftDatum@@
";
// Normalize line endings to LF to ensure consistent byte length across environments
content = content.Replace("\r\n", "\n");
// For testing purposes, we'll use a simple text representation
// In a real scenario, this would be a proper Word document
return Encoding.UTF8.GetBytes(content);
}
}
}