Created
April 10, 2017 01:16
-
-
Save jakkaj/b133f0aa69d2e296d381fb955ec2bb67 to your computer and use it in GitHub Desktop.
Login Handler for Ignite Australia bot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Net.Http; | |
using System.Text; | |
using System.Threading.Tasks; | |
using Arlo.SDK.Contract; | |
using EventBot.SupportLibrary.Contract; | |
using EventBot.SupportLibrary.Entity; | |
using EventBot.SupportLibrary.Utils.JwtHelpers; | |
using Microsoft.Bot.Builder.Dialogs; | |
using Microsoft.Bot.Connector; | |
using Xamling.Azure.Portable.Contract; | |
using XamlingCore.Portable.Contract.Config; | |
using XamlingCore.Portable.Model.Other; | |
using XamlingCore.Portable.View.Special; | |
namespace EventBot.SupportLibrary.Services | |
{ | |
/// <summary> | |
/// Handles the login returned from the external login provider | |
/// </summary> | |
public class LoginHandlerService : ILoginHandlerService | |
{ | |
private readonly ILogService _logService; | |
private readonly IContactService _contactService; | |
private readonly IEventService _eventService; | |
private readonly IConfig _config; | |
private Activity _activity; | |
public LoginHandlerService(ILogService logService, | |
IContactService contactService, IEventService eventService, IConfig config) | |
{ | |
_logService = logService; | |
_contactService = contactService; | |
_eventService = eventService; | |
_config = config; | |
} | |
public async Task Bounce(string queryString) | |
{ | |
var httpClient = new HttpClient(); | |
var message = new HttpRequestMessage(HttpMethod.Post, queryString); | |
message.Content = new StringContent("SomeToken"); | |
await httpClient.SendAsync(message); | |
} | |
public async Task<bool> HandleLoginReturned([NotNull]string resumptionCookieString, [NotNull]string token) | |
{ | |
var resumptionCookie = UrlToken.Decode<ResumptionCookie>(resumptionCookieString); | |
_activity = (Activity)resumptionCookie.GetMessage(); | |
_logService.TrackTrace("LoginToken", XSeverityLevel.Information, | |
new Dictionary<string, string> {{"Token", token}}); | |
var claims = _validateToken(token); | |
if (claims == null) | |
{ | |
await _returnClaimsFail(); | |
return false; | |
} | |
if (!claims.ContainsKey(WebConstants.Claims.ContactId)) | |
{ | |
await _returnClaimsFail(); | |
} | |
var contactId = claims[WebConstants.Claims.ContactId]; | |
var currentEvent = await _eventService.GetCurrentEvent(); | |
var contact = await _contactService.MapContactIdToRegistration(currentEvent, contactId); | |
if (contact == null) | |
{ | |
await _returnNoContact(); | |
return false; | |
} | |
var sc = _activity.GetStateClient(); | |
var data = await sc.BotState.GetUserDataAsync(_activity.ChannelId, _activity.From.Id); | |
data.SetProperty("Authenticated", true); | |
data.SetProperty("EmailAddress", contact.Contact.Email); | |
data.SetProperty("CID", contact.RegistrationID); | |
data.SetProperty("UserId", contact.Contact.ContactID); | |
data.SetProperty("AttendeeRole", "Idunno"); | |
data.SetProperty("AttendeeID", contact.RegistrationID); | |
data.SetProperty("FirstName", contact.Contact.FirstName ?? ""); | |
data.SetProperty("LastName", contact.Contact.LastName ?? ""); | |
_logService.TrackTrace("AuthController - cid: " + contact.RegistrationID); | |
await sc.BotState.SetUserDataAsync(_activity.ChannelId, _activity.From.Id, data); | |
_logService.TrackTrace($"Successfully authenticated. Email: {contact.Contact.Email}, CID: {contact.RegistrationID}, Role: {data.GetProperty<string>("AttendeeRole")}"); | |
await _reply($"Hi {contact.Contact.FirstName}, welcome to Ignite!"); | |
return true; | |
} | |
async Task _returnNoContact() | |
{ | |
_logService.TrackEvent("AuthenticationFailed"); | |
_logService.TrackTrace($"AuthenticationController::No arlo contact found"); | |
await _reply("We had some trouble finding you in the system! That doesn't sound terribly optimal. "); | |
} | |
async Task _returnClaimsFail() | |
{ | |
_logService.TrackEvent("AuthenticationFailed"); | |
_logService.TrackTrace($"AuthenticationController::Post: Couldn't find the required claims"); | |
await _reply("A claims error ocurred during authentication, please try again later."); | |
} | |
async Task _reply(string reply) | |
{ | |
var client = new ConnectorClient(new Uri(_activity.ServiceUrl)); | |
Activity replyActivity = _activity.CreateReply(reply); | |
await client.Conversations.ReplyToActivityAsync(replyActivity); | |
} | |
Dictionary<string, string> _validateToken(string token) | |
{ | |
//var dict = new Dictionary<string, string>(); | |
//dict.Add(WebConstants.Claims.ContactId, "3813"); | |
//return dict; | |
var key = _config[WebConstants.Config.JwtPublicKey]; | |
var audience = _config[WebConstants.Config.JwtAudience]; | |
var issuer = _config[WebConstants.Config.JwtIssuer]; | |
var result = JwtValidator.ValidateWithRsaKey(token, key, issuer, audience); | |
if (!result.IsValid) | |
{ | |
_logService.TrackTrace("JWT Validation Failed", XSeverityLevel.Critical, new Dictionary<string, string> | |
{ | |
{"Token", token}, | |
{"Fail Reason", result.FailReason} | |
}); | |
return null; | |
} | |
_logService.TrackTrace("JWT Validated", XSeverityLevel.Information, new Dictionary<string, string> | |
{ | |
{"Token", token} | |
}); | |
return result.Claims; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment