SecurityHandlers.cs
// 
// このコードは、DioDocs for PDF のサンプルの一部として提供されています。
// Copyright (c) GrapeCity 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 GcPdfWeb.Samples
{
    // このサンプルは、Security.EncryptHandler と Security.DecryptHandler の使用方法を示します。
    // Security.DecryptHandler を使用すると、既存の PDF のセキュリティ属性を調べることができます。
    // Security.EncryptHandler を使用すると、PDF を保存するときにセキュリティ属性を指定できます。
    // GcPdfは、標準セキュリティハンドラリビジョン2、3、4、5(PDF 仕様で定義)をサポートしています。
    // このサンプルでは、最も多く提供されている StandardSecurityHandlerRev4 を使用しています。
    public class SecurityHandlers
    {
        public int CreatePDF(Stream stream)
        {
            // サンプルのパスワード。
            var ownerPassword = "I'm the owner";
            var userPassword = "I'm a user";

            // Step 1: セキュリティ属性を含む文書を生成します。
            GcPdfDocument 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 = new FileStream(fn, FileMode.Open, FileAccess.Read))
            {
                // パスワードを指定してドキュメントを読み込みます。
                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)
                {
                    // 読み込まれたアクセス許可が 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("No way.");
                }
                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;
        }
    }
}