From e7908a0776f004a012cab74ebaedf57082b2bb66 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Tue, 15 Jun 2021 23:33:39 +0000 Subject: [PATCH] --- docs/8.0/ayanova/docs/adm-global-settings.md | 8 +- server/AyaNova/biz/UserBiz.cs | 77 +++++++++++++++++--- 2 files changed, 71 insertions(+), 14 deletions(-) diff --git a/docs/8.0/ayanova/docs/adm-global-settings.md b/docs/8.0/ayanova/docs/adm-global-settings.md index c664af7c..47a97e54 100644 --- a/docs/8.0/ayanova/docs/adm-global-settings.md +++ b/docs/8.0/ayanova/docs/adm-global-settings.md @@ -10,12 +10,12 @@ This section controls the rights granted to Customer type users (known as **"Con Each feature that Contacts have access to in AyaNova is listed with controls to grant or deny rights to that feature: * **Active** checkbox - enables or disables this particular feature entirely -* **Tagged With** tag control - grants access to those Contacts, Customers or Head Offices (checked in that order) with **any** matching tags -* **Not Tagged With** tag control - denies access to those Contacts, Customers or Head Offices (checked in that order) with **any** matching tags +* **Tagged With** tag control - grants access if tags on Contacts, Customers or Head Offices (related to Contact user) have **any** matching tags +* **Not Tagged With** tag control - denies access if tags on Contacts, Customers or Head Offices (related to Contact user) **any** matching tags -"Active" has the highest priority followed by "Not tagged with" and lastly "Tagged with". This means "Not tagged with" takes precedence over "Tagged with" if both match a Contact. +"Active" has the highest priority followed by "Not tagged with" and lastly "Tagged with". This means "Not tagged with" takes precedence over "Tagged with" if both match a Contact or it's ancestors tags. -Note that tags are matched to **any** single matching tag in the selected tags. This means the tags "red, green, brown" will match to a Contact tagged with any one of "red", "green" or "brown". +Tags are matched to **any single** matching tag in the selected tags. This means the tags "red, green, brown" will match to a Contact tagged with any one of "red", "green" or "brown". ### Customer Access settings diff --git a/server/AyaNova/biz/UserBiz.cs b/server/AyaNova/biz/UserBiz.cs index 1416d1bb..0054b39a 100644 --- a/server/AyaNova/biz/UserBiz.cs +++ b/server/AyaNova/biz/UserBiz.cs @@ -111,14 +111,7 @@ namespace AyaNova.Biz { using (AyContext ct = ServiceProviderProvider.DBContext) { - bool CSR = false; - bool WO = false; - bool WOWIKI = false; - bool UserSettings = false; - bool NotifyServiceImminent = false; - bool NotifyCSRAccepted = false; - bool NotifyCSRRejected = false; - bool NotifyWOCreated = false; + var UserInfo = await ct.User.AsNoTracking().Where(x => x.Id == userId).Select(x => new { x.UserType, x.HeadOfficeId, x.CustomerId, x.Tags }).FirstAsync(); @@ -127,22 +120,86 @@ namespace AyaNova.Biz List AllTags = new List(); AllTags.AddRange(UserInfo.Tags); + if (UserInfo.CustomerId != null && UserInfo.CustomerId != 0) AllTags.AddRange(await ct.Customer.AsNoTracking().Where(x => x.Id == UserInfo.CustomerId).Select(x => x.Tags).FirstAsync()); + if (UserInfo.HeadOfficeId != null && UserInfo.HeadOfficeId != 0) AllTags.AddRange(await ct.HeadOffice.AsNoTracking().Where(x => x.Id == UserInfo.HeadOfficeId).Select(x => x.Tags).FirstAsync()); + return new CustomerRightsRecord( + CustomerUserEffectiveRightsAllowed(AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowCSR, + AllTags, + AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowCSRInTags, + AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowCSROutTags), - AyaNova.Util.ServerGlobalBizSettings.Cache. + CustomerUserEffectiveRightsAllowed(AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowViewWO, + AllTags, + AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowViewWOInTags, + AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowViewWOOutTags), + CustomerUserEffectiveRightsAllowed(AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowWOWiki, + AllTags, + AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowWOWikiInTags, + AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowWOWikiOutTags), + CustomerUserEffectiveRightsAllowed(AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowUserSettings, + AllTags, + AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowUserSettingsInTags, + AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowUserSettingsOutTags), - return new CustomerRightsRecord(CSR, WO, WOWIKI, UserSettings, NotifyServiceImminent, NotifyCSRAccepted, NotifyCSRRejected, NotifyWOCreated); + CustomerUserEffectiveRightsAllowed(AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowNotifyServiceImminent, + AllTags, + AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowNotifyServiceImminentInTags, + AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowNotifyServiceImminentOutTags), + + CustomerUserEffectiveRightsAllowed(AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowNotifyCSRAccepted, + AllTags, + AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowNotifyCSRAcceptedInTags, + AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowNotifyCSRAcceptedOutTags), + + CustomerUserEffectiveRightsAllowed(AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowNotifyCSRRejected, + AllTags, + AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowNotifyCSRRejectedInTags, + AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowNotifyCSRRejectedOutTags), + + CustomerUserEffectiveRightsAllowed(AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowNotifyWOCreated, + AllTags, + AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowNotifyWOCreatedInTags, + AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowNotifyWOCreatedOutTags) + ); } } + internal static bool CustomerUserEffectiveRightsAllowed(bool allowed, List contactTags, List inTags, List outTags) + { + //Note: tag match rule as planned and documented is that it's a match if *any* single tag in intags or outtags are a match to any single tag in contact tags, + //not the whole list, just any one of them which differs from how notifications are checked for example which need to *all* match + + //if outright banned then quickest short circuit here + if (!allowed) return false; + + //No tags to verify means allowed + if (inTags.Count == 0 && outTags.Count == 0) return true; + + //if contact tags is empty and inclusive is empty then it's a match and can short circuit + if (contactTags.Count == 0 && inTags.Count == 0) return true; + + //if contact tags is empty and inclusive is not empty then no match is possible + if (contactTags.Count == 0 && inTags.Count > 0) return false; + + //any of the exclusive tags in contact tags? + if (contactTags.Intersect(outTags).Any()) return false; + + //any of the inclusive tags in contact tags? + if (contactTags.Intersect(inTags).Any()) return true; + + return false;//this is because there are contact and in tags but there is no match + } + + internal static UserBiz GetBiz(AyContext ct, Microsoft.AspNetCore.Http.HttpContext httpContext = null) { if (httpContext != null)