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

Entra/Library Updates #38532

Merged
merged 84 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from 74 commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
d279f42
Marked empty/null actions as failed
hakimms Jul 10, 2023
8792bb3
replaced tabs with spaces
hakimms Jul 10, 2023
738b7ed
Updated spacing
hakimms Jul 10, 2023
3bfb603
Replaced tab with spaces
hakimms Jul 11, 2023
fc8b677
Updates based on feedback
hakimms Jul 15, 2023
92dffa6
Updated Validation Logic
hakimms Jul 18, 2023
d5eb101
WIP Added test cases for OneOrMoreRequiredAttribute
hakimms Jul 19, 2023
bcc1696
Added test case for EnumberableItemsNotNull Attribute
hakimms Jul 19, 2023
9c3eff8
Feedback updates
hakimms Jul 19, 2023
e754635
Updates based on PR feedback
hakimms Jul 20, 2023
dc23ad0
Sort 'using' lists and removed unapplicable data annotation
hakimms Jul 20, 2023
f8d54e4
Removed xUnit reference now that we are using NUnit tests
hakimms Jul 25, 2023
bbec11f
removed Update-Snippets.ps1 changes and will rebase
hakimms Jul 25, 2023
0f74218
Added null check and test for response before marking as failed
hakimms Jul 27, 2023
dc7e054
Updated exception to validation exception and corrected test
hakimms Jul 27, 2023
ad25761
Changed back to argument null exception
hakimms Jul 28, 2023
49b91e8
Added response validation exception type
hakimms Jul 28, 2023
7632272
Update sdk/entra/Microsoft.Azure.WebJobs.Extensions.AuthenticationEve…
hakimms Aug 1, 2023
be27912
Added period
hakimms Aug 1, 2023
cbf1fd8
Added not null check for source field in payload
hakimms Jul 22, 2023
501a400
Changed source attribute to required
hakimms Jul 29, 2023
fd34095
Adding necessary updates to merge with azure main
hakimms Jul 20, 2023
6230dad
Added validation class
hakimms Aug 5, 2023
ef6e7b5
added logic to throw RequestValidationException
hakimms Aug 22, 2023
9d6ed8a
Replaced tabs with spaces
hakimms Aug 22, 2023
f48d46c
Added pull request template
hakimms Aug 23, 2023
e5d64b2
Added existing text to PR template
hakimms Aug 23, 2023
0a9d9ae
Removed pr template
hakimms Aug 24, 2023
65932db
Reverted IsMsaPassThroughEnabled and ran scripts to pass build merge
hakimms Aug 25, 2023
31d1517
Added comment
hakimms Aug 26, 2023
d5c9e38
Updated changelog
hakimms Aug 30, 2023
dd0f136
added more context to changelog file
hakimms Sep 1, 2023
3e89070
Revert changes
hakimms Sep 7, 2023
c429e23
ODataType property in Request is now required
hakimms Sep 7, 2023
d818b79
Add bug fix description to changelog
hakimms Sep 7, 2023
bb49dda
Corrected format
hakimms Sep 7, 2023
54baa7f
Add metrics to header
HarmanDhunna Sep 12, 2023
b67e5f0
Reverting code that was changed by accident
HarmanDhunna Sep 19, 2023
b410ea0
passing inner exception to RequestValidationException
hakimms Sep 20, 2023
5df7574
Modify version semantics
HarmanDhunna Sep 21, 2023
07e8250
Revert version name
HarmanDhunna Sep 25, 2023
6401df3
ChangeLog
HarmanDhunna Sep 25, 2023
8204e4a
Changes to metrics
HarmanDhunna Sep 28, 2023
80aed27
Change the metrics format string to match the general guidelines for …
HarmanDhunna Sep 28, 2023
2e34056
Sorted usings
HarmanDhunna Sep 29, 2023
9a44051
ran the scripts
HarmanDhunna Sep 29, 2023
9d9ada9
Updated Errors and added unit tests
hakimms Sep 26, 2023
0303673
Used newtonsoft to parse json and updated unit tests
hakimms Sep 26, 2023
1fdc7ce
Updated changelog
hakimms Sep 27, 2023
e8ac9c7
Updated error for invalid json characters
hakimms Oct 4, 2023
2d34cc1
Updated exception identifier
hakimms Oct 4, 2023
c46a94d
Replaced data with sanitized values
hakimms Oct 11, 2023
c79ff74
Updated GUIDs, IP address and emails
hakimms Oct 17, 2023
11400c4
Merge pull request #18 from hakimms/abdulhakim/Fix-Test-Payloads
hakimms Oct 17, 2023
135581e
Removed newtonsoft dependencies and used system.text.json instead
hakimms Oct 19, 2023
fc153ca
Removed newtonsoft dependency from AuthenticationEventDataTests
hakimms Oct 21, 2023
0f0a60f
Changing access level on AuthEventResponseHandler
HarmanDhunna Oct 18, 2023
afa0968
Change the which assembly is used for metrics
HarmanDhunna Oct 23, 2023
33ba0c3
Ran script
HarmanDhunna Oct 23, 2023
45c1eb6
Use type to look up assembly
HarmanDhunna Oct 23, 2023
b3c8682
Updated TestHelpers newtonsoft dependencies to stj
hakimms Oct 24, 2023
4350c23
Removed usings
hakimms Oct 24, 2023
e2e2657
Using assembly name instead of assembly itself
HarmanDhunna Oct 24, 2023
788ac1b
Modify the tests to check only for value exsistence and not actual value
HarmanDhunna Oct 24, 2023
21c742b
Adding using for JsonDocument and Used JsonObject
hakimms Oct 24, 2023
6a2b5cd
Changing metrics to a singleton pattern and modifing the tests to trim
HarmanDhunna Oct 24, 2023
0688fb5
Ran Scripts
HarmanDhunna Oct 24, 2023
befaee8
Added braces
hakimms Oct 24, 2023
8e7c2e8
Merge pull request #21 from hakimms/hadhunna/UpdateResponseAccess
HarmanDhunna Oct 24, 2023
1e62d7f
Reverted test project changes as newtonsoft linq is currently needed
hakimms Oct 25, 2023
8641df2
removed unnecessary comment and line
hakimms Oct 25, 2023
98f4580
replaced string quotes with string.empty
hakimms Oct 25, 2023
c8264f5
Merge pull request #20 from hakimms/abdulhakim/Revert-Newtonsoft-Depe…
hakimms Oct 25, 2023
071a453
Simplified isJson method and reverted project change
hakimms Oct 26, 2023
252c3c6
Updated IsJson boolean method to ValidateJson void
hakimms Oct 27, 2023
662397c
Updated spacing
hakimms Oct 27, 2023
905eaa2
Updated Json error string for empty payload
hakimms Oct 27, 2023
a38d753
Update error string
hakimms Oct 30, 2023
5fcdf97
Merge pull request #22 from hakimms/abdulhakim/Change-Json-Validation
hakimms Oct 30, 2023
898f69a
Added structure for Exception classes
hakimms Nov 2, 2023
eff078c
Made classes internal
hakimms Nov 2, 2023
70fbd78
Merge pull request #23 from hakimms/abdulhakim/Add-Custom-Exceptions
HarmanDhunna Nov 3, 2023
15780b6
Update class to remove Old exceptions
hakimms Nov 4, 2023
1d35022
Merge pull request #24 from hakimms/abdulhakim/Run-Scripts-for-Except…
hakimms Nov 4, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@

