using Newtonsoft.Json; using Sarand.BusinessMgr.Net.Standard.Base.Bus; using Sarand.BusinessMgr.Net.Standard.Base.Consoles; using Sarand.BusinessMgr.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.Bus; using Sarand.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.Security; using Sarand.Net.Standard.Base.Utils; using System; using System.Collections.Generic; using System.Linq; namespace Sarand.BusinessMgr.Net.Standard.Base.App { //======================================================================= /// /// Security Profile associated with Core BusinessMgr Session. /// Once populated from database (Security tables etc) data needs to be self-sustaining via Serialisation.deserialistion /// to ensure that no further database queries are required to reconsuct the data for each web request. /// Hence the local data structures to store the defined Security Rights and User/Host profiles. /// public class SbmSecurityProfile : ISbmSecurityProfile_Core { //------------------------------------------------------------------- // Data members. private static readonly String userNameUnknown = "Unknown"; private bool includeHostSecurityProfile = false; //------------------------------------------------------------------- // Construction. [JsonConstructor] private SbmSecurityProfile() { } public SbmSecurityProfile(bool includeHostSecurityProfile) { this.includeHostSecurityProfile = includeHostSecurityProfile; Admin = new AdminProfile(); Manage = new ManageProfile(); Financial = new FinancialProfile(); Contacts = new ContactsProfile(); Transaction = new TransactionsProfile(); } //------------------------------------------------------------------- // Properties. // User. public SysId UserId { get; protected set; } = new SysId(); public String UserDisplayName { get; private set; } public String UserLocation { get; private set; } public DateTime UserLastLogin { get; private set; } //------------------------------------------------------------------- // Refresh profile. public void RefreshProfile(SbmSessionConsole sessionConsole, SaSecurityConsole securityConsole, SysId userId, List securityRights) { // Make a note of the security right. PopulateSecurityRights(securityRights); SysId previousUserId = UserId; // Clear existing profile. UserId = SysId.InvalidOnNull(userId); // Load new profile. if (securityConsole != null) { RefreshProfile(sessionConsole, securityConsole.GetUserSecurityProfile(UserId), includeHostSecurityProfile ? securityConsole.GetHostSecurityProfile() : null); } SaLogger.Debug($"{SysUtil.Fn} User: '{UserDisplayName}' [Id: {UserId}]" + (SysId.IsValid(previousUserId) ? ". Previous UserId: " + SysId.ToString(previousUserId) : "")); } protected void RefreshProfile(SbmSessionConsole sessionConsole, SaSecurityProfile userSecurityProfile, SaSecurityProfile hostSecurityProfile) { UserDisplayName = (userSecurityProfile?.Description ?? userNameUnknown); UserLocation = StringUtil.NullOnBlank(userSecurityProfile?.Location ?? ""); UserLastLogin = (userSecurityProfile?.LastLogin ?? DateTime.MinValue); UserProfile.Populate(userSecurityProfile); if (hostSecurityProfile != null) HostProfile = new SecurityProfileData(hostSecurityProfile); RefreshProfileSettings(sessionConsole); } private void RefreshProfileSettings(SbmSessionConsole sessionConsole) { RefreshAdminProfile(sessionConsole); RefreshManageProfile(sessionConsole); RefreshFinancialProfile(sessionConsole); RefreshContactsProfile(sessionConsole); RefreshTransactionProfile(sessionConsole); RefreshItemTypeProfile(sessionConsole); // ToDo Commodities. } private void ClearProfile() { // Reset security profiles. Admin = new AdminProfile(); Manage = new ManageProfile(); Financial = new FinancialProfile(); Contacts = new ContactsProfile(); Transaction = new TransactionsProfile(); } //------------------------------------------------------------------- /// /// Registered Security Rights to identify code for enumerated right. /// Optinised for speed of conversin and serialised storage. /// [JsonProperty("SecurityRights")] public Dictionary SecurityRights { get; private set; } = new Dictionary(); private void PopulateSecurityRights(List rights) { SecurityRights = rights.ToDictionary(item => item.Type, item => item.Code); } //------------------------------------------------------------------- // Security Profiles. // Profile properties are stored locally in such a way to allow serialisation/deserialisation // and application of security rules without having to duplicate the complete Security Profile. public class SecurityProfileData { public SecurityProfileData() { } public SecurityProfileData(SaSecurityProfile securityProfile) { Populate(securityProfile); } // Security. /// Is the Security Right code granted access for the Data item (if specified). public bool IsSecurityRightGranted(String rightCode, SysId dataItemId = null) { if (SystemAdmin ?? false) return true; return ((Groups != null && Groups.Any(item => item.Rights.IsSecurityRightGranted(rightCode, dataItemId))) || (Rights != null && Rights.IsSecurityRightGranted(rightCode, dataItemId))); } /// Is the Security Right code denined access for the Data item (if specified). public bool IsSecurityRightDenied(String rightCode, SysId dataItemId = null) { if (SystemAdmin ?? false) return false; return ((Groups != null && Groups.Any(item => item.Rights.IsSecurityRightDenied(rightCode, dataItemId))) || (Rights != null && Rights.IsSecurityRightDenied(rightCode, dataItemId))); } // Population. public void Populate(SaSecurityProfile securityProfile) { Clear(); if (securityProfile.SystemAdmin) SystemAdmin = true; foreach (var group in securityProfile.Groups) { GroupData groupData = new GroupData() { Code = group.Code }; groupData.Rights.Populate(group.Rights); Groups.Add(groupData); } Rights.Populate(securityProfile.Rights); } public void Clear() { SystemAdmin = null; Groups.Clear(); Rights.Clear(); } // Properties. public bool? SystemAdmin { get; private set; } public class GroupData { public String Code { get; set; } public RightsData Rights { get; set; } = new RightsData(); } public List Groups { get; private set; } = new List(); public class RightData { public SysId DataItemId { get; set; } } public class RightsData { // Construction. public RightsData() { } public RightsData(IEnumerable rights) { Populate(rights); } // Security. public bool IsSecurityRightGranted(String rightCode, SysId dataItemId) { return Granted != null && (Granted.GetValueOrDefault(rightCode)?.Any(item => SysId.ToInt(dataItemId) == SysId.ToInt(item.DataItemId)) ?? false); } public bool IsSecurityRightDenied(String rightCode, SysId dataItemId) { return Denied != null && (Denied.GetValueOrDefault(rightCode)?.Any(item => SysId.ToInt(dataItemId) == SysId.ToInt(item.DataItemId)) ?? false); } // Population. public void Populate(IEnumerable rights) { Clear(); foreach (var right in rights) { RightData rightData = new RightData() { DataItemId = SysId.IsValid(right.DataItemId) ? right.DataItemId : null }; if (right.Granted) { if (Granted == null) Granted = new Dictionary>(); if (!Granted.ContainsKey(right.Code)) Granted[right.Code] = new List(); Granted[right.Code].Add(rightData); } else { if (Denied == null) Denied = new Dictionary>(); if (!Denied.ContainsKey(right.Code)) Denied[right.Code] = new List(); Denied[right.Code].Add(rightData); } } } public void Clear() { Granted = null; Denied = null; } public Dictionary> Granted { get; private set; } public Dictionary> Denied { get; private set; } } public RightsData Rights { get; private set; } = new RightsData(); } // User and Host profiles. public SecurityProfileData UserProfile { get; private set; } = new SecurityProfileData(); public SecurityProfileData HostProfile { get; private set; } //------------------------------------------------------------------- // Utilities. public String GetSecurityRightCode(Sbm.SecurityRight securityRight) { return SecurityRights.GetValueOrDefault((int)securityRight) ?? ""; } public bool IsSecurityRightGranted(Sbm.SecurityRight securityRight, SysId id = null) { if (UserProfile != null) return UserProfile.IsSecurityRightGranted(GetSecurityRightCode(securityRight), id); return false; } public bool IsSecurityRightDenied(Sbm.SecurityRight securityRight, SysId id = null) { if (UserProfile != null) return UserProfile.IsSecurityRightDenied(GetSecurityRightCode(securityRight), id); return true; } //------------------------------------------------------------------- // Security rights - Admin. public class AdminProfile { internal AdminProfile() { } public bool? ManageSecurity { get; internal set; } public bool? ManageDatabase { get; internal set; } public bool? ManageReferenceData { get; internal set; } public bool? ManageInterfaces { get; internal set; } } public AdminProfile Admin { get; internal set; } private void RefreshAdminProfile(SbmSessionConsole sessionConsole) { if (UserHasSecurityRight(Sbm.SecurityRight.Security_Admin)) Admin.ManageSecurity = true; if (UserHasSecurityRight(Sbm.SecurityRight.Database_Admin)) Admin.ManageDatabase = true; if (UserHasSecurityRight(Sbm.SecurityRight.ReferenceData_Admin)) Admin.ManageReferenceData = true; if (UserHasSecurityRight(Sbm.SecurityRight.InterfaceConfig)) Admin.ManageInterfaces = true; } // Admin. public bool UserCanManageSecurity() { return Admin.ManageSecurity ?? false; } public bool UserCanManageDatabase() { return Admin.ManageDatabase ?? false; } public bool UserCanManageReferenceData() { return Admin.ManageReferenceData ?? false; } public bool UserCanManageInterfaces() { return Admin.ManageInterfaces ?? false; } //------------------------------------------------------------------- // Security rights - Manage. public class ManageProfile { internal ManageProfile() { } public bool? CanManageTasks { get; internal set; } public bool? CanManageTimesheets { get; internal set; } } public ManageProfile Manage { get; internal set; } private void RefreshManageProfile(SbmSessionConsole sessionConsole) { if (UserHasSecurityRight(Sbm.SecurityRight.TaskManager)) Manage.CanManageTasks = true; if (UserHasSecurityRight(Sbm.SecurityRight.TimesheetManager)) Manage.CanManageTimesheets = true; } // Manage. public bool UserCanManageTasks() { return Manage.CanManageTasks ?? false; } public bool UserCanManageTimesheets() { return Manage.CanManageTimesheets ?? false; } //------------------------------------------------------------------- // Security rights - Financials. public class FinancialProfile { internal FinancialProfile() { } public bool? ViewFinancials { get; internal set; } public bool? UpdateFinancials { get; internal set; } public bool? ViewCommoditySupplyFinancials { get; internal set; } public bool? UpdateCommoditySupplyFinancials { get; internal set; } public bool? ViewCommoditySalesFinancials { get; internal set; } public bool? UpdateCommoditySalesFinancials { get; internal set; } public bool? FinancialsAccessControl { get; internal set; } } public FinancialProfile Financial { get; internal set; } private void RefreshFinancialProfile(SbmSessionConsole sessionConsole) { if (UserHasSecurityRight(Sbm.SecurityRight.Financial_View)) Financial.ViewFinancials = true; if (UserHasSecurityRight(Sbm.SecurityRight.Financial_Update)) Financial.UpdateFinancials = true; if (UserCanAccessFinancialViewOfType(Sbm.FinancialType.CommoditySupply)) Financial.ViewCommoditySupplyFinancials = true; if (UserCanAccessFinancialUpdateOfType(Sbm.FinancialType.CommoditySupply)) Financial.UpdateCommoditySupplyFinancials = true; if (UserCanAccessFinancialViewOfType(Sbm.FinancialType.CommoditySales)) Financial.ViewCommoditySalesFinancials = true; if (UserCanAccessFinancialUpdateOfType(Sbm.FinancialType.CommoditySales)) Financial.UpdateCommoditySalesFinancials = true; // Config options. if ((sessionConsole != null && !sessionConsole.AllowOption(Sbm.ConfigOption.FinancialsAccessControl))) Financial.FinancialsAccessControl = true; } private bool UserCanAccessFinancialViewOfType(Sbm.FinancialType financialType) { if ((int)financialType < 1) return false; // If specific type of financial is requested, check that view is not denied. if (IsSecurityRightDenied(Sbm.SecurityRight.Financial_ViewByType, new SysId((int)financialType))) return false; return true; } private bool UserCanAccessFinancialUpdateOfType(Sbm.FinancialType financialType) { if ((int)financialType < 1) return false; // If specific type of financial is requested, check that update is not denied. if (IsSecurityRightDenied(Sbm.SecurityRight.Financial_UpdateByType, new SysId((int)financialType))) return false; return true; } /// Does the user have sufficient rights to view the specified financials. public bool UserCanViewFinancials(Sbm.FinancialType financialType = Sbm.FinancialType.Any) { if (!Financial.FinancialsAccessControl ?? false) return true; if ((Financial.UpdateFinancials ?? false) || (Financial.ViewFinancials ?? false)) { // If specific type of financial is requested, check that view access is not denied. if (financialType == Sbm.FinancialType.CommoditySupply) return Financial.ViewCommoditySupplyFinancials ?? false; else if (financialType == Sbm.FinancialType.CommoditySales) return Financial.ViewCommoditySalesFinancials ?? false; else return true; } return false; } /// Does the user have sufficient rights to update the specified financials. public bool UserCanUpdateFinancials(Sbm.FinancialType financialType = Sbm.FinancialType.Any) { if (!Financial.FinancialsAccessControl ?? false) return true; if (Financial.UpdateFinancials ?? false) { // If specific type of financial is requested, check that update access is not denied. if (financialType == Sbm.FinancialType.CommoditySupply) return Financial.UpdateCommoditySupplyFinancials ?? false; else if (financialType == Sbm.FinancialType.CommoditySales) return Financial.UpdateCommoditySalesFinancials ?? false; else return true; } return false; } //------------------------------------------------------------------- // Security rights - Contacts. public class ContactsProfile { internal ContactsProfile() { } public bool? Create { get; internal set; } public bool? Update { get; internal set; } } public ContactsProfile Contacts { get; internal set; } private void RefreshContactsProfile(SbmSessionConsole sessionConsole) { if (UserHasSecurityRight(Sbm.SecurityRight.Affiliate_Update)) Contacts.Update = true; if (Contacts.Update ?? false || UserHasSecurityRight(Sbm.SecurityRight.Affiliate_Create)) Contacts.Create = true; } // Contacts. public bool UserCanCreateContacts() { return Contacts.Create ?? false; } public bool UserCanUpdateContacts() { return Contacts.Update ?? false; } //------------------------------------------------------------------- // Security rights - Transactions. public class TransactionsProfile { internal TransactionsProfile() { } public bool? Create { get; internal set; } public bool? Update { get; internal set; } } public TransactionsProfile Transaction { get; internal set; } private void RefreshTransactionProfile(SbmSessionConsole sessionConsole) { if ((UserHasSecurityRight(Sbm.SecurityRight.Transaction_Update))) Transaction.Update = true; if ((Transaction.Update ?? false || UserHasSecurityRight(Sbm.SecurityRight.Transaction_View))) Transaction.Create = true; } // Transactions. public bool UserCanAccessTransactionsOfType(Sbm.TransactionType transactionType) { if ((int)transactionType < 1) return false; // Check if specific type of transaction is denied. if (IsSecurityRightDenied(Sbm.SecurityRight.Transaction_ByType, new SysId((int)transactionType))) return false; return true; } public bool CanUpdateTransactionTypeStatusCat(Sbm.TransactionType transactionType, SbmTransaction.StatusCat transactionStatusCat) { SysId transactionTypeStatusCatId = SbmTransaction.GetTransactionTypeStatusId(transactionType, transactionStatusCat); // Check if update of this transaction type and status is denied: if (IsSecurityRightDenied(Sbm.SecurityRight.Transaction_UpdateByTypeStatus, transactionTypeStatusCatId)) return false; // Check if update of this transaction type and status is explicitly allowed: if (IsSecurityRightGranted(Sbm.SecurityRight.Transaction_UpdateByTypeStatus, transactionTypeStatusCatId)) return true; // Check if any other statuses for this type of transaction are allowed. foreach (TypeCodeDesc statusCat in SbmTransaction.GetTransactionStatusCats(transactionType)) { SbmTransaction.StatusCat transactionStatusCatOther = (SbmTransaction.StatusCat)statusCat.Type; // Ignore the transaction status category. if (transactionStatusCatOther == transactionStatusCat) continue; if (IsSecurityRightGranted(Sbm.SecurityRight.Transaction_UpdateByTypeStatus, SbmTransaction.GetTransactionTypeStatusId(transactionType, transactionStatusCatOther))) // Explicit granting of right to another status for this transaction right // implies that other statuses are implicitly denied. return false; } return true; } //------------------------------------------------------------------- // Security rights - ItemType. public class ItemTypesProfile { internal ItemTypesProfile() { } public bool? Create { get; internal set; } public bool? Update { get; internal set; } public bool? Remove { get; internal set; } // Config options. public bool? Processes { get; internal set; } public bool? Contacts { get; internal set; } public bool? Commodities { get; internal set; } public bool? Portfolios { get; internal set; } public bool? PriceSets { get; internal set; } public bool? CommodityCustomers { get; internal set; } public bool? CommoditySuppliers { get; internal set; } public bool? Transactions { get; internal set; } public bool? Assets { get; internal set; } public bool? Vehicles { get; internal set; } public bool? StockLocations { get; internal set; } public bool? StockContainers { get; internal set; } public bool? StockControl { get; internal set; } } public ItemTypesProfile ItemType { get; } = new ItemTypesProfile(); private void RefreshItemTypeProfile(SbmSessionConsole sessionConsole) { if (sessionConsole.AllowOption(Sbm.ConfigOption.Processes)) ItemType.Processes = true; if (sessionConsole.AllowOption(Sbm.ConfigOption.Contacts)) ItemType.Contacts = true; if (sessionConsole.AllowOption(Sbm.ConfigOption.Commodities)) ItemType.Commodities = true; if (sessionConsole.AllowOption(Sbm.ConfigOption.Portfolios)) ItemType.Portfolios = true; if (sessionConsole.AllowOption(Sbm.ConfigOption.PriceSets)) ItemType.PriceSets = true; if (sessionConsole.AllowOption(Sbm.ConfigOption.CommodityCustomers)) ItemType.CommodityCustomers = true; if (sessionConsole.AllowOption(Sbm.ConfigOption.CommoditySuppliers)) ItemType.CommoditySuppliers = true; if (sessionConsole.AllowOption(Sbm.ConfigOption.Transactions)) ItemType.Transactions = true; if (sessionConsole.AllowOption(Sbm.ConfigOption.Assets)) ItemType.Assets = true; if (sessionConsole.AllowOption(Sbm.ConfigOption.Vehicles)) ItemType.Vehicles = true; if (sessionConsole.GetStockControlConfig().AllowStockLocations()) ItemType.StockLocations = true; if (sessionConsole.GetStockControlConfig().AllowStockContainers()) ItemType.StockContainers = true; if (sessionConsole.GetStockControlConfig().AllowStockControl()) ItemType.StockControl = true; } // Item types. public bool UserCanViewItemType(Sbm.ItemType itemType) { return true; } public bool UserCanCreateItemType(Sbm.ItemType itemType) { if (UserProfile?.SystemAdmin ?? false) return true; switch (itemType) { case Sbm.ItemType.SecItem: return IsSecurityRightGranted(Sbm.SecurityRight.Security_Admin); case Sbm.ItemType.Currency: case Sbm.ItemType.Region: case Sbm.ItemType.Language: case Sbm.ItemType.TaxCode: case Sbm.ItemType.UnitMeasure: return IsSecurityRightGranted(Sbm.SecurityRight.ReferenceData_Admin); case Sbm.ItemType.Process: return IsSecurityRightGranted(Sbm.SecurityRight.ReferenceData_Admin); case Sbm.ItemType.Affiliate: return IsSecurityRightGranted(Sbm.SecurityRight.Affiliate_Create); case Sbm.ItemType.Address: return IsSecurityRightGranted(Sbm.SecurityRight.Affiliate_Update); case Sbm.ItemType.Commodity: return IsSecurityRightGranted(Sbm.SecurityRight.Commodity_Create); case Sbm.ItemType.PortfolioItem: return IsSecurityRightGranted(Sbm.SecurityRight.Commodity_Update); case Sbm.ItemType.Location: return IsSecurityRightGranted(Sbm.SecurityRight.ReferenceData_Admin); case Sbm.ItemType.Container: return IsSecurityRightGranted(Sbm.SecurityRight.Commodity_Create); case Sbm.ItemType.ContainerItem: return IsSecurityRightGranted(Sbm.SecurityRight.Commodity_Update); case Sbm.ItemType.Movement: return IsSecurityRightGranted(Sbm.SecurityRight.Commodity_Update); case Sbm.ItemType.StockLevel: return IsSecurityRightGranted(Sbm.SecurityRight.Commodity_Update); case Sbm.ItemType.PriceSet: case Sbm.ItemType.Price: return IsSecurityRightGranted(Sbm.SecurityRight.Commodity_Update) && UserCanUpdateFinancials(); case Sbm.ItemType.CommodityCustomer: case Sbm.ItemType.CommoditySupplier: return IsSecurityRightGranted(Sbm.SecurityRight.Association_Update) && IsSecurityRightGranted(Sbm.SecurityRight.Commodity_Update); case Sbm.ItemType.Association: return IsSecurityRightGranted(Sbm.SecurityRight.Association_Create); case Sbm.ItemType.Transaction: return IsSecurityRightGranted(Sbm.SecurityRight.Transaction_Create); case Sbm.ItemType.Requirement: case Sbm.ItemType.Constituent: return IsSecurityRightGranted(Sbm.SecurityRight.Transaction_Update); case Sbm.ItemType.SystemAccount: case Sbm.ItemType.SystemUser: case Sbm.ItemType.SystemAccountUser: return IsSecurityRightGranted(Sbm.SecurityRight.Security_Admin); case Sbm.ItemType.AssetCategory: case Sbm.ItemType.AssetCategoryProcess: case Sbm.ItemType.Asset: case Sbm.ItemType.AssetProcess: return IsSecurityRightGranted(Sbm.SecurityRight.Asset_Create); case Sbm.ItemType.VehicleClass: case Sbm.ItemType.Vehicle: case Sbm.ItemType.VehicleEvent: case Sbm.ItemType.VehicleFeature: return IsSecurityRightGranted(Sbm.SecurityRight.Asset_Create); case Sbm.ItemType.CommodityProcess: return IsSecurityRightGranted(Sbm.SecurityRight.Commodity_Update); case Sbm.ItemType.RequirementProcess: return IsSecurityRightGranted(Sbm.SecurityRight.Transaction_Update); case Sbm.ItemType.Interface: return IsSecurityRightGranted(Sbm.SecurityRight.InterfaceConfig); } return false; } public bool UserCanUpdateItemType(Sbm.ItemType itemType) { if (UserProfile?.SystemAdmin ?? false) return true; switch (itemType) { case Sbm.ItemType.SecItem: return IsSecurityRightGranted(Sbm.SecurityRight.Security_Admin); case Sbm.ItemType.Currency: case Sbm.ItemType.Region: case Sbm.ItemType.Language: case Sbm.ItemType.TaxCode: case Sbm.ItemType.UnitMeasure: return IsSecurityRightGranted(Sbm.SecurityRight.ReferenceData_Admin); case Sbm.ItemType.Process: return IsSecurityRightGranted(Sbm.SecurityRight.ReferenceData_Admin); case Sbm.ItemType.Affiliate: case Sbm.ItemType.Address: return IsSecurityRightGranted(Sbm.SecurityRight.Affiliate_Update); case Sbm.ItemType.Commodity: return IsSecurityRightGranted(Sbm.SecurityRight.Commodity_Update); case Sbm.ItemType.PortfolioItem: return IsSecurityRightGranted(Sbm.SecurityRight.Commodity_Update); case Sbm.ItemType.Location: return IsSecurityRightGranted(Sbm.SecurityRight.ReferenceData_Admin); case Sbm.ItemType.Container: case Sbm.ItemType.ContainerItem: return IsSecurityRightGranted(Sbm.SecurityRight.Commodity_Update); case Sbm.ItemType.Movement: case Sbm.ItemType.StockLevel: return IsSecurityRightGranted(Sbm.SecurityRight.Commodity_Update); case Sbm.ItemType.PriceSet: case Sbm.ItemType.Price: return IsSecurityRightGranted(Sbm.SecurityRight.Commodity_Update) && UserCanUpdateFinancials(); case Sbm.ItemType.CommodityCustomer: case Sbm.ItemType.CommoditySupplier: return IsSecurityRightGranted(Sbm.SecurityRight.Association_Update) && IsSecurityRightGranted(Sbm.SecurityRight.Commodity_Update); case Sbm.ItemType.Association: return IsSecurityRightGranted(Sbm.SecurityRight.Association_Update); case Sbm.ItemType.Transaction: case Sbm.ItemType.Requirement: case Sbm.ItemType.Constituent: return IsSecurityRightGranted(Sbm.SecurityRight.Transaction_Update); case Sbm.ItemType.SystemAccount: case Sbm.ItemType.SystemUser: case Sbm.ItemType.SystemAccountUser: return IsSecurityRightGranted(Sbm.SecurityRight.Security_Admin); case Sbm.ItemType.AssetCategory: case Sbm.ItemType.AssetCategoryProcess: case Sbm.ItemType.Asset: case Sbm.ItemType.AssetProcess: return IsSecurityRightGranted(Sbm.SecurityRight.Asset_Update); case Sbm.ItemType.VehicleClass: case Sbm.ItemType.Vehicle: case Sbm.ItemType.VehicleEvent: case Sbm.ItemType.VehicleFeature: return IsSecurityRightGranted(Sbm.SecurityRight.Asset_Update); case Sbm.ItemType.CommodityProcess: return IsSecurityRightGranted(Sbm.SecurityRight.Commodity_Update); case Sbm.ItemType.RequirementProcess: return IsSecurityRightGranted(Sbm.SecurityRight.Transaction_Update); case Sbm.ItemType.Interface: return IsSecurityRightGranted(Sbm.SecurityRight.InterfaceConfig); } return false; } public bool UserCanRemoveItemType(Sbm.ItemType itemType) { switch (itemType) { case Sbm.ItemType.Transaction: if (!IsSecurityRightGranted(Sbm.SecurityRight.Transaction_Remove)) return false; break; } return (UserCanCreateItemType(itemType) && UserCanUpdateItemType(itemType)); } //------------------------------------------------------------------- // Security rights. public bool UserHasSecurityRight(Sbm.SecurityRight securityRight, SysId dataItemId = null) { String rightCode = GetSecurityRightCode(securityRight); if (StringUtil.IsEmpty(rightCode)) return false; // Check if right is denied by either user or host profiles. if (UserProfile?.IsSecurityRightDenied(rightCode) ?? false) return false; if (HostProfile?.IsSecurityRightDenied(rightCode) ?? false) return false; // Check if right is granted by either user or host profiles. if (UserProfile?.IsSecurityRightGranted(rightCode) ?? false) return true; if (HostProfile?.IsSecurityRightGranted(rightCode) ?? false) return true; return false; } //------------------------------------------------------------------- public class SecurityProfileException : Exception { public SecurityProfileException(string message) : base(message) { } } /// Verify that the specified profiles matches this one, eg. after deserialisation. public bool CompareProfiles(ISbmSecurityProfile_Core securityProfile_Core) { // Profile. if (securityProfile_Core == null) throw new SecurityProfileException($"{SysUtil.Fn} Supplied profile is null."); SbmSecurityProfile securityProfile = securityProfile_Core as SbmSecurityProfile; if (securityProfile == null) throw new SecurityProfileException($"{SysUtil.Fn} Supplied profile does not match type."); // Security rights. if (SecurityRights.Count != securityProfile.SecurityRights.Count) throw new SecurityProfileException($"{SysUtil.Fn} Supplied profile has different number of Security Rights. Expected: {SecurityRights.Count}. Found: {securityProfile.SecurityRights}."); // User profile. if (UserProfile != null && securityProfile.UserProfile == null) throw new SecurityProfileException($"{SysUtil.Fn} Supplied profile is missing a User Profile."); if (UserProfile == null && securityProfile.UserProfile != null) throw new SecurityProfileException($"{SysUtil.Fn} Supplied profile includes a User Profile."); // User profile - Groups. if (UserProfile.Groups?.Count != securityProfile.UserProfile.Groups?.Count) throw new SecurityProfileException($"{SysUtil.Fn} Supplied profile has different number of User Groups. Expected: {UserProfile.Groups?.Count}. Found: {securityProfile.UserProfile.Groups?.Count}."); // User profile - Granted Rights. if (UserProfile.Rights?.Granted?.Count != securityProfile.UserProfile.Rights?.Granted?.Count) throw new SecurityProfileException($"{SysUtil.Fn} Supplied profile has different number of Granted User Rights. Expected: {UserProfile.Rights?.Granted?.Count}. Found: {securityProfile.UserProfile.Rights?.Granted?.Count}."); // User profile - Denied Rights. if (UserProfile.Rights?.Denied?.Count != securityProfile.UserProfile.Rights?.Denied?.Count) throw new SecurityProfileException($"{SysUtil.Fn} Supplied profile has different number of Denied User Rights. Expected: {UserProfile.Rights?.Denied?.Count}. Found: {securityProfile.UserProfile.Rights?.Denied?.Count}."); // Host profile. if (HostProfile != null && securityProfile.HostProfile == null) throw new SecurityProfileException($"{SysUtil.Fn} Supplied profile is missing a Host Profile."); if (HostProfile == null && securityProfile.HostProfile != null) throw new SecurityProfileException($"{SysUtil.Fn} Supplied profile includes a Host Profile."); // Host profile - Groups. if (HostProfile?.Groups?.Count != securityProfile.HostProfile?.Groups?.Count) throw new SecurityProfileException($"{SysUtil.Fn} Supplied profile has different number of Host Groups. Expected: {HostProfile?.Groups?.Count}. Found: {securityProfile.HostProfile?.Groups?.Count}."); // Host profile - Granted Rights. if (HostProfile?.Rights?.Granted?.Count != securityProfile.HostProfile?.Rights?.Granted?.Count) throw new SecurityProfileException($"{SysUtil.Fn} Supplied profile has different number of Granted Host Rights. Expected: {HostProfile?.Rights?.Granted?.Count}. Found: {securityProfile.HostProfile?.Rights?.Granted?.Count}."); // Host profile - Denied Rights. if (HostProfile?.Rights?.Denied?.Count != securityProfile.HostProfile?.Rights?.Denied?.Count) throw new SecurityProfileException($"{SysUtil.Fn} Supplied profile has different number of Denied Host Rights. Expected: {HostProfile?.Rights?.Denied?.Count}. Found: {securityProfile.HostProfile?.Rights?.Denied?.Count}."); return true; } //------------------------------------------------------------------- } //======================================================================= }