Open Closed

Unable to save the permission after creating it in an App Service #8410


User avatar
0
jordanchen98 created
  • ABP Framework version: v9.0.0
  • UI Type: Angular
  • Database System: EF Core (PostgreSQL)
  • Tiered (for MVC) or Auth Server Separated (for Angular): no
  • Exception message and full stack trace:
  • Steps to reproduce the issue:

I tried to create a permission using Static Permission Definition Store and without restarting the API (Swagger) I am unable to save the permission.

When I debug it, it goes to SetAsync() in PermissionManager class the PermissionDefinitionManager cant seem to find the permission.

Here is how I insert the permission:

// Add Branch
if (branch is not null && state is not null && input.FilterFieldID.Equals(branch.Id))
{
    var branch_state = input.FilterValueParts.FirstOrDefault(x => x.ID.Equals(state.Id))?.Value.Replace(" ", "");
    var statePermission = await _permissionDefinitionManager.GetAsync(KMSv4Permissions.States.Default + "." + branch_state);

    if(statePermission is not null)
    {
        statePermission.AddChild("KMSv4.Branches." + f.Value.Replace(" ", ""), L(f.Value));
        await _staticPermissionDefinitionStore.AddPermissionDefinitionAsync(statePermission.Name, statePermission);
    }
}

// Add State
if (state is not null && input.FilterFieldID.Equals(state.Id))
{
    var statePermission = await _permissionDefinitionManager.GetAsync(KMSv4Permissions.States.Default);
    string state_permission_name = KMSv4Permissions.States.Default + "." + f.Value.Replace(" ", "");

    if (statePermission is not null)
    {
        statePermission.AddChild(state_permission_name, L(f.Value));
        await _staticPermissionDefinitionStore.AddPermissionDefinitionAsync(statePermission.Name, statePermission);
    }
}

and here is a function I created by following https://abp.io/support/questions/5490/Need-to-refresh-the-list-of-static-permission-definitions-without-site-reload?CurrentPage=1.

public class ExtendedStaticPermissionDefinitionStore : StaticPermissionDefinitionStore, IExtendedStaticPermissionDefinitionStore
 {
     public ExtendedStaticPermissionDefinitionStore(IServiceProvider serviceProvider, IOptions options) : base(serviceProvider, options)
     {
     }

     public Task AddPermissionDefinitionAsync(string key, PermissionDefinition permissionDefinition)
     {
         if (!PermissionDefinitions.ContainsKey(key))
         {
             PermissionDefinitions.Add(key, permissionDefinition);
         }
         return Task.CompletedTask;
     }
 }

 public interface IExtendedStaticPermissionDefinitionStore : IStaticPermissionDefinitionStore
 {
     Task AddPermissionDefinitionAsync(string key, PermissionDefinition permissionDefinition);
 }

Thanks!


