/// <summary> /// Calculates the rights that a user effectively has for a page. /// </summary> /// <param name="permissions">Struct consisting of the following: /// Rights of specific to user is added to rights given to groups to which to user belongs /// Restriction flags associated with a page. These work to counter the effectiveUserGroupRights /// Effective grants associated with a page as a combinatation of user and group grants /// </param> /// <returns>The effective rights represented as a bitmask to a page</returns> public static ulong CalculateEffectivePageRights(PermissionStruct permissions) { //If a user's effective rights (independent of page) has admin flag, the effective page rights are same as user's effective rights. if((permissions.UserPermissions & Permissions.ADMIN) == Permissions.ADMIN) { return (ulong)permissions.UserPermissions; } return (ulong)(((permissions.UserPermissions & permissions.PageRestrictionsMask) | permissions.PageGrantPermissions) | (permissions.UserPermissions & PermissionSets.PAGE_INDEPENDENT)); }
private Dictionary <T, PermissionStruct> Grants_CalculateEffectivePermissions <T>(IEnumerable <uint> userIds, IEnumerable <ulong> pageIds, bool keyByUser) { Dictionary <T, PermissionStruct> ret = new Dictionary <T, PermissionStruct>(); pageIds = pageIds.Distinct(); userIds = userIds.Distinct(); // check if there are any results to return at all if ((pageIds.Count() == 0) || (userIds.Count() == 0)) { return(ret); } string pageIdsStr = pageIds.ToCommaDelimitedString(); string userIdsStr = userIds.ToCommaDelimitedString(); string selectUserPermissions = @" ( ( SELECT CAST(r.role_perm_flags AS unsigned) FROM users AS u JOIN roles AS r ON u.user_role_id = r.role_id WHERE u.user_id = mainu.user_id ) | ( SELECT CAST(bit_or(r.role_perm_flags) AS unsigned) FROM user_groups AS ug JOIN groups AS g ON ug.group_id = g.group_id JOIN roles AS r ON g.group_role_id = r.role_id WHERE ug.user_id = mainu.user_id ) ) AS effective_rights_flags"; string selectForZeroPageId = string.Format(@" SELECT mainp.page_id as pageid, mainu.user_id as userid, 0 AS page_restriction_flags, 0 AS effective_grant_flags, {0} FROM (select 0 as page_id) mainp JOIN users mainu WHERE mainu.user_id IN ({1})", selectUserPermissions, userIdsStr); string selectForNonZeroPageIds = string.Format(@" SELECT mainp.page_id as pageid, mainu.user_id as userid, (SELECT rs.restriction_perm_flags FROM pages p LEFT JOIN restrictions rs ON p.page_restriction_id = rs.restriction_id WHERE p.page_id = mainp.page_id ) AS page_restriction_flags, (select ( select ifnull(( SELECT r.role_perm_flags AS user_grant_flags FROM user_grants u JOIN roles r ON u.role_id = r.role_id WHERE u.user_id = mainu.user_id AND u.page_id = mainp.page_id ),0) ) | ( select ifnull(( SELECT bit_or(r.role_perm_flags) AS group_grant_flags FROM user_groups ug JOIN groups g ON ug.group_id = g.group_id JOIN group_grants gg ON ug.group_id=gg.group_id JOIN roles AS r ON gg.role_id = r.role_id WHERE ug.user_id = mainu.user_id AND gg.page_id = mainp.page_id ),0) )) as effective_grant_flags, {0} FROM pages mainp JOIN users mainu WHERE mainp.page_id IN ({1}) AND mainu.user_id IN ({2}) ", selectUserPermissions, pageIdsStr, userIdsStr); string query; if (pageIds.Contains <ulong>(0)) { if (pageIds.Count() > 1) { query = String.Format("({0}) UNION ({1})", selectForZeroPageId, selectForNonZeroPageIds); } else { query = selectForZeroPageId; } } else { query = selectForNonZeroPageIds; } Catalog.NewQuery(query) .Execute(delegate(IDataReader dr) { while (dr.Read()) { T pageid = dr.Read <T>("pageid", default(T)); T userid = dr.Read <T>("userid", default(T)); ulong effective_rights_flags = dr.Read <ulong>("effective_rights_flags", 0); ulong effective_grant_flags = dr.Read <ulong>("effective_grant_flags", 0); ulong page_restriction_flags = dr.Read <ulong>("page_restriction_flags", 0); if (page_restriction_flags == 0) { page_restriction_flags = ulong.MaxValue; } PermissionStruct flags = new PermissionStruct(effective_rights_flags, page_restriction_flags, effective_grant_flags); if (keyByUser) { ret[userid] = flags; } else { ret[pageid] = flags; } } }); return(ret); }