From c519acda3f23317d7780bc4450449dcb4472e8cc Mon Sep 17 00:00:00 2001 From: Yu Lin Date: Sun, 5 Nov 2023 03:31:20 +1300 Subject: [PATCH] fix: add enforcer API and tests (#88) --- .../Abstractions/ICasdoorClient.cs | 3 +- .../Abstractions/ICasdoorEnforcerlClient.cs | 26 ++++++ .../CasdoorClient.EnforcerApi.cs | 52 +++++++++++ src/Casdoor.Client/Models/CasdoorEnforcer.cs | 47 ++++++++++ .../ApiClientTests/EnforcerTest.cs | 86 +++++++++++++++++++ 5 files changed, 213 insertions(+), 1 deletion(-) create mode 100644 src/Casdoor.Client/Abstractions/ICasdoorEnforcerlClient.cs create mode 100644 src/Casdoor.Client/CasdoorClient.EnforcerApi.cs create mode 100644 src/Casdoor.Client/Models/CasdoorEnforcer.cs create mode 100644 tests/Casdoor.Client.UnitTests/ApiClientTests/EnforcerTest.cs diff --git a/src/Casdoor.Client/Abstractions/ICasdoorClient.cs b/src/Casdoor.Client/Abstractions/ICasdoorClient.cs index aa52c50..34398ae 100644 --- a/src/Casdoor.Client/Abstractions/ICasdoorClient.cs +++ b/src/Casdoor.Client/Abstractions/ICasdoorClient.cs @@ -16,7 +16,8 @@ namespace Casdoor.Client; public interface ICasdoorClient : ICasdoorUserClient, ICasdoorTokenClient, ICasdoorResourceClient, ICasdoorServiceClient, - ICasdoorApplicationClient, ICasdoorOrganizationClient, ICasdoorProviderClient, ICasdoorAccountClient, ICasdoorModelClient + ICasdoorApplicationClient, ICasdoorOrganizationClient, ICasdoorProviderClient, ICasdoorAccountClient, ICasdoorModelClient, + ICasdoorEnforcerClient { } diff --git a/src/Casdoor.Client/Abstractions/ICasdoorEnforcerlClient.cs b/src/Casdoor.Client/Abstractions/ICasdoorEnforcerlClient.cs new file mode 100644 index 0000000..dc45ddb --- /dev/null +++ b/src/Casdoor.Client/Abstractions/ICasdoorEnforcerlClient.cs @@ -0,0 +1,26 @@ +// Copyright 2022 The Casdoor Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Casdoor.Client; + +public interface ICasdoorEnforcerClient +{ + public Task AddEnforcerAsync(CasdoorEnforcer enforcer, CancellationToken cancellationToken = default); + + public Task UpdateEnforcerAsync(CasdoorEnforcer enforcer, string enforcerId, CancellationToken cancellationToken = default); + public Task DeleteEnforcerAsync(CasdoorEnforcer enforcer, CancellationToken cancellationToken = default); + public Task GetEnforcerAsync(string name, string? owner = null, CancellationToken cancellationToken = default); + + public Task?> GetEnforcersAsync(string? owner = null, CancellationToken cancellationToken = default); +} diff --git a/src/Casdoor.Client/CasdoorClient.EnforcerApi.cs b/src/Casdoor.Client/CasdoorClient.EnforcerApi.cs new file mode 100644 index 0000000..68a3d49 --- /dev/null +++ b/src/Casdoor.Client/CasdoorClient.EnforcerApi.cs @@ -0,0 +1,52 @@ +// Copyright 2022 The Casdoor Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System.Net.Http.Json; + +namespace Casdoor.Client; + +public partial class CasdoorClient +{ + public virtual async Task AddEnforcerAsync(CasdoorEnforcer enforcer, CancellationToken cancellationToken = default) => + await PostAsJsonAsync(_options.GetActionUrl("add-enforcer"), enforcer, cancellationToken); + + public virtual async Task UpdateEnforcerAsync(CasdoorEnforcer enforcer, string enforcerId, + CancellationToken cancellationToken = default) + { + string url = _options.GetActionUrl("update-enforcer", new QueryMapBuilder().Add("id", enforcerId).QueryMap); + return await PostAsJsonAsync(url, enforcer, cancellationToken); + } + + public virtual async Task DeleteEnforcerAsync(CasdoorEnforcer enforcer, CancellationToken cancellationToken = default) + { + string url = _options.GetActionUrl("delete-enforcer"); + return await PostAsJsonAsync(url, enforcer, cancellationToken); + } + + public virtual async Task GetEnforcerAsync(string name, string? owner = null, CancellationToken cancellationToken = default) + { + var queryMap = new QueryMapBuilder().Add("id", $"{owner ?? _options.OrganizationName}/{name}").QueryMap; + string url = _options.GetActionUrl("get-enforcer", queryMap); + var result = await _httpClient.GetFromJsonAsync(url, cancellationToken: cancellationToken); + return result.DeserializeData(); + } + + public virtual async Task?> GetEnforcersAsync(string? owner = null, CancellationToken cancellationToken = default) + { + var queryMap = new QueryMapBuilder().Add("owner", owner ?? _options.OrganizationName).QueryMap; + string url = _options.GetActionUrl("get-enforcers", queryMap); + var result = await _httpClient.GetFromJsonAsync(url, cancellationToken: cancellationToken); + return result.DeserializeData?>(); + } +} diff --git a/src/Casdoor.Client/Models/CasdoorEnforcer.cs b/src/Casdoor.Client/Models/CasdoorEnforcer.cs new file mode 100644 index 0000000..f7635ff --- /dev/null +++ b/src/Casdoor.Client/Models/CasdoorEnforcer.cs @@ -0,0 +1,47 @@ +// Copyright 2023 The Casdoor Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System.Text.Json.Serialization; + +namespace Casdoor.Client; + +public class CasdoorEnforcer +{ + [JsonPropertyName("owner")] + public string? Owner { get; set; } + + [JsonPropertyName("name")] + public string? Name { get; set; } + + [JsonPropertyName("createdTime")] + public string? CreatedTime { get; set; } + + [JsonPropertyName("updatedTime")] + public string? UpdatedTime { get; set; } + + [JsonPropertyName("displayName")] + public string? DisplayName { get; set; } + + [JsonPropertyName("description")] + public string? Description { get; set; } + + [JsonPropertyName("model")] + public string? Model { get; set; } + + [JsonPropertyName("adapter")] + public string? Adapter { get; set; } + + [JsonPropertyName("isEnabled")] + public bool? IsEnabled { get; set; } +} diff --git a/tests/Casdoor.Client.UnitTests/ApiClientTests/EnforcerTest.cs b/tests/Casdoor.Client.UnitTests/ApiClientTests/EnforcerTest.cs new file mode 100644 index 0000000..800eeaf --- /dev/null +++ b/tests/Casdoor.Client.UnitTests/ApiClientTests/EnforcerTest.cs @@ -0,0 +1,86 @@ +using System.Globalization; +using Casdoor.Client.UnitTests.Fixtures; +using Microsoft.Extensions.DependencyInjection; +using Xunit.Abstractions; + +namespace Casdoor.Client.UnitTests.ApiClientTests; + +public class EnforcerTest : IClassFixture +{ + private readonly ServicesFixture _servicesFixture; + private readonly ITestOutputHelper _testOutputHelper; + + public EnforcerTest(ServicesFixture servicesFixture, ITestOutputHelper testOutputHelper) + { + _servicesFixture = servicesFixture; + _testOutputHelper = testOutputHelper; + } + + [Fact] + public async void TestEnforcer() + { + var userClient = _servicesFixture.ServiceProvider.GetService(); + + const string appName = $"enforce-name"; + const string ownerName = "casbin"; + + var enforcer = new CasdoorEnforcer() + { + Owner = ownerName, + Name = appName, + CreatedTime = DateTime.Now.ToString(CultureInfo.InvariantCulture), + DisplayName = appName, + Model = "built-in/user-model-built-in", + Adapter = "built-in/user-adapter-built-in", + Description = "Casdoor website" + }; + // Add a new object + + Task responseAsync = userClient.AddEnforcerAsync(enforcer); + CasdoorResponse? response = await responseAsync; + Assert.Equal(CasdoorConstants.DefaultCasdoorSuccessStatus, response.Status); + _testOutputHelper.WriteLine(response.Status); + // Get all objects, check if our added object is inside the list + Task?> enforcesAsync = userClient.GetEnforcersAsync(); + IEnumerable? getEnforcers = await enforcesAsync; + Assert.True(getEnforcers.Any()); + bool found = false; + foreach (CasdoorEnforcer casdoorEnforcer in getEnforcers) + { + _testOutputHelper.WriteLine(casdoorEnforcer.Name); + if (casdoorEnforcer.Name is appName) + { + found = true; + } + } + + Assert.True(found); + + // Get the object + Task enforcerAsync = userClient.GetEnforcerAsync($"{appName}"); + CasdoorEnforcer? getEnforcer = await enforcerAsync; + Assert.Equal(appName, getEnforcer.Name); + //Update the object + const string updateDescription = "Update Casdoor Website"; + enforcer.Description = updateDescription; + // Update the object + responseAsync = + userClient.UpdateEnforcerAsync(enforcer, $"{ownerName}/{appName}"); + response = await responseAsync; + Assert.Equal(CasdoorConstants.DefaultCasdoorSuccessStatus, response.Status); + // Validate the update + enforcerAsync = userClient.GetEnforcerAsync($"{appName}"); + getEnforcer = await enforcerAsync; + Assert.Equal(updateDescription, getEnforcer.Description); + + // Delete the object + responseAsync = userClient.DeleteEnforcerAsync(enforcer); + response = await responseAsync; + Assert.Equal(CasdoorConstants.DefaultCasdoorSuccessStatus, response.Status); + // Validate the deletion + enforcerAsync = userClient.GetEnforcerAsync($"{appName}"); + getEnforcer = await enforcerAsync; + Assert.Null(getEnforcer); + + } +}