Open Closed

Multiple permission to services #1014


User avatar
0
tomcic created

Check the docs before asking a question: https://docs.abp.io/en/commercial/latest/ Check the samples, to see the basic tasks: https://docs.abp.io/en/commercial/latest/samples/index The exact solution to your question may have been answered before, please use the search on the homepage.

  • ABP Framework version: v4.2.2.
  • UI type: MVC
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): no

How to set permissions to gain access for the user who has been assigned the permission WorkAppPermissions.WorkLogs.Default or WorkAppPermissions.WorkLogsPowerAdmin.Default ?

Thanks :)

namespace WorkApp.WorkLogs {

[Authorize(WorkAppPermissions.WorkLogs.Default)] OR [Authorize(WorkAppPermissions.WorkLogsPowerAdmin.Default)]                       //<=================== pseudocode P1 OR P2

> public class WorkLogAppService : ApplicationService, IWorkLogAppService

{
    private readonly IWorkLogRepository _workLogRepository;
    private readonly IRepository<AppUser, Guid> _appUserRepository;

    public WorkLogAppService(IWorkLogRepository workLogRepository, IRepository<AppUser, Guid> appUserRepository)
    {
        _workLogRepository = workLogRepository; _appUserRepository = appUserRepository;
    }

    public virtual async Task<PagedResultDto<WorkLogWithNavigationPropertiesDto>> GetListAsync(GetWorkLogsInput input)
    {
        var totalCount = await _workLogRepository.GetCountAsync(input.FilterText, input.Title, input.StartDateMin, input.StartDateMax, input.EndDateMin, input.EndDateMax, input.Description, input.AppUserId);
        var items = await _workLogRepository.GetListWithNavigationPropertiesAsync(input.FilterText, input.Title, input.StartDateMin, input.StartDateMax, input.EndDateMin, input.EndDateMax, input.Description, input.AppUserId, input.Sorting, input.MaxResultCount, input.SkipCount);

        return new PagedResultDto<WorkLogWithNavigationPropertiesDto>
        {
            TotalCount = totalCount,
            Items = ObjectMapper.Map<List<WorkLogWithNavigationProperties>, List<WorkLogWithNavigationPropertiesDto>>(items)
        };
    }

    public virtual async Task<WorkLogWithNavigationPropertiesDto> GetWithNavigationPropertiesAsync(Guid id)
    {
        return ObjectMapper.Map<WorkLogWithNavigationProperties, WorkLogWithNavigationPropertiesDto>
            (await _workLogRepository.GetWithNavigationPropertiesAsync(id));
    }

    public virtual async Task<WorkLogDto> GetAsync(Guid id)
    {
        return ObjectMapper.Map<WorkLog, WorkLogDto>(await _workLogRepository.GetAsync(id));
    }

    public virtual async Task<PagedResultDto<LookupDto<Guid?>>> GetAppUserLookupAsync(LookupRequestDto input)
    {
        var query = _appUserRepository.AsQueryable()
            .WhereIf(!string.IsNullOrWhiteSpace(input.Filter),
                x => x.UserName != null &&
                     x.UserName.Contains(input.Filter));

        var lookupData = await query.PageBy(input.SkipCount, input.MaxResultCount).ToDynamicListAsync<AppUser>();
        var totalCount = query.Count();
        return new PagedResultDto<LookupDto<Guid?>>
        {
            TotalCount = totalCount,
            Items = ObjectMapper.Map<List<AppUser>, List<LookupDto<Guid?>>>(lookupData)
        };
    }

    [Authorize(WorkAppPermissions.WorkLogs.Delete)]
    public virtual async Task DeleteAsync(Guid id)
    {
        await _workLogRepository.DeleteAsync(id);
    }

    [Authorize(WorkAppPermissions.WorkLogs.Create)]
    public virtual async Task<WorkLogDto> CreateAsync(WorkLogCreateDto input)
    {
        var workLog = ObjectMapper.Map<WorkLogCreateDto, WorkLog>(input);

        workLog = await _workLogRepository.InsertAsync(workLog, autoSave: true);
        return ObjectMapper.Map<WorkLog, WorkLogDto>(workLog);
    }

    [Authorize(WorkAppPermissions.WorkLogs.Edit)]
    public virtual async Task<WorkLogDto> UpdateAsync(Guid id, WorkLogUpdateDto input)
    {
        var workLog = await _workLogRepository.GetAsync(id);
        ObjectMapper.Map(input, workLog);
        workLog = await _workLogRepository.UpdateAsync(workLog);
        return ObjectMapper.Map<WorkLog, WorkLogDto>(workLog);
    }
}

}


