Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 3 additions & 3 deletions Libraries/Microsoft.Teams.Apps/App.cs
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ private async Task<Response> Process(ISenderPlugin sender, ActivityEvent @event,

var reference = new ConversationReference()
{
ServiceUrl = @event.Activity.ServiceUrl ?? @event.Token.ServiceUrl,
ServiceUrl = @event.Activity.ServiceUrl ?? @event.Token?.ServiceUrl,
Comment thread
rajan-chari marked this conversation as resolved.
Outdated
ChannelId = @event.Activity.ChannelId,
Bot = @event.Activity.Recipient,
User = @event.Activity.From,
Expand All @@ -380,8 +380,8 @@ private async Task<Response> Process(ISenderPlugin sender, ActivityEvent @event,
var stream = sender.CreateStream(reference, cancellationToken);
var context = new Context<IActivity>(sender, stream)
{
AppId = @event.Token.AppId ?? Id ?? string.Empty,
TenantId = @event.Token.TenantId ?? string.Empty,
AppId = @event.Token?.AppId ?? Id ?? string.Empty,
TenantId = @event.Token?.TenantId ?? string.Empty,
Log = Logger.Child(path),
Storage = Storage,
Api = api,
Expand Down
2 changes: 1 addition & 1 deletion Libraries/Microsoft.Teams.Apps/Events/ActivityEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Microsoft.Teams.Apps.Events;

public class ActivityEvent : Event
{
public required IToken Token { get; set; }
public IToken? Token { get; set; }
public required IActivity Activity { get; set; }
public IServiceProvider? Services { get; set; }
public IDictionary<string, object?>? Extra { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,13 @@ await Events(
}
}

public JsonWebToken ExtractToken(HttpRequest httpRequest)
public JsonWebToken? ExtractToken(HttpRequest httpRequest)
{
var authHeader = httpRequest.Headers.Authorization.FirstOrDefault() ?? throw new UnauthorizedAccessException();
var authHeader = httpRequest.Headers.Authorization.FirstOrDefault();
if (string.IsNullOrEmpty(authHeader))
{
return null;
}
return new JsonWebToken(authHeader.Replace("Bearer ", ""));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@ private static DefaultHttpContext CreateHttpContext(IActivity activity, string b
return ctx;
}

private static DefaultHttpContext CreateHttpContextWithoutAuth(IActivity activity)
{
var ctx = new DefaultHttpContext();
ctx.TraceIdentifier = Guid.NewGuid().ToString();
// No Authorization header
var json = JsonSerializer.Serialize(activity, new JsonSerializerOptions { DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull });
var bytes = Encoding.UTF8.GetBytes(json);
ctx.Request.Body = new MemoryStream(bytes);
ctx.Request.ContentLength = bytes.Length;
return ctx;
}

private static MessageActivity CreateMessageActivity()
{
return new MessageActivity("hi")
Expand Down Expand Up @@ -196,4 +208,46 @@ public async Task Test_Do_Core_ReturnsResponseAndLogs()
Assert.Same(response, res);
logger.Verify(l => l.Debug(It.IsAny<object[]>()), Times.AtLeastOnce);
}

[Fact]
public void Test_ExtractToken_ReturnsNull_WhenNoAuthHeader()
{
// Arrange
var plugin = CreatePlugin();
var ctx = CreateHttpContextWithoutAuth(CreateMessageActivity());

// Act
var token = plugin.ExtractToken(ctx.Request);

// Assert
Assert.Null(token);
}

[Fact]
public async Task Test_Do_Http_WorksWithoutAuthHeader()
{
// Arrange - simulates skipAuth scenario where no Authorization header is present
var activity = CreateMessageActivity();
var coreResponse = new Response(HttpStatusCode.OK, new { ok = true });
EventFunction events = (plugin, name, payload, ct) =>
{
if (name == "activity")
{
var activityEvent = (ActivityEvent)payload;
Assert.Null(activityEvent.Token); // Token should be null when no auth header
return Task.FromResult<object?>(coreResponse);
}
return Task.FromResult<object?>(null);
};

var plugin = CreatePlugin(new Mock<ILogger>(), events);
var ctx = CreateHttpContextWithoutAuth(activity);

// Act
var result = await plugin.Do(ctx);

// Assert
var jsonResult = Assert.IsType<Microsoft.AspNetCore.Http.HttpResults.JsonHttpResult<object?>>(result);
Assert.Equal(200, jsonResult.StatusCode);
}
Comment thread
rajan-chari marked this conversation as resolved.
Comment thread
rajan-chari marked this conversation as resolved.
}
Loading