Skip to content

Commit f622d6c

Browse files
committed
Initial commit
1 parent e6dd234 commit f622d6c

13 files changed

+495
-1
lines changed

.github/workflows/gitleaks.yaml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Secret Value found!!
2+
on:
3+
push:
4+
public:
5+
jobs:
6+
scan:
7+
name: gitleaks
8+
runs-on: ubuntu-latest
9+
steps:
10+
- name: Checkout
11+
uses: actions/checkout@v4.2.2
12+
- name: Install the gitleaks
13+
run: wget https://github.com/zricethezav/gitleaks/releases/download/v8.15.2/gitleaks_8.15.2_linux_x64.tar.gz
14+
shell: pwsh
15+
- name: Extract the tar file
16+
run: tar xzvf gitleaks_8.15.2_linux_x64.tar.gz
17+
- name: Generate the report
18+
id: gitleaks
19+
run: $GITHUB_WORKSPACE/gitleaks detect -s $GITHUB_WORKSPACE -f json -r $GITHUB_WORKSPACE/leaksreport.json
20+
shell: bash
21+
continue-on-error: true
22+
- name: Setup NuGet.exe
23+
if: steps.gitleaks.outcome != 'success'
24+
uses: nuget/setup-nuget@v2
25+
with:
26+
nuget-version: latest
27+
- name: Install Mono
28+
if: steps.gitleaks.outcome != 'success'
29+
run: |
30+
sudo apt update
31+
sudo apt install -y mono-complete
32+
- name: Install the dotnet SDK to a custom directory
33+
if: steps.gitleaks.outcome != 'success'
34+
run: |
35+
mkdir -p $GITHUB_WORKSPACE/dotnet
36+
curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --install-dir $GITHUB_WORKSPACE/dotnet --channel 6.0
37+
- name: Install the report tool packages
38+
if: steps.gitleaks.outcome != 'success'
39+
run: |
40+
export PATH=$GITHUB_WORKSPACE/dotnet:$PATH
41+
nuget install "Syncfusion.Email" -source ${{ secrets.NexusFeedLink }} -ExcludeVersion
42+
dir $GITHUB_WORKSPACE/Syncfusion.Email/lib/net6.0
43+
dotnet $GITHUB_WORKSPACE/Syncfusion.Email/lib/net6.0/GitleaksReportMail.dll ${{ secrets.CITEAMCREDENTIALS }} "$GITHUB_REF_NAME" ${{ secrets.NETWORKCREDENTIALS }} ${{ secrets.NETWORKKEY }} "$GITHUB_WORKSPACE" ${{ secrets.ORGANIZATIONNAME }}
44+
exit 1

AccountStatement.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace SecurePdfGeneration
2+
{
3+
public class AccountStatement
4+
{
5+
public string CustomerName { get; set; }
6+
public string DateOfBirth { get; set; }
7+
public string AccountNumber { get; set; }
8+
public string IssueDate { get; set; }
9+
public string PeriodStart { get; set; }
10+
public string PeriodEnd { get; set; }
11+
}
12+
}

BankDetails.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace SecurePdfGeneration
2+
{
3+
public class BankDetails
4+
{
5+
public string Name { get; set; }
6+
public string Address { get; set; }
7+
public string Branch { get; set; }
8+
public string Email { get; set; }
9+
10+
}
11+
}

