Activities of "berkansasmaz"

Thanks, we will review the relevant document and update it if we need to update it. I created an internal issue for this.


I'm closing this issue for now. If you have a different question, feel free to create a new question.

Hello,

ABP allows you to extend permissions. You can add custom properties like below:

    var bookPermission = myGroup.AddPermission(AbpSolution2Permissions.Books.Default, L("Permission:Books"));
        bookPermission.WithProperty("moduleId", "CmsKit");
        
        bookPermission.AddChild(AbpSolution2Permissions.Books.Create, L("Permission:Create")).WithProperty("moduleId", "CmsKit");

Then you can add your own PermissionValueProvider as a contributor as follows:

ublic class ModulePermissionValueProvider : PermissionValueProvider
{
    public override string Name => "ModuleUser";
    
    public ModulePermissionValueProvider(IPermissionStore permissionStore)
        : base(permissionStore)
    {
    }

    public override Task<MultiplePermissionGrantResult> CheckAsync(PermissionValuesCheckContext context)
    {
        var permissionNames = context.Permissions.Select(x => x.Name).ToArray();

        foreach (var permission in context.Permissions)
        {
            if (!CheckAsync(context.Principal, permission.Properties["module_id"]?.ToString()))
            {
                return Task.FromResult(new MultiplePermissionGrantResult(permissionNames, PermissionGrantResult.Prohibited));
            }
        }

        return Task.FromResult(new MultiplePermissionGrantResult(permissionNames, PermissionGrantResult.Granted)); 
    }

   

    public override Task<PermissionGrantResult> CheckAsync(PermissionValueCheckContext context)
    {
        var moduleId = context.Permission.Properties["module_id"]?.ToString();
        if (moduleId.IsNullOrEmpty())
        {
            return Task.FromResult(PermissionGrantResult.Undefined); 
        }
        
        if (!CheckAsync(context.Principal, context.Permission.Properties["module_id"]!.ToString()))
        {
            return Task.FromResult(PermissionGrantResult.Prohibited);
        }

        return Task.FromResult(PermissionGrantResult.Granted);
    }
    
    private bool CheckAsync(ClaimsPrincipal? principal, string? moduleId)
    {
        if (moduleId.IsNullOrEmpty() || principal == null)
        {
            return false;
        }


        return principal!.HasClaim(x => x.Type == moduleId);
    }
}

Once a provider is defined, it should be added to the AbpPermissionOptions as shown below:

Configure<AbpPermissionOptions>(options =>
{
    options.ValueProviders.Add<ModulePermissionValueProvider>();
});

See more: https://abp.io/docs/latest/framework/fundamentals/authorization#permission-value-providers

**Disclaimler: ** This code is not recommended for direct use in a production environment. It was created just to give an idea, you can customize it according to your own needs.


Hi,

As far as I know, a new key is not created. So when your license expires, you can continue to develop in the current version. You can even update your application to the new patch versions that will be released. You can find more information here.

Hi,

I had difficulty understanding your question, but if I understand correctly, we can try the following methods:

Move the responsibility of calling initLeptonX and afterLeptonXInitialization to DynamicLayoutPicker, triggering it only when the layout changes like below:

namespace CFDataSystems.StructureCloud.Blazor.Themes.LeptonX.Layouts;

public partial class DynamicLayoutPicker : LayoutComponentBase, IDisposable
{
    [Inject] private NavigationManager _navManager { get; set; }
    [Inject] private IJSRuntime JSRuntime { get; set; }

    public Type CurrentLayout { get; set; } = typeof(SideMenuLayout);
    private Type _previousLayout = null;

    protected override Task OnInitializedAsync()
    {
        _navManager.LocationChanged += OnLocationChanged;
        SetLayout(_navManager.Uri);
        return base.OnInitializedAsync();
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender || _previousLayout != CurrentLayout)
        {
            // Reinitialize LeptonX only when layout changes
            await JSRuntime.InvokeVoidAsync("initLeptonX", new[] { "side-menu", "structurecloud" });
            await JSRuntime.InvokeVoidAsync("afterLeptonXInitialization", new[] { "side-menu", "structurecloud" });
            _previousLayout = CurrentLayout;
        }
    }

    public void Dispose()
    {
        _navManager.LocationChanged -= OnLocationChanged;
    }

    private void OnLocationChanged(object sender, LocationChangedEventArgs e)
    {
        SetLayout(e.Location);
    }

    private void SetLayout(string location)
    {
        if (location.Contains("tenant-procedure-list"))
        {
            CurrentLayout = typeof(ProceduresPageLayout);
        }
        else if (location.Contains("SampleTenantDefault"))
        {
            CurrentLayout = typeof(TenantDefaultLayout);
        }
        else
        {
            CurrentLayout = typeof(SideMenuLayout);
        }
        StateHasChanged();
    }
}


