Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Interface to Send Auth Info to Telemetry #421

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions src/Authentication.Abstractions/AuthTelemetryRecord.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// ----------------------------------------------------------------------------------
//
// Copyright Microsoft Corporation
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------------

using Newtonsoft.Json;

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;

namespace Microsoft.Azure.Commands.Common.Authentication.Abstractions
{
/// <summary>
/// Represents a telemetry record for authentication.
/// </summary>
public class AuthTelemetryRecord : IAuthTelemetryRecord
{
/// <summary>
/// Gets or sets the class name of the TokenCredential, which stands for the authentication method.
/// </summary>
public string TokenCredentialName { get; set; }

/// <summary>
/// Gets or sets a value indicating whether the authentication process succeeded or not.
/// </summary>
public bool AuthenticationSuccess { get; set; } = false;

/// <summary>
/// Gets or sets the correlation ID for the authentication.
/// </summary>
public string CorrelationId { get; set; }

/// <summary>
/// Gets the additional properties for AuthenticationInfo.
/// </summary>
[JsonIgnore]
public IDictionary<string, string> ExtendedProperties { get; } = new ConcurrentDictionary<string, string>(StringComparer.OrdinalIgnoreCase);

/// <summary>
/// Initializes a new instance of the <see cref="AuthTelemetryRecord"/> class.
/// </summary>
public AuthTelemetryRecord()
{
TokenCredentialName = null;
}

/// <summary>
/// Initializes a new instance of the <see cref="AuthTelemetryRecord"/> class based on another instance of <see cref="IAuthTelemetryRecord"/>.
/// </summary>
/// <param name="other">The other instance of <see cref="IAuthTelemetryRecord"/>.</param>
/// <param name="isSuccess">A value indicating whether the authentication was successful or not.</param>
public AuthTelemetryRecord(IAuthTelemetryRecord other, bool? isSuccess = null)
{
this.TokenCredentialName = other.TokenCredentialName;
this.AuthenticationSuccess = isSuccess ?? other.AuthenticationSuccess;
foreach(var property in other.ExtendedProperties)
{
this.SetProperty(property.Key, property.Value);
}
}

/// <summary>
/// Represents the key to indicate whether the token cache is enabled or not.
/// </summary>
public const string TokenCacheEnabled = "TokenCacheEnabled";

/// <summary>
/// Represents the prefix of properties of the first record of authentication telemetry record.
/// </summary>
public const string AuthTelemetryPropertyHeadPrefix = "auth-info-head";

/// <summary>
/// Represents the key of the left records of authentication telemetry.
/// </summary>
public const string AuthTelemetryPropertyTailKey = "auth-info-tail";
}
}
35 changes: 35 additions & 0 deletions src/Authentication.Abstractions/AuthenticationTelemetry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using Microsoft.Azure.Commands.Common.Authentication.Abstractions.Interfaces;

// ----------------------------------------------------------------------------------
//
// Copyright Microsoft Corporation
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------------

namespace Microsoft.Azure.Commands.Common.Authentication.Abstractions
{
/// <summary>
/// Represents a class for handling authentication telemetry.
/// </summary>
public class AuthenticationTelemetry : IAzureTelemetry<AuthTelemetryRecord>
{
/// <summary>
/// Gets the telemetry record for the specified cmdlet context.
/// </summary>
/// <param name="cmdletContext">The cmdlet context.</param>
/// <returns>The authentication telemetry data.</returns>
public AuthenticationTelemetryData GetTelemetryRecord(ICmdletContext cmdletContext)
{
var records = PopTelemetryRecord(cmdletContext);
return records == null ? null : new AuthenticationTelemetryData(records);
}
}
}
52 changes: 52 additions & 0 deletions src/Authentication.Abstractions/AuthenticationTelemetryData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// ----------------------------------------------------------------------------------
//
// Copyright Microsoft Corporation
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------------

using System.Collections.Generic;

namespace Microsoft.Azure.Commands.Common.Authentication.Abstractions
{
/// <summary>
/// Represents the telemetry data for authentication.
/// </summary>
public class AuthenticationTelemetryData
{
/// <summary>
/// Gets the first record of authentication telemetry data, usually describing the main method of the authentication process.
/// </summary>
public IAuthTelemetryRecord Head { get; } = null;

/// <summary>
/// Gets the remaining authentication telemetry records.
/// </summary>
public IList<IAuthTelemetryRecord> Tail { get; } = new List<IAuthTelemetryRecord>();

/// <summary>
/// Initializes a new instance of the <see cref="AuthenticationTelemetryData"/> class with the specified authentication telemetry records.
/// </summary>
/// <param name="records">The authentication telemetry records.</param>
public AuthenticationTelemetryData(IEnumerable<IAuthTelemetryRecord> records)
{
var enumerator = records.GetEnumerator();
if (enumerator.MoveNext())
{
Head = enumerator.Current;
}

while (enumerator.MoveNext())
{
Tail.Add(enumerator.Current);
}
}
}
}
56 changes: 56 additions & 0 deletions src/Authentication.Abstractions/AzureCmdletContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// ----------------------------------------------------------------------------------
//
// Copyright Microsoft Corporation
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------------
using Microsoft.Azure.Commands.Common.Authentication.Abstractions.Interfaces;

