Base solution for your next web application

Activities of "cpadmin"

Hi @ismcagdas,

We need to implement this requirement in our Asp.Net Core & Angular(v5.3.0) project. Before we start, we need to know if this requirement is in your road map feature named "Tenant subscription enhancements (like recurring payments)". If yes then what is the timeline?

Thanks

Hi @imcagdas,

Thanks for the information. We will give a try to find how much changes are involved and how does that affect when we upgrade AspNet Zero.

We will let you know if any specific code flow information is required.

Thanks

Thanks alper for the feedback. But as per requirements we did not mean to create Static Roles.

We meant that host user will create Roles and assigns it to tenant. These roles are the options to be chosen in Roles section while creating/editing a tenant user. Tenant admin user does not create/update roles/permissions, he just assigns role to a tenant user.

The main thing is to grab roles from host area in a way so as point 7 above is fulfilled(to propagate the Role's permissions changed by host user to all the tenant users who are assigned that role).

Please guide us on this if possible in single-DB approach as well as in DB-per-tenant approach.

Thanks

Hi,

We are using Asp.Net Core & Angular(v5.3.0). We have a requirement as below for multi-tenant application:

  1. Tenant users are not able to create Roles.
  2. Only Host user is able to create Roles to be used in tenants along with permissions. The roles to be used for host area will be differentiated with a flag in current role entity.
  3. While creating/updating an Edition, few roles are associated/attached to the edition from the roles created by host user for tenants.
  4. When a Tenant is created an Edition is attached, so the Roles in that Edition are applied to Tenant(not copied but linked).
  5. Tenant admin cannot change Roles and its permissions(as permissions are fetched from roles that are in host area).
  6. While creating a user in a tenant, roles can be chosen only from the linked Roles from edition. Permissions are taken from these assigned Roles( i.e. from host area).
  7. When a new entity is added for the tenant area and related permissions are created, only host can change Roles to have these new permissions. These permissions should be propagated among the roles in all the tenants.

In short, only host can add/edit Roles and its permissions. Tenant can only inherit these Roles and permissions, and tenant users will behave as per these permissions.

We need to know whether this is a possibility in current architecture(both Single-DB and DB-per-tenant approach). Guide us where the changes needs to be done if this is a possibility.

Thanks

How to do it in DB per Tenant approach?

Even after making the given changes I am still getting the same error: <span style="color:#FF0000">System.InvalidTimeZoneException: "Aleutian Standard Time" was not recognized as a valid IANA time zone name, or has no equivalant Windows time zone.</span>

It says: <span style="color:#FF0000">'ITimeZoneService' does not contain a definition for 'FindTimeZoneById'</span>

TimeZoneService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Abp.Application.Services.Dto;
using Abp.Configuration;
using Abp.Dependency;
using Abp.Timing;
using Abp.Timing.Timezone;
using TimeZoneConverter;

namespace PhoneBook.PhoneBookProjects_Demo.Timing
{
    public class TimeZoneService : ITimeZoneService, ITransientDependency
    {
        readonly ISettingManager _settingManager;
        readonly ISettingDefinitionManager _settingDefinitionManager;

        public TimeZoneService(
            ISettingManager settingManager,
            ISettingDefinitionManager settingDefinitionManager)
        {
            _settingManager = settingManager;
            _settingDefinitionManager = settingDefinitionManager;
        }

        public async Task<string> GetDefaultTimezoneAsync(SettingScopes scope, int? tenantId)
        {
            if (scope == SettingScopes.User)
            {
                if (tenantId.HasValue)
                {
                    return await _settingManager.GetSettingValueForTenantAsync(TimingSettingNames.TimeZone, tenantId.Value);
                }

                return await _settingManager.GetSettingValueForApplicationAsync(TimingSettingNames.TimeZone);
            }

            if (scope == SettingScopes.Tenant)
            {
                return await _settingManager.GetSettingValueForApplicationAsync(TimingSettingNames.TimeZone);
            }

            if (scope == SettingScopes.Application)
            {
                var timezoneSettingDefinition = _settingDefinitionManager.GetSettingDefinition(TimingSettingNames.TimeZone);
                return timezoneSettingDefinition.DefaultValue;
            }

            throw new Exception("Unknown scope for default timezone setting.");
        }

        public List<NameValueDto> GetWindowsTimezones()
        {
            return TimezoneHelper.GetWindowsTimeZoneInfos().OrderBy(tz => tz.BaseUtcOffset)
                .Select(tz => new NameValueDto
                {
                    Value = tz.Id,
                    Name = tz.DisplayName
                }).ToList();
        }
    }
}

TimingAppService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Abp.Application.Services.Dto;
using Abp.Configuration;
using PhoneBook.PhoneBookProjects_Demo.Timing.Dto;

namespace PhoneBook.PhoneBookProjects_Demo.Timing
{
    public class TimingAppService : PhoneBookProjects_DemoAppServiceBase, ITimingAppService
    {
        private readonly ITimeZoneService _timeZoneService;

        public TimingAppService(ITimeZoneService timeZoneService)
        {
            _timeZoneService = timeZoneService;
        }

        public async Task<ListResultDto<NameValueDto>> GetTimezones(GetTimezonesInput input)
        {
            var timeZones = await GetTimezoneInfos(input.DefaultTimezoneScope);
            return new ListResultDto<NameValueDto>(timeZones);
        }

        public async Task<List<ComboboxItemDto>> GetTimezoneComboboxItems(GetTimezoneComboboxItemsInput input)
        {
            var timeZones = await GetTimezoneInfos(input.DefaultTimezoneScope);
            var timeZoneItems = new ListResultDto<ComboboxItemDto>(timeZones.Select(e => new ComboboxItemDto(e.Value, e.Name)).ToList()).Items.ToList();

            if (!string.IsNullOrEmpty(input.SelectedTimezoneId))
            {
                var selectedEdition = timeZoneItems.FirstOrDefault(e => e.Value == input.SelectedTimezoneId);
                if (selectedEdition != null)
                {
                    selectedEdition.IsSelected = true;
                }
            }

            return timeZoneItems;
        }

        private async Task<List<NameValueDto>> GetTimezoneInfos(SettingScopes defaultTimezoneScope)
        {
            var defaultTimezoneId = await _timeZoneService.GetDefaultTimezoneAsync(defaultTimezoneScope, AbpSession.TenantId);
            var defaultTimezone = TimeZoneInfo.FindSystemTimeZoneById(defaultTimezoneId);
            var defaultTimezoneName = $"{L("Default")} [{defaultTimezone.DisplayName}]";

            var timeZones = _timeZoneService.GetWindowsTimezones();

            timeZones.Insert(0, new NameValueDto(defaultTimezoneName, string.Empty));
            return timeZones;
        }
    }
}

I am very sorry but I cannot share the project with you as it is client's property. But if you want I can share you the Audit logs related to Timezone.

It has to do something with TimingAppService as I can see from the Audit Log.

The log says:

System.InvalidTimeZoneException: "Aleutian Standard Time" was not recognized as a valid IANA time zone name, or has no equivalant Windows time zone.

What to do now?

Showing 1 to 10 of 15 entries