< Summary

Class:Azure.Messaging.ServiceBus.Management.SharedAccessAuthorizationRule
Assembly:Azure.Messaging.ServiceBus
File(s):C:\Git\azure-sdk-for-net\sdk\servicebus\Azure.Messaging.ServiceBus\src\Management\SharedAccessAuthorizationRule.cs
Covered lines:87
Uncovered lines:44
Coverable lines:131
Total lines:346
Line coverage:66.4% (87 of 131)
Covered branches:38
Total branches:78
Branch coverage:48.7% (38 of 78)

Metrics

MethodCyclomatic complexity Line coverage Branch coverage
.ctor()-100%100%
.ctor(...)-100%100%
.ctor(...)-0%100%
.ctor(...)-100%100%
Clone()-100%100%
get_ClaimType()-100%100%
get_ClaimValue()-100%100%
get_KeyName()-100%100%
set_KeyName(...)-72.73%50%
get_PrimaryKey()-100%100%
set_PrimaryKey(...)-50%50%
get_SecondaryKey()-100%100%
set_SecondaryKey(...)-45.45%50%
get_Rights()-100%100%
set_Rights(...)-66.67%58.33%
GetHashCode()-0%0%
Equals(...)-0%100%
Equals(...)-68.75%54.55%
op_Equality(...)-0%0%
op_Inequality(...)-0%100%
GenerateRandomKey()-100%100%
CheckBase64(...)-60%100%
ParseFromXElement(...)-78.95%87.5%
Serialize()-100%100%

File(s)

C:\Git\azure-sdk-for-net\sdk\servicebus\Azure.Messaging.ServiceBus\src\Management\SharedAccessAuthorizationRule.cs

