I feel like this structure could be better, but I can't realize how.
internal AuthenticationResult ProcessOpenIdResponse(IAuthenticationResponse response)
{
switch (response.Status)
{
case AuthenticationStatus.Authenticated:
{
string openId = response.ClaimedIdentifier;
User user = userRepository.GetByOpenId(openId);
bool userIsNew = false;
bool connectionIsNew = false;
if (user == null)
{
connectionIsNew = true;
string email = null;
string displayName = null;
var fetch = response.GetExtension<FetchResponse>();
if (fetch != null)
{
email = fetch.GetAttributeValue(WellKnownAttributes.Contact.Email);
displayName = fetch.GetAttributeValue(WellKnownAttributes.Name.FullName);
}
if (!email.NullOrEmpty()) // maybe they already have an account.
{
user = userRepository.GetByEmail(email);
}
if (user == null) // create a brand new account.
{
user = userRepository.CreateFromOpenId(openId, email, displayName);
userIsNew = true;
}
else // just connect the existing account to their OpenId account.
{
userRepository.AddOpenIdConnection(user, openId);
}
}
return new AuthenticationResult
{
Status = ConnectionStatus.Authenticated,
UserIsNew = userIsNew,
ConnectionIsNew = connectionIsNew,
DisplayName = user.DisplayName,
UserId = user.UserId
};
}
case AuthenticationStatus.Canceled:
{
return new AuthenticationResult
{
Status = ConnectionStatus.Canceled,
Message = Common.Resources.Authentication.CanceledAtProvider
};
}
case AuthenticationStatus.Failed:
{
return new AuthenticationResult
{
Status = ConnectionStatus.Faulted,
Message = response.Exception.Message,
Exception = response.Exception
};
}
default:
{
return new AuthenticationResult
{
Status = ConnectionStatus.Faulted
};
}
}
}
and another:
public AuthenticationResult AuthenticateWithFacebook(string facebookId, string accessToken)
{
if (facebookId == null)
{
throw new ArgumentNullException("facebookId");
}
if (accessToken == null)
{
throw new ArgumentNullException("accessToken");
}
dynamic response;
try
{
FacebookClient client = new FacebookClient(accessToken);
response = client.Get("me");
}
catch (FacebookApiException exception)
{
_log.Info(Common.Resources.Error.FacebookApiException, exception);
return new AuthenticationResult
{
Status = ConnectionStatus.Faulted,
Message = exception.Message,
Exception = exception
};
}
if (response == null) // sanity
{
return new AuthenticationResult
{
Status = ConnectionStatus.Faulted,
Message = Common.Resources.Error.FacebookApiException
};
}
else if (response.error != null)
{
return new AuthenticationResult
{
Status = ConnectionStatus.Faulted,
Message = response.error.message ?? Common.Resources.Error.FacebookApiException
};
}
else if (response.id != facebookId) // validate access token against facebookId for enhanced security.
{
return new AuthenticationResult
{
Status = ConnectionStatus.InvalidCredentials,
Message = Common.Resources.Authentication.InvalidCredentials
};
}
else
{
User user = userRepository.GetByFacebookGraphId(facebookId);
bool userIsNew = false;
bool connectionIsNew = false;
if (user == null)
{
connectionIsNew = true;
string email = response.email;
if (!email.NullOrEmpty()) // maybe they already have an account.
{
user = userRepository.GetByEmail(email);
}
if (user == null) // create a brand new account.
{
string displayName = response.name;
user = userRepository.CreateFromFacebook(facebookId, accessToken, email, displayName);
userIsNew = true;
}
else // just connect the existing account to their Facebook account.
{
userRepository.AddFacebookConnection(user, facebookId, accessToken);
}
}
return new AuthenticationResult
{
Status = ConnectionStatus.Authenticated,
UserIsNew = userIsNew,
ConnectionIsNew = connectionIsNew,
DisplayName = user.DisplayName,
UserId = user.UserId
};
}
}
Just in case anyone wonders about dependencies from outside the method, here is the class:
public class AuthenticationService
{
private static readonly ILog _log = LogManager.GetLogger(typeof(AuthenticationService));
private readonly OpenIdRelyingParty relyingParty;
private readonly IUserRepository userRepository;
private readonly IMembershipProvider membershipProvider;
public AuthenticationService(OpenIdRelyingParty relyingParty, IUserRepository userRepository, IMembershipProvider membershipProvider)
{
if (relyingParty == null)
{
throw new ArgumentNullException("relyingParty");
}
if (userRepository == null)
{
throw new ArgumentNullException("userRepository");
}
if (membershipProvider == null)
{
throw new ArgumentNullException("membershipProvider");
}
this.relyingParty = relyingParty;
this.userRepository = userRepository;
this.membershipProvider = membershipProvider;
}
[...]
}