Files
server/src/Core/IdentityServer/ProfileService.cs

121 lines
4.7 KiB
C#
Raw Normal View History

using IdentityServer4.Services;
using System.Threading.Tasks;
using IdentityServer4.Models;
using Bit.Core.Repositories;
using Bit.Core.Services;
using System.Security.Claims;
using System.Collections.Generic;
using System.Linq;
using System;
using IdentityModel;
2017-05-05 16:11:50 -04:00
namespace Bit.Core.IdentityServer
{
public class ProfileService : IProfileService
{
private readonly IUserService _userService;
private readonly IUserRepository _userRepository;
2017-04-05 15:31:33 -04:00
private readonly IOrganizationUserRepository _organizationUserRepository;
private readonly ILicensingService _licensingService;
2018-04-03 14:31:33 -04:00
private readonly CurrentContext _currentContext;
public ProfileService(
IUserRepository userRepository,
IUserService userService,
2017-04-05 15:31:33 -04:00
IOrganizationUserRepository organizationUserRepository,
2018-04-03 14:31:33 -04:00
ILicensingService licensingService,
CurrentContext currentContext)
{
_userRepository = userRepository;
_userService = userService;
2017-04-05 15:31:33 -04:00
_organizationUserRepository = organizationUserRepository;
_licensingService = licensingService;
2018-04-03 14:31:33 -04:00
_currentContext = currentContext;
}
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var existingClaims = context.Subject.Claims;
var newClaims = new List<Claim>();
2017-01-25 00:38:09 -05:00
var user = await _userService.GetUserByPrincipalAsync(context.Subject);
if(user != null)
{
2017-08-17 00:12:11 -04:00
var isPremium = await _licensingService.ValidateUserPremiumAsync(user);
newClaims.AddRange(new List<Claim>
2017-01-24 22:23:11 -05:00
{
new Claim("premium", isPremium ? "true" : "false", ClaimValueTypes.Boolean),
new Claim(JwtClaimTypes.Email, user.Email),
2017-07-01 23:20:30 -04:00
new Claim(JwtClaimTypes.EmailVerified, user.EmailVerified ? "true" : "false", ClaimValueTypes.Boolean),
new Claim("sstamp", user.SecurityStamp)
});
if(!string.IsNullOrWhiteSpace(user.Name))
{
newClaims.Add(new Claim(JwtClaimTypes.Name, user.Name));
}
2017-04-05 15:31:33 -04:00
// Orgs that this user belongs to
2018-04-03 14:31:33 -04:00
var orgs = await _currentContext.OrganizationMembershipAsync(_organizationUserRepository, user.Id);
2017-04-05 15:31:33 -04:00
if(orgs.Any())
{
foreach(var group in orgs.GroupBy(o => o.Type))
2017-04-05 15:31:33 -04:00
{
switch(group.Key)
{
case Enums.OrganizationUserType.Owner:
2017-04-05 15:31:33 -04:00
foreach(var org in group)
{
newClaims.Add(new Claim("orgowner", org.Id.ToString()));
2017-04-05 15:31:33 -04:00
}
break;
case Enums.OrganizationUserType.Admin:
2017-04-05 15:31:33 -04:00
foreach(var org in group)
{
newClaims.Add(new Claim("orgadmin", org.Id.ToString()));
2017-04-05 15:31:33 -04:00
}
break;
case Enums.OrganizationUserType.User:
2017-04-05 15:31:33 -04:00
foreach(var org in group)
{
newClaims.Add(new Claim("orguser", org.Id.ToString()));
2017-04-05 15:31:33 -04:00
}
break;
default:
break;
}
}
}
}
// filter out any of the new claims
var existingClaimsToKeep = existingClaims
2017-04-05 15:31:33 -04:00
.Where(c => !c.Type.StartsWith("org") && (newClaims.Count == 0 || !newClaims.Any(nc => nc.Type == c.Type)))
.ToList();
newClaims.AddRange(existingClaimsToKeep);
if(newClaims.Any())
{
context.AddRequestedClaims(newClaims);
}
}
public async Task IsActiveAsync(IsActiveContext context)
{
var securityTokenClaim = context.Subject?.Claims.FirstOrDefault(c => c.Type == "sstamp");
2017-01-25 00:38:09 -05:00
var user = await _userService.GetUserByPrincipalAsync(context.Subject);
if(user != null && securityTokenClaim != null)
{
context.IsActive = string.Equals(user.SecurityStamp, securityTokenClaim.Value,
StringComparison.InvariantCultureIgnoreCase);
return;
}
else
{
context.IsActive = true;
}
}
}
}