File: system\security\principal\genericprincipal.cs
Project: ndp\clr\src\bcl\mscorlib.csproj (mscorlib)
// ==++==
// 
//   Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// ==--==
// <OWNER>Microsoft</OWNER>
// 
 
//
// GenericPrincipal.cs
//
 
namespace System.Security.Principal
{
    using System;
    using System.Diagnostics.Contracts;
 
#if !FEATURE_CORECLR
    using System.Collections.Generic;
    using System.Runtime.Serialization;
    using System.Security.Claims;
#endif
 
    [Serializable]
    [System.Runtime.InteropServices.ComVisible(true)]
 
#if !FEATURE_CORECLR
    public class GenericPrincipal : ClaimsPrincipal {        
#else
    public class GenericPrincipal : IPrincipal {
#endif
        private IIdentity m_identity;
        private string[] m_roles;
 
        public GenericPrincipal(IIdentity identity, string[] roles) {
            if (identity == null)
                throw new ArgumentNullException("identity");
            Contract.EndContractBlock();
 
            m_identity = identity;
            if (roles != null) {
                m_roles = new string[roles.Length];
                for (int i = 0; i < roles.Length; ++i) {
                    m_roles[i] = roles[i];
                }
            }
            else {
                m_roles = null;
            }
 
#if !FEATURE_CORECLR
            AddIdentityWithRoles(m_identity, m_roles);
        }
 
        [OnDeserialized()]
        private void OnDeserializedMethod(StreamingContext context)
        {
            // Here it the matrix of possible serializations
            //
            // Version From  |  Version To | ClaimsIdentities | Roles
            // ============     ==========   ================   ========================================================
            // 4.0               4.5         None               We always need to add a ClaimsIdentity, if Roles add them
            //
            // 4.5               4.5         Yes                There should be a ClaimsIdentity, DebugAssert if this is not the case
            //                                                  If there are roles, attach them to the first ClaimsIdentity.
            //                                                  If there is no non-null ClaimsIdentity, add one.  However, this is unusual and may be a bug.
 
            ClaimsIdentity firstNonNullIdentity = null;
            foreach (var identity in base.Identities)
            {
                if (identity != null)
                {
                    firstNonNullIdentity = identity;
                    break;
                }
            }
 
            if (m_roles != null && m_roles.Length > 0 && firstNonNullIdentity != null)
            {
                firstNonNullIdentity.ExternalClaims.Add(new RoleClaimProvider(ClaimsIdentity.DefaultIssuer, m_roles, firstNonNullIdentity).Claims);
            }
            else if (firstNonNullIdentity == null)
            {
                AddIdentityWithRoles(m_identity, m_roles);
            }
        }
 
        /// <summary>
        /// helper method to add roles 
        /// </summary>
        [SecuritySafeCritical]
        void AddIdentityWithRoles(IIdentity identity, string[] roles)
        {
            ClaimsIdentity claimsIdentity = identity as ClaimsIdentity;
 
            if (claimsIdentity != null)
            {
                claimsIdentity = claimsIdentity.Clone();
            }
            else
            {
                claimsIdentity = new ClaimsIdentity(identity);
            }
 
            // if roles are not null then we need to add a provider
            if (roles != null && roles.Length > 0)
            {
                claimsIdentity.ExternalClaims.Add(new RoleClaimProvider(ClaimsIdentity.DefaultIssuer, roles, claimsIdentity).Claims);
            }
 
            base.AddIdentity(claimsIdentity);
        }
#else
        }
#endif
 
 
#if !FEATURE_CORECLR
        public override IIdentity Identity {
#else
        public virtual IIdentity Identity {
#endif
            get { return m_identity; }
        }
 
#if !FEATURE_CORECLR
        public override bool IsInRole(string role) {
#else
        public virtual bool IsInRole (string role) {
#endif
            if (role == null || m_roles == null)
                return false;
 
            for (int i = 0; i < m_roles.Length; ++i) {
                if (m_roles[i] != null && String.Compare(m_roles[i], role, StringComparison.OrdinalIgnoreCase) == 0)
                    return true;
            }
 
#if !FEATURE_CORECLR
            // it may be the case a ClaimsIdentity was passed in as the IIdentity which may have contained claims, they need to be checked.
            return base.IsInRole(role);
#else
            return false;
#endif
        }
    }
}