Skip to content

Commit

Permalink
Sync with latest changes. (#98)
Browse files Browse the repository at this point in the history
  • Loading branch information
ksikorsk authored Jul 12, 2019
1 parent 9db883a commit a26fed4
Show file tree
Hide file tree
Showing 550 changed files with 2,313 additions and 173,004 deletions.
7 changes: 4 additions & 3 deletions Samples/BetaSamples/RemoteMediaSamples/IncidentBot.sln
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2036
# Visual Studio Version 16
VisualStudioVersion = 16.0.29102.190
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DCC9792D-0B15-4167-8A9F-BB5DDDA6E7D6}"
ProjectSection(SolutionItems) = preProject
..\..\configure_cloud.ps1 = ..\..\configure_cloud.ps1
Getting Started with the Remote Media Samples.md = Getting Started with the Remote Media Samples.md
..\Graph.props = ..\Graph.props
..\nuget.config = ..\nuget.config
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IncidentBot", "IncidentBot\IncidentBot.csproj", "{FA70E97D-7018-4B08-A9D0-ABA9967AD7DC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.Common", "..\..\Common\Sample.Common\Sample.Common.csproj", "{3268E59C-90DC-4D7B-97EA-A1DBB2716DF3}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Common", "..\..\Common\Sample.Common\Sample.Common.csproj", "{3268E59C-90DC-4D7B-97EA-A1DBB2716DF3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
10 changes: 9 additions & 1 deletion Samples/BetaSamples/RemoteMediaSamples/IncidentBot/Bot/Bot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,10 @@ public class Bot
/// <param name="graphLogger">The graph logger.</param>
public Bot(BotOptions options, IGraphLogger graphLogger)
{
var instanceNotificationUri = CallAffinityMiddleware.GetWebInstanceCallbackUri(new Uri(options.BotBaseUrl, HttpRouteConstants.OnIncomingRequestRoute));
this.BotInstanceUri = CallAffinityMiddleware.GetWebInstanceCallbackUri(options.BotBaseUrl);

var instanceNotificationUri = CallAffinityMiddleware.GetWebInstanceCallbackUri(
new Uri(options.BotBaseUrl, HttpRouteConstants.OnIncomingRequestRoute));

this.graphLogger = graphLogger;
var name = this.GetType().Assembly.GetName().Name;
Expand Down Expand Up @@ -146,6 +149,11 @@ public Bot(BotOptions options, IGraphLogger graphLogger)
/// </summary>
public Dictionary<string, MediaPrompt> MediaMap { get; } = new Dictionary<string, MediaPrompt>();

/// <summary>
/// Gets the bots instance URI.
/// </summary>
public Uri BotInstanceUri { get; }

/// <summary>
/// Gets the client.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ namespace IcMBot.Controllers
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Graph.Communications.Common;
using Microsoft.Graph.Communications.Core.Serialization;
using Sample.Common.Logging;
using Sample.IncidentBot;
using Sample.IncidentBot.Bot;
using Sample.IncidentBot.Data;
using Sample.IncidentBot.IncidentStatus;
Expand Down Expand Up @@ -47,9 +49,24 @@ public async Task<IActionResult> PostIncidentAsync([FromBody] IncidentRequestDat

try
{
var botMeetingCall = await this.bot.RaiseIncidentAsync(incidentRequestData).ConfigureAwait(false);
var call = await this.bot.RaiseIncidentAsync(incidentRequestData).ConfigureAwait(false);

return this.Ok(botMeetingCall.Id);
var callUriTemplate = new UriBuilder(this.bot.BotInstanceUri);
callUriTemplate.Path = HttpRouteConstants.CallRoutePrefix.Replace("{callLegId}", call.Id);
callUriTemplate.Query = this.bot.BotInstanceUri.Query.Trim('?');

var callUri = callUriTemplate.Uri.AbsoluteUri;
var values = new Dictionary<string, string>
{
{ "legId", call.Id },
{ "scenarioId", call.ScenarioId.ToString() },
{ "call", callUri },
{ "logs", callUri.Replace("/calls/", "/logs/") },
};

var serializer = new CommsSerializer(pretty: true);
var json = serializer.SerializeObject(values);
return this.Ok(json);
}
catch (Exception e)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace Sample.IncidentBot.Http
using Microsoft.AspNetCore.Mvc;
using Microsoft.Graph.Communications.Common;
using Microsoft.Graph.Communications.Common.Telemetry;
using Microsoft.Graph.Communications.Core.Serialization;
using Sample.IncidentBot.Bot;
using Sample.IncidentBot.Data;

Expand Down Expand Up @@ -52,7 +53,23 @@ public async Task<IActionResult> JoinCallAsync([FromBody] JoinCallRequestData jo
try
{
var call = await this.bot.JoinCallAsync(joinCallBody).ConfigureAwait(false);
return this.Ok(call.Id);

var callUriTemplate = new UriBuilder(this.bot.BotInstanceUri);
callUriTemplate.Path = HttpRouteConstants.CallRoutePrefix.Replace("{callLegId}", call.Id);
callUriTemplate.Query = this.bot.BotInstanceUri.Query.Trim('?');

var callUri = callUriTemplate.Uri.AbsoluteUri;
var values = new Dictionary<string, string>
{
{ "legId", call.Id },
{ "scenarioId", call.ScenarioId.ToString() },
{ "call", callUri },
{ "logs", callUri.Replace("/calls/", "/logs/") },
};

var serializer = new CommsSerializer(pretty: true);
var json = serializer.SerializeObject(values);
return this.Ok(json);
}
catch (Exception e)
{
Expand Down Expand Up @@ -81,10 +98,17 @@ public ActionResult<List<Dictionary<string, string>>> OnGetCalls()
foreach (var callHandler in this.bot.CallHandlers.Values)
{
var call = callHandler.Call;
var callUriTemplate = new UriBuilder(this.bot.BotInstanceUri);
callUriTemplate.Path = HttpRouteConstants.CallRoutePrefix.Replace("{callLegId}", call.Id);
callUriTemplate.Query = this.bot.BotInstanceUri.Query.Trim('?');

var callUri = callUriTemplate.Uri.AbsoluteUri;
var values = new Dictionary<string, string>
{
{ "legId", call.Id },
{ "scenarioId", call.ScenarioId.ToString() },
{ "call", callUri },
{ "logs", callUri.Replace("/calls/", "/logs/") },
};
calls.Add(values);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<RootNamespace>Sample.IncidentBot</RootNamespace>
<AssemblyName>Sample.IncidentBot</AssemblyName>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<PlatformTarget>x64</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>

<Import Project="$(MSBuildThisFileDirectory)..\..\..\Graph.props" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
"Domain": "contoso.com",
"TenantId": "00000000-0000-0000-0000-000000000000",

"AppId": "00000000-0000-0000-0000-000000000000",
"AppSecret": "__placeholder__"
"AppId": "%AppId%",
"AppSecret": "%AppSecret%"
},
"Bot": {
"AppId": "00000000-0000-0000-0000-000000000000",
"AppSecret": "__placeholder__",
"AppId": "%AppId%",
"AppSecret": "%AppSecret%",
"PlaceCallEndpointUrl": "https://graph.microsoft.com/beta",
"BotBaseUrl": "https://incidentbot.contoso.com"
"BotBaseUrl": "%ServiceDns%"
}
}
121 changes: 29 additions & 92 deletions Samples/Common/Sample.Common/Authentication/AuthenticationProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,16 @@
namespace Sample.Common.Authentication
{
using System;
using System.Diagnostics;
using System.IdentityModel.Tokens.Jwt;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Graph.Communications.Client.Authentication;
using Microsoft.Graph.Communications.Common;
using Microsoft.Graph.Communications.Common.Telemetry;
using Microsoft.Identity.Client;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
Expand All @@ -28,10 +26,6 @@ namespace Sample.Common.Authentication
/// <seealso cref="IRequestAuthenticationProvider" />
public class AuthenticationProvider : ObjectRoot, IRequestAuthenticationProvider
{
private const string Resource = "https://graph.microsoft.com";
private const string DefaultScope = Resource + "/.default";
private static readonly string[] Scopes = new[] { DefaultScope };

/// <summary>
/// The application name.
/// </summary>
Expand All @@ -47,11 +41,6 @@ public class AuthenticationProvider : ObjectRoot, IRequestAuthenticationProvider
/// </summary>
private readonly string appSecret;

/// <summary>
/// The application certificate.
/// </summary>
private readonly X509Certificate2 appCert;

/// <summary>
/// The open ID configuration refresh interval.
/// </summary>
Expand Down Expand Up @@ -82,21 +71,6 @@ public AuthenticationProvider(string appName, string appId, string appSecret, IG
this.appSecret = appSecret.NotNullOrWhitespace(nameof(appSecret));
}

/// <summary>
/// Initializes a new instance of the <see cref="AuthenticationProvider" /> class.
/// </summary>
/// <param name="appName">The application name.</param>
/// <param name="appId">The application identifier.</param>
/// <param name="appCert">The application certificate.</param>
/// <param name="logger">The logger.</param>
public AuthenticationProvider(string appName, string appId, X509Certificate2 appCert, IGraphLogger logger)
: base(logger.NotNull(nameof(logger)).CreateShim(nameof(AuthenticationProvider)))
{
this.appName = appName.NotNullOrWhitespace(nameof(appName));
this.appId = appId.NotNullOrWhitespace(nameof(appId));
this.appCert = appCert.NotNull(nameof(appCert));
}

/// <summary>
/// Authenticates the specified request message.
/// This method will be called any time there is an outbound request.
Expand All @@ -111,31 +85,34 @@ public AuthenticationProvider(string appName, string appId, X509Certificate2 app
/// </returns>
public async Task AuthenticateOutboundRequestAsync(HttpRequestMessage request, string tenant)
{
const string Schema = "Bearer";
const string schema = "Bearer";
const string replaceString = "{tenant}";
const string oauthV2TokenLink = "https://login.microsoftonline.com/{tenant}";
const string resource = "https://graph.microsoft.com";

// If no tenant was specified, we craft the token link using the common tenant.
// https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols#endpoints
tenant = string.IsNullOrWhiteSpace(tenant) ? "common" : tenant;
var options = new ConfidentialClientApplicationOptions
{
ClientName = this.appName,
ClientId = this.appId,
ClientVersion = this.GetType().Assembly.GetName().Version.ToString(),
TenantId = tenant,
LogLevel = LogLevel.Info,
EnablePiiLogging = false,
IsDefaultPlatformLoggingEnabled = false,
AzureCloudInstance = AzureCloudInstance.AzurePublic,
};
var tokenLink = oauthV2TokenLink.Replace(replaceString, tenant);

this.GraphLogger.Info("AuthenticationProvider: Generating OAuth token.");
var context = new AuthenticationContext(tokenLink);
var creds = new ClientCredential(this.appId, this.appSecret);

ConfidentialClientApplicationBuilder builder = ConfidentialClientApplicationBuilder
.CreateWithApplicationOptions(options)
.WithLogging(this.LogCallback);
IConfidentialClientApplication app = string.IsNullOrEmpty(this.appSecret)
? builder.WithCertificate(this.appCert).Build()
: builder.WithClientSecret(this.appSecret).Build();
AuthenticationResult result;
try
{
result = await this.AcquireTokenWithRetryAsync(context, resource, creds, attempts: 3).ConfigureAwait(false);
}
catch (Exception ex)
{
this.GraphLogger.Error(ex, $"Failed to generate token for client: {this.appId}");
throw;
}

AuthenticationResult result = await this.AcquireTokenWithRetryAsync(app, 3).ConfigureAwait(false);
this.GraphLogger.Info($"AuthenticationProvider: Generated OAuth token. Expires in {result.ExpiresOn.Subtract(DateTimeOffset.UtcNow).TotalMinutes} minutes.");

request.Headers.Authorization = new AuthenticationHeaderValue(Schema, result.AccessToken);
request.Headers.Authorization = new AuthenticationHeaderValue(schema, result.AccessToken);
}

/// <summary>
Expand Down Expand Up @@ -223,65 +200,25 @@ public async Task<RequestValidationResult> ValidateInboundRequestAsync(HttpReque
return new RequestValidationResult { IsValid = true, TenantId = tenantClaim.Value };
}

/// <summary>
/// Callback delegate that allows application developers to consume logs, and handle them in a custom manner. This
/// callback is set using Microsoft.Identity.Client.AbstractApplicationBuilder`1.WithLogging(Microsoft.Identity.Client.LogCallback,System.Nullable{Microsoft.Identity.Client.LogLevel},System.Nullable{System.Boolean},System.Nullable{System.Boolean}).
/// If PiiLoggingEnabled is set to true, when registering the callback this method will receive the messages twice:
/// once with the containsPii parameter equals false and the message without PII,
/// and a second time with the containsPii parameter equals to true and the message might contain PII.
/// In some cases (when the message does not contain PII), the message will be the same.
/// For details see https://aka.ms/msal-net-logging.
/// </summary>
/// <param name="logLevel">Log level of the log message to process.</param>
/// <param name="message">Pre-formatted log message.</param>
/// <param name="containsPii">
/// Indicates if the log message contains Organizational Identifiable Information (OII)
/// or Personally Identifiable Information (PII) nor not.
/// If Microsoft.Identity.Client.Logger.PiiLoggingEnabled is set to false then this value is always false.
/// Otherwise it will be true when the message contains PII.
/// </param>
private void LogCallback(LogLevel logLevel, string message, bool containsPii)
{
TraceLevel level;
switch (logLevel)
{
case LogLevel.Error:
level = TraceLevel.Error;
break;
case LogLevel.Warning:
level = TraceLevel.Warning;
break;
case LogLevel.Info:
level = TraceLevel.Info;
break;
default:
level = TraceLevel.Verbose;
break;
}

this.GraphLogger.Log(level, message, nameof(IConfidentialClientApplication));
}

/// <summary>
/// Acquires the token and retries if failure occurs.
/// </summary>
/// <param name="app">The confidential application.</param>
/// <param name="context">The application context.</param>
/// <param name="resource">The resource.</param>
/// <param name="creds">The application credentials.</param>
/// <param name="attempts">The attempts.</param>
/// <returns>
/// The <see cref="AuthenticationResult" />.
/// </returns>
private async Task<AuthenticationResult> AcquireTokenWithRetryAsync(IConfidentialClientApplication app, int attempts)
private async Task<AuthenticationResult> AcquireTokenWithRetryAsync(AuthenticationContext context, string resource, ClientCredential creds, int attempts)
{
while (true)
{
attempts--;

try
{
return await app
.AcquireTokenForClient(Scopes)
.ExecuteAsync()
.ConfigureAwait(false);
return await context.AcquireTokenAsync(resource, creds).ConfigureAwait(false);
}
catch (Exception)
{
Expand Down
4 changes: 2 additions & 2 deletions Samples/Common/Sample.Common/Sample.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Graph.Communications.Client" Version="1.1.0-prerelease.581" />
<PackageReference Include="Microsoft.Graph.Communications.Core.Calls" Version="1.1.0-prerelease.581" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.0.0" />
<PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="5.1.0" />
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="5.5.0" />
</ItemGroup>

Expand All @@ -23,7 +23,7 @@
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="System.Net.Http" Version="4.3.3" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
</ItemGroup>

</Project>
8 changes: 4 additions & 4 deletions Samples/CommsSamples.sln
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,10 @@ Global
{3268E59C-90DC-4D7B-97EA-A1DBB2716DF3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3268E59C-90DC-4D7B-97EA-A1DBB2716DF3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3268E59C-90DC-4D7B-97EA-A1DBB2716DF3}.Release|Any CPU.Build.0 = Release|Any CPU
{64538D87-16CD-4A13-ADA9-63EBA7C80BBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{64538D87-16CD-4A13-ADA9-63EBA7C80BBE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{64538D87-16CD-4A13-ADA9-63EBA7C80BBE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{64538D87-16CD-4A13-ADA9-63EBA7C80BBE}.Release|Any CPU.Build.0 = Release|Any CPU
{64538D87-16CD-4A13-ADA9-63EBA7C80BBE}.Debug|Any CPU.ActiveCfg = Debug|x64
{64538D87-16CD-4A13-ADA9-63EBA7C80BBE}.Debug|Any CPU.Build.0 = Debug|x64
{64538D87-16CD-4A13-ADA9-63EBA7C80BBE}.Release|Any CPU.ActiveCfg = Release|x64
{64538D87-16CD-4A13-ADA9-63EBA7C80BBE}.Release|Any CPU.Build.0 = Release|x64
{24E33708-FB5C-45F8-81CA-B0C857435FFB}.Debug|Any CPU.ActiveCfg = Debug|x64
{24E33708-FB5C-45F8-81CA-B0C857435FFB}.Debug|Any CPU.Build.0 = Debug|x64
{24E33708-FB5C-45F8-81CA-B0C857435FFB}.Debug|Any CPU.Deploy.0 = Debug|x64
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ VisualStudioVersion = 16.0.28803.202
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36341412-BFDE-495F-8216-7736CE191F39}"
ProjectSection(SolutionItems) = preProject
configure_cloud.ps1 = configure_cloud.ps1
..\..\configure_cloud.ps1 = ..\..\configure_cloud.ps1
E-SDK Samples.postman_collection.json = E-SDK Samples.postman_collection.json
..\..\Graph.props = ..\..\Graph.props
..\..\nuget.config = ..\..\nuget.config
Expand Down
Loading

0 comments on commit a26fed4

Please sign in to comment.