Export with a password

Contents[Hide]

1. Overview

This sample shows how to use an extension to hook into the server event that fires when exporting completes. As an example, a password is added to exported PDF documents.

PDF in a browser with a password
PDF in a browser with a password

Note
In version 6 and up, another way to accomplish this example is to use custom export and delivery providers.

2. Getting started

The focus of this sample is to highlight the steps necessary to add a password to a PDF export. For more information about creating an extension and hooking into server events, see the Hook into Dundas BI server events sample.

The following prerequisites must be installed on your computer:

  • Visual Studio 2017, or higher
  • Microsoft .NET Framework 4.7.2
  • A deployed instance of Dundas BI version 7 or higher

2.1. Downloading sample solution

To download the export completed sample solution, click here.

(A sample solution is also available for Dundas BI versions 6 and 5, and version 4.)

2.2. Extract the sample to a folder

This sample is designed to automatically publish the extension to the instance. First, you must extract ExportCompletedSample.zip to a folder.

2.3. Opening solution

To open the Visual Studio solution:

  1. Right-click on the Microsoft Visual Studio shortcut and click Run as administrator.
  2. Click the File menu and then Open Solution.
  3. Choose the solution located at: [Extracted folder]\ExportCompletedSample\ExportCompletedSample.sln

Note
If you build the solution, it will be create an extension zip file that can be installed to the instance.

3. Creating an application setting for the passwords

The following example defines two new application settings to use as the user and owner passwords for the PDF documents:

using Dundas.BI;
using Dundas.BI.Configuration;
using Dundas.BI.Data.DataRetrieval;
using Dundas.BI.Export;
using Dundas.BI.Extensibility;

   ...

/// <summary>
/// Called after the extension package is loaded during engine startup.
/// </summary>
public override void OnLoaded()
{
	// Create application settings to store the passwords.
	CreatePasswordSettings();
}

private void CreatePasswordSettings()
{
	// Get the application configuration service.
	IAppConfigService appConfigService = Engine.Current.GetService<IAppConfigService>();

	// Create the properties for the user and owner passwords for the PDF document.

	AppSettingProperties appSettingProperties;

	appSettingProperties = new AppSettingProperties(
		PdfUserPasswordSettingId,
		"PdfUserPassword",
		ExportCompletedExtensionPackageInfo.ModuleId,
		typeof(string)
	);

	appSettingProperties.CategoryName = "CustomExtension";
	appSettingProperties.IsEncrypted = true;
	appSettingProperties.IsPassword = true;
	appSettingProperties.DefaultValue = "1234";

	appConfigService.RegisterSetting(appSettingProperties);

	appSettingProperties = new AppSettingProperties(
		PdfOwnerPasswordSettingId,
		"PdfOwnerPassword",
		ExportCompletedExtensionPackageInfo.ModuleId,
		typeof(string)
	);
	appSettingProperties.CategoryName = "CustomExtension";
	appSettingProperties.IsEncrypted = true;
	appSettingProperties.IsPassword = true;
	appSettingProperties.DefaultValue = "1234";

	appConfigService.RegisterSetting(appSettingProperties);
}

4. Hooking into the ExportCompleted event

The following example uses IEventHookService to hook into the ExportCompleted event, and then adds a password to PDF exports:

using Dundas.BI;
using Dundas.BI.Configuration;
using Dundas.BI.Data.DataRetrieval;
using Dundas.BI.Export;
using Dundas.BI.Extensibility;

   ...

/// <summary>
/// Called after the extension package is loaded during engine startup.
/// </summary>
public override void OnLoaded()
{
	// Create application settings to store the passwords.
	CreatePasswordSettings();

	IEventHookService eventHookService = Engine.Current.GetService<IEventHookService>();

	// Hooks up event handler when a file system entry is created.
	eventHookService.ExportCompleted += eventHookService_ExportCompleted;
}

private void eventHookService_ExportCompleted(
    object sender,
    Dundas.BI.Export.ExportCompletedEventArgs e
)
{
	ExportResult result = e.ExportResult;

	if (e.ExportRequest.ProviderId.Equals(
            Dundas.BI.Export.StandardExportProviders.StandardExportProviderIds.Pdf
	))
	{
		// The file is stored in.
		if (e.ExportResult.Content == null && result.BlobId.HasValue)
		{
			IExportService exportService = Engine.Current.GetService<IExportService>();
			result = exportService.GetExportBlobResult(result.BlobId.Value);
		}

		// Write the file back to disk to be able to manipulate it.
		string tempFilePath = Path.Combine(
			Path.GetTempPath(),
			Guid.NewGuid() + (".pdf")
		);

		using (FileStream tempFile = File.Create(tempFilePath))
		{
			result.Content.CopyTo(tempFile);
		}

		// Open an existing document.
		PdfDocument document = PdfReader.Open(tempFilePath);

		PdfSecuritySettings securitySettings = document.SecuritySettings;

		// Get the application configuration service.
		IAppConfigService appConfigService = Engine.Current.GetService<IAppConfigService>();

		// Setting one of the passwords automatically 
		// sets the security level to PdfDocumentSecurityLevel.Encrypted128Bit.
		securitySettings.UserPassword = appConfigService.GetString(PdfUserPasswordSettingId);
		securitySettings.OwnerPassword = appConfigService.GetString(PdfOwnerPasswordSettingId);

		// Don't use 40 bit encryption unless needed for compatibility.
		// securitySettings.DocumentSecurityLevel = PdfDocumentSecurityLevel.Encrypted40Bit;

		// Restrict some rights.
		securitySettings.PermitAccessibilityExtractContent = false;
		securitySettings.PermitAnnotations = false;
		securitySettings.PermitAssembleDocument = false;
		securitySettings.PermitExtractContent = false;
		securitySettings.PermitFormsFill = true;
		securitySettings.PermitFullQualityPrint = true;
		securitySettings.PermitModifyDocument = false;
		securitySettings.PermitPrint = true;

		// Save the document.
		document.Save(tempFilePath);

		// Set the UpdatedExportContentFileInfo to the new temp file path.
		e.UpdatedExportContentFileInfo = new System.IO.FileInfo(tempFilePath);
	}
}

Important
The most important part of the code above is setting the UpdatedExportContentFileInfo property to the modified file in the last line.

5. See also

Dundas Data Visualization, Inc.
400-15 Gervais Drive
Toronto, ON, Canada
M3C 1Y8

North America: 1.800.463.1492
International: 1.416.467.5100

Dundas Support Hours:
Phone: 9am-6pm, ET, Mon-Fri
Email: 7am-6pm, ET, Mon-Fri