If this does not solve your problem, I can help better if you can provide a minimal reproducible example where I can replicate the problem.

Hello,

Can you try the following code?

public sealed class MyPrepareIdentityTokenPrincipal : IOpenIddictServerHandler<OpenIddictServerEvents.ProcessSignInContext>
{
    public static OpenIddictServerHandlerDescriptor Descriptor { get; }
        = OpenIddictServerHandlerDescriptor.CreateBuilder<OpenIddictServerEvents.ProcessSignInContext>()
            .AddFilter<OpenIddictServerHandlerFilters.RequireIdentityTokenGenerated>()
            .UseSingletonHandler<MyPrepareIdentityTokenPrincipal>()
            .SetOrder(OpenIddictServerHandlers.PrepareIdentityTokenPrincipal.Descriptor.Order + 1)
            .SetType(OpenIddictServerHandlerType.Custom)
            .Build();

    public ValueTask HandleAsync(OpenIddictServerEvents.ProcessSignInContext context)
    {
        if (context is null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        // ....

        return default;
    }
}

Then add it to the PreConfigureServices method of the module class as follows:

        public override void PreConfigureServices(ServiceConfigurationContext context)
        {
            //  ....
            

            PreConfigure<OpenIddictServerBuilder>(builder =>
            {
                builder.AddEventHandler(MyPrepareIdentityTokenPrincipal.Descriptor);
            });
        }

App.razor files are part of the UI Theme. Each time implements it according to their requirements. You can create a new App.razor in your project and use it.

But ABP Framework and Modules can't support Lazy Loading since they register their services into the dependency injection container and UI Components are resolved from ServiceProvider before rendering. So, that logic makes all of them replaceable from outside of the original assembly.

You can see this issue: https://github.com/abpframework/abp/issues/5543

But Blazorise supports it by default and you don't need to do any configuration. It loads required js and dll files when you use a component.


There is a useful article about it: https://community.abp.io/posts/prerendering-blazor-wasm-application-with-abp-6.x-2v8590g3

Hi,

If you want to override only LoginModel you can do it as below:

[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(LoginModel))]
[DisableAuditing]
public class TappLoginModel : LoginModel
{

    public TappLoginModel(
        IAuthenticationSchemeProvider schemeProvider,
        IOptions<AbpAccountOptions> accountOptions,
        IAbpRecaptchaValidatorFactory recaptchaValidatorFactory,
        IAccountExternalProviderAppService accountExternalProviderAppService,
        ICurrentPrincipalAccessor currentPrincipalAccessor,
        IOptions<IdentityOptions> identityOptions,
        IOptionsSnapshot<reCAPTCHAOptions> reCaptchaOptions) : base(
        schemeProvider,
        accountOptions,
        recaptchaValidatorFactory,
        accountExternalProviderAppService,
        currentPrincipalAccessor,
        identityOptions,
        reCaptchaOptions)
    {

    }

    public override Task<IActionResult> OnGetAsync()
    {
        return base.OnGetAsync();
    }


    [UnitOfWork] //TODO: Will be removed when we implement action filter
    public virtual async Task<IActionResult> OnPostAsync(string action)
    {
        try
        {
            await ReCaptchaVerification();
        }
        catch (UserFriendlyException e)
        {
            if (e is ScoreBelowThresholdException)
            {
                var onScoreBelowThresholdResult = OnRecaptchaScoreBelowThreshold();
                if (onScoreBelowThresholdResult != null)
                {
                    return await onScoreBelowThresholdResult;
                }
            }

            Alerts.Danger(GetLocalizeExceptionMessage(e));
            return Page();
        }

        ValidateModel();

        await IdentityOptions.SetAsync();

        var localLoginResult = await CheckLocalLoginAsync();
        if (localLoginResult != null)
        {
            return localLoginResult;
        }

        IsSelfRegistrationEnabled = await SettingProvider.IsTrueAsync(AccountSettingNames.IsSelfRegistrationEnabled);

        await ReplaceEmailToUsernameOfInputIfNeeds();

        IsLinkLogin = await VerifyLinkTokenAsync();

        var result = await SignInManager.PasswordSignInAsync(
            LoginInput.UserNameOrEmailAddress,
            LoginInput.Password,
            LoginInput.RememberMe,
            true
        );

        await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext
        {
            Identity = IdentitySecurityLogIdentityConsts.Identity,
            Action = result.ToIdentitySecurityLogAction(),
            UserName = LoginInput.UserNameOrEmailAddress
        });

        if (result.RequiresTwoFactor)
        {
            return RedirectToPage("./SendSecurityCode", new {
                returnUrl = ReturnUrl,
                returnUrlHash = ReturnUrlHash,
                rememberMe = LoginInput.RememberMe,
                linkUserId = LinkUserId,
                linkTenantId = LinkTenantId,
                linkToken = LinkToken
            });
        }