27 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Inject the IDynamicPermissionDefinitionStoreInMemoryCache and set LastCheckTime and CacheStamp

    DynamicPermissionDefinitionStoreInMemoryCache.LastCheckTime = null;
    DynamicPermissionDefinitionStoreInMemoryCache.CacheStamp = Guid.NewGuid().ToString();
    

    After this, try to get the permission definition from PermissionDefinitionManager(IDynamicPermissionDefinitionStore) again.

  • User Avatar
    0
    jordanchen98 created

    Hi, I have injected `` in my AppService constructor. and I've tried to set both the LastCheckTime and CacheStamp after I added them to the PermissionDefinition but it is still not saving.

    Am I doing it in the right place?

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    So the permission definition still null?

    Can you share a simple project to reproduce? I will debug it.

    Thanks.

    liming.ma@volosoft.com

  • User Avatar
    0
    jordanchen98 created

    Yes the permission is still null.

    I have email you the test project. Thanks!

    1. Run the API and Angular
    2. Login with default admin credentials 
    3. Head to “Group Management”
    4. Click “+New Group” on top right corner
    5. In the dropdown “Filter Type” select “State”
    6. Give it a testing name and a code.
    7. Click “Save”
    8. Head to “Administration” > “Identity Management” > “Roles” > “admin” > “Permission”
    9. The newly created permission is under the Group KMSv4
    10. Scroll all the way down, and check the newly created state and select save.
    11. Reopen the permission menu to see if it is assigned.
    
    Note: the code for adding the new permission in the “Group Management” is in the FilterValueAppService.cs
    
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    ok, I will check it.

  • User Avatar
    0
    jordanchen98 created

    Thanks!

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    I cant restore the DevExpress packages.

    Can you share a template project instead of the huge project?

    Thanks.

  • User Avatar
    0
    jordanchen98 created

    Hi,

    I've emailed you a new project.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    The project still has some problems.

    Can you add your test code in a new template project? That will be the easiest.

    Thanks

    [11:19:09 ERR] An exception was thrown while activating SSDM.KMSv4.Permissions.KMSv4PermissionDefinitionProvider.
    Autofac.Core.DependencyResolutionException: An exception was thrown while activating SSDM.KMSv4.Permissions.KMSv4PermissionDefinitionProvider.
     ---> Autofac.Core.DependencyResolutionException: None of the constructors found on type 'SSDM.KMSv4.Permissions.KMSv4PermissionDefinitionProvider' can be invoked with the available services and parameters:
    Cannot resolve parameter 'SSDM.KMSv4.FilterValues.IFilterValueAppService filterValueAppService' of constructor 'Void .ctor(SSDM.KMSv4.FilterValues.IFilterValueAppService)'.
    
    See https://autofac.rtfd.io/help/no-constructors-bindable for more info.
       at Autofac.Core.Activators.Reflection.ReflectionActivator.<>c__DisplayClass14_0.<UseSingleConstructorActivation>b__0(ResolveRequestContext context, Action`1 next)
       at Autofac.Core.Resolving.Middleware.DelegateMiddleware.Execute(ResolveRequestContext context, Action`1 next)
       at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext context)
       at Autofac.Core.Resolving.Middleware.DisposalTrackingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
       at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.&lt;&gt;c__DisplayClass14_0.&lt;BuildPipeline&gt;b__1(ResolveRequestContext context)
       at Autofac.Builder.RegistrationBuilder`3.<>c__DisplayClass41_0.<PropertiesAutowired>b__0(ResolveRequestContext context, Action`1 next)
       at Autofac.Core.Resolving.Middleware.DelegateMiddleware.Execute(ResolveRequestContext context, Action`1 next)
       at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext context)
       at Autofac.Extensions.DependencyInjection.KeyedServiceMiddleware.Execute(ResolveRequestContext context, Action`1 next)
       at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.&lt;&gt;c__DisplayClass14_0.&lt;BuildPipeline&gt;b__1(ResolveRequestContext context)
       at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
       --- End of inner exception stack trace ---
       at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
       at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.&lt;&gt;c__DisplayClass14_0.&lt;BuildPipeline&gt;b__1(ResolveRequestContext context)
       at Autofac.Core.Pipeline.ResolvePipeline.Invoke(ResolveRequestContext context)
       at Autofac.Core.Resolving.Middleware.RegistrationPipelineInvokeMiddleware.Execute(ResolveRequestContext context, Action`1 next)
       at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext context)
       at Autofac.Core.Resolving.Middleware.SharingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
       at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.&lt;&gt;c__DisplayClass14_0.&lt;BuildPipeline&gt;b__1(ResolveRequestContext context)
       at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.&lt;&gt;c__DisplayClass14_0.&lt;BuildPipeline&gt;b__1(ResolveRequestContext context)
       at Autofac.Core.Resolving.Middleware.CircularDependencyDetectorMiddleware.Execute(ResolveRequestContext context, Action`1 next)
       at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext context)
       at Autofac.Core.Pipeline.ResolvePipeline.Invoke(ResolveRequestContext context)
       at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ResolveRequest& request)
       at Autofac.Core.Resolving.ResolveOperation.ExecuteOperation(ResolveRequest& request)
       at Autofac.Core.Resolving.ResolveOperation.Execute(ResolveRequest& request)
       at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(ResolveRequest& request)
       at Autofac.Core.Lifetime.LifetimeScope.Autofac.IComponentContext.ResolveComponent(ResolveRequest& request)
       at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance)
       at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters)
       at Autofac.ResolutionExtensions.Resolve(IComponentContext context, Type serviceType, IEnumerable`1 parameters)
       at Autofac.ResolutionExtensions.Resolve(IComponentContext context, Type serviceType)
       at Autofac.Extensions.DependencyInjection.AutofacServiceProvider.GetRequiredService(Type serviceType)
       at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
       at Volo.Abp.Authorization.Permissions.StaticPermissionDefinitionStore.&lt;&gt;c__DisplayClass13_0.&lt;CreatePermissionGroupDefinitions&gt;b__0(Type p)
       at System.Linq.Enumerable.IListSelectIterator`2.Fill(IList`1 source, Span`1 results, Func`2 func)
       at System.Linq.Enumerable.IListSelectIterator`2.ToList()
       at Volo.Abp.Authorization.Permissions.StaticPermissionDefinitionStore.CreatePermissionGroupDefinitions()
       at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
       at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
       at System.Lazy`1.CreateValue()
       at Volo.Abp.Authorization.Permissions.StaticPermissionDefinitionStore.get_PermissionGroupDefinitions()
       at Volo.Abp.Authorization.Permissions.StaticPermissionDefinitionStore.GetGroupsAsync()
       at Volo.Abp.PermissionManagement.StaticPermissionSaver.SaveAsync() in C:\Users\malim\Downloads\NewTestProject\aspnet-core\modules\Volo.Abp.PermissionManagement\src\Volo.Abp.PermissionManagement.Domain\Volo\Abp\PermissionManagement\StaticPermissionSaver.cs:line 84
       at Volo.Abp.PermissionManagement.StaticPermissionSaver.SaveAsync() in C:\Users\malim\Downloads\NewTestProject\aspnet-core\modules\Volo.Abp.PermissionManagement\src\Volo.Abp.PermissionManagement.Domain\Volo\Abp\PermissionManagement\StaticPermissionSaver.cs:line 156
       at Volo.Abp.PermissionManagement.AbpPermissionManagementDomainModule.&lt;&gt;c__DisplayClass8_0.&lt;&lt;SaveStaticPermissionsToDatabaseAsync&gt;b__1>d.MoveNext() in C:\Users\malim\Downloads\NewTestProject\aspnet-core\modules\Volo.Abp.PermissionManagement\src\Volo.Abp.PermissionManagement.Domain\Volo\Abp\PermissionManagement\AbpPermissionManagementDomainModule.cs:line 134
    --- End of stack trace from previous location ---
       at Polly.AsyncPolicy.&lt;&gt;c__DisplayClass44_0.&lt;&lt;ImplementationAsync&gt;b__0>d.MoveNext()
    --- End of stack trace from previous location ---
       at Polly.Retry.AsyncRetryEngine.ImplementationAsync[TResult](Func`3 action, Context context, ExceptionPredicates shouldRetryExceptionPredicates, ResultPredicates`1 shouldRetryResultPredicates, Func`5 onRetryAsync, CancellationToken cancellationToken, Int32 permittedRetryCount, IEnumerable`1 sleepDurationsEnumerable, Func`4 sleepDurationProvider, Boolean continueOnCapturedContext)
    [11:19:09 ERR] ---------- Exception Data ----------
    ActivatorChain = SSDM.KMSv4.Permissions.KMSv4PermissionDefinitionProvider
    
    [11:19:09 INF] Started database migrations...
    [11:19:09 INF] Migrating schema for host database...
    [11:19:09 ERR] An error occurred using the connection to database 'KMSv4_Testing2' on server 'tcp://localhost:5432'.
    [11:19:12 ERR] Failed executing DbCommand (16ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
    CREATE TABLE "AppDeploymentAssignments" (
        "KioskId" bigint NOT NULL,
        "DeploymentId" bigint NOT NULL,
        "Status" text NOT NULL,
        CONSTRAINT "PK_AppDeploymentAssignment" PRIMARY KEY ("KioskId", "DeploymentId"),
        CONSTRAINT "FK_AppDeploymentAssignment_AppKiosks_KioskId" FOREIGN KEY ("KioskId") REFERENCES "AppKiosks" ("Id") ON DELETE CASCADE,
        CONSTRAINT "FK_AppDeploymentAssignment_AppDeployments_DeploymentId" FOREIGN KEY ("DeploymentId") REFERENCES "AppDeployments" ("Id") ON DELETE CASCADE
    );
    Unhandled exception. Npgsql.PostgresException (0x80004005): 42P07: relation "PK_AppDeploymentAssignment" already exists
       at Npgsql.Internal.NpgsqlConnector.ReadMessageLong(Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
       at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
       at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
       at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
       at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
       at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
       at Npgsql.NpgsqlCommand.ExecuteNonQuery(Boolean async, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQueryAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQueryAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQueryAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteAsync(IReadOnlyList`1 migrationCommands, IRelationalConnection connection, MigrationExecutionState executionState, Boolean beginTransaction, Boolean commitTransaction, Nullable`1 isolationLevel, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteAsync(IReadOnlyList`1 migrationCommands, IRelationalConnection connection, MigrationExecutionState executionState, Boolean beginTransaction, Boolean commitTransaction, Nullable`1 isolationLevel, CancellationToken cancellationToken)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQueryAsync(IReadOnlyList`1 migrationCommands, IRelationalConnection connection, MigrationExecutionState executionState, Boolean commitTransaction, Nullable`1 isolationLevel, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.MigrateImplementationAsync(DbContext context, String targetMigration, MigrationExecutionState state, Boolean useTransaction, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.MigrateImplementationAsync(DbContext context, String targetMigration, MigrationExecutionState state, Boolean useTransaction, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.<>c.<<MigrateAsync>b__22_1>d.MoveNext()
    --- End of stack trace from previous location ---
       at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.MigrateAsync(String targetMigration, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.MigrateAsync(String targetMigration, CancellationToken cancellationToken)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Migrations.Internal.NpgsqlMigrator.MigrateAsync(String targetMigration, CancellationToken cancellationToken)
       at SSDM.KMSv4.EntityFrameworkCore.EntityFrameworkCoreKMSv4DbSchemaMigrator.MigrateAsync() in C:\Users\malim\Downloads\NewTestProject\aspnet-core\src\SSDM.KMSv4.EntityFrameworkCore\EntityFrameworkCore\EntityFrameworkCoreKMSv4DbSchemaMigrator.cs:line 28
       at SSDM.KMSv4.Data.KMSv4DbMigrationService.MigrateDatabaseSchemaAsync(Tenant tenant) in C:\Users\malim\Downloads\NewTestProject\aspnet-core\src\SSDM.KMSv4.Domain\Data\KMSv4DbMigrationService.cs:line 95
       at SSDM.KMSv4.Data.KMSv4DbMigrationService.MigrateAsync() in C:\Users\malim\Downloads\NewTestProject\aspnet-core\src\SSDM.KMSv4.Domain\Data\KMSv4DbMigrationService.cs:line 52
       at SSDM.KMSv4.DbMigrator.DbMigratorHostedService.StartAsync(CancellationToken cancellationToken) in C:\Users\malim\Downloads\NewTestProject\aspnet-core\src\SSDM.KMSv4.DbMigrator\DbMigratorHostedService.cs:line 36
       at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
       at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
       at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
       at SSDM.KMSv4.DbMigrator.Program.Main(String[] args) in C:\Users\malim\Downloads\NewTestProject\aspnet-core\src\SSDM.KMSv4.DbMigrator\Program.cs:line 29
       at SSDM.KMSv4.DbMigrator.Program.<Main>(String[] args)
      Exception data:
        Severity: ERROR
        SqlState: 42P07
        MessageText: relation "PK_AppDeploymentAssignment" already exists
        File: index.c
        Line: 885
        Routine: index_create
    

  • User Avatar
    0
    jordanchen98 created

    Hi,

    I have emailed you the template project with the test code.

    I think I've missed the .sql to restore so here it is: https://drive.google.com/file/d/1dIy4aG86qzAZ9TII0YJGDn_ftVZjkxvV/view?usp=drive_link

    Thanks!

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Thanks . I will check your project.

  • User Avatar
    0
    jordanchen98 created

    Thanks!

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    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);
    }
    
    
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    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.

  • User Avatar
    0
    jordanchen98 created

    Hi,

    I tried it, it works well! When but when I restart the API the permission goes away so I guess I HAVE to save it into the database.

    Do I store it into AbpPermissions after I added it into the static permission? Note: I saw that the new permission is added to AbpPermissionGrants

    Thanks!

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You can insert it into AbpPermissions table.

    Then call the DynamicPermissionDefinitionStoreInMemoryCache method to clear the memory cache.

    DynamicPermissionDefinitionStoreInMemoryCache.LastCheckTime = null;
    DynamicPermissionDefinitionStoreInMemoryCache.CacheStamp = Guid.NewGuid().ToString();
    

    In other words: you can use DynamicPermissionDefinitionStore to add new permission to the database instead of using StaticPermissionDefinitionStore

    Dynamic means getting permissions from the database. and use DynamicPermissionDefinitionStoreInMemoryCache to cache it

  • User Avatar
    0
    jordanchen98 created

    Hi,

    I tried your method in my project and when I tried to run HttpApi.Host it said something about having an issue with the ISingletonDependancy.

    using Microsoft.AspNetCore.Authorization;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Options;
    using SSDM.KMSv4.FilterFields;
    using SSDM.KMSv4.FilterFieldShared;
    using SSDM.KMSv4.ItemFilters;
    using SSDM.KMSv4.Kiosks;
    using SSDM.KMSv4.Localization;
    using SSDM.KMSv4.Permissions;
    using System;
    using System.Collections.Generic;
    using System.Collections.Immutable;
    using System.Linq;
    using System.Threading.Tasks;
    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;
    
    namespace SSDM.KMSv4.FilterValues;
    
    [RemoteService(IsEnabled = false)]
    [Authorize(KMSv4Permissions.FilterValues.Default)]
    public class FilterValueAppService : ApplicationService, IFilterValueAppService
    {
        private readonly FilterValueChildSharedService _fv;
    
        private readonly IKioskRepository _kioskRepository;
        private readonly IItemFilterRepository _itemFilterRepository;
        private readonly IFilterFieldRepository _filterFieldRepository;
        private readonly IFilterValueRepository _filterValueRepository;
        
        private readonly IExtendedStaticPermissionDefinitionStore _staticPermissionDefinitionStore;
        private readonly IPermissionDefinitionManager _permissionDefinitionManager;
    
        public FilterValueAppService(
            IItemFilterRepository itemFilterRepository, IFilterFieldRepository filterFieldRepository,
            IFilterValueRepository filterValueRepository, IKioskRepository kioskRepository,
            IExtendedStaticPermissionDefinitionStore staticPermissionDefinitionStore,
            IPermissionDefinitionManager permissionDefinitionManager
        )
        {
            _kioskRepository = kioskRepository;
            _itemFilterRepository = itemFilterRepository;
            _filterFieldRepository = filterFieldRepository;
            _filterValueRepository = filterValueRepository;
            _staticPermissionDefinitionStore = staticPermissionDefinitionStore;
            _permissionDefinitionManager = permissionDefinitionManager;
    
            _fv = new FilterValueChildSharedService(itemFilterRepository);
        }
    
        //---- Other functions ----//
    
        [Authorize(KMSv4Permissions.FilterValues.Create)]
        public virtual async Task<FilterValueDto> CreateAsync(FilterValueCreateDto input)
        {
            // Fetch records by FilterFieldId
            var recordsByFilterFieldId = await _filterValueRepository.GetListAsync(x => x.FilterFieldId.Equals(input.FilterFieldID));
            var ids = recordsByFilterFieldId.Select(x => x.Id).ToList();
    
            // Define the range
            int min = 1;
            int max = 2000000;
    
            // Get a random number not in the excluded list
            var generatedId = await GetRandomNumberNotInList(min, max, ids);
    
            FilterValue f = await _filterValueRepository.FirstOrDefaultAsync(x => x.Code == input.Code || x.Value == input.Value);
            if (f == null)
            {
                f = new FilterValue
                {
                    Id = generatedId,
                    Code = input.Code ?? "",
                    Value = input.Value ?? "",
                    FilterFieldId = input.FilterFieldID
                };
            }
            try
            {
                await _filterValueRepository.InsertAsync(f, true);
            }
            catch (Exception ex)
            {
                throw new UserFriendlyException(ex.Message);
            }
            await _fv.UpdateCreateItemFilter(f.Id, input.FilterValueParts);
    
            var branch = await _filterFieldRepository.FirstOrDefaultAsync(x => x.Desc.ToLower().Equals("branch"));
            var state = await _filterFieldRepository.FirstOrDefaultAsync(x => x.Desc.ToLower().Equals("state"));
    
            // Add Branch
            if (branch is not null && state is not null && input.FilterFieldID.Equals(branch.Id))
            {
                var branch_state = input.FilterValueParts.FirstOrDefault(x => x.ID.Equals(state.Id))?.Value.Replace(" ", "");
                var statePermission = await _permissionDefinitionManager.GetAsync(KMSv4Permissions.States.Default + "." + branch_state);
    
                if(statePermission is not null)
                {
                    var permission = statePermission.AddChild("KMSv4.Branches." + f.Value.Replace(" ", ""), L(f.Value));
                    await _staticPermissionDefinitionStore.AddPermissionDefinitionAsync(permission);
                }
            }
    
            // Add State
            if (state is not null && input.FilterFieldID.Equals(state.Id))
            {
                var statePermission = await _permissionDefinitionManager.GetAsync(KMSv4Permissions.States.Default);
                string state_permission_name = KMSv4Permissions.States.Default + "." + f.Value.Replace(" ", "");
    
                if (statePermission is not null)
                {
                    var permission = statePermission.AddChild(state_permission_name, L(f.Value));
                    await _staticPermissionDefinitionStore.AddPermissionDefinitionAsync(permission);
                }
            }
    
            return null;
        }
    
    }
    
    [Dependency(ReplaceServices = true)]
    [ExposeServices(typeof(IStaticPermissionDefinitionStore), typeof(IExtendedStaticPermissionDefinitionStore))]
    public class MyStaticPermissionDefinitionStore : 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);
    }
    

    And I got this error:

     at Autofac.Core.Pipeline.ResolvePipeline.Invoke(Autofac.Core.Resolving.Pipeline.ResolveRequestContext)
       at Autofac.Core.Resolving.ResolveOperation.InvokePipeline(Autofac.ResolveRequest ByRef, Autofac.Core.Resolving.Pipeline.DefaultResolveRequestContext)
       at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(Autofac.Core.ISharingLifetimeScope, Autofac.ResolveRequest ByRef)
       at Autofac.Core.Resolving.ResolveOperation.ExecuteOperation(Autofac.ResolveRequest ByRef)
       at Autofac.Core.Resolving.ResolveOperation.Execute(Autofac.ResolveRequest ByRef)
       at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(Autofac.ResolveRequest ByRef)
       at Autofac.Core.Lifetime.LifetimeScope.Autofac.IComponentContext.ResolveComponent(Autofac.ResolveRequest ByRef)
       at Autofac.ResolutionExtensions.TryResolveService(Autofac.IComponentContext, Autofac.Core.Service, System.Collections.Generic.IEnumerable`1&lt;Autofac.Core.Parameter&gt;, System.Object ByRef)
       at Autofac.ResolutionExtensions.ResolveService(Autofac.IComponentContext, Autofac.Core.Service, System.Collections.Generic.IEnumerable`1<Autofac.Core.Parameter>)
       at Autofac.ResolutionExtensions.Resolve(Autofac.IComponentContext, System.Type, System.Collections.Generic.IEnumerable`1&lt;Autofac.Core.Parameter&gt;)
       at Autofac.ResolutionExtensions.Resolve(Autofac.IComponentContext, System.Type)
       at Autofac.Extensions.DependencyInjection.AutofacServiceProvider.GetRequiredService(System.Type)
       at SSDM.KMSv4.FilterValues.MyStaticPermissionDefinitionStore+&lt;&gt;c__DisplayClass10_0.&lt;CreatePermissionGroupDefinitions&gt;b__0(System.Type)
       at System.Linq.Enumerable+IListSelectIterator`2[[System.__Canon, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Fill(System.Collections.Generic.IList`1&lt;System.__Canon&gt;, System.Span`1<System.__Canon>, System.Func`2&lt;System.__Canon,System.__Canon&gt;)
       at System.Linq.Enumerable+IListSelectIterator`2[[System.__Canon, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].ToList()
       at SSDM.KMSv4.FilterValues.MyStaticPermissionDefinitionStore.CreatePermissionGroupDefinitions()
       at DynamicClass.lambda_method1092(System.Runtime.CompilerServices.Closure, System.Object[])
       at Autofac.Core.Activators.Reflection.BoundConstructor.Instantiate()
       at Autofac.Core.Activators.Reflection.ReflectionActivator+<>c__DisplayClass14_0.<UseSingleConstructorActivation>b__0(Autofac.Core.Resolving.Pipeline.ResolveRequestContext, System.Action`1&lt;Autofac.Core.Resolving.Pipeline.ResolveRequestContext&gt;)
    

    Not sure what this means.

  • User Avatar
    0
    jordanchen98 created

    DynamicPermissionDefinitionStoreInMemoryCache.LastCheckTime = null; DynamicPermissionDefinitionStoreInMemoryCache.CacheStamp = Guid.NewGuid().ToString();

    Does this mean I can skip the static portion? and just use Dynamic Permission?

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Does this mean I can skip the static portion? and just use Dynamic Permission?

    Yes.

    You can upload your test project to Github, and invite me to join.

    https://github.com/maliming

  • User Avatar
    0
    jordanchen98 created

    I've added the dynamic permission but when I restarted the API, its not showing up.

    Here is my implementation

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    You can upload your test project to Github, and invite me to join.

    https://github.com/maliming

  • User Avatar
    0
    jordanchen98 created

    I've invited you to my repository.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    ok, I will check your project.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    I have fixed the problem.

    The key code is: Dynamic permissions over static permissions. The default logic of abp is We prefer static permissions over dynamics, but it is unsuitable for your situation.

    See: https://github.com/AldanJdc/AbpSolutionForPermission/pull/1

Made with ❤️ on ABP v9.1.0-preview. Updated on December 13, 2024, 06:09