SecurityHandlers.cs
// 
// このコードは、DioDocs for PDF のサンプルの一部として提供されています。
// © MESCIUS inc. All rights reserved.
// 
using System;
using System.IO;
using System.Drawing;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Pdf.Security;

namespace DsPdfWeb.Demos
{
    // このサンプルでは、Security.EncryptHandler と Security.DecryptHandler の使用方法を説明しています。
    // Security.DecryptHandler を使用すると、既存の PDF のセキュリティ属性を調べることができます。
    // Security.EncryptHandler を使用すると、PDF を保存するときにセキュリティ属性を指定することができます。
    // DsPdfは、PDF 1.7 および PDF 2.0 で定義されている標準セキュリティハンドラのリビジョン2、3、4、5、6に
    // 対応しています。このサンプルでは、StandardSecurityHandlerRev4 を使用しています。
    // 
    // 標準セキュリティハンドラのリビジョン6のデモについては SecurityHandlerRev6 をご参照ください。
    public class SecurityHandlers
    {
        public int CreatePDF(Stream stream)
        {
            // サンプルのパスワード
            const string ownerPassword = "I'm the owner";
            const string userPassword = "I'm a user";

            // Step 1: セキュリティ属性を含むドキュメントを生成します。
            var doc0 = new GcPdfDocument();
            var rc0 = Common.Util.AddNote(
                "セキュリティのデモ:\n" +
                "この PDF では、特定の暗号化オプションを指定し、\n" +
                "所有者とユーザーのパスワードを設定します。",
                doc0.NewPage());

            // Rev4 のセキュリティハンドラを作成します。
            var ssh4 = new StandardSecurityHandlerRev4()
            {
                // Rev4 固有のプロパティを設定します。
                EncryptionAlgorithm = EncryptionAlgorithm.AES,
                EncryptStrings = true,
            };
            // StandardSecurityHandlerRev4 は StandardSecurityHandlerRev3 から派生しているので、
            // Rev3 固有のプロパティのみを操作させるためにこれを行うことができます
            // (キャストは用例なので、これらの詳細項目をすべて設定する必要はありません)。
            if (ssh4 is StandardSecurityHandlerRev3 ssh3)
            {
                ssh3.EditingPermissions = EditingPermissions.AssembleDocument;
                ssh3.PrintingPermissions = PrintingPermissions.LowResolution;
            }
            // しかし、StandardSecurityHandlerRev3 は StandardSecurityHandlerRev2 から派生した
            // ものではありません。いくつかのプロパティの意味は同じですが構文は異なるため、
            // if(ssh3 is StandardSecurityHandlerRev2 ssh2){...} は動作しません。

            // パスワードを設定します。
            ssh4.OwnerPassword = ownerPassword;
            ssh4.UserPassword = userPassword;

            // 作成したハンドラをドキュメントに割り当て、PDF を保存するときに使用されるようにします。
            doc0.Security.EncryptHandler = ssh4;

            // PDF を一時ファイルに保存し、読み込めるようにします。
            var fn = Path.GetTempFileName();
            doc0.Save(fn);

            // Step 2: 生成された PDF を読み込み、そのセキュリティ属性を検査します。
            var doc = new GcPdfDocument();
            using (var fs = File.OpenRead(fn))
            {
                // パスワードを指定してドキュメントを読み込みます。
                doc.Load(fs, userPassword);

                // この時点で、doc.Security.DecryptHandler が存在する場合はそれを調べることができますが、
                // Security.EncryptHandler が存在しません。
                if (doc.Security.EncryptHandler != null)
                    throw new Exception("この例外は発生しないはずです。");

                var dh = doc.Security.DecryptHandler;
                if (dh is StandardSecurityHandlerRev4 dh_ssh4)
                {
                    // 読み込まれた PDF のセキュリティ属性が Step1 で指定したものであることを確認します。
                    Common.Util.AddNote(
                        string.Format("読み込まれた PDF の DecryptHandler にあるセキュリティ属性:\n" +
                            "編集権限: {0}\n" +
                            "印刷権限: {1}",
                        dh_ssh4.EditingPermissions, dh_ssh4.PrintingPermissions),
                        doc.Pages[0],
                        new RectangleF(72, rc0.Bottom + 36, 72 * 6, 72 * 2));
                    // 申し訳ありませんが、これはうまくいきません。
                    var noway = dh_ssh4.OwnerPassword;
                    if (noway != null)
                        throw new Exception("この例外は発生しないはずです。");
                }
                else if (dh is StandardSecurityHandlerRev3 dh_ssh3)
                {
                    // Rev4 ハンドラがあることが分からない場合は、ここにコードを追加します。
                }
                else if (dh is StandardSecurityHandlerRev2 dh_ssh2)
                {
                    // ... そして、ここにも。
                }
                else
                {
                    // ... そして、この場合も何かを行います。
                }

                // 新しい PDF を保存します。ただし、Security.EncryptHandler を設定しなかったので、
                // 新しく保存されたドキュメントにはセキュリティがないことにご注意ください。
                doc.Save(stream);
            }
            // 一時ファイルを削除します。
            File.Delete(fn);
            // PDF ドキュメントを保存します。
            return doc.Pages.Count;
        }
    }
}