JabbRAuthenticationCallbackProvider used by JabbR, mirrored here for blog post to prevent dead-links in the future.

  • Download Gist
JabbRAuthenticationCallbackProvider.cs
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
using System;
using JabbR.Infrastructure;
using JabbR.Models;
using JabbR.Services;
using Nancy;
using Nancy.Authentication.WorldDomination;
using WorldDomination.Web.Authentication;
 
namespace JabbR.Nancy
{
public class JabbRAuthenticationCallbackProvider : IAuthenticationCallbackProvider
{
private readonly IAuthenticationTokenService _authenticationTokenService;
private readonly IMembershipService _membershipService;
private readonly IJabbrRepository _repository;
 
public JabbRAuthenticationCallbackProvider(IAuthenticationTokenService authenticationTokenService,
IMembershipService membershipService,
IJabbrRepository repository)
{
_authenticationTokenService = authenticationTokenService;
_membershipService = membershipService;
_repository = repository;
}
 
public dynamic Process(NancyModule nancyModule, AuthenticateCallbackData model)
{
ChatUser loggedInUser = null;
 
if (nancyModule.Context.CurrentUser != null)
{
loggedInUser = _repository.GetUserById(nancyModule.Context.CurrentUser.UserName);
}
 
if (model.Exception == null)
{
UserInformation userInfo = model.AuthenticatedClient.UserInformation;
string providerName = model.AuthenticatedClient.ProviderName;
 
ChatUser user = _repository.GetUserByIdentity(providerName, userInfo.Id);
 
// User with that identity doesn't exist, check if a user is logged in
if (user == null)
{
if (loggedInUser != null)
{
// Link to the logged in user
LinkIdentity(userInfo, providerName, loggedInUser);
 
// If a user is already logged in, then we know they could only have gotten here via the account page,
// so we will redirect them there
nancyModule.AddAlertMessage("success", String.Format("Successfully linked {0} account.", providerName));
return nancyModule.Response.AsRedirect("~/account/#identityProviders");
}
else
{
// Check the identity field to see if we need to migrate this user to the new
// non janrain identity model
string legacyIdentity = IdentityUtility.MakeLegacyIdentity(providerName, userInfo.Id);
 
if (legacyIdentity == null)
{
// No identity found so just add a new user
user = _membershipService.AddUser(userInfo.UserName, providerName, userInfo.Id, userInfo.Email);
}
else
{
// Try to get a legacy identity
user = _repository.GetUserByLegacyIdentity(legacyIdentity);
 
if (user == null)
{
// User doesn't exist
user = _membershipService.AddUser(userInfo.UserName, providerName, userInfo.Id, userInfo.Email);
}
else
{
// We found a legacy user via this id so convert them to the new format
LinkIdentity(userInfo, providerName, user);
}
}
}
}
else if (loggedInUser != null && user != loggedInUser)
{
// You can't link an account that's already attached to another user
nancyModule.AddAlertMessage("error", String.Format("This {0} account has already been linked to another user.", providerName));
// If a user is logged in then we know they got here from the account page, and we should redirect them back there
return nancyModule.Response.AsRedirect("~/account/#identityProviders");
}
 
return nancyModule.CompleteLogin(_authenticationTokenService, user);
}
 
nancyModule.AddAlertMessage("error", model.Exception.Message);
 
// If a user is logged in, then they got here from the account page, send them back there
if (loggedInUser != null)
{
return nancyModule.Response.AsRedirect("~/account/#identityProviders");
}
 
// At this point, send the user back to the root, everything else will work itself out
return nancyModule.Response.AsRedirect("~/");
}
 
private void LinkIdentity(UserInformation userInfo, string providerName, ChatUser user)
{
// Link this new identity
user.Identities.Add(new ChatUserIdentity
{
Email = userInfo.Email,
Identity = userInfo.Id,
ProviderName = providerName
});
 
_repository.CommitChanges();
}
}
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.