Skip to content

Commit 96e3600

Browse files
blackchoeysinghk97
authored andcommitted
[C#] feat: add teams sso implementation (#929)
## Linked issues closes: #861 ## Details 1. Implement token exchange and sign in logic for Teams SSO auth implementation 2. Updated the `IAuthentication` interface to initialize after `Application` instance is created - the authentication classes has dependency to `Application` when initialize 3. Change visibility of some classes to `internal` 4. Update the namespace of authentication classes to `Microsoft.Teams.AI` to align with other classes under the `Application` folder ## Attestation Checklist - [x] My code follows the style guidelines of this project - I have checked for/fixed spelling, linting, and other errors - I have commented my code for clarity - I have made corresponding changes to the documentation (we use [TypeDoc](https://typedoc.org/) to document our code) - My changes generate no new warnings - I have added tests that validates my changes, and provides sufficient test coverage. I have tested with: - Local testing - E2E testing in Teams - New and existing unit tests pass locally with my changes ### Additional information Because some classes from botbuilder cannot be mocked, the UT for the new code is some kind of blocked. I have finished manual testing against the code. Will follow up with the UT problem.
1 parent 3b3c276 commit 96e3600

24 files changed

+725
-81
lines changed

dotnet/packages/Microsoft.TeamsAI/Microsoft.TeamsAI.Tests/Application/Authentication/Bot/BotAuthenticationBaseTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using Microsoft.Bot.Builder;
22
using Microsoft.Bot.Builder.Dialogs;
33
using Microsoft.Bot.Schema;
4-
using Microsoft.Teams.AI.Application.Authentication.Bot;
54
using Microsoft.Teams.AI.Exceptions;
65
using Microsoft.Teams.AI.State;
76
using Microsoft.Teams.AI.Tests.TestUtils;

dotnet/packages/Microsoft.TeamsAI/Microsoft.TeamsAI.Tests/Application/Authentication/MessageExtensions/MessageExtensionsAuthenticationBaseTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public override Task<string> GetSignInLink(ITurnContext context)
2222
return Task.FromResult("mocked link");
2323
}
2424

