CSDNCurrent de:QUICK Transfer versenden

Aus Cryptshare Documentation
Wechseln zu:Navigation, Suche



Einleitung

Allgemeine Informationen zu QUICK Technology
Für allgemeine Informationen zur Funktionsweise von QUICK Technology und für ein besseres Verständnis über die genutzte Terminologie empfehlen wir Ihnen den Artikel Einleitung zu QUICK.

In diesem Artikel erfahren Sie, wie Sie mithilfe der Cryptshare .NET API einen mit QUICK gesicherten Transfer versenden. Alternativ können Sie im Abschnitt Zusammenfassung sofort den gesamten Quelltext betrachten.

Implementierung

Nachfolgend werden wir Schritt für Schritt den Code zusammenstellen, der für einen erfolgreichen, mit QUICK gesicherten Transfer benötigt wird.

Vorbereiten des Programms

Wir bereiten eine einfache Konsolenanwendung vor und definieren im Voraus Informationen, die im Laufe des Programms benötigt werden. Um den `Cryptshare.*` namespace nutzen zu können, sollten Sie vorher sicherstellen, dass .

using Cryptshare.API;
using System;
using System.Collections.Generic;
using System.Linq;

namespace QuickTransfer
{
	class Program
	{
		private static readonly string SenderEmailAddress = "max.mustermann@beispiel.de";
		private static readonly string SenderName = "Max Mustermann";
		private static readonly string SenderPhoneNumber = "+49 (0) 1234 56789";
		private static readonly string ServerUrl = "https://cryptshare.beispiel.de";
		// New "client.store" file will be created if it doesn't already exist.
		private static readonly string ClientStoreLocation = @"C:\temp"; 
		private static readonly string RecipientEmailAddress = "erika.mustermann@beispiel.de";
		private static readonly string FilePath = @"C:\temp\pdf-sample.pdf";

		static void Main(string[] args)
		{
			try
			{
				// All following code snippets are to be inserted here.
			}
			catch (Exception e)
			{
				Console.Error.WriteLine("An error has occurred: " + e);
			}
			finally
			{
				Console.WriteLine("Press any key to terminate the program.");
				Console.ReadKey();
			}
		}
	}
}

Erzeugen der `Client`-Instanz

Wie auch für reguläre Transfers ist es notwendig, eine Client-Instanz zu erzeugen, die den Absender des Transfers darstellt. Die hierfür benötigten Informationen sind:

  • E-Mail-Adresse des Absenders
  • URL des Cryptshare Servers
  • Pfad zum Ablegen des Verifizierungsspeichers
Client client = new Client(
	SenderEmailAddress,
	new CryptshareConnection(new WebServiceUri(ServerUrl)),
	ClientStoreLocation
);

Erzeugen und Vorbereiten der Transfer-Instanz

Die Informationen über den Transfer sind, wie auch die oben beschriebenen Informationen über den Absender, integraler Bestandteil eines Cryptshare-Transfers.

Transfer transfer = new Transfer();

Für einen erfolgreichen Transfer werden mindestens folgende Angaben benötigt:

  • Name des Absenders
transfer.SenderName = SenderName;
  • Telefonnummer des Absenders
transfer.SenderPhone = SenderPhoneNumber;
  • Mindestens ein Empfänger (der zweite Parameter definiert, ob für diesen Empfänger der Transfer mit QUICK gesichert werden soll)
// Activate QUICK for the given recipient.
transfer.Recipients.Add(new Recipient(RecipientEmailAddress, true));
  • Der zu verwendende Passwortmodus
transfer.PasswordMode = PasswordMode.Manual;
 
  • Mindestens eine zu versendende Datei
    • Bitte beachten Sie, dass immer eine Datei angegeben werden muss, auch wenn Sie nur eine vertrauliche Nachricht versenden möchten. Das Versenden von vertraulichen Nachrichten ohne Dateianhänge ist für eine spätere Version geplant.
transfer.Files = new List<string>() { FilePath };
  • Optional: Angabe, ob der Cryptshare Server den E-Mail Versand zum Benachrichtigen des Absenders und Empfängers übernehmen soll.
transfer.SendEmails = true;
transfer.NotifySender = true;
transfer.NotifyRecipients = true;
transfer.InformAboutDownload = true;
  • Ablaufdatum des Transfers. Hinweis: Da wir zum Setzen des Ablaufdatums auf eine Policy-Abfrage angewiesen sind, ist für diesen Abschnitt eine gültige Verifizierung notwendig. Daher sollte die maximale Liegezeit erst dann abgefragt werden, wenn sichergestellt wurde, dass eine gültige Verifizierung vorhanden ist. Bitte beachten Sie die Reihenfolge der Aufrufe im Abschnitt Zusammenfassung.
// Query the maximum possible storage duration for the given sender-recipient policy.
Policy policy = client.RequestPolicy(transfer.Recipients.ConvertAll(recipient => recipient.EmailAddress));
transfer.ExpirationDate = DateTime.Now.AddDays(policy.StorageDuration);

