/// <summary> /// Creates and returns a permission that is the intersection of the current permission and the specified permission. /// </summary> /// <param name="target">A permission to intersect with the current permission. It must be of the same type as the current /// permission.</param> /// <returns>A new permission that represents the intersection of the current permission and the specified permission. This /// new permission is null if the intersection is empty.</returns> public IPermission Intersect(IPermission target) { // An intersection operation isn't possible unless both operands employ the same permissioning scheme. if (target is ClaimsPrincipalPermission) { // This is the source Permission scheme for the operation. ClaimsPrincipalPermission targetPermission = target as ClaimsPrincipalPermission; // If this permission scheme allows unrestricted access, then it has nothing it can add to the intersection of the // two schemes. if (this.IsUnrestricted()) { return(target.Copy()); } // If the other permission scheme is unrestricted, it has nothing to add to the intersection of the two schemes. if (targetPermission.IsUnrestricted()) { return(this.Copy()); } // Both permission schemes must share the requirement that the user is authenticated and both issuers must be the // same for the claims to be merged. if (this.isAuthenticated == targetPermission.IsAuthenticated && IsExactIssuerMatch(targetPermission.Issuer)) { // This creates a list that is the intersection of the claims in the two permission schemes. List <Claim> claims = new List <Claim>(); foreach (Claim claim in this.requiredClaims) { if (targetPermission.RequiredClaims.ContainsClaim(claim)) { claims.Add(claim); } } // Once the set of interesecting claims is created, the permission scheme can be created. It is known at this // point that the authenticated state of the user and the issuer are equivalent. return(new ClaimsPrincipalPermission(this.isAuthenticated, new DefaultClaimSet(this.requiredClaims.Issuer, claims))); } } // An intersection of the two permission schemes could not be constructed at this point. return(null); }
/// <summary> /// Determines whether the current permission is a subset of the specified permission. /// </summary> /// <param name="target">A permission that is to be tested for the subset relationship. This permission must be of the same /// type as the current permission.</param> /// <returns>true if the current permission is a subset of the specified permission; otherwise, false.</returns> public bool IsSubsetOf(IPermission target) { // A subset operation isn't possible unless both operands employ the same permissioning scheme. if (target is ClaimsPrincipalPermission) { // This is the source Permission scheme for the operation. ClaimsPrincipalPermission targetPermission = target as ClaimsPrincipalPermission; // Unrestricted permission sets are basically the set of every claim, so this permission set, no matter what is in // it, is a subset of everything. if (targetPermission.IsUnrestricted()) { return(true); } // At this point we know that the target set contains a finite number of claims. If this permission set contains // an inifinite number of claims, it can't be a subset of the target. if (this.IsUnrestricted()) { return(false); } // The two sets of permissions can only be compared if they require the same authentication state for the two // Principals and the issuers of both sets are exactly the same. if (this.isAuthenticated == targetPermission.IsAuthenticated && IsExactIssuerMatch(targetPermission.Issuer)) { // Any claim in the required set that doesn't belong to the target set of permissions will disqualify the // required ClaimSet as a subset of the target. foreach (Claim claim in this.requiredClaims) { if (!targetPermission.RequiredClaims.ContainsClaim(claim)) { return(false); } } // At this point, the required ClaimSet is a subset of the target set of permissions. return(true); } } // The required ClaimSet is not a subset of the target at this point. return(false); }
/// <summary> /// Creates a permission that is the union of the current permission and the specified permission. /// </summary> /// <param name="target">A permission to combine with the current permission. It must be of the same type as the /// current permission.</param> /// <returns>A new permission that represents the union of the current permission and the specified permission.</returns> public IPermission Union(IPermission target) { // A union operation isn't possible unless both operands employ the same permissioning scheme. if (target is ClaimsPrincipalPermission) { // This is the source Permission scheme for the operation. ClaimsPrincipalPermission targetPermission = target as ClaimsPrincipalPermission; // If either premission contains an infinite set of claims, the union is an infinite (unrestricted) permission set. if (targetPermission.IsUnrestricted() || this.IsUnrestricted()) { return(new ClaimsPrincipalPermission(PermissionState.Unrestricted)); } // The two sets of permissions can only be merged if they require the same authentication state for the two // Principals and the issuers of both sets are exactly the same. if (this.isAuthenticated == targetPermission.IsAuthenticated && IsExactIssuerMatch(targetPermission.Issuer)) { // This creates a list of claims that is the union between the two sets of permissions. List <Claim> claims = new List <Claim>(); foreach (Claim claim in this.requiredClaims) { claims.Add(claim); } foreach (Claim claim in targetPermission.RequiredClaims) { if (!claims.Contains(claim)) { claims.Add(claim); } } // The state of authentication and the issuer are the same at this point. This will create and return a // permission that is the union of the claims of the two permissions. return(new ClaimsPrincipalPermission(this.isAuthenticated, new DefaultClaimSet(this.requiredClaims.Issuer, claims))); } } // At this point, the two premissions couldn't be merged. return(null); }