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
248 lines
12 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|