mirror of
https://github.com/bitwarden/server.git
synced 2025-05-22 12:04:27 -05:00
added user orgs to claims
This commit is contained in:
parent
fee9bde12f
commit
a474449354
@ -20,7 +20,10 @@ namespace Bit.Api.IdentityServer
|
|||||||
"email",
|
"email",
|
||||||
"sstamp", // security stamp
|
"sstamp", // security stamp
|
||||||
"plan",
|
"plan",
|
||||||
"device"
|
"device",
|
||||||
|
"orgowner",
|
||||||
|
"orgadmin",
|
||||||
|
"orguser"
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ namespace Bit.Api.IdentityServer
|
|||||||
|
|
||||||
public class ApiClient : Client
|
public class ApiClient : Client
|
||||||
{
|
{
|
||||||
public ApiClient(string id)
|
public ApiClient(string id, string[] additionalScopes = null)
|
||||||
{
|
{
|
||||||
ClientId = id;
|
ClientId = id;
|
||||||
RequireClientSecret = false;
|
RequireClientSecret = false;
|
||||||
@ -26,7 +26,13 @@ namespace Bit.Api.IdentityServer
|
|||||||
UpdateAccessTokenClaimsOnRefresh = true;
|
UpdateAccessTokenClaimsOnRefresh = true;
|
||||||
AccessTokenLifetime = 60 * 60; // 1 hour
|
AccessTokenLifetime = 60 * 60; // 1 hour
|
||||||
AllowOfflineAccess = true;
|
AllowOfflineAccess = true;
|
||||||
AllowedScopes = new string[] { "api" };
|
|
||||||
|
var scopes = new List<string> { "api" };
|
||||||
|
if(additionalScopes != null)
|
||||||
|
{
|
||||||
|
scopes.AddRange(additionalScopes);
|
||||||
|
}
|
||||||
|
AllowedScopes = scopes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,15 +16,18 @@ namespace Bit.Api.IdentityServer
|
|||||||
{
|
{
|
||||||
private readonly IUserService _userService;
|
private readonly IUserService _userService;
|
||||||
private readonly IUserRepository _userRepository;
|
private readonly IUserRepository _userRepository;
|
||||||
|
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||||
private IdentityOptions _identityOptions;
|
private IdentityOptions _identityOptions;
|
||||||
|
|
||||||
public ProfileService(
|
public ProfileService(
|
||||||
IUserRepository userRepository,
|
IUserRepository userRepository,
|
||||||
IUserService userService,
|
IUserService userService,
|
||||||
|
IOrganizationUserRepository organizationUserRepository,
|
||||||
IOptions<IdentityOptions> identityOptionsAccessor)
|
IOptions<IdentityOptions> identityOptionsAccessor)
|
||||||
{
|
{
|
||||||
_userRepository = userRepository;
|
_userRepository = userRepository;
|
||||||
_userService = userService;
|
_userService = userService;
|
||||||
|
_organizationUserRepository = organizationUserRepository;
|
||||||
_identityOptions = identityOptionsAccessor?.Value ?? new IdentityOptions();
|
_identityOptions = identityOptionsAccessor?.Value ?? new IdentityOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +45,7 @@ namespace Bit.Api.IdentityServer
|
|||||||
new Claim("sstamp", user.SecurityStamp),
|
new Claim("sstamp", user.SecurityStamp),
|
||||||
new Claim("email", user.Email),
|
new Claim("email", user.Email),
|
||||||
|
|
||||||
// Deprecated claims for backwards compatability,
|
// Deprecated claims for backwards compatability
|
||||||
new Claim(_identityOptions.ClaimsIdentity.UserNameClaimType, user.Email),
|
new Claim(_identityOptions.ClaimsIdentity.UserNameClaimType, user.Email),
|
||||||
new Claim(_identityOptions.ClaimsIdentity.SecurityStampClaimType, user.SecurityStamp)
|
new Claim(_identityOptions.ClaimsIdentity.SecurityStampClaimType, user.SecurityStamp)
|
||||||
});
|
});
|
||||||
@ -51,11 +54,47 @@ namespace Bit.Api.IdentityServer
|
|||||||
{
|
{
|
||||||
newClaims.Add(new Claim("name", user.Name));
|
newClaims.Add(new Claim("name", user.Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Orgs that this user belongs to
|
||||||
|
var orgs = await _organizationUserRepository.GetManyByUserAsync(user.Id);
|
||||||
|
if(orgs.Any())
|
||||||
|
{
|
||||||
|
var groupedOrgs = orgs.Where(o => o.Status == Core.Enums.OrganizationUserStatusType.Confirmed)
|
||||||
|
.GroupBy(o => o.Type);
|
||||||
|
|
||||||
|
foreach(var group in groupedOrgs)
|
||||||
|
{
|
||||||
|
switch(group.Key)
|
||||||
|
{
|
||||||
|
case Core.Enums.OrganizationUserType.Owner:
|
||||||
|
foreach(var org in group)
|
||||||
|
{
|
||||||
|
newClaims.Add(new Claim("orgowner", org.Id.ToString()));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Core.Enums.OrganizationUserType.Admin:
|
||||||
|
foreach(var org in group)
|
||||||
|
{
|
||||||
|
newClaims.Add(new Claim("orgadmin", org.Id.ToString()));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Core.Enums.OrganizationUserType.User:
|
||||||
|
foreach(var org in group)
|
||||||
|
{
|
||||||
|
newClaims.Add(new Claim("orguser", org.Id.ToString()));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// filter out any of the new claims
|
// filter out any of the new claims
|
||||||
var existingClaimsToKeep = existingClaims
|
var existingClaimsToKeep = existingClaims
|
||||||
.Where(c => newClaims.Count == 0 || !newClaims.Any(nc => nc.Type == c.Type)).ToList();
|
.Where(c => !c.Type.StartsWith("org") && (newClaims.Count == 0 || !newClaims.Any(nc => nc.Type == c.Type)))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
newClaims.AddRange(existingClaimsToKeep);
|
newClaims.AddRange(existingClaimsToKeep);
|
||||||
if(newClaims.Any())
|
if(newClaims.Any())
|
||||||
|
@ -10,6 +10,7 @@ namespace Bit.Core.Repositories
|
|||||||
public interface IOrganizationUserRepository : IRepository<OrganizationUser, Guid>
|
public interface IOrganizationUserRepository : IRepository<OrganizationUser, Guid>
|
||||||
{
|
{
|
||||||
Task<OrganizationUser> GetByOrganizationAsync(Guid organizationId, Guid userId);
|
Task<OrganizationUser> GetByOrganizationAsync(Guid organizationId, Guid userId);
|
||||||
|
Task<ICollection<OrganizationUser>> GetManyByUserAsync(Guid userId);
|
||||||
Task<ICollection<OrganizationUser>> GetManyByOrganizationAsync(Guid organizationId, OrganizationUserType? type);
|
Task<ICollection<OrganizationUser>> GetManyByOrganizationAsync(Guid organizationId, OrganizationUserType? type);
|
||||||
Task<OrganizationUser> GetByOrganizationAsync(Guid organizationId, string email);
|
Task<OrganizationUser> GetByOrganizationAsync(Guid organizationId, string email);
|
||||||
Task<Tuple<OrganizationUserUserDetails, ICollection<SubvaultUserSubvaultDetails>>> GetDetailsByIdAsync(Guid id);
|
Task<Tuple<OrganizationUserUserDetails, ICollection<SubvaultUserSubvaultDetails>>> GetDetailsByIdAsync(Guid id);
|
||||||
|
@ -47,6 +47,19 @@ namespace Bit.Core.Repositories.SqlServer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<OrganizationUser>> GetManyByUserAsync(Guid userId)
|
||||||
|
{
|
||||||
|
using(var connection = new SqlConnection(ConnectionString))
|
||||||
|
{
|
||||||
|
var results = await connection.QueryAsync<OrganizationUser>(
|
||||||
|
"[dbo].[OrganizationUser_ReadByUserId]",
|
||||||
|
new { UserId = userId },
|
||||||
|
commandType: CommandType.StoredProcedure);
|
||||||
|
|
||||||
|
return results.ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<ICollection<OrganizationUser>> GetManyByOrganizationAsync(Guid organizationId,
|
public async Task<ICollection<OrganizationUser>> GetManyByOrganizationAsync(Guid organizationId,
|
||||||
OrganizationUserType? type)
|
OrganizationUserType? type)
|
||||||
{
|
{
|
||||||
|
@ -183,5 +183,6 @@
|
|||||||
<Build Include="dbo\Stored Procedures\Subvault_ReadByOrganizationIdAdminUserId.sql" />
|
<Build Include="dbo\Stored Procedures\Subvault_ReadByOrganizationIdAdminUserId.sql" />
|
||||||
<Build Include="dbo\User Defined Types\GuidIdArray.sql" />
|
<Build Include="dbo\User Defined Types\GuidIdArray.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\SubvaultCipher_ReadByCipherId.sql" />
|
<Build Include="dbo\Stored Procedures\SubvaultCipher_ReadByCipherId.sql" />
|
||||||
|
<Build Include="dbo\Stored Procedures\OrganizationUser_ReadByUserId.sql" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -0,0 +1,13 @@
|
|||||||
|
CREATE PROCEDURE [dbo].[OrganizationUser_ReadByUserId]
|
||||||
|
@UserId UNIQUEIDENTIFIER
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
*
|
||||||
|
FROM
|
||||||
|
[dbo].[OrganizationUserView]
|
||||||
|
WHERE
|
||||||
|
[UserId] = @UserId
|
||||||
|
END
|
Loading…
x
Reference in New Issue
Block a user