mirror of
https://github.com/zoriya/octokit.net.git
synced 2025-12-06 07:16:09 +00:00
Add client for organization outside collaborators (#1639)
* Add client for organization outside collaborators * Add unit/integration tests * Add methods for removing an outside collaborator * Add unit/integration tests * Add new Put method to Connection which accepts a preview header * Add methods for converting an org member to an outside collaborator * Fix copy paste errors in new exceptions * According to API docs, a 403 should be returned if the member is not a member of the org, but a 404 is actually returned * Add unit/integration tests * Remove unused using directives * Got a bit overzealous with my removal of using directives * Fix integration tests by using the configured Organization and test username rather than henrik's :) * Remove ApiOptions overloads as it isn't currently supported * Fix XML doc grammar * Fix failing unit tests * Missed a couple of nameof replacements
This commit is contained in:
committed by
Ryan Gribble
parent
cda714bef6
commit
1d1ca0a572
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Octokit.Reactive
|
||||
{
|
||||
public interface IObservableOrganizationOutsideCollaboratorsClient
|
||||
{
|
||||
/// <summary>
|
||||
/// List all users who are outside collaborators of an organization. An outside collaborator is a user that
|
||||
/// is not a member of the organization.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the <a href="https://developer.github.com/v3/orgs/outside_collaborators/#list-outside-collaborators">API documentation</a>
|
||||
/// for more information.
|
||||
/// </remarks>
|
||||
/// <param name="org">The login for the organization</param>
|
||||
/// <returns>The users</returns>
|
||||
IObservable<User> GetAll(string org);
|
||||
|
||||
/// <summary>
|
||||
/// List all users who are outside collaborators of an organization. An outside collaborator is a user that
|
||||
/// is not a member of the organization.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the <a href="https://developer.github.com/v3/orgs/outside_collaborators/#list-outside-collaborators">API documentation</a>
|
||||
/// for more information.
|
||||
/// </remarks>
|
||||
/// <param name="org">The login for the organization</param>
|
||||
/// <param name="filter">The filter to use when getting the users, <see cref="OrganizationMembersFilter"/></param>
|
||||
/// <returns>The users</returns>
|
||||
IObservable<User> GetAll(string org, OrganizationMembersFilter filter);
|
||||
|
||||
/// <summary>
|
||||
/// Removes a user as an outside collaborator from the organization, this will remove them from all repositories
|
||||
/// within the organization.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the <a href="https://developer.github.com/v3/orgs/outside_collaborators/#remove-outside-collaborator">API documentation</a>
|
||||
/// for more information.
|
||||
/// </remarks>
|
||||
/// <param name="org">The login for the organization</param>
|
||||
/// <param name="user">The login of the user</param>
|
||||
/// <returns></returns>
|
||||
IObservable<bool> Delete(string org, string user);
|
||||
|
||||
/// <summary>
|
||||
/// Converts an organization member to an outside collaborator,
|
||||
/// when an organization member is converted to an outside collaborator,
|
||||
/// they'll only have access to the repositories that their current team membership allows.
|
||||
/// The user will no longer be a member of the organization.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the <a href="https://developer.github.com/v3/orgs/outside_collaborators/#convert-member-to-outside-collaborator"> API documentation</a>
|
||||
/// for more information.
|
||||
/// </remarks>
|
||||
/// <param name="org">The login for the organization</param>
|
||||
/// <param name="user">The login for the user</param>
|
||||
/// <returns></returns>
|
||||
IObservable<bool> ConvertFromMember(string org, string user);
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,11 @@ namespace Octokit.Reactive
|
||||
/// </summary>
|
||||
IObservableTeamsClient Team { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns a client to manage outside collaborators of an organization.
|
||||
/// </summary>
|
||||
IObservableOrganizationOutsideCollaboratorsClient OutsideCollaborator { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the specified organization.
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using System.Reactive.Threading.Tasks;
|
||||
using Octokit.Reactive.Internal;
|
||||
|
||||
namespace Octokit.Reactive
|
||||
{
|
||||
public class ObservableOrganizationOutsideCollaboratorsClient : IObservableOrganizationOutsideCollaboratorsClient
|
||||
{
|
||||
readonly IOrganizationOutsideCollaboratorsClient _client;
|
||||
readonly IConnection _connection;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new Organization Outside Collaborators API client.
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
public ObservableOrganizationOutsideCollaboratorsClient(IGitHubClient client)
|
||||
{
|
||||
Ensure.ArgumentNotNull(client, nameof(client));
|
||||
|
||||
_client = client.Organization.OutsideCollaborator;
|
||||
_connection = client.Connection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List all users who are outside collaborators of an organization. An outside collaborator is a user that
|
||||
/// is not a member of the organization.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the <a href="https://developer.github.com/v3/orgs/outside_collaborators/#list-outside-collaborators">API documentation</a>
|
||||
/// for more information.
|
||||
/// </remarks>
|
||||
/// <param name="org">The login for the organization</param>
|
||||
/// <returns>The users</returns>
|
||||
public IObservable<User> GetAll(string org)
|
||||
{
|
||||
Ensure.ArgumentNotNullOrEmptyString(org, nameof(org));
|
||||
|
||||
return _connection.GetAndFlattenAllPages<User>(ApiUrls.OutsideCollaborators(org), null, AcceptHeaders.OrganizationMembershipPreview);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List all users who are outside collaborators of an organization. An outside collaborator is a user that
|
||||
/// is not a member of the organization.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the <a href="https://developer.github.com/v3/orgs/outside_collaborators/#list-outside-collaborators">API documentation</a>
|
||||
/// for more information.
|
||||
/// </remarks>
|
||||
/// <param name="org">The login for the organization</param>
|
||||
/// <param name="filter">The filter to use when getting the users, <see cref="OrganizationMembersFilter"/></param>
|
||||
/// <returns>The users</returns>
|
||||
public IObservable<User> GetAll(string org, OrganizationMembersFilter filter)
|
||||
{
|
||||
Ensure.ArgumentNotNullOrEmptyString(org, nameof(org));
|
||||
|
||||
return _connection.GetAndFlattenAllPages<User>(ApiUrls.OutsideCollaborators(org, filter), null, AcceptHeaders.OrganizationMembershipPreview);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a user as an outside collaborator from the organization, this will remove them from all repositories
|
||||
/// within the organization.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the <a href="https://developer.github.com/v3/orgs/outside_collaborators/#remove-outside-collaborator">API documentation</a>
|
||||
/// for more information.
|
||||
/// </remarks>
|
||||
/// <param name="org">The login for the organization</param>
|
||||
/// <param name="user">The login of the user</param>
|
||||
/// <returns></returns>
|
||||
public IObservable<bool> Delete(string org, string user)
|
||||
{
|
||||
Ensure.ArgumentNotNullOrEmptyString(org, nameof(org));
|
||||
Ensure.ArgumentNotNullOrEmptyString(user, nameof(user));
|
||||
|
||||
return _client.Delete(org, user).ToObservable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts an organization member to an outside collaborator,
|
||||
/// when an organization member is converted to an outside collaborator,
|
||||
/// they'll only have access to the repositories that their current team membership allows.
|
||||
/// The user will no longer be a member of the organization.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the <a href="https://developer.github.com/v3/orgs/outside_collaborators/#convert-member-to-outside-collaborator"> API documentation</a>
|
||||
/// for more information.
|
||||
/// </remarks>
|
||||
/// <param name="org">The login for the organization</param>
|
||||
/// <param name="user">The login for the user</param>
|
||||
/// <returns></returns>
|
||||
public IObservable<bool> ConvertFromMember(string org, string user)
|
||||
{
|
||||
Ensure.ArgumentNotNullOrEmptyString(org, nameof(org));
|
||||
Ensure.ArgumentNotNullOrEmptyString(user, nameof(user));
|
||||
|
||||
return _client.ConvertFromMember(org, user).ToObservable();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ namespace Octokit.Reactive
|
||||
|
||||
Member = new ObservableOrganizationMembersClient(client);
|
||||
Team = new ObservableTeamsClient(client);
|
||||
OutsideCollaborator = new ObservableOrganizationOutsideCollaboratorsClient(client);
|
||||
|
||||
_client = client.Organization;
|
||||
_connection = client.Connection;
|
||||
@@ -34,6 +35,11 @@ namespace Octokit.Reactive
|
||||
/// </summary>
|
||||
public IObservableTeamsClient Team { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns a client to manage outside collaborators of an organization.
|
||||
/// </summary>
|
||||
public IObservableOrganizationOutsideCollaboratorsClient OutsideCollaborator { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the specified organization.
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Octokit.Tests.Integration.Helpers;
|
||||
using Xunit;
|
||||
|
||||
namespace Octokit.Tests.Integration.Clients
|
||||
{
|
||||
public class OrganizationOutsideCollaboratorsClientTests
|
||||
{
|
||||
public class TheGetAllMethod
|
||||
{
|
||||
readonly IGitHubClient _gitHub;
|
||||
readonly string _fixtureCollaborator = "alfhenrik-test-2";
|
||||
public TheGetAllMethod()
|
||||
{
|
||||
_gitHub = Helper.GetAuthenticatedClient();
|
||||
}
|
||||
|
||||
[IntegrationTest]
|
||||
public async Task ReturnsNoOutsideCollaborators()
|
||||
{
|
||||
var repoName = Helper.MakeNameWithTimestamp("public-repo");
|
||||
using (var context = await _gitHub.CreateRepositoryContext(Helper.Organization, new NewRepository(repoName)))
|
||||
{
|
||||
var outsideCollaborators = await _gitHub.Organization
|
||||
.OutsideCollaborator
|
||||
.GetAll(Helper.Organization);
|
||||
|
||||
Assert.NotNull(outsideCollaborators);
|
||||
Assert.Empty(outsideCollaborators);
|
||||
}
|
||||
}
|
||||
|
||||
[IntegrationTest]
|
||||
public async Task ReturnsOutsideCollaborators()
|
||||
{
|
||||
var repoName = Helper.MakeNameWithTimestamp("public-repo");
|
||||
using (var context = await _gitHub.CreateRepositoryContext(Helper.Organization, new NewRepository(repoName)))
|
||||
{
|
||||
await _gitHub.Repository.Collaborator.Add(context.RepositoryOwner, context.RepositoryName, _fixtureCollaborator);
|
||||
|
||||
var outsideCollaborators = await _gitHub.Organization
|
||||
.OutsideCollaborator
|
||||
.GetAll(Helper.Organization);
|
||||
|
||||
Assert.NotNull(outsideCollaborators);
|
||||
Assert.Equal(1, outsideCollaborators.Count);
|
||||
}
|
||||
}
|
||||
|
||||
[IntegrationTest]
|
||||
public async Task ReturnsCorrectCountOfOutsideCollaboratorsWithAllFilter()
|
||||
{
|
||||
var repoName = Helper.MakeNameWithTimestamp("public-repo");
|
||||
using (var context = await _gitHub.CreateRepositoryContext(Helper.Organization, new NewRepository(repoName)))
|
||||
{
|
||||
await _gitHub.Repository.Collaborator.Add(context.RepositoryOwner, context.RepositoryName, _fixtureCollaborator);
|
||||
await _gitHub.Repository.Collaborator.Add(context.RepositoryOwner, context.RepositoryName, "alfhenrik");
|
||||
|
||||
var outsideCollaborators = await _gitHub.Organization
|
||||
.OutsideCollaborator
|
||||
.GetAll(Helper.Organization, OrganizationMembersFilter.All);
|
||||
|
||||
Assert.NotNull(outsideCollaborators);
|
||||
Assert.Equal(2, outsideCollaborators.Count);
|
||||
}
|
||||
}
|
||||
|
||||
[IntegrationTest]
|
||||
public async Task ReturnsCorrectCountOfOutsideCollaboratorsWithTwoFactorFilter()
|
||||
{
|
||||
var repoName = Helper.MakeNameWithTimestamp("public-repo");
|
||||
using (var context = await _gitHub.CreateRepositoryContext(Helper.Organization, new NewRepository(repoName)))
|
||||
{
|
||||
await _gitHub.Repository.Collaborator.Add(context.RepositoryOwner, context.RepositoryName, _fixtureCollaborator);
|
||||
await _gitHub.Repository.Collaborator.Add(context.RepositoryOwner, context.RepositoryName, "alfhenrik");
|
||||
|
||||
var outsideCollaborators = await _gitHub.Organization
|
||||
.OutsideCollaborator
|
||||
.GetAll(Helper.Organization, OrganizationMembersFilter.TwoFactorAuthenticationDisabled);
|
||||
|
||||
Assert.NotNull(outsideCollaborators);
|
||||
Assert.Equal(1, outsideCollaborators.Count);
|
||||
Assert.Equal(_fixtureCollaborator, outsideCollaborators[0].Login);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TheDeleteMethod
|
||||
{
|
||||
readonly IGitHubClient _gitHub;
|
||||
readonly string _fixtureCollaborator = "alfhenrik-test-2";
|
||||
|
||||
public TheDeleteMethod()
|
||||
{
|
||||
_gitHub = Helper.GetAuthenticatedClient();
|
||||
}
|
||||
|
||||
[IntegrationTest]
|
||||
public async Task CanRemoveOutsideCollaborator()
|
||||
{
|
||||
var repoName = Helper.MakeNameWithTimestamp("public-repo");
|
||||
using (var context = await _gitHub.CreateRepositoryContext(Helper.Organization, new NewRepository(repoName)))
|
||||
{
|
||||
await _gitHub.Repository.Collaborator.Add(context.RepositoryOwner, context.RepositoryName, _fixtureCollaborator);
|
||||
|
||||
var result = await _gitHub
|
||||
.Organization
|
||||
.OutsideCollaborator
|
||||
.Delete(Helper.Organization, _fixtureCollaborator);
|
||||
|
||||
Assert.True(result);
|
||||
|
||||
var outsideCollaborators = await _gitHub
|
||||
.Organization
|
||||
.OutsideCollaborator
|
||||
.GetAll(Helper.Organization);
|
||||
|
||||
Assert.NotNull(outsideCollaborators);
|
||||
Assert.Empty(outsideCollaborators);
|
||||
}
|
||||
}
|
||||
|
||||
[IntegrationTest]
|
||||
public async Task CannotRemoveMemberOfOrganizationAsOutsideCollaborator()
|
||||
{
|
||||
var ex = await Assert.ThrowsAsync<UserIsOrganizationMemberException>(()
|
||||
=> _gitHub.Organization.OutsideCollaborator.Delete(Helper.Organization, Helper.UserName));
|
||||
|
||||
Assert.True(string.Equals(
|
||||
"You cannot specify an organization member to remove as an outside collaborator.",
|
||||
ex.Message,
|
||||
StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
|
||||
public class TheConvertFromMemberMethod
|
||||
{
|
||||
readonly IGitHubClient _gitHub;
|
||||
readonly string _fixtureCollaborator = "alfhenrik-test-2";
|
||||
|
||||
public TheConvertFromMemberMethod()
|
||||
{
|
||||
_gitHub = Helper.GetAuthenticatedClient();
|
||||
}
|
||||
|
||||
[IntegrationTest(Skip = "This test relies on https://github.com/octokit/octokit.net/issues/1533 being implemented before being re-enabled as there's currently no way to invite a member to an org")]
|
||||
public async Task CanConvertOrgMemberToOutsideCollaborator()
|
||||
{
|
||||
var result = await _gitHub.Organization.OutsideCollaborator.ConvertFromMember(Helper.Organization, _fixtureCollaborator);
|
||||
Assert.True(result);
|
||||
|
||||
var outsideCollaborators = await _gitHub.Organization.OutsideCollaborator.GetAll(Helper.Organization);
|
||||
|
||||
Assert.Equal(1, outsideCollaborators.Count);
|
||||
Assert.Equal(_fixtureCollaborator, outsideCollaborators[0].Login);
|
||||
}
|
||||
|
||||
[IntegrationTest]
|
||||
public async Task CannotConvertNonOrgMemberToOutsideCollaborator()
|
||||
{
|
||||
var ex = await Assert.ThrowsAsync<UserIsNotMemberOfOrganizationException>(()
|
||||
=> _gitHub.Organization.OutsideCollaborator.ConvertFromMember(Helper.Organization, _fixtureCollaborator));
|
||||
|
||||
Assert.True(string.Equals(
|
||||
$"{_fixtureCollaborator} is not a member of the {Helper.Organization} organization.",
|
||||
ex.Message,
|
||||
StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
[IntegrationTest]
|
||||
public async Task CannotConvertLastOrgOwnerToOutsideCollaborator()
|
||||
{
|
||||
var ex = await Assert.ThrowsAsync<UserIsLastOwnerOfOrganizationException>(()
|
||||
=> _gitHub.Organization.OutsideCollaborator.ConvertFromMember(Helper.Organization, Helper.UserName));
|
||||
|
||||
Assert.True(string.Equals(
|
||||
"Cannot convert the last owner to an outside collaborator",
|
||||
ex.Message,
|
||||
StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
using System.Reactive.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Octokit.Reactive;
|
||||
using Octokit.Tests.Integration.Helpers;
|
||||
using Xunit;
|
||||
|
||||
namespace Octokit.Tests.Integration.Reactive
|
||||
{
|
||||
public class ObservableOrganizationOutsideCollaboratorsClientTests
|
||||
{
|
||||
public class TheGetAllMethod
|
||||
{
|
||||
readonly IGitHubClient _gitHub;
|
||||
readonly ObservableOrganizationOutsideCollaboratorsClient _client;
|
||||
readonly string _fixtureCollaborator = "alfhenrik-test-2";
|
||||
|
||||
public TheGetAllMethod()
|
||||
{
|
||||
_gitHub = Helper.GetAuthenticatedClient();
|
||||
_client = new ObservableOrganizationOutsideCollaboratorsClient(_gitHub);
|
||||
}
|
||||
|
||||
[IntegrationTest]
|
||||
public async Task ReturnsNoOutsideCollaborators()
|
||||
{
|
||||
var outsideCollaborators = await _client
|
||||
.GetAll(Helper.Organization).ToList();
|
||||
|
||||
Assert.NotNull(outsideCollaborators);
|
||||
Assert.Empty(outsideCollaborators);
|
||||
}
|
||||
|
||||
[IntegrationTest]
|
||||
public async Task ReturnsOutsideCollaborators()
|
||||
{
|
||||
var repoName = Helper.MakeNameWithTimestamp("public-repo");
|
||||
using (var context = await _gitHub.CreateRepositoryContext(Helper.Organization, new NewRepository(repoName)))
|
||||
{
|
||||
await _gitHub.Repository.Collaborator.Add(context.RepositoryOwner, context.RepositoryName, _fixtureCollaborator);
|
||||
|
||||
var outsideCollaborators = await _client
|
||||
.GetAll(Helper.Organization).ToList();
|
||||
|
||||
Assert.NotNull(outsideCollaborators);
|
||||
Assert.Equal(1, outsideCollaborators.Count);
|
||||
}
|
||||
}
|
||||
|
||||
[IntegrationTest]
|
||||
public async Task ReturnsCorrectCountOfOutsideCollaboratorsWithAllFilter()
|
||||
{
|
||||
var repoName = Helper.MakeNameWithTimestamp("public-repo");
|
||||
using (var context = await _gitHub.CreateRepositoryContext(Helper.Organization, new NewRepository(repoName)))
|
||||
{
|
||||
await _gitHub.Repository.Collaborator.Add(context.RepositoryOwner, context.RepositoryName, _fixtureCollaborator);
|
||||
await _gitHub.Repository.Collaborator.Add(context.RepositoryOwner, context.RepositoryName, "alfhenrik");
|
||||
|
||||
var outsideCollaborators = await _client
|
||||
.GetAll(Helper.Organization, OrganizationMembersFilter.All).ToList();
|
||||
|
||||
Assert.NotNull(outsideCollaborators);
|
||||
Assert.Equal(2, outsideCollaborators.Count);
|
||||
}
|
||||
}
|
||||
|
||||
[IntegrationTest]
|
||||
public async Task ReturnsCorrectCountOfOutsideCollaboratorsWithTwoFactorFilter()
|
||||
{
|
||||
var repoName = Helper.MakeNameWithTimestamp("public-repo");
|
||||
using (var context = await _gitHub.CreateRepositoryContext(Helper.Organization, new NewRepository(repoName)))
|
||||
{
|
||||
await _gitHub.Repository.Collaborator.Add(context.RepositoryOwner, context.RepositoryName, _fixtureCollaborator);
|
||||
await _gitHub.Repository.Collaborator.Add(context.RepositoryOwner, context.RepositoryName, "alfhenrik");
|
||||
|
||||
var outsideCollaborators = await _client
|
||||
.GetAll(Helper.Organization, OrganizationMembersFilter.TwoFactorAuthenticationDisabled).ToList();
|
||||
|
||||
Assert.NotNull(outsideCollaborators);
|
||||
Assert.Equal(1, outsideCollaborators.Count);
|
||||
Assert.Equal("alfhenrik-test-2", outsideCollaborators[0].Login);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TheDeleteMethod
|
||||
{
|
||||
readonly IGitHubClient _gitHub;
|
||||
readonly ObservableOrganizationOutsideCollaboratorsClient _client;
|
||||
readonly string _fixtureCollaborator = "alfhenrik-test-2";
|
||||
|
||||
public TheDeleteMethod()
|
||||
{
|
||||
_gitHub = Helper.GetAuthenticatedClient();
|
||||
_client = new ObservableOrganizationOutsideCollaboratorsClient(_gitHub);
|
||||
}
|
||||
|
||||
[IntegrationTest]
|
||||
public async Task CanRemoveOutsideCollaborator()
|
||||
{
|
||||
var repoName = Helper.MakeNameWithTimestamp("public-repo");
|
||||
using (var context = await _gitHub.CreateRepositoryContext(Helper.Organization, new NewRepository(repoName)))
|
||||
{
|
||||
await _gitHub.Repository.Collaborator.Add(context.RepositoryOwner, context.RepositoryName, _fixtureCollaborator);
|
||||
|
||||
var result = await _client.Delete(Helper.Organization, _fixtureCollaborator);
|
||||
Assert.True(result);
|
||||
|
||||
var outsideCollaborators = await _client
|
||||
.GetAll(Helper.Organization).ToList();
|
||||
|
||||
Assert.Empty(outsideCollaborators);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TheConvertFromMemberMethod
|
||||
{
|
||||
readonly IGitHubClient _gitHub;
|
||||
readonly ObservableOrganizationOutsideCollaboratorsClient _client;
|
||||
readonly string _fixtureCollaborator = "alfhenrik-test-2";
|
||||
|
||||
public TheConvertFromMemberMethod()
|
||||
{
|
||||
_gitHub = Helper.GetAuthenticatedClient();
|
||||
_client = new ObservableOrganizationOutsideCollaboratorsClient(_gitHub);
|
||||
}
|
||||
|
||||
[IntegrationTest(Skip = "This test relies on https://github.com/octokit/octokit.net/issues/1533 being implemented before being re-enabled as there's currently no way to invite a member to an org")]
|
||||
public async Task CanConvertOrgMemberToOutsideCollaborator()
|
||||
{
|
||||
var result = await _client.ConvertFromMember(Helper.Organization, _fixtureCollaborator);
|
||||
Assert.True(result);
|
||||
|
||||
var outsideCollaborators = await _client
|
||||
.GetAll(Helper.Organization).ToList();
|
||||
|
||||
Assert.Equal(1, outsideCollaborators.Count);
|
||||
Assert.Equal(_fixtureCollaborator, outsideCollaborators[0].Login);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
|
||||
namespace Octokit.Tests.Clients
|
||||
{
|
||||
public class OrganizationOutsideCollaboratorsClientTests
|
||||
{
|
||||
public class TheCtor
|
||||
{
|
||||
[Fact]
|
||||
public void EnsuresNonNullArguments()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => new OrganizationOutsideCollaboratorsClient(null));
|
||||
}
|
||||
}
|
||||
|
||||
public class TheGetAllMethod
|
||||
{
|
||||
[Fact]
|
||||
public void RequestsTheCorrectUrl()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new OrganizationOutsideCollaboratorsClient(connection);
|
||||
|
||||
client.GetAll("org");
|
||||
|
||||
connection.Received().GetAll<User>(Arg.Is<Uri>(u => u.ToString() == "orgs/org/outside_collaborators"), null, "application/vnd.github.korra-preview+json");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task EnsuresNonNullArguments()
|
||||
{
|
||||
var client = new OrganizationOutsideCollaboratorsClient(Substitute.For<IApiConnection>());
|
||||
|
||||
|
||||
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAll(null));
|
||||
|
||||
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAll(null, OrganizationMembersFilter.All));
|
||||
|
||||
await Assert.ThrowsAsync<ArgumentException>(() => client.GetAll(""));
|
||||
await Assert.ThrowsAsync<ArgumentException>(() => client.GetAll("", OrganizationMembersFilter.All));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AllFilterRequestsTheCorrectUrl()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new OrganizationOutsideCollaboratorsClient(connection);
|
||||
|
||||
client.GetAll("org", OrganizationMembersFilter.All);
|
||||
|
||||
connection.Received().GetAll<User>(Arg.Is<Uri>(u => u.ToString() == "orgs/org/outside_collaborators?filter=all"), null, "application/vnd.github.korra-preview+json");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TwoFactorFilterRequestsTheCorrectUrl()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new OrganizationOutsideCollaboratorsClient(connection);
|
||||
|
||||
client.GetAll("org", OrganizationMembersFilter.TwoFactorAuthenticationDisabled);
|
||||
|
||||
connection.Received().GetAll<User>(Arg.Is<Uri>(u => u.ToString() == "orgs/org/outside_collaborators?filter=2fa_disabled"), null, "application/vnd.github.korra-preview+json");
|
||||
}
|
||||
}
|
||||
|
||||
public class TheDeleteMethod
|
||||
{
|
||||
[Fact]
|
||||
public void RequestsTheCorrectUrl()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new OrganizationOutsideCollaboratorsClient(connection);
|
||||
|
||||
client.Delete("org", "user");
|
||||
|
||||
connection.Connection.Received().Delete(
|
||||
Arg.Is<Uri>(u => u.ToString() == "orgs/org/outside_collaborators/user"),
|
||||
Arg.Any<object>(),
|
||||
"application/vnd.github.korra-preview+json");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task EnsuresNonNullArguments()
|
||||
{
|
||||
var client = new OrganizationOutsideCollaboratorsClient(Substitute.For<IApiConnection>());
|
||||
|
||||
await Assert.ThrowsAsync<ArgumentNullException>(() => client.Delete(null, "user"));
|
||||
await Assert.ThrowsAsync<ArgumentNullException>(() => client.Delete("org", null));
|
||||
|
||||
await Assert.ThrowsAsync<ArgumentException>(() => client.Delete("", "user"));
|
||||
await Assert.ThrowsAsync<ArgumentException>(() => client.Delete("org", ""));
|
||||
}
|
||||
}
|
||||
|
||||
public class TheConvertFromMemberMethod
|
||||
{
|
||||
[Fact]
|
||||
public void RequestsTheCorrectUrl()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new OrganizationOutsideCollaboratorsClient(connection);
|
||||
|
||||
client.ConvertFromMember("org", "user");
|
||||
|
||||
connection.Connection.Received().Put(
|
||||
Arg.Is<Uri>(u => u.ToString() == "orgs/org/outside_collaborators/user"),
|
||||
"application/vnd.github.korra-preview+json");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task EnsuresNonNullArgument()
|
||||
{
|
||||
var client = new OrganizationOutsideCollaboratorsClient(Substitute.For<IApiConnection>());
|
||||
|
||||
await Assert.ThrowsAsync<ArgumentNullException>(() => client.ConvertFromMember(null, "user"));
|
||||
await Assert.ThrowsAsync<ArgumentNullException>(() => client.ConvertFromMember("org", null));
|
||||
|
||||
await Assert.ThrowsAsync<ArgumentException>(() => client.ConvertFromMember("", "user"));
|
||||
await Assert.ThrowsAsync<ArgumentException>(() => client.ConvertFromMember("org", ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using NSubstitute;
|
||||
using Octokit.Reactive;
|
||||
using Xunit;
|
||||
|
||||
namespace Octokit.Tests.Reactive
|
||||
{
|
||||
public class ObservableOrganizationOutsideCollaboratorsClientTests
|
||||
{
|
||||
public class TheCtor
|
||||
{
|
||||
[Fact]
|
||||
public void EnsuresNonNullArguments()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(()
|
||||
=> new ObservableOrganizationOutsideCollaboratorsClient(null));
|
||||
}
|
||||
}
|
||||
|
||||
public class TheGetAllMethod
|
||||
{
|
||||
[Fact]
|
||||
public void RequestsTheCorrectUrl()
|
||||
{
|
||||
var gitHubClient = Substitute.For<IGitHubClient>();
|
||||
var client = new ObservableOrganizationOutsideCollaboratorsClient(gitHubClient);
|
||||
|
||||
client.GetAll("org");
|
||||
|
||||
gitHubClient.Connection.Received(1).Get<List<User>>(
|
||||
Arg.Is<Uri>(u => u.ToString() == "orgs/org/outside_collaborators"),
|
||||
null,
|
||||
"application/vnd.github.korra-preview+json");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task EnsuresNonNullArguments()
|
||||
{
|
||||
var client = new ObservableOrganizationOutsideCollaboratorsClient(Substitute.For<IGitHubClient>());
|
||||
|
||||
|
||||
Assert.Throws<ArgumentNullException>(() => client.GetAll(null));
|
||||
|
||||
Assert.Throws<ArgumentNullException>(() => client.GetAll(null, OrganizationMembersFilter.All));
|
||||
|
||||
Assert.Throws<ArgumentException>(() => client.GetAll(""));
|
||||
Assert.Throws<ArgumentException>(() => client.GetAll("", OrganizationMembersFilter.All));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AllFilterRequestsTheCorrectUrl()
|
||||
{
|
||||
var gitHubClient = Substitute.For<IGitHubClient>();
|
||||
var client = new ObservableOrganizationOutsideCollaboratorsClient(gitHubClient);
|
||||
|
||||
client.GetAll("org", OrganizationMembersFilter.All);
|
||||
|
||||
gitHubClient.Connection.Received(1).Get<List<User>>(
|
||||
Arg.Is<Uri>(u => u.ToString() == "orgs/org/outside_collaborators?filter=all"),
|
||||
null,
|
||||
"application/vnd.github.korra-preview+json");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TwoFactorFilterRequestsTheCorrectUrl()
|
||||
{
|
||||
var gitHubClient = Substitute.For<IGitHubClient>();
|
||||
var client = new ObservableOrganizationOutsideCollaboratorsClient(gitHubClient);
|
||||
|
||||
client.GetAll("org", OrganizationMembersFilter.TwoFactorAuthenticationDisabled);
|
||||
|
||||
gitHubClient.Connection.Received(1).Get<List<User>>(
|
||||
Arg.Is<Uri>(u => u.ToString() == "orgs/org/outside_collaborators?filter=2fa_disabled"),
|
||||
null,
|
||||
"application/vnd.github.korra-preview+json");
|
||||
}
|
||||
}
|
||||
|
||||
public class TheDeleteMethod
|
||||
{
|
||||
[Fact]
|
||||
public void RequestsTheCorrectUrl()
|
||||
{
|
||||
var gitHubClient = Substitute.For<IGitHubClient>();
|
||||
var client = new ObservableOrganizationOutsideCollaboratorsClient(gitHubClient);
|
||||
|
||||
client.Delete("org", "user");
|
||||
|
||||
gitHubClient.Organization.OutsideCollaborator.Received().Delete(
|
||||
Arg.Is("org"),
|
||||
Arg.Is("user"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EnsuresNonNullArguments()
|
||||
{
|
||||
var client = new ObservableOrganizationOutsideCollaboratorsClient(Substitute.For<IGitHubClient>());
|
||||
|
||||
Assert.Throws<ArgumentNullException>(() => client.Delete(null, "user"));
|
||||
Assert.Throws<ArgumentNullException>(() => client.Delete("org", null));
|
||||
|
||||
Assert.Throws<ArgumentException>(() => client.Delete("", "user"));
|
||||
Assert.Throws<ArgumentException>(() => client.Delete("org", ""));
|
||||
}
|
||||
}
|
||||
|
||||
public class TheConvertFromMemberMethod
|
||||
{
|
||||
[Fact]
|
||||
public void RequestsTheCorrectUrl()
|
||||
{
|
||||
var gitHubClient = Substitute.For<IGitHubClient>();
|
||||
var client = new ObservableOrganizationOutsideCollaboratorsClient(gitHubClient);
|
||||
|
||||
client.ConvertFromMember("org", "user");
|
||||
|
||||
gitHubClient.Organization.OutsideCollaborator.Received().ConvertFromMember(
|
||||
Arg.Is("org"),
|
||||
Arg.Is("user"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EnsuresNonNullArgument()
|
||||
{
|
||||
var client = new ObservableOrganizationOutsideCollaboratorsClient(Substitute.For<IGitHubClient>());
|
||||
|
||||
Assert.Throws<ArgumentNullException>(() => client.ConvertFromMember(null, "user"));
|
||||
Assert.Throws<ArgumentNullException>(() => client.ConvertFromMember("org", null));
|
||||
|
||||
Assert.Throws<ArgumentException>(() => client.ConvertFromMember("", "user"));
|
||||
Assert.Throws<ArgumentException>(() => client.ConvertFromMember("org", ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
61
Octokit/Clients/IOrganizationOutsideCollaboratorsClient.cs
Normal file
61
Octokit/Clients/IOrganizationOutsideCollaboratorsClient.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Octokit
|
||||
{
|
||||
public interface IOrganizationOutsideCollaboratorsClient
|
||||
{
|
||||
/// <summary>
|
||||
/// List all users who are outside collaborators of an organization. An outside collaborator is a user that
|
||||
/// is not a member of the organization.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the <a href="https://developer.github.com/v3/orgs/outside_collaborators/#list-outside-collaborators">API documentation</a>
|
||||
/// for more information.
|
||||
/// </remarks>
|
||||
/// <param name="org">The login for the organization</param>
|
||||
/// <returns>The users</returns>
|
||||
Task<IReadOnlyList<User>> GetAll(string org);
|
||||
|
||||
/// <summary>
|
||||
/// List all users who are outside collaborators of an organization. An outside collaborator is a user that
|
||||
/// is not a member of the organization.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the <a href="https://developer.github.com/v3/orgs/outside_collaborators/#list-outside-collaborators">API documentation</a>
|
||||
/// for more information.
|
||||
/// </remarks>
|
||||
/// <param name="org">The login for the organization</param>
|
||||
/// <param name="filter">The filter to use when getting the users, <see cref="OrganizationMembersFilter"/></param>
|
||||
/// <returns>The users</returns>
|
||||
Task<IReadOnlyList<User>> GetAll(string org, OrganizationMembersFilter filter);
|
||||
|
||||
/// <summary>
|
||||
/// Removes a user as an outside collaborator from the organization, this will remove them from all repositories
|
||||
/// within the organization.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the <a href="https://developer.github.com/v3/orgs/outside_collaborators/#remove-outside-collaborator">API documentation</a>
|
||||
/// for more information.
|
||||
/// </remarks>
|
||||
/// <param name="org">The login for the organization</param>
|
||||
/// <param name="user">The login of the user</param>
|
||||
/// <returns></returns>
|
||||
Task<bool> Delete(string org, string user);
|
||||
|
||||
/// <summary>
|
||||
/// Converts an organization member to an outside collaborator,
|
||||
/// when an organization member is converted to an outside collaborator,
|
||||
/// they'll only have access to the repositories that their current team membership allows.
|
||||
/// The user will no longer be a member of the organization.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the <a href="https://developer.github.com/v3/orgs/outside_collaborators/#convert-member-to-outside-collaborator"> API documentation</a>
|
||||
/// for more information.
|
||||
/// </remarks>
|
||||
/// <param name="org">The login for the organization</param>
|
||||
/// <param name="user">The login for the user</param>
|
||||
/// <returns></returns>
|
||||
Task<bool> ConvertFromMember(string org, string user);
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,11 @@ namespace Octokit
|
||||
/// </summary>
|
||||
ITeamsClient Team { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns a client to manage outside collaborators of an organization.
|
||||
/// </summary>
|
||||
IOrganizationOutsideCollaboratorsClient OutsideCollaborator { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the specified <see cref="Organization"/>.
|
||||
/// </summary>
|
||||
|
||||
153
Octokit/Clients/OrganizationOutsideCollaboratorsClient.cs
Normal file
153
Octokit/Clients/OrganizationOutsideCollaboratorsClient.cs
Normal file
@@ -0,0 +1,153 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Octokit
|
||||
{
|
||||
/// <summary>
|
||||
/// A client for GitHub's Organization Outside Collaborators API.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the <a href="http://developer.github.com/v3/orgs/outside_collaborators/">Orgs API documentation</a> for more information.
|
||||
/// </remarks>
|
||||
public class OrganizationOutsideCollaboratorsClient : ApiClient, IOrganizationOutsideCollaboratorsClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new Organization Outside Collaborators API client.
|
||||
/// </summary>
|
||||
/// <param name="apiConnection">An API connection</param>
|
||||
public OrganizationOutsideCollaboratorsClient(IApiConnection apiConnection)
|
||||
: base(apiConnection)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List all users who are outside collaborators of an organization. An outside collaborator is a user that
|
||||
/// is not a member of the organization.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the <a href="https://developer.github.com/v3/orgs/outside_collaborators/#list-outside-collaborators">API documentation</a>
|
||||
/// for more information.
|
||||
/// </remarks>
|
||||
/// <param name="org">The login for the organization</param>
|
||||
/// <returns>The users</returns>
|
||||
public Task<IReadOnlyList<User>> GetAll(string org)
|
||||
{
|
||||
Ensure.ArgumentNotNullOrEmptyString(org, nameof(org));
|
||||
|
||||
return ApiConnection.GetAll<User>(ApiUrls.OutsideCollaborators(org), null, AcceptHeaders.OrganizationMembershipPreview);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List all users who are outside collaborators of an organization. An outside collaborator is a user that
|
||||
/// is not a member of the organization.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the <a href="https://developer.github.com/v3/orgs/outside_collaborators/#list-outside-collaborators">API documentation</a>
|
||||
/// for more information.
|
||||
/// </remarks>
|
||||
/// <param name="org">The login for the organization</param>
|
||||
/// <param name="filter">The filter to use when getting the users, <see cref="OrganizationMembersFilter"/></param>
|
||||
/// <returns>The users</returns>
|
||||
public Task<IReadOnlyList<User>> GetAll(string org, OrganizationMembersFilter filter)
|
||||
{
|
||||
Ensure.ArgumentNotNullOrEmptyString(org, nameof(org));
|
||||
|
||||
return ApiConnection.GetAll<User>(ApiUrls.OutsideCollaborators(org, filter), null, AcceptHeaders.OrganizationMembershipPreview);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a user as an outside collaborator from the organization, this will remove them from all repositories
|
||||
/// within the organization.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the <a href="https://developer.github.com/v3/orgs/outside_collaborators/#remove-outside-collaborator">API documentation</a>
|
||||
/// for more information.
|
||||
/// </remarks>
|
||||
/// <param name="org">The login for the organization</param>
|
||||
/// <param name="user">The login of the user</param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> Delete(string org, string user)
|
||||
{
|
||||
Ensure.ArgumentNotNullOrEmptyString(org, nameof(org));
|
||||
Ensure.ArgumentNotNullOrEmptyString(user, nameof(user));
|
||||
|
||||
try
|
||||
{
|
||||
var statusCode = await Connection.Delete(ApiUrls.OutsideCollaborator(org, user), null, AcceptHeaders.OrganizationMembershipPreview).ConfigureAwait(false);
|
||||
|
||||
if (statusCode != HttpStatusCode.NoContent
|
||||
&& statusCode != (HttpStatusCode)422)
|
||||
{
|
||||
throw new ApiException("Invalid Status Code returned. Expected a 204 or a 422", statusCode);
|
||||
}
|
||||
return statusCode == HttpStatusCode.NoContent;
|
||||
}
|
||||
catch (ApiException ex)
|
||||
{
|
||||
if (ex.StatusCode == (HttpStatusCode)422)
|
||||
{
|
||||
throw new UserIsOrganizationMemberException(ex.HttpResponse);
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts an organization member to an outside collaborator,
|
||||
/// when an organization member is converted to an outside collaborator,
|
||||
/// they'll only have access to the repositories that their current team membership allows.
|
||||
/// The user will no longer be a member of the organization.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the <a href="https://developer.github.com/v3/orgs/outside_collaborators/#convert-member-to-outside-collaborator"> API documentation</a>
|
||||
/// for more information.
|
||||
/// </remarks>
|
||||
/// <param name="org">The login for the organization</param>
|
||||
/// <param name="user">The login for the user</param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> ConvertFromMember(string org, string user)
|
||||
{
|
||||
Ensure.ArgumentNotNullOrEmptyString(org, nameof(org));
|
||||
Ensure.ArgumentNotNullOrEmptyString(user, nameof(user));
|
||||
|
||||
try
|
||||
{
|
||||
var statusCode = await Connection.Put(ApiUrls.OutsideCollaborator(org, user), AcceptHeaders.OrganizationMembershipPreview);
|
||||
|
||||
if (statusCode != HttpStatusCode.NoContent
|
||||
&& statusCode != HttpStatusCode.Forbidden)
|
||||
{
|
||||
throw new ApiException("Invalid Status Code returned. Expected a 204 or a 403", statusCode);
|
||||
}
|
||||
|
||||
return statusCode == HttpStatusCode.NoContent;
|
||||
}
|
||||
catch (ForbiddenException fex)
|
||||
{
|
||||
if (string.Equals(
|
||||
"Cannot convert the last owner to an outside collaborator",
|
||||
fex.Message,
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new UserIsLastOwnerOfOrganizationException(fex.HttpResponse);
|
||||
}
|
||||
throw;
|
||||
}
|
||||
catch (NotFoundException nfex)
|
||||
{
|
||||
if (string.Equals(
|
||||
$"{user} is not a member of the {org} organization.",
|
||||
nfex.Message,
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new UserIsNotMemberOfOrganizationException(nfex.HttpResponse);
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ namespace Octokit
|
||||
{
|
||||
Member = new OrganizationMembersClient(apiConnection);
|
||||
Team = new TeamsClient(apiConnection);
|
||||
OutsideCollaborator = new OrganizationOutsideCollaboratorsClient(apiConnection);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -32,6 +33,11 @@ namespace Octokit
|
||||
/// </summary>
|
||||
public ITeamsClient Team { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns a client to manage outside collaborators of an organization.
|
||||
/// </summary>
|
||||
public IOrganizationOutsideCollaboratorsClient OutsideCollaborator { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the specified <see cref="Organization"/>.
|
||||
/// </summary>
|
||||
|
||||
63
Octokit/Exceptions/UserIsLastOwnerOfOrganizationException.cs
Normal file
63
Octokit/Exceptions/UserIsLastOwnerOfOrganizationException.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Net;
|
||||
#if !NO_SERIALIZABLE
|
||||
using System.Runtime.Serialization;
|
||||
#endif
|
||||
|
||||
namespace Octokit
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an error that occurs when trying to convert the
|
||||
/// last owner of the organization to an outside collaborator
|
||||
/// </summary>
|
||||
#if !NO_SERIALIZABLE
|
||||
[Serializable]
|
||||
#endif
|
||||
[SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors",
|
||||
Justification = "These exceptions are specific to the GitHub API and not general purpose exceptions")]
|
||||
public class UserIsLastOwnerOfOrganizationException : ApiException
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructs an instance of the <see cref="UserIsLastOwnerOfOrganizationException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="response">The HTTP payload from the server</param>
|
||||
public UserIsLastOwnerOfOrganizationException(IResponse response) : this(response, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs an instance of the <see cref="UserIsLastOwnerOfOrganizationException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="response">The HTTP payload from the server</param>
|
||||
/// <param name="innerException">The inner exception</param>
|
||||
public UserIsLastOwnerOfOrganizationException(IResponse response, ApiException innerException)
|
||||
: base(response, innerException)
|
||||
{
|
||||
Debug.Assert(response != null && response.StatusCode == HttpStatusCode.Forbidden,
|
||||
"UserIsLastOwnerOfOrganizationException created with the wrong HTTP status code");
|
||||
}
|
||||
|
||||
// https://developer.github.com/v3/orgs/outside_collaborators/#response-if-user-is-the-last-owner-of-the-organization
|
||||
public override string Message => ApiErrorMessageSafe ?? "User is the last owner of the organization.";
|
||||
|
||||
#if !NO_SERIALIZABLE
|
||||
/// <summary>
|
||||
/// Constructs an instance of <see cref="UserIsLastOwnerOfOrganizationException"/>.
|
||||
/// </summary>
|
||||
/// <param name="info">
|
||||
/// The <see cref="SerializationInfo"/> that holds the
|
||||
/// serialized object data about the exception being thrown.
|
||||
/// </param>
|
||||
/// <param name="context">
|
||||
/// The <see cref="StreamingContext"/> that contains
|
||||
/// contextual information about the source or destination.
|
||||
/// </param>
|
||||
protected UserIsLastOwnerOfOrganizationException(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
63
Octokit/Exceptions/UserIsNotMemberOfOrganizationException.cs
Normal file
63
Octokit/Exceptions/UserIsNotMemberOfOrganizationException.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Net;
|
||||
#if !NO_SERIALIZABLE
|
||||
using System.Runtime.Serialization;
|
||||
#endif
|
||||
|
||||
namespace Octokit
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an error that occurs when trying to convert a user
|
||||
/// that is not a member of the organization to an outside collaborator
|
||||
/// </summary>
|
||||
#if !NO_SERIALIZABLE
|
||||
[Serializable]
|
||||
#endif
|
||||
[SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors",
|
||||
Justification = "These exceptions are specific to the GitHub API and not general purpose exceptions")]
|
||||
public class UserIsNotMemberOfOrganizationException : ApiException
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructs an instance of the <see cref="UserIsNotMemberOfOrganizationException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="response">The HTTP payload from the server</param>
|
||||
public UserIsNotMemberOfOrganizationException(IResponse response) : this(response, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs an instance of the <see cref="UserIsNotMemberOfOrganizationException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="response">The HTTP payload from the server</param>
|
||||
/// <param name="innerException">The inner exception</param>
|
||||
public UserIsNotMemberOfOrganizationException(IResponse response, ApiException innerException)
|
||||
: base(response, innerException)
|
||||
{
|
||||
Debug.Assert(response != null && response.StatusCode == HttpStatusCode.NotFound,
|
||||
"UserIsNotMemberOfOrganizationException created with the wrong HTTP status code");
|
||||
}
|
||||
|
||||
// https://developer.github.com/v3/orgs/outside_collaborators/#response-if-user-is-not-a-member-of-the-organization
|
||||
public override string Message => ApiErrorMessageSafe ?? "User is not a member of the organization.";
|
||||
|
||||
#if !NO_SERIALIZABLE
|
||||
/// <summary>
|
||||
/// Constructs an instance of ForbiddenException
|
||||
/// </summary>
|
||||
/// <param name="info">
|
||||
/// The <see cref="SerializationInfo"/> that holds the
|
||||
/// serialized object data about the exception being thrown.
|
||||
/// </param>
|
||||
/// <param name="context">
|
||||
/// The <see cref="StreamingContext"/> that contains
|
||||
/// contextual information about the source or destination.
|
||||
/// </param>
|
||||
protected UserIsNotMemberOfOrganizationException(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
63
Octokit/Exceptions/UserIsOrganizationMemberException.cs
Normal file
63
Octokit/Exceptions/UserIsOrganizationMemberException.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Net;
|
||||
#if !NO_SERIALIZABLE
|
||||
using System.Runtime.Serialization;
|
||||
#endif
|
||||
|
||||
namespace Octokit
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an error that occurs when trying to remove an
|
||||
/// outside collaborator that is a member of the organization
|
||||
/// </summary>
|
||||
#if !NO_SERIALIZABLE
|
||||
[Serializable]
|
||||
#endif
|
||||
[SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors",
|
||||
Justification = "These exceptions are specific to the GitHub API and not general purpose exceptions")]
|
||||
public class UserIsOrganizationMemberException : ApiException
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructs an instance of the <see cref="UserIsOrganizationMemberException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="response">The HTTP payload from the server</param>
|
||||
public UserIsOrganizationMemberException(IResponse response) : this(response, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs an instance of the <see cref="UserIsOrganizationMemberException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="response">The HTTP payload from the server</param>
|
||||
/// <param name="innerException">The inner exception</param>
|
||||
public UserIsOrganizationMemberException(IResponse response, ApiException innerException)
|
||||
: base(response, innerException)
|
||||
{
|
||||
Debug.Assert(response != null && response.StatusCode == (HttpStatusCode)422,
|
||||
"UserIsOrganizationMemberException created with the wrong HTTP status code");
|
||||
}
|
||||
|
||||
// https://developer.github.com/v3/orgs/outside_collaborators/#response-if-user-is-a-member-of-the-organization
|
||||
public override string Message => ApiErrorMessageSafe ?? "User could not be removed as an outside collaborator.";
|
||||
|
||||
#if !NO_SERIALIZABLE
|
||||
/// <summary>
|
||||
/// Constructs an instance of <see cref="UserIsOrganizationMemberException"/>.
|
||||
/// </summary>
|
||||
/// <param name="info">
|
||||
/// The <see cref="SerializationInfo"/> that holds the
|
||||
/// serialized object data about the exception being thrown.
|
||||
/// </param>
|
||||
/// <param name="context">
|
||||
/// The <see cref="StreamingContext"/> that contains
|
||||
/// contextual information about the source or destination.
|
||||
/// </param>
|
||||
protected UserIsOrganizationMemberException(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -661,6 +661,32 @@ namespace Octokit
|
||||
return "orgs/{0}/public_members/{1}".FormatUri(org, name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="Uri"/> that returns all of the outside collaborators of the organization
|
||||
/// </summary>
|
||||
/// <param name="org">The organization</param>
|
||||
/// <returns></returns>
|
||||
public static Uri OutsideCollaborators(string org)
|
||||
{
|
||||
return "orgs/{0}/outside_collaborators".FormatUri(org);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="Uri"/> that returns all of the outside collaborators of the organization
|
||||
/// </summary>
|
||||
/// <param name="org">The organization</param>
|
||||
/// <param name="filter">The collaborator filter, <see cref="OrganizationMembersFilter"/></param>
|
||||
/// <returns>The correct uri</returns>
|
||||
public static Uri OutsideCollaborators(string org, OrganizationMembersFilter filter)
|
||||
{
|
||||
return "orgs/{0}/outside_collaborators?filter={1}".FormatUri(org, filter.ToParameter());
|
||||
}
|
||||
|
||||
public static Uri OutsideCollaborator(string org, string user)
|
||||
{
|
||||
return "orgs/{0}/outside_collaborators/{1}".FormatUri(org, user);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="Uri"/> that returns the issue/pull request event and issue info for the specified repository.
|
||||
/// </summary>
|
||||
|
||||
@@ -430,6 +430,21 @@ namespace Octokit
|
||||
return response.HttpResponse.StatusCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an asynchronous HTTP PUT request that expects an empty response.
|
||||
/// </summary>
|
||||
/// <param name="uri">URI endpoint to send request to</param>
|
||||
/// <param name="accepts">Specifies accepted response media types.</param>
|
||||
/// <returns>The returned <seealso cref="HttpStatusCode"/></returns>
|
||||
public async Task<HttpStatusCode> Put(Uri uri, string accepts)
|
||||
{
|
||||
Ensure.ArgumentNotNull(uri, nameof(uri));
|
||||
Ensure.ArgumentNotNull(accepts, nameof(accepts));
|
||||
|
||||
var response = await SendData<object>(uri, HttpMethod.Put, null, accepts, null, CancellationToken.None).ConfigureAwait(false);
|
||||
return response.HttpResponse.StatusCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an asynchronous HTTP DELETE request that expects an empty response.
|
||||
/// </summary>
|
||||
|
||||
@@ -214,6 +214,14 @@ namespace Octokit
|
||||
/// <returns>The returned <seealso cref="HttpStatusCode"/></returns>
|
||||
Task<HttpStatusCode> Put(Uri uri);
|
||||
|
||||
/// <summary>
|
||||
/// Performs an asynchronous HTTP PUT request that expects an empty response.
|
||||
/// </summary>
|
||||
/// <param name="uri">URI endpoint to send request to</param>
|
||||
/// <param name="accepts">Specifies accepted response media types.</param>
|
||||
/// <returns>The returned <seealso cref="HttpStatusCode"/></returns>
|
||||
Task<HttpStatusCode> Put(Uri uri, string accepts);
|
||||
|
||||
/// <summary>
|
||||
/// Performs an asynchronous HTTP DELETE request that expects an empty response.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user