Skip to content

Commit

Permalink
Document remaining types
Browse files Browse the repository at this point in the history
  • Loading branch information
poulad committed Sep 3, 2018
1 parent 7b7b242 commit d5df077
Show file tree
Hide file tree
Showing 24 changed files with 232 additions and 109 deletions.
Binary file added package-icon.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/Quickstart/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ static async Task SendAuthorizationRequestAsync(int userId)
new PassportScopeElementOne(PassportEnums.Scope.Address),
new PassportScopeElementOne(PassportEnums.Scope.PhoneNumber),
});
AuthorizationRequest authReq = new AuthorizationRequest(
AuthorizationRequestParameters authReq = new AuthorizationRequestParameters(
botId: _botClient.BotId,
publicKey: PublicKey,
nonce: "Test nonce for this demo",
Expand Down
4 changes: 1 addition & 3 deletions src/Telegram.Bot.Extensions.Passport/Decryption/Decrypter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
// ReSharper disable once CheckNamespace
namespace Telegram.Bot.Passport
{
/// <summary>
/// Default implementation of <see cref="IDecrypter"/>
/// </summary>
/// <inheritdoc />
public class Decrypter : IDecrypter
{
/// <inheritdoc />
Expand Down
52 changes: 52 additions & 0 deletions src/Telegram.Bot.Extensions.Passport/Decryption/IDecrypter.cs
Original file line number Diff line number Diff line change
@@ -1,30 +1,82 @@
using System;
using System.IO;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Telegram.Bot.Exceptions;
using Telegram.Bot.Types.Passport;

// ReSharper disable once CheckNamespace
namespace Telegram.Bot.Passport
{
/// <summary>
/// Provides decryption utilities for encrypted Telegram Passport data
/// </summary>
public interface IDecrypter
{
/// <summary>
/// Decrypts encrypted credentials in <see cref="PassportData"/> using RSA key
/// </summary>
/// <param name="encryptedCredentials">Encrypted credentials in Passport data</param>
/// <param name="key">RSA private key</param>
/// <returns>Decrypted credentials</returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="FormatException"></exception>
/// <exception cref="PassportDataDecryptionException"></exception>
/// <exception cref="CryptographicException"></exception>
Credentials DecryptCredentials(
EncryptedCredentials encryptedCredentials,
RSA key
);

/// <summary>
/// Decrypts encrypted data using its accompanying data credentials and deserializes the result
/// from JSON to an instance of <typeparamref name="TValue"/>
/// </summary>
/// <param name="encryptedData">Encrypted Passport data</param>
/// <param name="dataCredentials">Accompanying data credentials required for decryption</param>
/// <returns>Decrypted data</returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="FormatException"></exception>
/// <exception cref="PassportDataDecryptionException"></exception>
/// <exception cref="JsonSerializationException"></exception>
TValue DecryptData<TValue>(
string encryptedData,
DataCredentials dataCredentials
)
where TValue : class, IDecryptedValue;

/// <summary>
/// Decrypts encrypted file bytes using its accompanying file credentials
/// </summary>
/// <param name="encryptedContent">Encrypted Passport file</param>
/// <param name="fileCredentials">Accompanying file credentials required for decryption</param>
/// <returns>Decrypted file bytes</returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="FormatException"></exception>
/// <exception cref="PassportDataDecryptionException"></exception>
byte[] DecryptFile(
byte[] encryptedContent,
FileCredentials fileCredentials
);

/// <summary>
/// Decrypts encrypted file from stream using its accompanying file credentials and writes it
/// to <paramref name="destination"/> stream
/// </summary>
/// <param name="encryptedContent">Encrypted Passport file stream</param>
/// <param name="fileCredentials">Accompanying file credentials required for decryption</param>
/// <param name="destination">Stream to write decrypted file content to</param>
/// <param name="cancellationToken">The cancellation token to cancel operation</param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="FormatException"></exception>
/// <exception cref="PassportDataDecryptionException"></exception>
/// <exception cref="CryptographicException"></exception>
Task DecryptFileAsync(
Stream encryptedContent,
FileCredentials fileCredentials,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// ReSharper disable CommentTypo
// ReSharper disable CheckNamespace
// ReSharper disable StringLiteralTypo

using System;
using Newtonsoft.Json;

namespace Telegram.Bot.Passport.Request
{
/// <summary>
/// Parameters for making a Telegram Passport authorization request
/// </summary>
public class AuthorizationRequestParameters
{
/// <summary>
/// Unique identifier for the bot. You can get it from bot token. For example, for the bot token
/// "1234567:4TT8bAc8GHUspu3ERYn-KGcvsvGB9u_n4ddy", the bot id is 1234567.
/// </summary>
public int BotId { get; }

/// <summary>
/// Public key of the bot
/// </summary>
public string PublicKey { get; }

/// <summary>
/// Bot-specified nonce.
/// Important: For security purposes it should be a cryptographically secure unique identifier of the request.
/// In particular, it should be long enough and it should be generated using a cryptographically secure
/// pseudorandom number generator. You should never accept credentials with the same nonce twice.
/// </summary>
public string Nonce { get; }

/// <summary>
/// Description of the data you want to request
/// </summary>
public PassportScope PassportScope { get; }

/// <summary>
/// Query string part of the URI generated from the parameters
/// </summary>
public string Query { get; }

/// <summary>
/// Authorization request URI
/// </summary>
public string Uri => "tg://resolve?" + Query;

/// <summary>
/// Authorization request URI for Android devices
/// </summary>
public string AndroidUri => "tg:resolve?" + Query;

/// <summary>
/// Initializes a new instance of <see cref="AuthorizationRequestParameters"/>
/// </summary>
/// <param name="botId">
/// Unique identifier for the bot. You can get it from bot token. For example, for the bot token
/// "1234567:4TT8bAc8GHUspu3ERYn-KGcvsvGB9u_n4ddy", the bot id is 1234567.
/// </param>
/// <param name="publicKey">Public key of the bot</param>
/// <param name="nonce">
/// Bot-specified nonce.
/// Important: For security purposes it should be a cryptographically secure unique identifier of the request.
/// In particular, it should be long enough and it should be generated using a cryptographically secure
/// pseudorandom number generator. You should never accept credentials with the same nonce twice.
/// </param>
/// <param name="scope">Description of the data you want to request</param>
public AuthorizationRequestParameters(
int botId,
string publicKey,
string nonce,
PassportScope scope
)
{
BotId = botId;
PublicKey = publicKey ?? throw new ArgumentNullException(nameof(publicKey));
Nonce = nonce ?? throw new ArgumentNullException(nameof(nonce));
PassportScope = scope ?? throw new ArgumentNullException(nameof(PassportScope));

var scopeJson = JsonConvert.SerializeObject(scope);

Query = "domain=telegrampassport" +
$"&bot_id={System.Uri.EscapeDataString(botId + "")}" +
$"&scope={System.Uri.EscapeDataString(scopeJson)}" +
$"&public_key={System.Uri.EscapeDataString(publicKey)}" +
$"&nonce={System.Uri.EscapeDataString(nonce)}";
}

/// <summary>
/// Converts the parameters to their "tg://" URI string representation
/// </summary>
/// <returns>URI representation of this request</returns>
public override string ToString() => Uri;
}
}
17 changes: 2 additions & 15 deletions src/Telegram.Bot.Extensions.Passport/Request/PassportScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,16 @@ public class PassportScope
[JsonProperty(Required = Required.Always)]
public int V { get; }

/// <summary>
/// Initializes a new instance of <see cref="PassportScope"/> with latest scope version
/// </summary>
/// <param name="data">
/// List of requested elements, each type may be used only once in the entire array of
/// <see cref="IPassportScopeElement"/> objects
/// </param>
/// <exception cref="ArgumentNullException"></exception>
public PassportScope(IEnumerable<IPassportScopeElement> data)
: this(data, 1)
{
}

/// <summary>
/// Initializes a new instance of <see cref="PassportScope"/> with required parameters
/// </summary>
/// <param name="data">
/// List of requested elements, each type may be used only once in the entire array of
/// <see cref="IPassportScopeElement"/> objects
/// </param>
/// <param name="v">Scope version</param>
/// <param name="v">Scope version. Defaults to 1.</param>
/// <exception cref="ArgumentNullException"></exception>
public PassportScope(IEnumerable<IPassportScopeElement> data, int v)
public PassportScope(IEnumerable<IPassportScopeElement> data, int v = 1)
{
Data = data ?? throw new ArgumentNullException(nameof(data));
V = v;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
<VersionPrefix>0.1.0</VersionPrefix>
<VersionSuffix>alpha</VersionSuffix>
<VersionPrefix>1.0.0</VersionPrefix>
<!--<VersionSuffix></VersionSuffix>-->
<LangVersion>latest</LangVersion>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<Title>Passport Extension for Telegram Bot API Client</Title>
<Description>The Bot API is an HTTP-based interface created for developers keen on building bots for Telegram.</Description>
<Title>Telegram Passport Extension for Telegram Bot API Client</Title>
<Description>
Telegram Passport is a unified authorization method for services that require personal identification.
This package provides extension methods for Telegram Passport API and decryption utilities for
Telegram Passport encrypted data.
</Description>
<Authors>TelegramBots</Authors>
<Copyright>Copyright © Telegram Bots 2018</Copyright>
<PackageIconUrl>https://telegram.org/file/811140058/2/7GzMJk4Ij54/a1649c56fa9f805828</PackageIconUrl>
<RepositoryUrl>https://github.com/TelegramBots/Telegram.Bot.Extensions.Passport</RepositoryUrl>
<PackageProjectUrl>https://github.com/TelegramBots/Telegram.Bot.Extensions.Passport</PackageProjectUrl>
<PackageLicenseUrl>https://raw.githubusercontent.com/TelegramBots/Telegram.Bot.Extensions.Passport/master/LICENSE</PackageLicenseUrl>
<RepositoryUrl>https://github.com/TelegramBots/Telegram.Bot.Extensions.Passport</RepositoryUrl>
<PackageTags>Telegram;Bot;Api;Passport</PackageTags>
<PackageIconUrl>https://raw.githubusercontent.com/TelegramBots/Telegram.Bot.Extensions.Passport/master/package-icon.gif</PackageIconUrl>
<PackageTags>Telegram;Bot;Api;Passport;Telegram Passport</PackageTags>
</PropertyGroup>
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
<ProjectReference Include="..\..\deps\Telegram.Bot\src\Telegram.Bot\Telegram.Bot.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)' == 'Release'">
<PackageReference Include="Telegram.Bot" Version="14.9.0" />
<PackageReference Include="Telegram.Bot" Version="14.10.0" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public static Task SetPassportDataErrorsAsync(
botClient.MakeRequestAsync(new SetPassportDataErrorsRequest(userId, errors), cancellationToken);

/// <summary>
/// Downloads an ecnrypted Passport file, decrypts it, and writes the content to
/// Downloads an encrypted Passport file, decrypts it, and writes the content to
/// <paramref name="destination"/> stream
/// </summary>
/// <param name="botClient">Instance of bot client</param>
Expand All @@ -48,10 +48,7 @@ public static Task SetPassportDataErrorsAsync(
/// <param name="destination"></param>
/// <param name="cancellationToken">The cancellation token to cancel operation.</param>
/// <returns>File information of the encrypted Passport file on Telegram servers.</returns>
/// <exception cref="ArgumentNullException">If null arguments are passed</exception>
/// <exception cref="ArgumentException">
/// If <paramref name="destination"/> stream is not writable.
/// </exception>
/// <exception cref="ArgumentNullException"></exception>
public static async Task<File> DownloadAndDecryptPassportFileAsync(
this ITelegramBotClient botClient,
PassportFile passportFile,
Expand All @@ -62,8 +59,10 @@ public static async Task<File> DownloadAndDecryptPassportFileAsync(
{
if (passportFile == null)
throw new ArgumentNullException(nameof(passportFile));
if (!destination.CanWrite)
throw new ArgumentException("Stream msut be writable.", nameof(destination));
if (fileCredentials == null)
throw new ArgumentNullException(nameof(fileCredentials));
if (destination == null)
throw new ArgumentNullException(nameof(destination));

File fileInfo;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class IdDocumentData : IDecryptedValue
public string ExpiryDate { get; set; }

/// <summary>
/// Date of exprity if available
/// Date of expiry if available
/// </summary>
public DateTime? Expiry
{
Expand Down
2 changes: 1 addition & 1 deletion test/IntegrationTests/Framework/OrderedFactAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace IntegrationTests.Framework
{
/// <summary>
/// Attribute that is applied to a test method. Test methods in a collection will be executed in order based on their line number.
/// By defalut, test cases will rerun once if test method throws a <see cref="TaskCanceledException"/>.
/// By default, test cases will rerun once if test method throws a <see cref="TaskCanceledException"/>.
/// </summary>
[XunitTestCaseDiscoverer(Constants.TestCaseDiscoverer, Constants.AssemblyName)]
public class OrderedFactAttribute : FactAttribute
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public async Task Should_Generate_Auth_Link()
// Selfie = null // selfie cannot be requested for documents used as proof of address
},
});
AuthorizationRequest authReq = new AuthorizationRequest(
AuthorizationRequestParameters authReq = new AuthorizationRequestParameters(
botId: _fixture.BotUser.Id,
publicKey: publicKey,
nonce: "Test nonce for id card & utility bill",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public async Task Should_generate_auth_link()
new PassportScopeElementOne(PassportEnums.Scope.PhoneNumber),
new PassportScopeElementOne(PassportEnums.Scope.Email),
});
AuthorizationRequest authReq = new AuthorizationRequest(
AuthorizationRequestParameters authReq = new AuthorizationRequestParameters(
botId: _fixture.BotUser.Id,
publicKey: publicKey,
nonce: "Test nonce for phone and email",
Expand Down
Loading

0 comments on commit d5df077

Please sign in to comment.