diff --git a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/AuthorizationRolePermissionsTests.cs b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/AuthorizationRolePermissionsTests.cs index 0364468..e61bbf1 100644 --- a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/AuthorizationRolePermissionsTests.cs +++ b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/AuthorizationRolePermissionsTests.cs @@ -1,6 +1,4 @@ -using EasyMicroservices.AuthenticationsMicroservice.VirtualServerForTests; -using EasyMicroservices.AuthenticationsMicroservice.VirtualServerForTests.TestResources; -using EasyMicroservices.Cores.AspCore.Tests.Fixtures; +using EasyMicroservices.Cores.AspCore.Tests.Fixtures; using EasyMicroservices.ServiceContracts; using System.Net.Http.Headers; @@ -14,7 +12,7 @@ public AuthorizationRolePermissionsTests() : base() protected override void AssertTrue(MessageContract messageContract) { - Assert.False(messageContract.IsSuccess); + Assert.False(messageContract.IsSuccess, "Access true, expect false"); Assert.True(messageContract.Error.FailedReasonType == FailedReasonType.AccessDenied, messageContract.ToString()); } @@ -29,85 +27,72 @@ protected override void AuthorizeAssert(MessageContract messageContract) AssertTrue(messageContract); } - static AuthenticationVirtualTestManager AuthenticationVirtualTestManager = new(); - [Theory] - [InlineData("TestExampleFailed", "EndUser", "NoAccess", "NoAccess", false)] - [InlineData("TestExample", "EndUser", "User", "CheckHasAccess", true)] - [InlineData("TestExample", "EndUser", null, "CheckHasAccess", true)] - [InlineData("TestExample", "EndUser", null, null, true)] - [InlineData("TestExample", "EndUser", "User", null, true)] - public async Task WriterRoleTest(string microserviceName, string roleName, string serviceName, string methodName, bool result) + async Task AddPermissions(HttpClient currentHttpClient, string microserviceName, string roleName, string serviceName, string methodName, bool hasAccess) { - int portNumber = 1045; - await AuthenticationVirtualTestManager.OnInitialize(portNumber); - var resources = AuthenticationResource.GetResources(microserviceName, new Dictionary>() + if (!hasAccess) + return; + var loginResult = await currentHttpClient.GetFromJsonAsync>($"{GetBaseUrl()}/api/user/login2?role=Owner&uniqueIdentity=1-2"); + Assert.True(loginResult); + currentHttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", loginResult.Result); + var roleClient = new Authentications.GeneratedServices.RoleClient("http://localhost:1044", currentHttpClient); + var addRole = await roleClient.AddAsync(new Authentications.GeneratedServices.AddRoleRequestContract() { - { - roleName , - new List() - { - new TestServicePermissionContract() - { - MicroserviceName = microserviceName, - MethodName = methodName, - ServiceName = serviceName - } - } - } - }); + Name = roleName, + }).AsCheckedResult(x => x.Result); - foreach (var resource in resources) + var servicePermissionClient = new Authentications.GeneratedServices.ServicePermissionClient("http://localhost:1044", currentHttpClient); + var addServicePermission = await servicePermissionClient.AddAsync(new Authentications.GeneratedServices.AddServicePermissionRequestContract { - AuthenticationVirtualTestManager.AppendService(portNumber, resource.Key, resource.Value); - } + AccessType = Authentications.GeneratedServices.AccessPermissionType.Granted, + MethodName = methodName, + ServiceName = serviceName, + MicroserviceName = microserviceName + }).AsCheckedResult(x => x.Result); - HttpClient CurrentHttpClient = new HttpClient(); - if (result) + var roleServicePermissionClient = new Authentications.GeneratedServices.RoleServicePermissionClient("http://localhost:1044", currentHttpClient); + var addRolePermission = await roleServicePermissionClient.AddAsync(new Authentications.GeneratedServices.AddRoleServicePermissionRequestContract { - var loginResult = await CurrentHttpClient.GetFromJsonAsync>($"{GetBaseUrl()}/api/user/login"); - Assert.True(loginResult); - CurrentHttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", loginResult.Result); - } - var data = await CurrentHttpClient.GetFromJsonAsync($"{GetBaseUrl()}/api/user/CheckHasAccess"); - if (!result) - AssertTrue(data); - else - Assert.True(data, data.ToString()); + RoleId = addRole, + ServicePermissionId = addServicePermission + }).AsCheckedResult(x => x.Result); } + //static AuthenticationVirtualTestManager AuthenticationVirtualTestManager = new(); + //[Theory] + //[InlineData("TestExampleFailed", "EndUser", "NoAccess", "NoAccess", false)] + //[InlineData("TestExample", "EndUser", "User", "CheckHasAccess", true)] + //[InlineData("TestExample", "EndUser", null, "CheckHasAccess", true)] + //[InlineData("TestExample", "EndUser", null, null, true)] + //[InlineData("TestExample", "EndUser", "User", null, true)] + //public async Task WriterRoleTest(string microserviceName, string roleName, string serviceName, string methodName, bool result) + //{ + // HttpClient currentHttpClient = new HttpClient(); + // await AddPermissions(currentHttpClient, microserviceName, roleName, serviceName, methodName, result); + // if (result) + // { + // var loginResult = await currentHttpClient.GetFromJsonAsync>($"{GetBaseUrl()}/api/user/login"); + // Assert.True(loginResult); + // currentHttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", loginResult.Result); + // } + // var data = await currentHttpClient.GetFromJsonAsync($"{GetBaseUrl()}/api/user/CheckHasAccess"); + // if (!result) + // AssertTrue(data); + // else + // Assert.True(data, data.ToString()); + //} + [Theory] - [InlineData("TestExampleFailed", "EndUser", "NoAccess")] - [InlineData("TestExample", "EndUser", "User")] - [InlineData("TestExample", "EndUser", null)] + [InlineData("TestExampleFailed", "TestEndUser", "NoAccess")] + [InlineData("TestExample", "TestEndUser", "User")] + [InlineData("TestExample", "TestEndUser", null)] public async Task ReaderRoleTest(string microserviceName, string roleName, string serviceName) { - int portNumber = 1045; - await AuthenticationVirtualTestManager.OnInitialize(portNumber); - var resources = AuthenticationResource.GetResources(microserviceName, new Dictionary>() - { - { - roleName , - new List() - { - new TestServicePermissionContract() - { - MicroserviceName = microserviceName, - MethodName = "CheckHasAccess", - ServiceName = serviceName - } - } - } - }); - - foreach (var resource in resources) - { - AuthenticationVirtualTestManager.AppendService(portNumber, resource.Key, resource.Value); - } - HttpClient CurrentHttpClient = new HttpClient(); - var loginResult = await CurrentHttpClient.GetFromJsonAsync>($"{GetBaseUrl()}/api/user/login"); - Assert.True(loginResult, loginResult.Error?.ToString()); - CurrentHttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", loginResult.Result); - var data = await CurrentHttpClient.GetFromJsonAsync($"{GetBaseUrl()}/api/user/CheckHasNoAccess"); + HttpClient currentHttpClient = new HttpClient(); + //await AddPermissions(currentHttpClient, microserviceName, roleName, serviceName, null, true); + //var loginResult = await currentHttpClient.GetFromJsonAsync>($"{GetBaseUrl()}/api/user/Login2?role={roleName}"); + //Assert.True(loginResult, loginResult.Error?.ToString()); + //currentHttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", loginResult.Result); + var data = await currentHttpClient.GetFromJsonAsync($"{GetBaseUrl()}/api/user/CheckHasNoAccess"); AssertTrue(data); } } diff --git a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Fixtures/AuthorizationRolePermissionsFixture.cs b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Fixtures/AuthorizationRolePermissionsFixture.cs index e098bc6..d0c1210 100644 --- a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Fixtures/AuthorizationRolePermissionsFixture.cs +++ b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Fixtures/AuthorizationRolePermissionsFixture.cs @@ -54,7 +54,7 @@ public override ServiceAddressInfo GetServiceAddress(string name) return new ServiceAddressInfo() { Name = name, - Address = "http://localhost:1045" + Address = "http://localhost:1044" }; return base.GetServiceAddress(name); } diff --git a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Security/UniqueIdentityTests.cs b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Security/UniqueIdentityTests.cs index 3f11c01..ab3e118 100644 --- a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Security/UniqueIdentityTests.cs +++ b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Security/UniqueIdentityTests.cs @@ -1,4 +1,5 @@ using EasyMicroservices.Cores.AspCore.Tests.Fixtures; +using EasyMicroservices.Cores.Contracts.Requests; using EasyMicroservices.Cores.Tests.DatabaseLogics.Database.Entities; using EasyMicroservices.ServiceContracts; using System.Net.Http.Headers; @@ -81,6 +82,38 @@ public async Task UpdateAsync(string roleName, string controller, string method, } + [Theory] + [InlineData("Owner", "User", "GetByUniqueIdentity", "1-2", "1-2", "1-2", "{}", true)] + [InlineData("Owner", "User", "GetByUniqueIdentity", "1-2", "1-2", "1-2", @"{""UniqueIdentity"":""1-2-3-4""}", true)] + [InlineData("Owner", "User", "GetByUniqueIdentity", "1-2", "3-4", "1-2", @"{""UniqueIdentity"":""3-4""}", true)] + [InlineData("Moderator", "User", "GetByUniqueIdentity", "1-2", "3-4", "1-2", @"{""UniqueIdentity"":""3-4""}", false)] + [InlineData("Moderator", "User", "GetByUniqueIdentity", "3-4", "3-4", "3-4", @"{""UniqueIdentity"":""3-4""}", true)] + [InlineData("Moderator", "User", "GetByUniqueIdentity", "1-2", "1-2", "1-2", @"{""UniqueIdentity"":""1-2""}", true)] + public async Task GetByUniqueIdentityAsync(string roleName, string controller, string method,string userUniqueIdentity, string fromUniqueIdentity, string toUniqueIdentity, string data, bool canHaveAccess) + { + var model = JsonSerializer.Deserialize(data); + model.Id = await AddAsync(roleName, controller, "Add", fromUniqueIdentity, data, true); + HttpClient currentHttpClient = new HttpClient(); + await Login(currentHttpClient, roleName, userUniqueIdentity); + var apiResult = await currentHttpClient.PostAsJsonAsync($"{GetBaseUrl()}/api/{controller}/{method}", new GetByUniqueIdentityRequestContract() + { + UniqueIdentity = fromUniqueIdentity, + Type = DataTypes.GetUniqueIdentityType.All + }); + var response = await apiResult.Content.ReadAsStringAsync(); + var result = Newtonsoft.Json.JsonConvert.DeserializeObject>(response); + if (canHaveAccess) + { + Assert.True(result, result.Error?.ToString()); + Assert.True(result.Result.UniqueIdentity.StartsWith(fromUniqueIdentity)); + } + else + { + Assert.False(result, "User has access, expect: no access!"); + Assert.True(result.Error.FailedReasonType == FailedReasonType.NotFound || result.Error.FailedReasonType == FailedReasonType.AccessDenied, result.Error.ToString()); + } + } + class DataModel { public long Id { get; set; } diff --git a/src/CSharp/EasyMicroservices.Cores.Database/Database/Logics/DatabaseLogicInfrastructure.cs b/src/CSharp/EasyMicroservices.Cores.Database/Database/Logics/DatabaseLogicInfrastructure.cs index ec92a2a..6451416 100644 --- a/src/CSharp/EasyMicroservices.Cores.Database/Database/Logics/DatabaseLogicInfrastructure.cs +++ b/src/CSharp/EasyMicroservices.Cores.Database/Database/Logics/DatabaseLogicInfrastructure.cs @@ -79,6 +79,24 @@ private async Task CheckUniqueIdentityAccess(params IEntityEntr return true; } + + private async Task HasUniqueIdentityPermission(string uniqueIdentity) + where TEntity : class + { + bool hasUniqueIdentityRole = await _baseUnitOfWork.HasUniqueIdentityRole(); + if (hasUniqueIdentityRole) + return true; + if (!typeof(IUniqueIdentitySchema).IsAssignableFrom(typeof(TEntity))) + return (FailedReasonType.AccessDenied, $"type of {typeof(TEntity)} is not inheritance from IUniqueIdentitySchema and user has no UniqueIdentityRole access!"); + + var currentUserUniqueIdentity = await _baseUnitOfWork.GetCurrentUserUniqueIdentity(); + if (uniqueIdentity.IsNullOrEmpty() && !hasUniqueIdentityRole) + return (FailedReasonType.AccessDenied, $"With the UniqueIdentity: {currentUserUniqueIdentity} you have not access, please send me your UniqueIdentity!"); + else if (!uniqueIdentity.StartsWith(currentUserUniqueIdentity)) + return (FailedReasonType.AccessDenied, $"With the UniqueIdentity: {currentUserUniqueIdentity} you have not access, You sent me: {uniqueIdentity}!"); + return true; + } + private async Task> UniqueIdentityQueryMaker(IEasyReadableQueryableAsync easyReadableQueryable, string uniqueIdentity, GetUniqueIdentityType type) where TEntity : class { @@ -223,12 +241,13 @@ public async Task> GetAllBy(IEasyReadableQ /// /// /// + /// /// /// - public async Task> GetBy(IEasyReadableQueryableAsync easyReadableQueryable, Func, IEasyReadableQueryableAsync> query = default, CancellationToken cancellationToken = default) + public async Task> GetBy(IEasyReadableQueryableAsync easyReadableQueryable, Func, IEasyReadableQueryableAsync> query = default, bool doNeedSetUniqueIdentityQuery = true, CancellationToken cancellationToken = default) where TEntity : class { - IEasyReadableQueryableAsync queryable = await SetTheUserUniqueIdentityToQuery(easyReadableQueryable); + IEasyReadableQueryableAsync queryable = doNeedSetUniqueIdentityQuery ? await SetTheUserUniqueIdentityToQuery(easyReadableQueryable) : easyReadableQueryable; if (query != null) queryable = query(queryable); @@ -300,8 +319,14 @@ public async Task> GetByUniqueIdentity queryable = await UniqueIdentityQueryMaker(easyReadableQueryable, request.UniqueIdentity, type); - var entityResult = await GetBy(queryable, query, cancellationToken); + var uniqueIdentityPermission = await HasUniqueIdentityPermission(request.UniqueIdentity); + if (!uniqueIdentityPermission) + return uniqueIdentityPermission.ToContract(); + if (request.UniqueIdentity.HasValue() && typeof(IUniqueIdentitySchema).IsAssignableFrom(typeof(TEntity))) + { + easyReadableQueryable = await UniqueIdentityQueryMaker(easyReadableQueryable, request.UniqueIdentity, type); + } + var entityResult = await GetBy(easyReadableQueryable, query, false, cancellationToken); if (!entityResult) return entityResult.ToContract(); var result = await MapAsync(entityResult.Result);