Weitere Voraussetzungen für einen erfolgreichen Transfer

Sowohl unsere Client- als auch Transfer-Instanzen erfüllen die Voraussetzungen für einen Transfer. Allerdings müssen weitere vom Cryptshare Server auferlegte Voraussetzungen beachtet und behandelt werden. Im Einzelnen wird vorausgesetzt, dass:

  • die Absender-E-Mail-Adresse verifiziert ist.
CheckVerificationResult checkVerificationResult = client.CheckVerification();
if (!checkVerificationResult.UserVerified)
{
    switch (checkVerificationResult.VerificationMode)
    {
        case VerificationMode.Sender:
            Console.WriteLine($"Requesting a verification code for {client.UserEmailAddress}...");
            client.RequestSenderVerification();
            Console.WriteLine($"Please enter the code below and confirm with [Enter]:");
            string code = Console.ReadLine().Trim();
            client.ConfirmSenderVerification(code);
            break;
        case VerificationMode.Client:
            if (checkVerificationResult.ClientVerificationAllowed)
            {
                client.RequestClientVerification();
            }
            else
            {
                throw new UnauthorizedAccessException(
                    $"Your client ID is not whitelisted. Please whitelist the following client ID before proceeding: {client.ClientId}"
                );
            }
            break;
        default:
            break;
    }
}
  • keine Aktivierung von QUICK notwendig ist - eine Aktivierung ist z.B. dann notwendig, wenn für die angegebene Absender-E-Mail-Adresse bereits ein QUICK-Zugang auf dem Server existiert, falls QUICK bspw. zuvor auf einem anderen Gerät genutzt wurde.
    • Falls ja, wird der eigene QUICK-Zugang zurückgesetzt.
    • Hinweis: Setzen Sie den QUICK-Zugang nur dann zurück, wenn Sie sich den Konsequenzen bewusst sind. Grundsätzlich kann ein existierender QUICK Zugang auch programmatisch aktiviert werden. Dieser Vorgang ist in folgendem Artikel beschrieben.
if (checkVerificationResult.ActivationRequired)
{
    // WARNING: Only reset the QUICK state if you are aware of the consequences. When in doubt, please
    // consult the Wiki article about QUICK Technology: http://cryptshare.click/webapp-quick-activation-en
    client.ResetQuickState();
}
  • die bestehende Verifizierung für die Nutzung von QUICK zugelassen ist.
if (!checkVerificationResult.QuickEnabled)
{
    client.EnableVerificationForQuick();
}
  • ein Passwort gesetzt wird, wenn mindestens ein Empfänger existiert, zu welchem noch keine QUICK-Verbindung besteht.
    • Für diesen Empfänger fungiert der Transfer gleichzeitig als Einladung für den Aufbau einer QUICK-Verbindung.
{
	// ...
    HashSet<string> recipients = new HashSet<string>(transfer.Recipients.Select(r => r.EmailAddress));
    IDictionary<string, QuickConnectionState> quickConnectionStates = client.RequestQuickConnectionStates(recipients);
    if (!IsPureQuickTransfer(quickConnectionStates))
    {
        // Not a pure QUICK transfer, password needs to be set.
        Console.Write("Not a pure QUICK transfer; generating a one-time-password... ");
        PasswordPolicy passwordPolicy = client.RequestPasswordPolicy();
        transfer.Password = client.RequestGeneratedPassword(passwordPolicy.MinimumLength);
        Console.WriteLine(transfer.Password);
    }
	// ...
}

private static bool IsPureQuickTransfer(IDictionary<string, QuickConnectionState> quickConnectionStates)
{
	return quickConnectionStates
		.Select(entry => entry.Value)
		.All(recipient => recipient == QuickConnectionState.Established);
}

Wenn diese Voraussetzungen berücksichtigt werden, steht dem Transfer nichts mehr im Wege.

{
    // ...
    client.PerformTransfer(transfer, null, HandleUploadComplete, null, null);
    // ...
}

