Select Git revision
MergeController.cs
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
MergeController.cs 6.57 KiB
using Coscine.Api.STS.Data;
using Coscine.Api.STS.Utils;
using Coscine.Database.Models;
using Coscine.JwtHandler;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
namespace Coscine.Api.STS.Controllers
{
public class MergeController : Controller
{
public const string MERGETOKENKEY = "coscine.mergetoken";
private readonly SignInManager<CoscineUser> _signInManager;
public MergeController(SignInManager<CoscineUser> signInManager)
{
_signInManager = signInManager;
}
[Route("[controller]/login")]
public ActionResult Login(string returnUrl = null)
{
var contents = GetContents();
if (contents != null && contents.Any((claim) => claim.Type == "LoginMethod"))
{
var loginMethodClaim = contents.Where((claim) => claim.Type == "LoginMethod").First();
switch (loginMethodClaim.Value)
{
case "orcid":
string orcidUrl = ORCiDHandler.GetORCiDOAuthUrl() + UrlGenerator.ORCiDRedirectUrl();
return Redirect(orcidUrl);
case "shibboleth":
string shibbolethUrl = UrlGenerator.ShibbolethRedirectUrl();
return Redirect(shibbolethUrl);
default:
break;
}
}
// If something is wrong with the token or method, just redirect back to login page and invalidate the token
DeleteCookie();
string loginUrl = UrlGenerator.GetLoginUrl(Request);
return Redirect(loginUrl);
}
[Route("[controller]/callback")]
public async Task<ActionResult> Callback(string returnUrl = null)
{
var contents = GetContents();
DeleteCookie();
var validMerge = false;
var userModel = new UserModel();
var userIdString = User.Identity.Name;
var userId = new Guid(userIdString);
var mergeFromUser = userModel.GetById(userId);
var externalAuthenticatorModel = new ExternalAuthenticatorModel();
var externalIdModel = new ExternalIdModel();
// Check if logged in user has a possible login from the defined LoginMethod
if (contents != null && contents.Any((claim) => claim.Type == "LoginMethod"))
{
var loginMethodClaim = contents.Where((claim) => claim.Type == "LoginMethod").First();
switch (loginMethodClaim.Value)
{
case "orcid":
var orcidAuthItem = externalAuthenticatorModel.GetWhere((externalAuthenticator) => externalAuthenticator.DisplayName == "ORCiD");
var orcidMapping = externalIdModel.GetAllWhere((map) => map.UserId == userId && map.ExternalAuthenticatorId == orcidAuthItem.Id);
validMerge = orcidMapping.Count() > 0;
break;
case "shibboleth":
var shibbolethAuthItem = externalAuthenticatorModel.GetWhere((externalAuthenticator) => externalAuthenticator.DisplayName == "Shibboleth");
var shibbolethMapping = externalIdModel.GetAllWhere((map) => map.UserId == userId && map.ExternalAuthenticatorId == shibbolethAuthItem.Id);
validMerge = shibbolethMapping.Count() > 0;
break;
default:
break;
}
}
if (validMerge && contents?.Any((claim) => claim.Type == "UserGuid") == true)
{
var userGuidString = contents.First((claim) => claim.Type == "UserGuid");
var correctGuid = Guid.TryParse(userGuidString.Value, out Guid userGuid);
if (correctGuid)
{
var userList = userModel.GetAllWhere((user) => user.Id == userGuid);
if (userList.Any())
{
var mergeIntoUser = userList.First();
if (mergeFromUser.Id != mergeIntoUser.Id)
{
var mergeUtil = new MergeUtil();
mergeUtil.MergeFromUserIntoUser(mergeFromUser, mergeIntoUser);
// Logout the old account and login the user into his merged account after merging has finished
await _signInManager.SignOutAsync();
var coscineUser = new CoscineUser()
{
UserName = mergeIntoUser.Id.ToString(),
Email = mergeIntoUser.EmailAddress ?? ""
};
var result = await _signInManager.UserManager.CreateAsync(coscineUser);
await _signInManager.SignInAsync(coscineUser, isPersistent: false);
return Redirect(UrlGenerator.ExtendReturnUrl(returnUrl, Request));
}
}
}
}
else if (contents?.Any((claim) => claim.Type == "UserGuid") == true)
{
var userGuidString = contents.First((claim) => claim.Type == "UserGuid");
var coscineUser = new CoscineUser()
{
UserName = userGuidString.Value,
Email = ""
};
await _signInManager.SignInAsync(coscineUser, isPersistent: false);
return Redirect(UrlGenerator.ExtendReturnUrl(returnUrl, Request));
}
string loginUrl = UrlGenerator.GetLoginUrl(Request);
return Redirect(loginUrl);
}
private IEnumerable<Claim> GetContents()
{
if (Request.Cookies.ContainsKey(MERGETOKENKEY))
{
var mergeToken = Request.Cookies[MERGETOKENKEY];
var handler = new JWTHandler(Program.Configuration);
if (handler.TryValidateToken(mergeToken))
{
return handler.GetContents(mergeToken);
}
}
return null;
}
private void DeleteCookie()
{
if (Request.Cookies.ContainsKey(MERGETOKENKEY))
{
Response.Cookies.Delete(MERGETOKENKEY);
}
}
}
}