But the new permission definition only exists in memory. You better add it to the database as well.
You can test it and give feedback here.
Thanks.
The new app service. You are add permission definition to static permission. you don't need to clear the cache of dynamic permission store.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;
using AbpSolution1.Localization;
using AbpSolution1.Permissions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Localization;
using Volo.Abp.PermissionManagement;
namespace AbpSolution1.Books;
public class BookAppService :
CrudAppService<
Book, //The Book entity
BookDto, //Used to show books
Guid, //Primary key of the book entity
PagedAndSortedResultRequestDto, //Used for paging/sorting
CreateUpdateBookDto>, //Used to create/update a book
IBookAppService //implement the IBookAppService
{
private readonly IPermissionDefinitionManager _permissionDefinitionManager;
private readonly IExtendedStaticPermissionDefinitionStore _staticPermissionDefinitionStore;
public BookAppService(IRepository<Book, Guid> repository, IExtendedStaticPermissionDefinitionStore staticPermissionDefinitionStore, IPermissionDefinitionManager permissionDefinitionManager)
: base(repository)
{
GetPolicyName = AbpSolution1Permissions.Books.Default;
GetListPolicyName = AbpSolution1Permissions.Books.Default;
CreatePolicyName = AbpSolution1Permissions.Books.Create;
UpdatePolicyName = AbpSolution1Permissions.Books.Edit;
DeletePolicyName = AbpSolution1Permissions.Books.Delete;
_staticPermissionDefinitionStore = staticPermissionDefinitionStore;
_permissionDefinitionManager = permissionDefinitionManager;
}
private static LocalizableString L(string name)
{
return LocalizableString.Create<AbpSolution1Resource>(name);
}
public override async Task<BookDto> CreateAsync(CreateUpdateBookDto input)
{
var publishedPermission = await _permissionDefinitionManager.GetAsync(AbpSolution1Permissions.Books.Published);
string published_permission_name = AbpSolution1Permissions.Books.Published + "." + input.Name.Replace(" ", "");
var published_permission_nameDefinition = publishedPermission?.AddChild(published_permission_name, L(input.Name));
await _staticPermissionDefinitionStore.AddPermissionDefinitionAsync(published_permission_nameDefinition);
var book = ObjectMapper.Map<CreateUpdateBookDto, Book>(input);
var thisIsNotNull = await _permissionDefinitionManager.GetOrNullAsync(published_permission_name);
var content = await Repository.InsertAsync(
book, autoSave: true
);
return ObjectMapper.Map<Book, BookDto>(content);
}
}
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IStaticPermissionDefinitionStore), typeof(IExtendedStaticPermissionDefinitionStore))]
public class MyStaticPermissionDefinitionStore : IStaticPermissionDefinitionStore, IExtendedStaticPermissionDefinitionStore, ISingletonDependency
{
protected readonly IDictionary<string, PermissionGroupDefinition> PermissionGroupDefinitions;
protected readonly IDictionary<string, PermissionDefinition> PermissionDefinitions;
protected AbpPermissionOptions Options { get; }
private readonly IServiceProvider _serviceProvider;
public MyStaticPermissionDefinitionStore(
IServiceProvider serviceProvider,
IOptions<AbpPermissionOptions> options)
{
_serviceProvider = serviceProvider;
Options = options.Value;
PermissionGroupDefinitions = CreatePermissionGroupDefinitions();
PermissionDefinitions = CreatePermissionDefinitions();
}
public Task AddPermissionDefinitionAsync(PermissionDefinition permissionDefinition)
{
if (!PermissionDefinitions.ContainsKey(permissionDefinition.Name))
{
PermissionDefinitions.Add(permissionDefinition.Name, permissionDefinition);
}
return Task.CompletedTask;
}
protected virtual Dictionary<string, PermissionDefinition> CreatePermissionDefinitions()
{
var permissions = new Dictionary<string, PermissionDefinition>();
foreach (var groupDefinition in PermissionGroupDefinitions.Values)
{
foreach (var permission in groupDefinition.Permissions)
{
AddPermissionToDictionaryRecursively(permissions, permission);
}
}
return permissions;
}
protected virtual void AddPermissionToDictionaryRecursively(
Dictionary<string, PermissionDefinition> permissions,
PermissionDefinition permission)
{
if (permissions.ContainsKey(permission.Name))
{
throw new AbpException("Duplicate permission name: " + permission.Name);
}
permissions[permission.Name] = permission;
foreach (var child in permission.Children)
{
AddPermissionToDictionaryRecursively(permissions, child);
}
}
protected virtual Dictionary<string, PermissionGroupDefinition> CreatePermissionGroupDefinitions()
{
using (var scope = _serviceProvider.CreateScope())
{
var context = new PermissionDefinitionContext(scope.ServiceProvider);
var providers = Options
.DefinitionProviders
.Select(p => (scope.ServiceProvider.GetRequiredService(p) as IPermissionDefinitionProvider)!)
.ToList();
foreach (var provider in providers)
{
provider.PreDefine(context);
}
foreach (var provider in providers)
{
provider.Define(context);
}
foreach (var provider in providers)
{
provider.PostDefine(context);
}
return context.Groups;
}
}
public Task<PermissionDefinition?> GetOrNullAsync(string name)
{
return Task.FromResult(PermissionDefinitions.GetOrDefault(name));
}
public virtual Task<IReadOnlyList<PermissionDefinition>> GetPermissionsAsync()
{
return Task.FromResult<IReadOnlyList<PermissionDefinition>>(
PermissionDefinitions.Values.ToImmutableList()
);
}
public Task<IReadOnlyList<PermissionGroupDefinition>> GetGroupsAsync()
{
return Task.FromResult<IReadOnlyList<PermissionGroupDefinition>>(
PermissionGroupDefinitions.Values.ToImmutableList()
);
}
}
public interface IExtendedStaticPermissionDefinitionStore : IStaticPermissionDefinitionStore
{
Task AddPermissionDefinitionAsync(PermissionDefinition permissionDefinition);
}
hi
You can get the source code of the SaaS module to see the management connection strings for different tenants or microservices.
This is the best way to learn how to implement Tenant-Based Dynamic Database Connection Management and Separate Servers
hi
The switch tenant component will hidden if the current tenant is not resolved by cookies or query string.
So you can override the Account layout of LeptonX theme.
add your custom tenant switch component to change the current URL.
Please send an email to liming.ma@volosoft.com; I will share the source code of the Account layout with you.
Page: /Themes/LeptonX/Layouts/Account/Default.cshtml
https://abp.io/docs/latest/framework/ui/mvc-razor-pages/customization-user-interface
hi
hi
I have a use case where i want to add roles by member for each organization unit and not maintain the role by organization unit.
In this case, you can use the organization manager to add roles. which means adding code to do this. The UI doesn't have this feature
if a member is belonging to branch USA and Turkey but USA branch has permission to view the book list but Turkey branch does not have permission to view the book list how does that scenario being handled here if i do not want to switch between the branch and display book list data at once if i disable the filter?
You can check the permission first and get the branch that has permission. then switch to this branch in the code to query the data.
Yes, Keeping them won't affect you. : )
ok, Can you share a screenshot of current page(include url)?
Thanks . I will check your project.