## 1.0.0-beta.4 (Unreleased)

### Features

- Added metrics to header. Will be used to track the number of requests and responses for each action.

### Bugs Fixed

- Updated ODataType signature
- Empty or null response actions will throw a bad response
- Made the source field in the request a required field
- Updated ODataType signature. This was done to make sure the contracts were consistent across all services.
- Empty or null response actions will throw a bad response. There should be at lease one action passed as this is the main purpose of the SDK library.
- Made the source field in the request a required field.
- Made the request validation errors return 500. This way, we can identify that 500 errors as internal and should be marked as failures whereas response object errors should return 400s since they are customer input errors and should be identified as CallerErrors in our service.
- Made the ODataType field in the request a required field.
- Made the errors for JSON payload more descriptive when an invalid character is passed.
- Added JsonDocument TryParse check to validate payload is JSON format.

## 1.0.0-beta.3 (2022-12-13)

Expand All @@ -17,7 +25,7 @@
- Added createdDateTime to AuthenticationEventContextUser
- Added new request status type for validation failure.
- Validation Errors raise 500 response.
- Added CustomAuthenticaionExtensionId to Data.
- Added CustomAuthenticationExtensionId to Data.
- Removed AuthenticationEventsId from Data.

## 1.0.0-beta.2 (2022-11-08)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ internal AuthenticationEventMetadataAttribute() { }
}
public partial class AuthenticationEventResponseHandler : Microsoft.Azure.WebJobs.Host.Bindings.IValueBinder, Microsoft.Azure.WebJobs.Host.Bindings.IValueProvider
{
public AuthenticationEventResponseHandler() { }
internal AuthenticationEventResponseHandler() { }
public Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.Framework.AuthenticationEventRequestBase Request { get { throw null; } }
public Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.Framework.AuthenticationEventResponse Response { get { throw null; } }
public System.Type Type { get { throw null; } }
Expand All @@ -34,6 +34,16 @@ public enum EventDefinition
[Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.AuthenticationEventMetadataAttribute(typeof(Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.TokenIssuanceStart.TokenIssuanceStartRequest), "microsoft.graph.authenticationEvent.TokenIssuanceStart", "TokenIssuanceStart", "CloudEventActionableTemplate.json")]
TokenIssuanceStart = 0,
}
public sealed partial class EventTriggerMetrics
{
internal EventTriggerMetrics() { }
public const string MetricsHeader = "User-Agent";
public const string ProductName = "AuthenticationEvents";
public static string Framework { get { throw null; } }
public static Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.EventTriggerMetrics Instance { get { throw null; } }
public static string Platform { get { throw null; } }
public static string ProductVersion { get { throw null; } }
}
public enum EventType
{
OnTokenIssuanceStart = 0,
Expand All @@ -45,6 +55,11 @@ public enum RequestStatusType
Successful = 2,
ValidationError = 3,
}
public partial class RequestValidationException : System.Exception
{
public RequestValidationException(string message) { }
public RequestValidationException(string message, System.Exception innerException) { }
}
public partial class ResponseValidationException : System.Exception
{
public ResponseValidationException(string message) { }
Expand Down Expand Up @@ -128,6 +143,7 @@ protected CloudEventData() { }
public abstract partial class CloudEventRequest<TResponse, TData> : Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.Framework.AuthenticationEventRequest<TResponse, TData> where TResponse : Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.Framework.AuthenticationEventResponse, new() where TData : Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.Framework.CloudEventData
{
internal CloudEventRequest() { }
[System.ComponentModel.DataAnnotations.RequiredAttribute]
[System.Text.Json.Serialization.JsonPropertyNameAttribute("oDataType")]
public string ODataType { get { throw null; } set { } }
[System.ComponentModel.DataAnnotations.RequiredAttribute]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.Framework;
using Microsoft.Azure.WebJobs.Host.Bindings;
using Microsoft.Azure.WebJobs.Host.Listeners;
using Microsoft.Azure.WebJobs.Host.Protocols;
using Microsoft.Azure.WebJobs.Host.Triggers;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
Expand All @@ -14,8 +9,14 @@
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.Framework;
using Microsoft.Azure.WebJobs.Host.Bindings;
using Microsoft.Azure.WebJobs.Host.Listeners;
using Microsoft.Azure.WebJobs.Host.Protocols;
using Microsoft.Azure.WebJobs.Host.Triggers;
using static Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.Framework.EmptyResponse;
using AuthenticationEventMetadata = Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.Framework.AuthenticationEventMetadata;

Expand Down Expand Up @@ -84,7 +85,8 @@ private static IReadOnlyDictionary<string, Type> GetBindingDataContract(Paramete
public async Task<ITriggerData> BindAsync(object value, ValueBindingContext context)
{
var request = (HttpRequestMessage)value;
AuthenticationEventResponseHandler eventResponseHandler = (AuthenticationEventResponseHandler)request.Properties[AuthenticationEventResponseHandler.EventResponseProperty];
AuthenticationEventResponseHandler eventResponseHandler =
(AuthenticationEventResponseHandler)request.Properties[AuthenticationEventResponseHandler.EventResponseProperty];
try
{
if (request == null)
Expand All @@ -97,7 +99,15 @@ public async Task<ITriggerData> BindAsync(object value, ValueBindingContext cont
AuthenticationEventMetadata eventMetadata = GetEventAndValidateSchema(payload);

eventResponseHandler.Request = GetRequestForEvent(request, payload, eventMetadata, Claims);
return new TriggerData(new AuthenticationEventValueBinder(eventResponseHandler.Request, _authEventTriggerAttr), GetBindingData(context, value, eventResponseHandler))

return new TriggerData(
new AuthenticationEventValueBinder(
eventResponseHandler.Request,
_authEventTriggerAttr),
GetBindingData(
context,
value,
eventResponseHandler))
{
ReturnValueProvider = eventResponseHandler
};
Expand All @@ -118,7 +128,12 @@ public async Task<ITriggerData> BindAsync(object value, ValueBindingContext cont
/// <returns>A TriggerData Object with the failed event request based on the event. With the related request status set.</returns>
/// <seealso cref="TriggerData" />
/// <seealso cref="AuthenticationEventResponseHandler" />
private TriggerData GetFaultyRequest(ValueBindingContext context, object value, HttpRequestMessage request, AuthenticationEventResponseHandler eventResponseHandler, Exception ex)
private TriggerData GetFaultyRequest(
ValueBindingContext context,
object value,
HttpRequestMessage request,
AuthenticationEventResponseHandler eventResponseHandler,
Exception ex)
{
eventResponseHandler.Request = _parameterInfo.ParameterType == typeof(string) ? new EmptyRequest(request) : AuthenticationEventMetadata.CreateEventRequest(request, _parameterInfo.ParameterType, null);
eventResponseHandler.Request.StatusMessage = ex.Message;
Expand All @@ -127,6 +142,7 @@ private TriggerData GetFaultyRequest(ValueBindingContext context, object value,
{
UnauthorizedAccessException => RequestStatusType.TokenInvalid,
ValidationException => RequestStatusType.ValidationError,
RequestValidationException => RequestStatusType.ValidationError,
_ => RequestStatusType.Failed,
};

Expand Down Expand Up @@ -228,11 +244,18 @@ private async Task<Dictionary<string, string>> GetClaimsAndValidateRequest(HttpR
/// <returns>The Event Metadata object.</returns>
/// <exception cref="AggregateException">Aggregates all the schema validation exceptions.</exception>
/// <exception cref="Exception">IF the event cannot be determined or if the object model event differs from the requested event on the incoming payload.</exception>
private static AuthenticationEventMetadata GetEventAndValidateSchema(string body)
internal static AuthenticationEventMetadata GetEventAndValidateSchema(string body)
{
if (!Helpers.IsJson(body))
try
{
if (!Helpers.IsJson(body))
hakimms marked this conversation as resolved.
Show resolved Hide resolved
{
throw new RequestValidationException(AuthenticationEventResource.Ex_Invalid_JsonPayload);
}
}
catch (JsonException ex)
{
throw new InvalidDataException();
throw new RequestValidationException($"{AuthenticationEventResource.Ex_Invalid_JsonPayload}: {ex.Message}", ex.InnerException);
}

return AuthenticationEventMetadataLoader.GetEventMetadata(body);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,10 @@ public async Task<HttpResponseMessage> ConvertAsync(HttpRequestMessage input, Ca
};

FunctionResult result = await listener.Value.FunctionExecutor.TryExecuteAsync(triggerData, cancellationToken).ConfigureAwait(false);
return result.Succeeded ? (HttpResponseMessage)eventsResponseHandler.Response : Helpers.HttpErrorResponse(result.Exception);

return result.Succeeded ?
eventsResponseHandler.Response :
Helpers.HttpErrorResponse(result.Exception);
}
catch (Exception ex)
{
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,8 @@
<data name="Ex_Invalid_JsonPath" xml:space="preserve">
<value>Cannot find json path set value</value>
</data>
<data name="Ex_Invalid_Payload" xml:space="preserve">
<value>Invalid Payload detected.</value>
<data name="Ex_Invalid_JsonPayload" xml:space="preserve">
<value>Invalid Json Payload</value>
</data>
<data name="Ex_Invalid_Response" xml:space="preserve">
<value>Response validation failed, see inner exceptions.</value>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Microsoft.AspNetCore.Http;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.Framework;
using Microsoft.Azure.WebJobs.Host.Bindings;
using System;
using System.Buffers;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.Framework;
using Microsoft.Azure.WebJobs.Host.Bindings;

namespace Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents
{
Expand All @@ -24,9 +23,26 @@ public class AuthenticationEventResponseHandler : IValueBinder
/// <summary>The response property.</summary>
internal const string EventResponseProperty = "$event$response";

private AuthenticationEventResponse _response;

/// <summary>Gets or sets the action result.</summary>
/// <value>The action result.</value>
public AuthenticationEventResponse Response { get; internal set; }
public AuthenticationEventResponse Response
{
get => _response;
private set
{
if (value != null)
HarmanDhunna marked this conversation as resolved.
Show resolved Hide resolved
{
_response = value;

// Set metrics on the headers for the response
EventTriggerMetrics.Instance.SetMetricHeaders(_response);
}
}
}

internal AuthenticationEventResponseHandler() { }

/// <summary>Gets the type.</summary>
/// <value>The type.</value>
Expand Down Expand Up @@ -69,7 +85,7 @@ public Task SetValueAsync(object result, CancellationToken cancellationToken)
AuthenticationEventResponse response = Request.GetResponseObject();
if (response == null)
{
throw new InvalidOperationException(AuthenticationEventResource.Ex_Missing_Request_Response);
throw new RequestValidationException(AuthenticationEventResource.Ex_Missing_Request_Response);
}

Response = GetActionResult(result, response);
Expand Down Expand Up @@ -209,9 +225,19 @@ internal static AuthenticationEventJsonElement GetJsonObjectFromStream(Stream st

internal static AuthenticationEventJsonElement GetJsonObjectFromString(string result)
{
return !Helpers.IsJson(result)
? throw new InvalidCastException(AuthenticationEventResource.Ex_Invalid_Return)
: new AuthenticationEventJsonElement(result);
try
{
if (!Helpers.IsJson(result))
{
throw new ResponseValidationException(AuthenticationEventResource.Ex_Invalid_Return);
}
}
catch (JsonException ex)
{
throw new ResponseValidationException($"{AuthenticationEventResource.Ex_Invalid_Return}: {ex.Message}", ex.InnerException);
}

return new AuthenticationEventJsonElement(result);
}

internal static AuthenticationEventResponse GetAuthEventFromJObject(AuthenticationEventJsonElement result, AuthenticationEventResponse response)
Expand Down
Loading