private static void HandleUploadComplete(IDictionary<string, string> urlMappings, IDictionary<string, string> smtpMappings, string serverGenPassword, TransferError transferError, string trackingID)
{
	Console.WriteLine("URL mappings:");
	foreach (var mapping in urlMappings)
	{
		Console.WriteLine($"{mapping.Key}: {mapping.Value}");
	}
	Console.WriteLine("SMTP mappings:");
	foreach (var mapping in smtpMappings)
	{
		Console.WriteLine($"{mapping.Key}: {mapping.Value}");
	}
	Console.WriteLine($"Tracking ID: {trackingID}");

Zusammenfassung

Wenn Sie alle Punkte der Reihe nach berücksichtigt haben, sollte Ihr Programm wie nachfolgend abgebildet aussehen:

Klicken Sie hier, um den Quelltext zu betrachten...  Expand source

using Cryptshare.API;
using System;
using System.Collections.Generic;
using System.Linq;

namespace QuickTransfer
{
	class Program
	{
		private static readonly string SenderEmailAddress = "max.mustermann@beispiel.de";
		private static readonly string SenderName = "Max Mustermann";
		private static readonly string SenderPhoneNumber = "+49 (0) 1234 56789";
		private static readonly string ServerUrl = "https://cryptshare.beispiel.de";
        // New "client.store" file will be created if it doesn't already exist.
		private static readonly string ClientStoreLocation = @"C:\temp";
		private static readonly string RecipientEmailAddress = "erika.mustermann@beispiel.de";
		private static readonly string FilePath = @"C:\temp\pdf-sample.pdf";

		static void Main(string[] args)
		{
			try
			{
				Client client = new Client(
					SenderEmailAddress,
					new CryptshareConnection(new WebServiceUri(ServerUrl)),
					ClientStoreLocation
				);
				Transfer transfer = new Transfer();
				transfer.SenderName = SenderName;
				transfer.SenderPhone = SenderPhoneNumber;
				// Activate QUICK for the given recipient.
				transfer.Recipients.Add(new Recipient(RecipientEmailAddress, true));
				transfer.PasswordMode = PasswordMode.Manual;
				transfer.Files = new List<string>() { FilePath };
				// Optional: Let the Cryptshare Server handle the email sending process.
				transfer.SendEmails = true;
				transfer.NotifySender = true;
				transfer.NotifyRecipients = true;
				transfer.InformAboutDownload = true;

				CheckVerificationResult checkVerificationResult = client.CheckVerification();
				if (!checkVerificationResult.UserVerified)
				{
					switch (checkVerificationResult.VerificationMode)
					{
						case VerificationMode.Sender:
							Console.WriteLine($"Requesting a verification code for {client.UserEmailAddress}...");
							client.RequestSenderVerification();
							Console.WriteLine($"Please enter the code below and confirm with [Enter]:");
							string code = Console.ReadLine().Trim();
							client.ConfirmSenderVerification(code);
							break;
						case VerificationMode.Client:
							if (checkVerificationResult.ClientVerificationAllowed)
							{
								client.RequestClientVerification();
							}
							else
							{
								throw new UnauthorizedAccessException(
									$"Your client ID is not whitelisted. Please whitelist the following client ID before proceeding: {client.ClientId}"
								);
							}
							break;
						default:
							break;
					}
				}

				// Query the maximum possible storage duration for the given sender-recipient policy.
				Policy policy = client.RequestPolicy(transfer.Recipients.ConvertAll(recipient => recipient.EmailAddress));
				transfer.ExpirationDate = DateTime.Now.AddDays(policy.StorageDuration);

				// If the user already has a personal key on this server, reset the QUICK state. We could activate the
				// QUICK access using the API, but choose to reset the QUICK state for the sake of brevity.
				if (checkVerificationResult.ActivationRequired)
				{
					// WARNING: Only reset the QUICK state if you are aware of the consequences. When in doubt, please
					// consult the Wiki article about QUICK Technology: http://cryptshare.click/webapp-quick-activation-en
					client.ResetQuickState();
				}

				// A regular verification needs to be enabled for QUICK, if not already done.
				if (!checkVerificationResult.QuickEnabled)
				{
					client.EnableVerificationForQuick();
				}

				// We must define a password if there is at least one recipient who has not yet accepted the QUICK invitation.
				HashSet<string> recipients = new HashSet<string>(transfer.Recipients.Select(r => r.EmailAddress));
				IDictionary<string, QuickConnectionState> quickConnectionStates = client.RequestQuickConnectionStates(recipients);
				if (!IsPureQuickTransfer(quickConnectionStates))
				{
					// Not a pure QUICK transfer, password needs to be set.
					Console.Write("Not a pure QUICK transfer; generating a one-time-password... ");
					PasswordPolicy passwordPolicy = client.RequestPasswordPolicy();
					transfer.Password = client.RequestGeneratedPassword(passwordPolicy.MinimumLength);
					Console.WriteLine(transfer.Password);
				}

				client.PerformTransfer(transfer, null, HandleUploadComplete, null, null);
			}
			catch (Exception e)
			{
				Console.Error.WriteLine("An error has occurred: " + e);
			}
			finally
			{
				Console.WriteLine("Press any key to terminate the program.");
				Console.ReadKey();
			}
		}

		private static bool IsPureQuickTransfer(IDictionary<string, QuickConnectionState> quickConnectionStates)
		{
			return quickConnectionStates
				.Select(entry => entry.Value)
				.All(recipient => recipient == QuickConnectionState.Established);
		}

		private static void HandleUploadComplete(IDictionary<string, string> urlMappings, IDictionary<string, string> smtpMappings, string serverGenPassword, TransferError transferError, string trackingID)
		{
			Console.WriteLine("URL mappings:");
			foreach (var mapping in urlMappings)
			{
				Console.WriteLine($"{mapping.Key}: {mapping.Value}");
			}
			Console.WriteLine("SMTP mappings:");
			foreach (var mapping in smtpMappings)
			{
				Console.WriteLine($"{mapping.Key}: {mapping.Value}");
			}
			Console.WriteLine($"Tracking ID: {trackingID}");
		}
	}
}