namespace Microsoft.Azure.Commands.Common.Authentication.Abstractions
{
/// <summary>
/// Represents the context for an Azure cmdlet.
/// </summary>
public class AzureCmdletContext : ICmdletContext
{
private string cmdletId;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private string cmdletId;
private string _cmdletId;

suggest using '_' as the prefix of private field.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have both private data members that start with lower case and "_". Let get a unified decision for it.


/// <summary>
/// Represents a constant value indicating that no cmdlet context is specified.
/// </summary>
public const ICmdletContext CmdletNone = null;

/// <summary>
/// Initializes a new instance of the <see cref="AzureCmdletContext"/> class with the specified ID.
/// </summary>
/// <param name="id">The ID of the cmdlet.</param>
public AzureCmdletContext(string id)
{
cmdletId = id;
}

/// <summary>
/// Gets or sets the ID of the cmdlet.
/// </summary>
public string CmdletId
{
get => cmdletId;
set => cmdletId = value;
}

/// <summary>
/// Gets a value indicating whether the cmdlet context is valid.
/// </summary>
public bool IsValid
{
get => !string.IsNullOrEmpty(cmdletId);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// ----------------------------------------------------------------------------------
//
// Copyright Microsoft Corporation
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------------

using Microsoft.Azure.Commands.Common.Authentication.Abstractions.Interfaces;

using System.Collections.Generic;

namespace Microsoft.Azure.Commands.Common.Authentication.Abstractions.Extensions
{
/// <summary>
/// Provides extension methods for the <see cref="ICmdletContext"/> interface.
/// </summary>
public static class CmdletContextExtension
{
/// <summary>
/// Converts the <see cref="ICmdletContext"/> object to a dictionary of extensible parameters.
/// </summary>
/// <param name="cmdletContext">The <see cref="ICmdletContext"/> object to convert.</param>
/// <returns>A dictionary of extensible parameters.</returns>
public static IDictionary<string, object> ToExtensibleParameters(this ICmdletContext cmdletContext)
{
if (cmdletContext != null)
{
return new Dictionary<string, object> { { nameof(ICmdletContext), cmdletContext } };
}
return null;
}
}
}
37 changes: 37 additions & 0 deletions src/Authentication.Abstractions/Interfaces/IAuthTelemetryRecord.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// ----------------------------------------------------------------------------------
//
// Copyright Microsoft Corporation
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------------

namespace Microsoft.Azure.Commands.Common.Authentication.Abstractions
{
/// <summary>
/// Represents a telemetry record for authentication.
/// </summary>
public interface IAuthTelemetryRecord : IExtensibleModel
{
/// <summary>
/// Gets or sets the class name of the TokenCredential, which stands for the authentication method.
/// </summary>
string TokenCredentialName { get; set; }

/// <summary>
/// Gets or sets a value indicating whether the authentication process succeeded or not.
/// </summary>
bool AuthenticationSuccess { get; set; }

/// <summary>
/// Gets or sets the correlation ID for the authentication process.
/// </summary>
string CorrelationId { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
using Microsoft.Rest;
using System;
using System.Security;
using Microsoft.Azure.Commands.Common.Authentication.Abstractions.Interfaces;
using System.Collections.Generic;

namespace Microsoft.Azure.Commands.Common.Authentication.Abstractions
{
Expand All @@ -23,6 +25,27 @@ namespace Microsoft.Azure.Commands.Common.Authentication.Abstractions
/// </summary>
public interface IAuthenticationFactory : IHyakAuthenticationFactory
{

/// <summary>
/// Returns IAccessToken if authentication succeeds or throws an exception if authentication fails.
/// </summary>
/// <param name="account">The azure account object</param>
/// <param name="environment">The azure environment object</param>
/// <param name="tenant">The AD tenant in most cases should be 'common'</param>
/// <param name="password">The AD account password</param>
/// <param name="promptBehavior">The prompt behavior</param>
/// <param name="promptAction">The prompt action used in DeviceFlow authentication</param>
/// <param name="optionalParameters">The optional parameters, may include TokenCache, ResourceId and CmdletContext</param>
/// <returns></returns>
IAccessToken Authenticate(
IAzureAccount account,
IAzureEnvironment environment,
string tenant,
SecureString password,
string promptBehavior,
Action<string> promptAction,
IDictionary<string, object> optionalParameters);

/// <summary>
/// Returns IAccessToken if authentication succeeds or throws an exception if authentication fails.
/// </summary>
Expand Down Expand Up @@ -72,6 +95,14 @@ IAccessToken Authenticate(
/// <returns>AutoRest client credentials targeting the given context</returns>
ServiceClientCredentials GetServiceClientCredentials(IAzureContext context);

/// <summary>
/// Get AutoRest credentials for the given context
/// </summary>
/// <param name="context">The target azure context</param>
/// <param name="cmdletContext">The caller cmdlet context</param>
/// <returns>AutoRest client credentials targeting the given context</returns>
ServiceClientCredentials GetServiceClientCredentials(IAzureContext context, ICmdletContext cmdletContext);

/// <summary>
/// Get AutoRest credebntials using the given context and named endpoint
/// </summary>
Expand All @@ -80,6 +111,15 @@ IAccessToken Authenticate(
/// <returns>AutoRest client crentials targeting the given context and endpoint</returns>
ServiceClientCredentials GetServiceClientCredentials(IAzureContext context, string targetEndpoint);

/// <summary>
/// Get AutoRest credebntials using the given context and named endpoint
/// </summary>
/// <param name="context">The context to use for authentication</param>
/// <param name="targetEndpoint">The named endpoint the AutoRest client will target</param>
/// <param name="cmdletContext">The caller cmdlet context</param>
/// <returns>AutoRest client crentials targeting the given context and endpoint</returns>
ServiceClientCredentials GetServiceClientCredentials(IAzureContext context, string targetEndpoint, ICmdletContext cmdletContext);

/// <summary>
/// Get service client credentials with initial token and delegate for renewing
/// </summary>
Expand Down
Loading