-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1343 from alfhenrik/enh-gpgkeysclient
User GPG Keys client
- Loading branch information
Showing
34 changed files
with
1,007 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics.CodeAnalysis; | ||
using System.Linq; | ||
using System.Reactive; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace Octokit.Reactive | ||
{ | ||
/// <summary> | ||
/// A client for GitHub's UserUser GPG Keys API. | ||
/// </summary> | ||
/// <remarks> | ||
/// See the <a href="https://developer.github.com/v3/users/gpg_keys/">User GPG Keys documentation</a> for more information. | ||
/// </remarks> | ||
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpg")] | ||
public interface IObservableUserGpgKeysClient | ||
{ | ||
/// <summary> | ||
/// Gets all GPG keys for the authenticated user. | ||
/// </summary> | ||
/// <remarks> | ||
/// See the <a href="https://developer.github.com/v3/users/gpg_keys/#list-your-gpg-keys">API documentation</a> for more information. | ||
/// </remarks> | ||
/// <returns>A <see cref="IReadOnlyList{GpgKey}"/> of <see cref="GpgKey"/>s for the current user.</returns> | ||
IObservable<GpgKey> GetAllForCurrent(); | ||
|
||
/// <summary> | ||
/// Gets all GPG keys for the authenticated user. | ||
/// </summary> | ||
/// <param name="options">Options for changing the API response</param> | ||
/// <remarks> | ||
/// See the <a href="https://developer.github.com/v3/users/gpg_keys/#list-your-gpg-keys">API documentation</a> for more information. | ||
/// </remarks> | ||
/// <returns>A <see cref="IReadOnlyList{GpgKey}"/> of <see cref="GpgKey"/>s for the current user.</returns> | ||
IObservable<GpgKey> GetAllForCurrent(ApiOptions options); | ||
|
||
/// <summary> | ||
/// View extended details of the <see cref="GpgKey"/> for the specified id. | ||
/// </summary> | ||
/// <param name="id">The ID of the GPG key</param> | ||
/// <remarks> | ||
/// See the <a href="https://developer.github.com/v3/users/gpg_keys/#get-a-single-gpg-key">API documentation</a> for more information. | ||
/// </remarks> | ||
/// <returns>The <see cref="GpgKey"/> for the specified ID.</returns> | ||
[SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get")] | ||
IObservable<GpgKey> Get(int id); | ||
|
||
/// <summary> | ||
/// Creates a new <see cref="GpgKey"/> for the authenticated user. | ||
/// </summary> | ||
/// <param name="newGpgKey">The new GPG key to add.</param> | ||
/// <remarks> | ||
/// See the <a href="https://developer.github.com/v3/users/gpg_keys/#create-a-gpg-key">API documentation</a> for more information. | ||
/// </remarks> | ||
/// <returns>The newly created <see cref="GpgKey"/>.</returns> | ||
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpg")] | ||
IObservable<GpgKey> Create(NewGpgKey newGpgKey); | ||
|
||
/// <summary> | ||
/// Deletes the GPG key for the specified ID. | ||
/// </summary> | ||
/// <param name="id">The ID of the GPG key to delete.</param> | ||
/// <remarks> | ||
/// See the <a href="https://developer.github.com/v3/users/gpg_keys/#delete-a-gpg-key">API documentation</a> for more information. | ||
/// </remarks> | ||
/// <returns></returns> | ||
IObservable<Unit> Delete(int id); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics.CodeAnalysis; | ||
using System.Linq; | ||
using System.Reactive; | ||
using System.Reactive.Linq; | ||
using System.Reactive.Threading.Tasks; | ||
using System.Runtime.InteropServices; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using Octokit.Reactive.Internal; | ||
|
||
namespace Octokit.Reactive | ||
{ | ||
/// <summary> | ||
/// A client for GitHub's UserUser GPG Keys API. | ||
/// </summary> | ||
/// <remarks> | ||
/// See the <a href="https://developer.github.com/v3/users/gpg_keys/">User GPG Keys documentation</a> for more information. | ||
/// </remarks> | ||
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpg")] | ||
public class ObservableUserGpgKeysClient : IObservableUserGpgKeysClient | ||
{ | ||
readonly IUserGpgKeysClient _client; | ||
|
||
public ObservableUserGpgKeysClient(IGitHubClient client) | ||
{ | ||
Ensure.ArgumentNotNull(client, "client"); | ||
|
||
_client = client.User.GpgKey; | ||
} | ||
|
||
/// <summary> | ||
/// Gets all GPG keys for the authenticated user. | ||
/// </summary> | ||
/// <remarks> | ||
/// See the <a href="https://developer.github.com/v3/users/gpg_keys/#list-your-gpg-keys">API documentation</a> for more information. | ||
/// </remarks> | ||
/// <returns>A <see cref="IReadOnlyList{GpgKey}"/> of <see cref="GpgKey"/>s for the current user.</returns> | ||
public IObservable<GpgKey> GetAllForCurrent() | ||
{ | ||
return GetAllForCurrent(ApiOptions.None); | ||
} | ||
|
||
/// <summary> | ||
/// Gets all GPG keys for the authenticated user. | ||
/// </summary> | ||
/// <param name="options">Options for changing the API response</param> | ||
/// <remarks> | ||
/// See the <a href="https://developer.github.com/v3/users/gpg_keys/#list-your-gpg-keys">API documentation</a> for more information. | ||
/// </remarks> | ||
/// <returns>A <see cref="IReadOnlyList{GpgKey}"/> of <see cref="GpgKey"/>s for the current user.</returns> | ||
public IObservable<GpgKey> GetAllForCurrent(ApiOptions options) | ||
{ | ||
return _client.GetAllForCurrent(options).ToObservable().SelectMany(k => k); | ||
} | ||
|
||
/// <summary> | ||
/// View extended details of the <see cref="GpgKey"/> for the specified id. | ||
/// </summary> | ||
/// <param name="id">The ID of the GPG key</param> | ||
/// <remarks> | ||
/// See the <a href="https://developer.github.com/v3/users/gpg_keys/#get-a-single-gpg-key">API documentation</a> for more information. | ||
/// </remarks> | ||
/// <returns>The <see cref="GpgKey"/> for the specified ID.</returns> | ||
public IObservable<GpgKey> Get(int id) | ||
{ | ||
return _client.Get(id).ToObservable(); | ||
} | ||
|
||
/// <summary> | ||
/// Creates a new <see cref="GpgKey"/> for the authenticated user. | ||
/// </summary> | ||
/// <param name="newGpgKey">The new GPG key to add.</param> | ||
/// <remarks> | ||
/// See the <a href="https://developer.github.com/v3/users/gpg_keys/#create-a-gpg-key">API documentation</a> for more information. | ||
/// </remarks> | ||
/// <returns>The newly created <see cref="GpgKey"/>.</returns> | ||
public IObservable<GpgKey> Create(NewGpgKey newGpgKey) | ||
{ | ||
Ensure.ArgumentNotNull(newGpgKey, "newGpgKey"); | ||
|
||
return _client.Create(newGpgKey).ToObservable(); | ||
} | ||
|
||
/// <summary> | ||
/// Deletes the GPG key for the specified ID. | ||
/// </summary> | ||
/// <param name="id">The ID of the GPG key to delete.</param> | ||
/// <remarks> | ||
/// See the <a href="https://developer.github.com/v3/users/gpg_keys/#delete-a-gpg-key">API documentation</a> for more information. | ||
/// </remarks> | ||
/// <returns></returns> | ||
public IObservable<Unit> Delete(int id) | ||
{ | ||
return _client.Delete(id).ToObservable(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
102 changes: 102 additions & 0 deletions
102
Octokit.Tests.Integration/Clients/UserGpgKeysClientTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using Octokit.Tests.Integration.Helpers; | ||
using Xunit; | ||
|
||
namespace Octokit.Tests.Integration.Clients | ||
{ | ||
public class UserGpgKeysClientTests | ||
{ | ||
readonly string knownKeyId = "E88402D2E127A23A"; | ||
readonly string knownPublicKey = "xsBNBFdTvCUBCADOaVtPoJTQOgMIVYEpI8uT60LA/kDqw/1OKn7ftKjAtxNVSgjQi/ZqZp8XKjTg2u6l4c/aPjER2BGTg90xCcbmpwq/kkQuHR4DK7dOlEOoTzDDESEFv6XXlXGCnxN8AD8YNvSO+Sy4+35ihuKUBAHDxmOl7ZAMH0STo10KuW82/DhfT3cCJNqmID7H+CW1H6IhwutPKt8XsVq2FQg2RMx+uX1KqkuBAd7b30KJ93SJqzgq5CC3DticaC0/WdZnxmYD01UvMAS6o/REs+SICdsyTxgBx/X8SIXuX2TD9PG/O2785JI5/xvBd4jU6bBH/4oWoHr3e/lyNqb1+GSeTFX3ABEBAAE="; | ||
|
||
readonly string publicKey = @" | ||
-----BEGIN PGP PUBLIC KEY BLOCK----- | ||
Version: BCPG C# v1.6.1.0 | ||
mQENBFdTvCUBCADOaVtPoJTQOgMIVYEpI8uT60LA/kDqw/1OKn7ftKjAtxNVSgjQ | ||
i/ZqZp8XKjTg2u6l4c/aPjER2BGTg90xCcbmpwq/kkQuHR4DK7dOlEOoTzDDESEF | ||
v6XXlXGCnxN8AD8YNvSO+Sy4+35ihuKUBAHDxmOl7ZAMH0STo10KuW82/DhfT3cC | ||
JNqmID7H+CW1H6IhwutPKt8XsVq2FQg2RMx+uX1KqkuBAd7b30KJ93SJqzgq5CC3 | ||
DticaC0/WdZnxmYD01UvMAS6o/REs+SICdsyTxgBx/X8SIXuX2TD9PG/O2785JI5 | ||
/xvBd4jU6bBH/4oWoHr3e/lyNqb1+GSeTFX3ABEBAAG0AIkBHAQQAQIABgUCV1O8 | ||
JQAKCRDohALS4SeiOs/QB/9PMeFNdPkB1xfBm3qvTErqvhTcQspPibucYefG6JHL | ||
vhm6iCOVBeCuPS4P/T8RTzb0qJaTdZZWcwZ9UjRVqF/RKwdMJTBKBHRegc5hRjLH | ||
Koxk0zXosk+CapIR6eVhHe4IzpVVxZOvunsFOclIh+qHx9UzJhz9wSO/XBn/6Rzr | ||
DGzE9fpK1JRKC0I3PuiDCNuZvojXeUsT/zuHYsz00wnA2Em7CmcWWng3nPUSHvBB | ||
GUJ7YE7NvYXqT09PdhoZnf9p1wOugiuG6CLzWf8stlNV3mZptpP+sCGcz/UVffRO | ||
VO/+BCBsaoT4g1FFOmJhbBAD3G72yslBnUJmqKP/39pi | ||
=O7Yi | ||
-----END PGP PUBLIC KEY BLOCK----- | ||
"; | ||
|
||
[IntegrationTest] | ||
public async Task CanGetAllForCurrentUser() | ||
{ | ||
var github = Helper.GetBasicAuthClient(); | ||
|
||
using (var context = await github.CreateGpgKeyContext()) | ||
{ | ||
var keys = await github.User.GpgKey.GetAllForCurrent(); | ||
Assert.NotEmpty(keys); | ||
|
||
var first = keys[0]; | ||
Assert.NotNull(first.Id); | ||
Assert.NotNull(first.KeyId); | ||
Assert.NotNull(first.PublicKey); | ||
Assert.Null(first.PrimaryKeyId); | ||
Assert.Empty(first.Subkeys); | ||
} | ||
} | ||
|
||
[IntegrationTest] | ||
public async Task CanGetKeyById() | ||
{ | ||
var github = Helper.GetBasicAuthClient(); | ||
using (var context = await github.CreateGpgKeyContext()) | ||
{ | ||
var key = await github.User.GpgKey.Get(context.GpgKeyId); | ||
|
||
Assert.Equal(context.GpgKeyId, key.Id); | ||
Assert.Equal(context.KeyId, key.KeyId); | ||
Assert.Equal(context.PublicKeyData, key.PublicKey); | ||
} | ||
} | ||
|
||
[IntegrationTest] | ||
public async Task CanCreateAndDeleteKey() | ||
{ | ||
var github = Helper.GetBasicAuthClient(); | ||
|
||
var key = await github.User.GpgKey.Create(new NewGpgKey(publicKey)); | ||
Assert.NotNull(key); | ||
Assert.Equal(knownPublicKey, key.PublicKey); | ||
Assert.Equal(knownKeyId, key.KeyId); | ||
|
||
// Delete the key | ||
await github.User.GpgKey.Delete(key.Id); | ||
|
||
// Verify key no longer exists | ||
var keys = await github.User.GpgKey.GetAllForCurrent(); | ||
Assert.False(keys.Any(k => k.KeyId == knownKeyId && k.PublicKey == knownPublicKey)); | ||
} | ||
|
||
[IntegrationTest] | ||
public async Task CanNotCreateSameKeyTwice() | ||
{ | ||
var github = Helper.GetBasicAuthClient(); | ||
|
||
var key = await github.User.GpgKey.Create(new NewGpgKey(publicKey)); | ||
Assert.NotNull(key); | ||
|
||
Assert.ThrowsAsync<ApiValidationException>(async () => await github.User.GpgKey.Create(new NewGpgKey(publicKey))); | ||
|
||
await github.User.GpgKey.Delete(key.Id); | ||
var keys = await github.User.GpgKey.GetAllForCurrent(); | ||
Assert.False(keys.Any(k => k.KeyId == knownKeyId && k.PublicKey == knownPublicKey)); | ||
} | ||
} | ||
} |
Oops, something went wrong.