private bool Can(string permission, ItemKey leaf, bool inherit, ItemKey viewer) { bool allow = false; bool deny = false; long permissionId = 0; PermissionCacheKey cachedKey = new PermissionCacheKey(permission, viewer); if (cachedPermissions != null && cachedPermissions.ContainsKey(cachedKey)) { //HttpContext.Current.Response.Write("<br />cached result "); return cachedPermissions[cachedKey]; } AccessControlPermission acp = null; if (permissions == null) { try { acp = core.AcessControlCache[ItemKey.TypeId, permission]; } catch (InvalidAccessControlPermissionException) { acp = null; } } else { if (permissions.ContainsKey(permission)) { acp = permissions[permission]; } else { acp = null; } } if (acp == null && permission == "EDIT_PERMISSIONS") { return CachePermission(permission, viewer, Owner.CanEditPermissions()); } // Fall back if no overriding permission attribute for edit exists in the database if (acp == null && permission == "EDIT") { return CachePermission(permission, viewer, Owner.CanEditItem()); } // Fall back if no overriding permission attribute for delete exists in the database if (acp == null && permission == "DELETE") { return CachePermission(permission, viewer, Owner.CanDeleteItem()); } if (acp == null) { if (inherit) { return CachePermission(permission, viewer, false); } else { /* Fall through to owner, this is useful where items can * only have the same VIEW status as their parent (usually * a Primitive). Normally you would call on the parent * directly, however there are a few use cases where you * don't know if the item has a separately defined VIEW * permission or not. */ if (ItemKey != Item.PermissiveParentKey && Item.PermissiveParentKey != null) { Access parentAccess = new Access(core, Item.PermissiveParentKey, Owner); //HttpContext.Current.Response.Write("parent result null acp"); return parentAccess.Can(permission, itemKey, true, viewer); //return item.PermissiveParent.Access.Can(permission, item, true); } else { throw new InvalidAccessControlPermissionException(permission); } } } permissionId = acp.Id; if (Grants != null) { foreach (AccessControlGrant grant in Grants) { if (grant.PermissionId > 0 && grant.PermissionId == acp.Id) { core.PrimitiveCache.LoadPrimitiveProfile(grant.PrimitiveKey); } } foreach (AccessControlGrant grant in Grants) { if (grant.PermissionId > 0 && grant.PermissionId == acp.Id) { if (owner != null) { if (grant.PrimitiveKey.TypeId == ItemType.GetTypeId(core, typeof(User)) && viewer.Id > 0 && grant.PrimitiveKey.Id == viewer.Id) { switch (grant.Allow) { case AccessControlGrants.Allow: //HttpContext.Current.Response.Write(" allow User"); allow = true; break; case AccessControlGrants.Deny: //HttpContext.Current.Response.Write(" deny User"); deny = true; break; case AccessControlGrants.Inherit: break; } } if (owner.GetIsMemberOfPrimitive(viewer, grant.PrimitiveKey)) { switch (grant.Allow) { case AccessControlGrants.Allow: //HttpContext.Current.Response.Write(" allow GetIsMemberOfPrimitive"); allow = true; break; case AccessControlGrants.Deny: //HttpContext.Current.Response.Write(" deny GetIsMemberOfPrimitive"); deny = true; break; case AccessControlGrants.Inherit: break; } } if (grant.PrimitiveKey.Equals(User.GetCreatorKey(core)) && viewer != null && owner.ItemKey.Equals(viewer)) { switch (grant.Allow) { case AccessControlGrants.Allow: //HttpContext.Current.Response.Write(" allow Creator"); allow = true; break; case AccessControlGrants.Deny: //HttpContext.Current.Response.Write(" deny Creator"); deny = true; break; case AccessControlGrants.Inherit: break; } } } if (Item.IsItemGroupMember(viewer, grant.PrimitiveKey)) { switch (grant.Allow) { case AccessControlGrants.Allow: //HttpContext.Current.Response.Write(" allow IsItemGroupMember"); allow = true; break; case AccessControlGrants.Deny: //HttpContext.Current.Response.Write(" deny IsItemGroupMember"); deny = true; break; case AccessControlGrants.Inherit: break; } } if (grant.PrimitiveKey.Equals(User.GetRegisteredUsersGroupKey(core)) && viewer != null) { switch (grant.Allow) { case AccessControlGrants.Allow: //HttpContext.Current.Response.Write(" allow User.RegisteredUsersGroupKey"); allow = true; break; case AccessControlGrants.Deny: //HttpContext.Current.Response.Write(" deny User.RegisteredUsersGroupKey"); deny = true; break; case AccessControlGrants.Inherit: break; } } if (grant.PrimitiveKey.Equals(User.GetEveryoneGroupKey(core))) { switch (grant.Allow) { case AccessControlGrants.Allow: //HttpContext.Current.Response.Write(" allow User.EveryoneGroupKey"); allow = true; break; case AccessControlGrants.Deny: //HttpContext.Current.Response.Write(" deny User.EveryoneGroupKey"); deny = true; break; case AccessControlGrants.Inherit: break; } } } } } if (Grants == null || Grants.Count == 0 || (!permissionsEnacted.Contains(permissionId))) { IPermissibleItem leafItem = null; //HttpContext.Current.Response.Write(" fall back"); if (owner == null && viewer != null) { if (viewer.Equals(leaf)) { //HttpContext.Current.Response.Write(" cached result 0x02"); return CachePermission(permission, viewer, true); } else { //HttpContext.Current.Response.Write(" cached result 0x03"); if (leafItem == null) { leafItem = (IPermissibleItem)NumberedItem.Reflect(core, leaf); } return CachePermission(permission, viewer, leafItem.GetDefaultCan(permission, viewer)); } } else if (ItemKey.Equals(owner.ItemKey)) { if (viewer != null && owner.ItemKey.Equals(viewer)) { //HttpContext.Current.Response.Write(" cached result 0x04"); return CachePermission(permission, viewer, true); } else { //HttpContext.Current.Response.Write(" cached result 0x05"); if (leafItem == null) { leafItem = (IPermissibleItem)NumberedItem.Reflect(core, leaf); } return CachePermission(permission, viewer, leafItem.GetDefaultCan(permission, viewer)); } } else { if ((typeof(INestableItem).IsAssignableFrom(ItemKey.GetType(core).GetItemType()))) { INestableItem ni = (INestableItem)Item; ParentTree parents = ni.GetParents(); if (parents == null || parents.Nodes.Count == 0) { if (Item.PermissiveParentKey == null) { //HttpContext.Current.Response.Write(" cached result 0x06"); return CachePermission(permission, viewer, Item.GetDefaultCan(permission, viewer)); //Owner.Access.Can(permission, leaf, true, viewer)); } else { Access parentAccess = new Access(core, Item.PermissiveParentKey, Owner); //HttpContext.Current.Response.Write(" cached result 0x07"); return CachePermission(permission, viewer, parentAccess.Can(Item.ParentPermissionKey(Item.PermissiveParentKey.GetType(core).GetItemType(), permission), leaf, true, viewer)); //return CachePermission(permission, item.PermissiveParent.Access.Can(item.ParentPermissionKey(item.PermissiveParentKey.Type, permission), leaf, true)); } } else { Access parentAccess = new Access(core, new ItemKey(parents.Nodes[parents.Nodes.Count - 1].ParentId, ni.ParentTypeId), Owner); //HttpContext.Current.Response.Write(" cached result 0x08"); return CachePermission(permission, viewer, parentAccess.Can(permission, leaf, true, viewer)); //return CachePermission(permission, ((IPermissibleItem)NumberedItem.Reflect(core, new ItemKey(parents.Nodes[parents.Nodes.Count - 1].ParentId, ni.ParentTypeId))).Access.Can(permission, leaf, true)); } } else { if (Item.PermissiveParentKey == null) { //HttpContext.Current.Response.Write(" cached result 0x09"); return CachePermission(permission, viewer, Item.GetDefaultCan(permission, viewer)); //Owner.Access.Can(permission, leaf, true, viewer)); } else { Access parentAccess = new Access(core, Item.PermissiveParentKey, Owner); //HttpContext.Current.Response.Write(" cached result 0x10"); return CachePermission(permission, viewer, parentAccess.Can(Item.ParentPermissionKey(Item.PermissiveParentKey.GetType(core).GetItemType(), permission), leaf, true, viewer)); //return CachePermission(permission, item.PermissiveParent.Access.Can(item.ParentPermissionKey(item.PermissiveParent.GetType(), permission), leaf, true)); } } } } //HttpContext.Current.Response.Write(" cached result 0x10 " + allow.ToString() + ", " + (allow && (!deny)).ToString()); return CachePermission(permission, viewer, (allow && (!deny))); }
private bool CachePermission(string permission, ItemKey viewer, bool access) { if (cachedPermissions == null) { cachedPermissions = new Dictionary<PermissionCacheKey, bool>(8); } PermissionCacheKey key = new PermissionCacheKey(permission, viewer); if (cachedPermissions.ContainsKey(key)) { cachedPermissions[key] = access; } else { cachedPermissions.Add(key, access); } return access; }