diff --git a/src/Microsoft.IdentityModel.Logging/GlobalSuppressions.cs b/src/Microsoft.IdentityModel.Logging/GlobalSuppressions.cs index c544c4d70c..dbc50a6607 100644 --- a/src/Microsoft.IdentityModel.Logging/GlobalSuppressions.cs +++ b/src/Microsoft.IdentityModel.Logging/GlobalSuppressions.cs @@ -7,3 +7,4 @@ [assembly: SuppressMessage("Design", "CA1052:Static holder types should be Static or NotInheritable", Justification = "Previously released as non-static / inheritable", Scope = "type", Target = "~T:Microsoft.IdentityModel.Logging.LogHelper")] [assembly: SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Execution should not be altered for exceptions on format", Scope = "member", Target = "~M:Microsoft.IdentityModel.Logging.IdentityModelEventSource.PrepareMessage(System.Diagnostics.Tracing.EventLevel,System.String,System.Object[])~System.String")] +[assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Breaking change", Scope = "member", Target = "~P:Microsoft.IdentityModel.Logging.LoggerContext.PropertyBag")] diff --git a/src/Microsoft.IdentityModel.Logging/LoggerContext.cs b/src/Microsoft.IdentityModel.Logging/LoggerContext.cs new file mode 100644 index 0000000000..77481be63e --- /dev/null +++ b/src/Microsoft.IdentityModel.Logging/LoggerContext.cs @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; + +namespace Microsoft.IdentityModel.Logging +{ + /// + /// A context class that can be used to store work per request to aid with debugging. + /// + public class LoggerContext + { + /// + /// Instantiates a new with the default activityId. + /// + public LoggerContext() + { + } + + /// + /// Instantiates a new with an activityId. + /// + /// + public LoggerContext(Guid activityId) + { + ActivityId = activityId; + } + + /// + /// Gets or set a that will be used in the call to EventSource.SetCurrentThreadActivityId before logging. + /// + public Guid ActivityId { get; set; } = Guid.Empty; + + /// + /// Gets or sets a boolean controlling if logs are written into the context. + /// Useful when debugging. + /// + public bool CaptureLogs { get; set; } = false; + + /// + /// Gets or sets a string that helps with setting breakpoints when debugging. + /// + public string Id { get; set; } = string.Empty; + + /// + /// The collection of logs associated with a request. Use to control capture. + /// + public ICollection Logs { get; private set; } = new Collection(); + + /// + /// Gets or sets an that enables custom extensibility scenarios. + /// + public IDictionary PropertyBag { get; set; } + } +} diff --git a/src/Microsoft.IdentityModel.Tokens/CallContext.cs b/src/Microsoft.IdentityModel.Tokens/CallContext.cs index 5e1195377d..d800d7dd05 100644 --- a/src/Microsoft.IdentityModel.Tokens/CallContext.cs +++ b/src/Microsoft.IdentityModel.Tokens/CallContext.cs @@ -26,50 +26,27 @@ //------------------------------------------------------------------------------ using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; +using Microsoft.IdentityModel.Logging; namespace Microsoft.IdentityModel.Tokens { /// /// An opaque context used to store work when working with authentication artifacts. /// - public class CallContext + public class CallContext : LoggerContext { /// /// Instantiates a new with a default activityId. /// - public CallContext() + public CallContext() : base() { } /// /// Instantiates a new with an activityId. /// - public CallContext(Guid activityId) + public CallContext(Guid activityId) : base(activityId) { - ActivityId = activityId; } - - /// - /// Gets or set a that will be used in the call to EventSource.SetCurrentThreadActivityId before logging. - /// - public Guid ActivityId { get; set; } = Guid.Empty; - - /// - /// Gets or sets a boolean controlling if logs are written into the context. - /// Useful when debugging. - /// - public bool CaptureLogs { get; set; } = false; - - /// - /// The collection of logs associated with a request. Use to control capture. - /// - public ICollection Logs { get; private set; } = new Collection(); - - /// - /// Gets or sets an that enables custom extensibility scenarios. - /// - public IDictionary PropertyBag { get; set; } } } diff --git a/src/Microsoft.IdentityModel.Tokens/GlobalSuppressions.cs b/src/Microsoft.IdentityModel.Tokens/GlobalSuppressions.cs index 83ef0e0a80..86381917d7 100644 --- a/src/Microsoft.IdentityModel.Tokens/GlobalSuppressions.cs +++ b/src/Microsoft.IdentityModel.Tokens/GlobalSuppressions.cs @@ -24,7 +24,6 @@ [assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Breaking change", Scope = "member", Target = "~P:Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor.AdditionalHeaderClaims")] [assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Breaking change", Scope = "member", Target = "~P:Microsoft.IdentityModel.Tokens.SecurityTokenDescriptor.Claims")] [assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Breaking change", Scope = "member", Target = "~P:Microsoft.IdentityModel.Tokens.JsonWebKey.Oth")] -[assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Breaking change", Scope = "member", Target = "~P:Microsoft.IdentityModel.Tokens.CallContext.PropertyBag")] [assembly: SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "Breaking chnage", Scope = "member", Target = "~P:Microsoft.IdentityModel.Tokens.TokenValidationParameters.PropertyBag")] [assembly: SuppressMessage("Usage", "CA2214:Do not call overridable methods in constructors", Justification = "Current design", Scope = "member", Target = "~M:Microsoft.IdentityModel.Tokens.TokenValidationParameters.#ctor(Microsoft.IdentityModel.Tokens.TokenValidationParameters)")] [assembly: SuppressMessage("Usage", "CA2213:Disposable fields should be disposed", Justification = "Disposed through ReleaseSignatureProvider", Scope = "member", Target = "~F:Microsoft.IdentityModel.Tokens.AuthenticatedEncryptionProvider._symmetricSignatureProvider")] diff --git a/test/Microsoft.IdentityModel.Tokens.Tests/CallContextTests.cs b/test/Microsoft.IdentityModel.Tokens.Tests/CallContextTests.cs new file mode 100644 index 0000000000..50a5e1ec63 --- /dev/null +++ b/test/Microsoft.IdentityModel.Tokens.Tests/CallContextTests.cs @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.CodeDom; +using Microsoft.IdentityModel.Logging; +using Microsoft.IdentityModel.TestUtils; +using Xunit; + +#pragma warning disable CS3016 // Arrays as attribute arguments is not CLS-compliant + +namespace Microsoft.IdentityModel.Tokens.Tests +{ + public class CallContextTests + { + [Theory, MemberData(nameof(CallContextTestTheoryData))] + public void LoggerInstanceTests(CallContextTheoryData theoryData) + { + var context = new CallContext(theoryData.ActivityId) { Id = theoryData.TestId }; + + Assert.IsAssignableFrom(context); + Assert.Equal(theoryData.TestId, context.Id); + Assert.Equal(theoryData.ActivityId, context.ActivityId); + Assert.False(context.CaptureLogs); + Assert.Empty(context.Logs); + Assert.Null(context.PropertyBag); + } + + public static TheoryData CallContextTestTheoryData + { + get + { + var theoryData = new TheoryData(); + + theoryData.Add(new CallContextTheoryData + { + TestId = "abdc", + ActivityId = new Guid() + }); + + return theoryData; + } + } + } + + public class CallContextTheoryData : TheoryDataBase + { + public Guid ActivityId; + } +} + +#pragma warning restore CS3016 // Arrays as attribute arguments is not CLS-compliant