25-
public override Task<TokenResponse> HandlerUserSignIn(ITurnContext context, string magicCode)
25+
public override Task<TokenResponse> HandleUserSignIn(ITurnContext context, string magicCode)
2626
{
2727
if (_signInResponse == null)
2828
{

dotnet/packages/Microsoft.TeamsAI/Microsoft.TeamsAI.Tests/Application/Authentication/MockedAuthentication.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
using Microsoft.Bot.Builder;
2+
using Microsoft.Teams.AI.Exceptions;
23
using Microsoft.Teams.AI.State;
34

45
namespace Microsoft.Teams.AI.Tests.Application.Authentication
56
{
67
public class MockedAuthentication<TState> : IAuthentication<TState>
7-
where TState : TurnState
8+
where TState : TurnState, new()
89
{
910
private string _mockedToken;
1011
private SignInStatus _mockedStatus;
@@ -17,11 +18,26 @@ public MockedAuthentication(SignInStatus mockedStatus = SignInStatus.Complete, s
1718
_validActivity = validActivity;
1819
}
1920

21+
public void Initialize(Application<TState> app, string name, IStorage? storage = null)
22+
{
23+
return;
24+
}
25+
2026
public Task<bool> IsValidActivity(ITurnContext context)
2127
{
2228
return Task.FromResult(_validActivity);
2329
}
2430

31+
public IAuthentication<TState> OnUserSignInFailure(Func<ITurnContext, TState, TeamsAIAuthException, Task> handler)
32+
{
33+
return this;
34+
}
35+
36+
public IAuthentication<TState> OnUserSignInSuccess(Func<ITurnContext, TState, Task> handler)
37+
{
38+
return this;
39+
}
40+
2541
public Task<SignInResponse> SignInUser(ITurnContext context, TState state)
2642
{
2743
var result = new SignInResponse(_mockedStatus);

dotnet/packages/Microsoft.TeamsAI/Microsoft.TeamsAI/Application/Application.cs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,25 @@ public Application(ApplicationOptions<TState> options)
6666
MessageExtensions = new MessageExtensions<TState>(this);
6767
TaskModules = new TaskModules<TState>(this);
6868

69+
// Validate long running messages configuration
70+
if (Options.LongRunningMessages && (Options.Adapter == null || Options.BotAppId == null))
71+
{
72+
throw new ArgumentException("The ApplicationOptions.LongRunningMessages property is unavailable because no adapter or botAppId was configured.");
73+
}
74+
75+
_routes = new ConcurrentQueue<Route<TState>>();
76+
_invokeRoutes = new ConcurrentQueue<Route<TState>>();
77+
_beforeTurn = new ConcurrentQueue<TurnEventHandlerAsync<TState>>();
78+
_afterTurn = new ConcurrentQueue<TurnEventHandlerAsync<TState>>();
79+
6980
if (options.Authentication != null)
7081
{
82+
// Initialize the authentication classes
83+
foreach (KeyValuePair<string, IAuthentication<TState>> pair in options.Authentication.Authentications)
84+
{
85+
pair.Value.Initialize(this, pair.Key, options.Storage);
86+
}
87+
7188
Authentication = new AuthenticationManager<TState>(options.Authentication);
7289
if (options.Authentication.AutoSignIn != null)
7390
{
@@ -78,17 +95,6 @@ public Application(ApplicationOptions<TState> options)
7895
_startSignIn = (context, cancellationToken) => Task.FromResult(true);
7996
}
8097
}
81-
82-
// Validate long running messages configuration
83-
if (Options.LongRunningMessages && (Options.Adapter == null || Options.BotAppId == null))
84-
{
85-
throw new ArgumentException("The ApplicationOptions.LongRunningMessages property is unavailable because no adapter or botAppId was configured.");
86-
}
87-
88-
_routes = new ConcurrentQueue<Route<TState>>();
89-
_invokeRoutes = new ConcurrentQueue<Route<TState>>();
90-
_beforeTurn = new ConcurrentQueue<TurnEventHandlerAsync<TState>>();
91-
_afterTurn = new ConcurrentQueue<TurnEventHandlerAsync<TState>>();
9298
}
9399

94100
/// <summary>

dotnet/packages/Microsoft.TeamsAI/Microsoft.TeamsAI/Application/ApplicationOptions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Microsoft.Teams.AI
1010
/// </summary>
1111
/// <typeparam name="TState">Type of the turn state.</typeparam>
1212
public class ApplicationOptions<TState>
13-
where TState : TurnState
13+
where TState : TurnState, new()
1414
{
1515
/// <summary>
1616
/// Optional. Bot adapter being used.

dotnet/packages/Microsoft.TeamsAI/Microsoft.TeamsAI/Application/Authentication/AdaptiveCards/AdaptiveCardsAuthenticationBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using Microsoft.Bot.Builder;
22
using Microsoft.Bot.Schema;
33

4-
namespace Microsoft.Teams.AI.Application.Authentication.AdaptiveCards
4+
namespace Microsoft.Teams.AI
55
{
66
/// <summary>
77
/// Base class for adaptive card authentication that handles common logic

dotnet/packages/Microsoft.TeamsAI/Microsoft.TeamsAI/Application/Authentication/AdaptiveCards/OAuthAdaptiveCardsAuthentication.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace Microsoft.Teams.AI.Application.Authentication.AdaptiveCards
1+
namespace Microsoft.Teams.AI
22
{
33
/// <summary>
44
/// Handles authentication for Adaptive Cards in Teams using OAuth Connection.

dotnet/packages/Microsoft.TeamsAI/Microsoft.TeamsAI/Application/Authentication/AdaptiveCards/TeamsSsoAdaptiveCardsAuthentication.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace Microsoft.Teams.AI.Application.Authentication.AdaptiveCards
1+
namespace Microsoft.Teams.AI
22
{
33
/// <summary>
44
/// Handles authentication for Adaptive Cards in Teams based on Teams SSO.

dotnet/packages/Microsoft.TeamsAI/Microsoft.TeamsAI/Application/Authentication/AuthUtilities.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace Microsoft.Teams.AI
55
/// <summary>
66
/// Authentication utilities
77
/// </summary>
8-
public class AuthUtilities
8+
internal class AuthUtilities
99
{
1010
/// <summary>
1111
/// Set token in state

dotnet/packages/Microsoft.TeamsAI/Microsoft.TeamsAI/Application/Authentication/AuthenticationManager.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,13 @@ public async Task<bool> IsValidActivity(ITurnContext context, string? handlerNam
9090
return await auth.IsValidActivity(context);
9191
}
9292

93-
private IAuthentication<TState> Get(string name)
93+
/// <summary>
94+
/// Get an authentication class via name
95+
/// </summary>
96+
/// <param name="name">The name of authentication class</param>
97+
/// <returns>The authentication class</returns>
98+
/// <exception cref="TeamsAIException">When cannot find the class with given name</exception>
99+
public IAuthentication<TState> Get(string name)
94100
{
95101
if (_authentications.ContainsKey(name))
96102
{

0 commit comments

Comments
 (0)