        if (result.IsLockedOut)
        {
            var lockedUser = await GetIdentityUser(LoginInput.UserNameOrEmailAddress);
            await StoreLockedUser(lockedUser);
            return RedirectToPage("./LockedOut", new {
                returnUrl = ReturnUrl,
                returnUrlHash = ReturnUrlHash
            });
        }

        if (result.IsNotAllowed)
        {
            var notAllowedUser = await GetIdentityUser(LoginInput.UserNameOrEmailAddress);

            if (!await UserManager.CheckPasswordAsync(notAllowedUser, LoginInput.Password))
            {
                Alerts.Danger(L["InvalidUserNameOrPassword"]);
                return Page();
            }

            if (notAllowedUser.ShouldChangePasswordOnNextLogin || await UserManager.ShouldPeriodicallyChangePasswordAsync(notAllowedUser))
            {
                await StoreChangePasswordUser(notAllowedUser);
                return RedirectToPage("./ChangePassword", new {
                    returnUrl = ReturnUrl,
                    returnUrlHash = ReturnUrlHash,
                    RememberMe = LoginInput.RememberMe
                });
            }

            if (notAllowedUser.IsActive)
            {
                await StoreConfirmUser(notAllowedUser);
                return RedirectToPage("./ConfirmUser", new {
                    returnUrl = ReturnUrl,
                    returnUrlHash = ReturnUrlHash
                });
            }

            Alerts.Danger(L["LoginIsNotAllowed"]);
            return Page();
        }

        if (!result.Succeeded)
        {
            Alerts.Danger(L["InvalidUserNameOrPassword"]);
            return Page();
        }

        var user = await GetIdentityUser(LoginInput.UserNameOrEmailAddress);

        if (IsLinkLogin)
        {
            using (CurrentPrincipalAccessor.Change(await SignInManager.CreateUserPrincipalAsync(user)))
            {
                await IdentityLinkUserAppService.LinkAsync(new LinkUserInput
                {
                    UserId = LinkUserId.Value,
                    TenantId = LinkTenantId,
                    Token = LinkToken
                });

                await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext
                {
                    Identity = IdentitySecurityLogIdentityConsts.Identity,
                    Action = IdentityProSecurityLogActionConsts.LinkUser,
                    UserName = user.UserName,
                    ExtraProperties =
                        {
                            { IdentityProSecurityLogActionConsts.LinkTargetTenantId, LinkTenantId },
                            { IdentityProSecurityLogActionConsts.LinkTargetUserId, LinkUserId }
                        }
                });

                using (CurrentTenant.Change(LinkTenantId))
                {
                    var targetUser = await UserManager.GetByIdAsync(LinkUserId.Value);
                    using (CurrentPrincipalAccessor.Change(await SignInManager.CreateUserPrincipalAsync(targetUser)))
                    {
                        await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext
                        {
                            Identity = IdentitySecurityLogIdentityConsts.Identity,
                            Action = IdentityProSecurityLogActionConsts.LinkUser,
                            UserName = targetUser.UserName,
                            ExtraProperties =
                                {
                                    { IdentityProSecurityLogActionConsts.LinkTargetTenantId, targetUser.TenantId },
                                    { IdentityProSecurityLogActionConsts.LinkTargetUserId, targetUser.Id }
                                }
                        });
                    }
                }

                return RedirectToPage("./LinkLogged", new {
                    returnUrl = ReturnUrl,
                    returnUrlHash = ReturnUrlHash,
                    targetLinkUserId = LinkUserId,
                    targetLinkTenantId = LinkTenantId
                });
            }
        }

        // Clear the dynamic claims cache.
        await IdentityDynamicClaimsPrincipalContributorCache.ClearAsync(user.Id, user.TenantId);

        return await RedirectSafelyAsync(ReturnUrl, ReturnUrlHash);
    }
}

Hello,

You cannot access the packages of ABP Pro modules from nuget.org. We have our own NuGet server due to some license validations.

Does the project you created have a NuGet.Config file? If so, can you check if the nuget.abp.io source has been added like below?

Hi,

Thanks for this feature request. I am opening an internal issue(internal repo issue number 19424) for this. We will review this feature and then if we see that it is necessary, it can be added in a short time. However, if it is not a must, we may not be able to spend time on it as a priority. Thank you for your understanding.

Hi,

Can you add the [DisableAuditing] attribute to the related entity? I think this restriction comes from the AuditLogging module.

https://abp.io/docs/latest/framework/infrastructure/audit-logging#enable-disable-for-entities-properties

Showing 261 to 270 of 742 entries
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.2.0-preview. Updated on February 17, 2026, 09:10
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.