Program.cs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
using Syncfusion.Drawing;
2+
using Syncfusion.HtmlConverter;
3+
using Syncfusion.Pdf;
4+
using Syncfusion.Pdf.Security;
5+
using System.Text.Json;
6+
using SecurePdfGeneration;
7+
using System.Text;
8+
using Syncfusion.Licensing;
9+
10+
Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("Ngo9BigBOggjHTQxAR8/V1JEaF5cXmRCdkx3Qnxbf1x1ZFZMYFpbQXZPMyBoS35Rc0VkWHdec3RTQ2RfVEF3VEFd");
11+
/// Loads and deserializes the bank statement data from a JSON file.
12+
string jsonPath = "UserAccountDetails.json";
13+
string jsonContent = File.ReadAllText(jsonPath);
14+
StatementBuilder statement = JsonSerializer.Deserialize<StatementBuilder>(jsonContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
15+
16+
// Load HTML template
17+
string templatePath = "bank-statement-template.html";
18+
string htmlTemplate = File.ReadAllText(templatePath);
19+
20+
// Replace top-level placeholders with actual data.
21+
string filledHtmlContent = htmlTemplate
22+
.Replace("{{statement.issue_date}}", statement.Statement.IssueDate)
23+
.Replace("{{statement.period_start}}", statement.Statement.PeriodStart)
24+
.Replace("{{statement.period_end}}", statement.Statement.PeriodEnd)
25+
.Replace("{{bank.name}}", statement.Bank.Name)
26+
.Replace("{{bank.account_number}}", statement.Statement.AccountNumber)
27+
.Replace("{{bank.address}}", statement.Bank.Address)
28+
.Replace("{{bank.customername}}", statement.Statement.CustomerName);
29+
30+
31+
/// Builds the HTML table rows for each transaction in the bank statement
32+
/// and replaces the {{ transaction_rows }} placeholder in the HTML template.
33+
StringBuilder transactionRows = new StringBuilder();
34+
foreach (var txn in statement.Transactions)
35+
{
36+
transactionRows.AppendLine($@"
37+
<tr>
38+
<td>{txn.Date}</td>
39+
<td>{txn.Type}</td>
40+
<td>{txn.Detail}</td>
41+
<td>{txn.Debited}</td>
42+
<td>{txn.Credited}</td>
43+
<td>{txn.Balance}</td>
44+
</tr>");
45+
}
46+
filledHtmlContent = filledHtmlContent.Replace("{{ transaction_rows }}", transactionRows.ToString());
47+
48+
49+
/// Converts the filled HTML content into a PDF document using Syncfusion's HTML to PDF converter.
50+
HtmlToPdfConverter htmlConverter = new HtmlToPdfConverter();
51+
BlinkConverterSettings settings = new BlinkConverterSettings
52+
{
53+
Scale = 0.7f
54+
};
55+
56+
// Apply the settings to the converter
57+
htmlConverter.ConverterSettings = settings;
58+
59+
// Convert the filled HTML content into a PDF document
60+
PdfDocument document = htmlConverter.Convert(filledHtmlContent, Path.GetFullPath("."));
61+
62+
/// Sets PDF security by applying a user password and restricting permissions to printing only.
63+
// Access the security settings of the PDF document
64+
PdfSecurity security = document.Security;
65+
66+
// Retrieve customer name and date of birth from the statement
67+
string customerName = statement.Statement.CustomerName;
68+
string dateOfBirth = statement.Statement.DateOfBirth;
69+
70+
// Extract the first 4 characters of the customer name and convert to uppercase
71+
string namePrefix = (customerName.Substring(0, Math.Min(4, customerName.Length))).ToUpper();
72+
73+
// Parse the date of birth and format it to get day and month as "ddMM"
74+
DateTime dob = DateTime.Parse(dateOfBirth);
75+
string dateAndMonth = dob.ToString("ddMM");
76+
77+
// Combine name prefix and date/month to form the user password
78+
string userPassword = namePrefix + dateAndMonth;
79+
80+
// Set the owner password to retain full control over the PDF, including editing and security settings.
81+
// Required to enforce user-level restrictions like printing-only access and prevent unauthorized changes.
82+
security.OwnerPassword = "G2bank1234";
83+
84+
// Set the user password for the PDF document
85+
security.UserPassword = userPassword;
86+
87+
// Restrict permissions to allow only printing
88+
security.Permissions = PdfPermissionsFlags.Print;
89+
90+
//Save the PDF document
91+
Directory.CreateDirectory("../../../Output");
92+
string outputPath = $"../../../Output/BankStatement_" + statement.Statement.CustomerName + "_" + statement.Statement.IssueDate + ".pdf";
93+
MemoryStream stream = new MemoryStream();
94+
document.Save(stream);
95+
File.WriteAllBytes(outputPath, stream.ToArray());
96+
97+
// Close the document to release resources
98+
document.Close(true);
99+
100+
Console.WriteLine("Documents saved successfully!");
101+
Console.WriteLine("The password to open the document is: " + userPassword);
102+
103+

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
# Secure-PDF-Creation-from-HTML-with-Passwords-and-Permissions
1+
# Secure PDF Creation from HTML with Passwords and Permissions
22
This repository provides a working example of securely generating PDF documents from HTML in .NET C# using the Syncfusion HTML to PDF Converter. It demonstrates how to convert HTML to PDF, apply password protection, and configure document permissions to control access and editing capabilities

SecurePdfGeneration.csproj

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
</PropertyGroup>
8+
<ItemGroup>
9+
<PackageReference Include="Syncfusion.HtmlToPdfConverter.Net.Windows" Version="30.1.42" />
10+
</ItemGroup>
11+
<ItemGroup>
12+
<None Update="bank-logo.jpg">
13+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
14+
</None>
15+
<None Update="style.css">
16+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
17+
</None>
18+
<None Update="UserAccountDetails.json">
19+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
20+
</None>
21+
<None Update="bank-statement-template.html">
22+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
23+
</None>
24+
</ItemGroup>
25+
</Project>

SecurePdfGeneration.sln

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.9.34723.18
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SecurePdfGeneration", "SecurePdfGeneration.csproj", "{7B3304A1-C5D5-4F2F-ACDC-F1763AA8F43C}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{7B3304A1-C5D5-4F2F-ACDC-F1763AA8F43C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{7B3304A1-C5D5-4F2F-ACDC-F1763AA8F43C}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{7B3304A1-C5D5-4F2F-ACDC-F1763AA8F43C}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{7B3304A1-C5D5-4F2F-ACDC-F1763AA8F43C}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {641AB913-1205-459E-B9BF-BA5AB0CDEABD}
24+
EndGlobalSection
25+
EndGlobal

StatementBuilder.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace SecurePdfGeneration
2+
{
3+
public class StatementBuilder
4+
{
5+
public BankDetails Bank { get; set; }
6+
public AccountStatement Statement { get; set; }
7+
public List<TransactionDetail> Transactions { get; set; }
8+
}
9+
}

TransactionDetail.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace SecurePdfGeneration
2+
{
3+
public class TransactionDetail
4+
{
5+
public string Date { get; set; }
6+
public string Type { get; set; }
7+
public string Detail { get; set; }
8+
public string Debited { get; set; }
9+
public string Credited { get; set; }
10+
public string Balance { get; set; }
11+
}
12+
}

UserAccountDetails.json

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
{
2+
"bank": {
3+
"name": "G2 Bank",
4+
"address": "2450 Courage St, STE 108, Brownsville, TX 78521",
5+
"branch": "G2 Bank at Santa Monica",
6+
"email": "bickslowbank@domain.com"
7+
},
8+
"statement": {
9+
"customername": "John.P",
10+
"Dateofbirth":"1993-05-01",
11+
"accountnumber": "111-234-567-890",
12+
"issuedate": "2025-08-01",
13+
"periodstart": "2025-07-01",
14+
"periodend": "2025-07-31"
15+
},
16+
"transactions": [
17+
{
18+
"date": "2025-07-01",
19+
"type": "Opening Balance",
20+
"detail": "Balance Brought Forward",
21+
"debited": "",
22+
"credited": "",
23+
"balance": "8,313.30"
24+
},
25+
{
26+
"date": "2025-07-02",
27+
"type": "Transfer",
28+
"detail": "Amazon",
29+
"debited": "",
30+
"credited": "371.76",
31+
"balance": "8,685.06"
32+
},
33+
{
34+
"date": "2025-07-03",
35+
"type": "Deposit",
36+
"detail": "Insurance",
37+
"debited": "",
38+
"credited": "586.08",
39+
"balance": "9,271.14"
40+
},
41+
{
42+
"date": "2025-07-04",
43+
"type": "Refund",
44+
"detail": "eBay",
45+
"debited": "",
46+
"credited": "906.43",
47+
"balance": "10,177.57"
48+
},
49+
{
50+
"date": "2025-07-05",
51+
"type": "Opening Balance",
52+
"detail": "Utilities",
53+
"debited": "237.97",
54+
"credited": "",
55+
"balance": "9,939.60"
56+
},
57+
{
58+
"date": "2025-07-06",
59+
"type": "Deposit",
60+
"detail": "Salary",
61+
"debited": "",
62+
"credited": "399.56",
63+
"balance": "10,339.16"
64+
},
65+
{
66+
"date": "2025-07-07",
67+
"type": "Deposit",
68+
"detail": "Utilities",
69+
"debited": "",
70+
"credited": "716.17",
71+
"balance": "11,055.33"
72+
},
73+
{
74+
"date": "2025-07-08",
75+
"type": "Refund",
76+
"detail": "Coffee Shop",
77+
"debited": "",
78+
"credited": "913.75",
79+
"balance": "11,969.08"
80+
},
81+
{
82+
"date": "2025-07-09",
83+
"type": "Opening Balance",
84+
"detail": "Salary",
85+
"debited": "103.54",
86+
"credited": "",
87+
"balance": "11,865.54"
88+
},
89+
{
90+
"date": "2025-07-10",
91+
"type": "Direct Debit",
92+
"detail": "Utilities",
93+
"debited": "357.27",
94+
"credited": "",
95+
"balance": "11,508.27"
96+
},
97+
{
98+
"date": "2025-07-11",
99+
"type": "Transfer",
100+
"detail": "Coffee Shop",
101+
"debited": "",
102+
"credited": "679.03",
103+
"balance": "12,187.30"
104+
},
105+
{
106+
"date": "2025-07-12",
107+
"type": "Transfer",
108+
"detail": "Utilities",
109+
"debited": "",
110+
"credited": "593.14",
111+
"balance": "12,780.44"
112+
},
113+
{
114+
"date": "2025-07-13",
115+
"type": "ATM Withdrawal",
116+
"detail": "eBay",
117+
"debited": "345.81",
118+
"credited": "",
119+
"balance": "12,434.63"
120+
},
121+
{
122+
"date": "2025-07-14",
123+
"type": "Direct Debit",
124+
"detail": "Amazon",
125+
"debited": "429.24",
126+
"credited": "",
127+
"balance": "12,005.39"
128+
},
129+
{
130+
"date": "2025-07-15",
131+
"type": "Direct Debit",
132+
"detail": "Coffee Shop",
133+
"debited": "56.33",
134+
"credited": "",
135+
"balance": "11,949.06"
136+
}
137+
]
138+
}

0 commit comments

Comments
 (0)