7 Answer(s)
  • User Avatar
    0
    gterdem created
    Support Team Senior .NET Developer

    I couldn't understand the reason behind requiring two individual different permission for a single resource.

    Logically, permissions are the privillage representations of your resource for the consumers. You expose WorkLog application service so that the service methods can have different delete/edit etc permissions or just under an umbrella like WorkAppPermissions.WorkLogs.Default.

    However WorkAppPermissions.WorkLogsPowerAdmin.Default does sound more like a role representation instead of resource privillage. So why not create something like LogPowerAdmin role granting this permission already?

  • User Avatar
    0
    tomcic created

    I would like to give the entry owner permissions and the same permissions for all records to the administrator. In the code I want to include filter if LogPowerAdmin show all, if WorkLogs show only current user resources. Is this the right way?

  • User Avatar
    0
    gterdem created
    Support Team Senior .NET Developer

    I would like to give the entry owner permissions and the same permissions for all records to the administrator.

    What do you mean by entry owner permissions?

    In the code I want to include filter if LogPowerAdmin show all, if WorkLogs show only current user resources. Is this the right way?

    Is showing users resources related with data? You want to query data based on user or role? If requester is an admin, get all the data from db; if a user, get only data that the user has created. Do I understand correctly?

  • User Avatar
    0
    tomcic created

    If requester is an admin, get all the data from db; if a user, get only data that the user has created.

    Exacly, this is what I want to do.

  • User Avatar
    0
    gterdem created
    Support Team Senior .NET Developer

    If requester is an admin, get all the data from db; if a user, get only data that the user has created.

    Exacly, this is what I want to do.

    Cool!

    I don't think you need to drag or bend permission system for this.

    In Domain layer, you can write query filters or interceptor based on your needs.

    Or if you want to handle in application service layer, you can inject ICurrentUser and check if user has admin role under currentUser.Roles so that you can pass something like query = query.Where(q => q.CreatorId == _currentUser.Id) if currentUser.Roles does not contain admin role (or however you decide).

  • User Avatar
    0
    tomcic created

    I would like to define Permissions:

            public static class WorkAppPermissions
            {
                public const string GroupName = "WorkApp";
    
                public static class Dashboard
                {
                    public const string DashboardGroup = GroupName + ".Dashboard";
                    public const string Host = DashboardGroup + ".Host";
                    public const string Tenant = DashboardGroup + ".Tenant";
                }
    
                //Add your own permission names. Example:
                //public const string MyPermission1 = GroupName + ".MyPermission1";
    
                public class WorkLogs
                {
                    public const string Default = GroupName + ".WorkLogs";
                    public const string Edit = Default + ".Edit";
                    public const string Create = Default + ".Create";
                    public const string Delete = Default + ".Delete";
                }
    
                public class WorkLogsPowerAdmin
                {
                    public const string Default = GroupName + ".WorkLogs";
                    public const string Edit = Default + ".Edit";
                    public const string Create = Default + ".Create";
                    public const string Delete = Default + ".Delete";
                }
            }
    

    To be able to use them when configuring the system in Identity Management -> Roles -> Permissions. Your solution severely limits configuration flexibility. In the domain layer, It should refer to Permissions, Roles should be remained flexible. Therefore, I would like to know how to handle this case in endpoint.

  • User Avatar
    0
    sgal created

    I think business (data) permissions and functional permissions need to be distinguished. I use organizational structure to solve these problems.

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11