#LineLine coverage
 1// Copyright (c) Microsoft Corporation. All rights reserved.
 2// Licensed under the MIT License.
 3
 4using System;
 5using System.Collections.Generic;
 6using System.Linq;
 7using System.Security.Cryptography;
 8using System.Text;
 9using System.Web;
 10using System.Xml;
 11using System.Xml.Linq;
 12using Azure.Core;
 13using Azure.Messaging.ServiceBus.Authorization;
 14
 15namespace Azure.Messaging.ServiceBus.Management
 16{
 17    /// <summary>
 18    /// Defines the authorization rule for an entity using SAS.
 19    /// </summary>
 20    public class SharedAccessAuthorizationRule : AuthorizationRule
 21    {
 22        private const int SupportedSASKeyLength = 44;
 23        private const string FixedClaimType = "SharedAccessKey";
 24
 25        private string internalKeyName;
 26        private string internalPrimaryKey;
 27        private string internalSecondaryKey;
 28        private List<AccessRights> internalRights;
 29
 4030        internal SharedAccessAuthorizationRule()
 31        {
 4032        }
 33
 34        /// <summary>Initializes a new instance of the <see cref="SharedAccessAuthorizationRule" /> class.</summary>
 35        /// <param name="keyName">The authorization rule key name.</param>
 36        /// <param name="rights">The list of rights.</param>
 37        public SharedAccessAuthorizationRule(string keyName, IEnumerable<AccessRights> rights)
 1238            : this(keyName, SharedAccessAuthorizationRule.GenerateRandomKey(), SharedAccessAuthorizationRule.GenerateRan
 39        {
 1240        }
 41
 42        /// <summary>Initializes a new instance of the <see cref="SharedAccessAuthorizationRule" /> class.</summary>
 43        /// <param name="keyName">The authorization rule key name.</param>
 44        /// <param name="primaryKey">The primary key for the authorization rule.</param>
 45        /// <param name="rights">The list of rights.</param>
 46        public SharedAccessAuthorizationRule(string keyName, string primaryKey, IEnumerable<AccessRights> rights)
 047            : this(keyName, primaryKey, SharedAccessAuthorizationRule.GenerateRandomKey(), rights)
 48        {
 049        }
 50
 51        /// <summary>Initializes a new instance of the <see cref="SharedAccessAuthorizationRule" /> class.</summary>
 52        /// <param name="keyName">The authorization rule key name.</param>
 53        /// <param name="primaryKey">The primary key for the authorization rule.</param>
 54        /// <param name="secondaryKey">The secondary key for the authorization rule.</param>
 55        /// <param name="rights">The list of rights.</param>
 3256        public SharedAccessAuthorizationRule(string keyName, string primaryKey, string secondaryKey, IEnumerable<AccessR
 57        {
 3258            PrimaryKey = primaryKey;
 3259            SecondaryKey = secondaryKey;
 3260            Rights = new List<AccessRights>(rights);
 3261            KeyName = keyName;
 3262        }
 63
 64        internal override AuthorizationRule Clone() =>
 2065            new SharedAccessAuthorizationRule(KeyName, PrimaryKey, SecondaryKey, Rights);
 66
 67        /// <inheritdoc/>
 1668        public override string ClaimType => FixedClaimType;
 1669        internal override string ClaimValue => "None";
 70
 71        /// <summary>Gets or sets the authorization rule key name.</summary>
 72        /// <value>The authorization rule key name.</value>
 73        public sealed override string KeyName
 74        {
 13275            get { return internalKeyName; }
 76            set
 77            {
 7278                Argument.AssertNotNullOrWhiteSpace(value, nameof(KeyName));
 7279                Argument.AssertNotTooLong(
 7280                    value,
 7281                    SharedAccessSignature.MaximumKeyNameLength,
 7282                    nameof(KeyName));
 83
 7284                if (!string.Equals(value, HttpUtility.UrlEncode(value), StringComparison.InvariantCulture))
 85                {
 86#pragma warning disable CA2208 // Instantiate argument exceptions correctly
 087                    throw new ArgumentException(
 088                        "The key name specified contains invalid characters",
 089                        nameof(KeyName));
 90#pragma warning restore CA2208 // Instantiate argument exceptions correctly
 91                }
 92
 7293                internalKeyName = value;
 7294            }
 95        }
 96
 97        /// <summary>Gets or sets the primary key for the authorization rule.</summary>
 98        /// <value>The primary key for the authorization rule.</value>
 99        public string PrimaryKey
 100        {
 84101            get { return internalPrimaryKey; }
 102            set
 103            {
 72104                Argument.AssertNotNullOrWhiteSpace(value, nameof(PrimaryKey));
 105
 72106                if (Encoding.ASCII.GetByteCount(value) != SupportedSASKeyLength)
 107                {
 108#pragma warning disable CA2208 // Instantiate argument exceptions correctly
 0109                    throw new ArgumentOutOfRangeException(
 0110                        nameof(PrimaryKey),
 0111                        $"{nameof(SharedAccessAuthorizationRule)} only supports keys of size {SupportedSASKeyLength} byt
 112#pragma warning restore CA2208 // Instantiate argument exceptions correctly
 113                }
 114
 72115                if (!CheckBase64(value))
 116                {
 117#pragma warning disable CA2208 // Instantiate argument exceptions correctly
 0118                    throw new ArgumentException($"{nameof(SharedAccessAuthorizationRule)} only supports base64 keys.",
 0119                        nameof(PrimaryKey));
 120#pragma warning restore CA2208 // Instantiate argument exceptions correctly
 121                }
 122
 72123                internalPrimaryKey = value;
 72124            }
 125        }
 126
 127        /// <summary>Gets or sets the secondary key for the authorization rule.</summary>
 128        /// <value>The secondary key for the authorization rule.</value>
 129        public string SecondaryKey
 130        {
 84131            get { return internalSecondaryKey; }
 132            set
 133            {
 72134                Argument.AssertNotNullOrWhiteSpace(value, nameof(SecondaryKey));
 135
 72136                if (Encoding.ASCII.GetByteCount(value) != SupportedSASKeyLength)
 137                {
 138#pragma warning disable CA2208 // Instantiate argument exceptions correctly
 0139                    throw new ArgumentOutOfRangeException(
 0140                        nameof(SecondaryKey),
 0141                        $"{nameof(SharedAccessAuthorizationRule)} only supports keys of size {SupportedSASKeyLength} byt
 142#pragma warning restore CA2208 // Instantiate argument exceptions correctly
 143                }
 144
 72145                if (!CheckBase64(value))
 146                {
 147#pragma warning disable CA2208 // Instantiate argument exceptions correctly
 0148                    throw new ArgumentException(
 0149                        $"{nameof(SharedAccessAuthorizationRule)} only supports base64 keys.",
 0150                    nameof(SecondaryKey));
 151#pragma warning restore CA2208 // Instantiate argument exceptions correctly
 152                }
 153
 72154                internalSecondaryKey = value;
 72155            }
 156        }
 157
 158        /// <inheritdoc/>
 159        [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2227:Collection properties should be read only", Ju
 160        public override List<AccessRights> Rights
 161        {
 228162            get => internalRights;
 163            set
 164            {
 72165                if (value == null || value.Count < 0 || value.Count > ManagementClientConstants.SupportedClaimsCount)
 166                {
 0167                    throw new ArgumentException($"Rights cannot be null, empty or greater than {ManagementClientConstant
 168                }
 169
 72170                HashSet<AccessRights> dedupedAccessRights = new HashSet<AccessRights>(value);
 72171                if (value.Count != dedupedAccessRights.Count)
 172                {
 0173                    throw new ArgumentException("Access rights on an authorization rule must be unique");
 174                }
 175
 72176                if (value.Contains(AccessRights.Manage) && value.Count != 3)
 177                {
 0178                    throw new ArgumentException("Manage permission should also include Send and Listen");
 179                }
 180
 72181                internalRights = value;
 72182            }
 183        }
 184
 185        /// <summary>Returns the hash code for this instance.</summary>
 186        public override int GetHashCode()
 187        {
 0188            int hash = 13;
 189            unchecked
 190            {
 0191                hash = (hash * 7) + KeyName?.GetHashCode() ?? 0;
 0192                hash = (hash * 7) + PrimaryKey?.GetHashCode() ?? 0;
 0193                hash = (hash * 7) + SecondaryKey?.GetHashCode() ?? 0;
 0194                hash = (hash * 7) + Rights.GetHashCode();
 195            }
 196
 0197            return hash;
 198        }
 199
 200        /// <summary>Determines whether the specified object is equal to the current object.</summary>
 201        public override bool Equals(object obj)
 202        {
 0203            var other = obj as AuthorizationRule;
 0204            return Equals(other);
 205        }
 206
 207        /// <summary>Determines whether the specified object is equal to the current object.</summary>
 208        /// <param name="other">The object to compare with the current object.</param>
 209        /// <returns>true if the specified object is equal to the current object; otherwise, false.</returns>
 210        public override bool Equals(AuthorizationRule other)
 211        {
 24212            if (!(other is SharedAccessAuthorizationRule))
 213            {
 0214                return false;
 215            }
 216
 24217            SharedAccessAuthorizationRule comparand = (SharedAccessAuthorizationRule)other;
 24218            if (!string.Equals(KeyName, comparand.KeyName, StringComparison.OrdinalIgnoreCase) ||
 24219                !string.Equals(PrimaryKey, comparand.PrimaryKey, StringComparison.Ordinal) ||
 24220                !string.Equals(SecondaryKey, comparand.SecondaryKey, StringComparison.Ordinal))
 221            {
 0222                return false;
 223            }
 224
 24225            if ((Rights != null && comparand.Rights == null) ||
 24226                (Rights == null && comparand.Rights != null))
 227            {
 0228                return false;
 229            }
 230
 24231            if (Rights != null && comparand.Rights != null)
 232            {
 24233                HashSet<AccessRights> thisRights = new HashSet<AccessRights>(Rights);
 24234                if (comparand.Rights.Count != thisRights.Count)
 235                {
 0236                    return false;
 237                }
 238
 24239                return thisRights.SetEquals(comparand.Rights);
 240            }
 241
 0242            return true;
 243        }
 244
 245        /// <summary></summary>
 246        public static bool operator ==(SharedAccessAuthorizationRule left, SharedAccessAuthorizationRule right)
 247        {
 0248            if (ReferenceEquals(left, right))
 249            {
 0250                return true;
 251            }
 252
 0253            if (ReferenceEquals(left, null) || ReferenceEquals(right, null))
 254            {
 0255                return false;
 256            }
 257
 0258            return left.Equals(right);
 259        }
 260
 261        /// <summary></summary>
 262        public static bool operator !=(SharedAccessAuthorizationRule left, SharedAccessAuthorizationRule right)
 263        {
 0264            return !(left == right);
 265        }
 266
 267        /// <summary>Generates the random key for the authorization rule.</summary>
 268        private static string GenerateRandomKey()
 269        {
 24270            byte[] key256 = new byte[32];
 24271            using (var rngCryptoServiceProvider = new RNGCryptoServiceProvider())
 272            {
 24273                rngCryptoServiceProvider.GetBytes(key256);
 24274            }
 275
 24276            return Convert.ToBase64String(key256);
 277        }
 278
 279        private static bool CheckBase64(string base64EncodedString)
 280        {
 281            try
 282            {
 144283                Convert.FromBase64String(base64EncodedString);
 144284                return true;
 285            }
 0286            catch (Exception)
 287            {
 0288                return false;
 289            }
 144290        }
 291
 292        internal static new SharedAccessAuthorizationRule ParseFromXElement(XElement xElement)
 293        {
 40294            var rule = new SharedAccessAuthorizationRule();
 560295            foreach (var element in xElement.Elements())
 296            {
 240297                switch (element.Name.LocalName)
 298                {
 299                    case "CreatedTime":
 0300                        rule.CreatedTime = XmlConvert.ToDateTime(element.Value, XmlDateTimeSerializationMode.Utc);
 0301                        break;
 302                    case "ModifiedTime":
 0303                        rule.ModifiedTime = XmlConvert.ToDateTime(element.Value, XmlDateTimeSerializationMode.Utc);
 0304                        break;
 305                    case "KeyName":
 40306                        rule.KeyName = element.Value;
 40307                        break;
 308                    case "PrimaryKey":
 40309                        rule.PrimaryKey = element.Value;
 40310                        break;
 311                    case "SecondaryKey":
 40312                        rule.SecondaryKey = element.Value;
 40313                        break;
 314                    case "Rights":
 40315                        var rights = new List<AccessRights>();
 40316                        var xRights = element.Elements(XName.Get("AccessRights", ManagementClientConstants.ServiceBusNam
 296317                        foreach (var xRight in xRights)
 318                        {
 108319                            rights.Add((AccessRights)Enum.Parse(typeof(AccessRights), xRight.Value));
 320                        }
 40321                        rule.Rights = rights;
 322                        break;
 323                }
 324            }
 325
 40326            return rule;
 327        }
 328
 329        internal override XElement Serialize()
 330        {
 16331            XElement rule = new XElement(
 16332                XName.Get("AuthorizationRule", ManagementClientConstants.ServiceBusNamespace),
 16333                new XAttribute(XName.Get("type", ManagementClientConstants.XmlSchemaInstanceNamespace), nameof(SharedAcc
 16334                new XElement(XName.Get("ClaimType", ManagementClientConstants.ServiceBusNamespace), ClaimType),
 16335                new XElement(XName.Get("ClaimValue", ManagementClientConstants.ServiceBusNamespace), ClaimValue),
 16336                new XElement(XName.Get("Rights", ManagementClientConstants.ServiceBusNamespace),
 60337                    Rights.Select(right => new XElement(XName.Get("AccessRights", ManagementClientConstants.ServiceBusNa
 16338                new XElement(XName.Get("KeyName", ManagementClientConstants.ServiceBusNamespace), KeyName),
 16339                new XElement(XName.Get("PrimaryKey", ManagementClientConstants.ServiceBusNamespace), PrimaryKey),
 16340                new XElement(XName.Get("SecondaryKey", ManagementClientConstants.ServiceBusNamespace), SecondaryKey)
 16341            );
 342
 16343            return rule;
 344        }
 345    }
 346}