mirror of
https://github.com/bitwarden/server.git
synced 2025-04-12 16:48:12 -05:00
subvault user apis
This commit is contained in:
parent
0961d86d65
commit
f1fc7832a0
src
Api
Core
Models
Api/Response
OrganizationUserResponseModel.csOrganizationUserSubvaultResponseModel.csSubvaultUserResponseModel.cs
Data
Repositories
Services
Sql
54
src/Api/Controllers/SubvaultUsersController.cs
Normal file
54
src/Api/Controllers/SubvaultUsersController.cs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Bit.Core.Repositories;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Bit.Core.Models.Api;
|
||||||
|
using Bit.Core.Exceptions;
|
||||||
|
using Bit.Core.Services;
|
||||||
|
|
||||||
|
namespace Bit.Api.Controllers
|
||||||
|
{
|
||||||
|
[Route("organizations/{orgId}/subvaultUsers")]
|
||||||
|
[Authorize("Application")]
|
||||||
|
public class SubvaultUsersController : Controller
|
||||||
|
{
|
||||||
|
private readonly ISubvaultRepository _subvaultRepository;
|
||||||
|
private readonly ISubvaultUserRepository _subvaultUserRepository;
|
||||||
|
private readonly IUserService _userService;
|
||||||
|
|
||||||
|
public SubvaultUsersController(
|
||||||
|
ISubvaultRepository subvaultRepository,
|
||||||
|
ISubvaultUserRepository subvaultUserRepository,
|
||||||
|
IUserService userService)
|
||||||
|
{
|
||||||
|
_subvaultRepository = subvaultRepository;
|
||||||
|
_subvaultUserRepository = subvaultUserRepository;
|
||||||
|
_userService = userService;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{subvaultId}")]
|
||||||
|
public async Task<ListResponseModel<SubvaultUserResponseModel>> GetBySubvault(string orgId, string subvaultId)
|
||||||
|
{
|
||||||
|
// TODO: permission check
|
||||||
|
var subvaultUsers = await _subvaultUserRepository.GetManyDetailsBySubvaultIdAsync(new Guid(subvaultId));
|
||||||
|
var responses = subvaultUsers.Select(s => new SubvaultUserResponseModel(s));
|
||||||
|
return new ListResponseModel<SubvaultUserResponseModel>(responses);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete("{id}")]
|
||||||
|
[HttpPost("{id}/delete")]
|
||||||
|
public async Task Delete(string orgId, string id)
|
||||||
|
{
|
||||||
|
var user = await _subvaultUserRepository.GetByIdAsync(new Guid(id));
|
||||||
|
if(user == null)
|
||||||
|
{
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: permission check
|
||||||
|
await _subvaultUserRepository.DeleteAsync(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -198,6 +198,7 @@ namespace Bit.Api
|
|||||||
services.AddScoped<IDeviceService, DeviceService>();
|
services.AddScoped<IDeviceService, DeviceService>();
|
||||||
services.AddScoped<IBlockIpService, AzureQueueBlockIpService>();
|
services.AddScoped<IBlockIpService, AzureQueueBlockIpService>();
|
||||||
services.AddScoped<IOrganizationService, OrganizationService>();
|
services.AddScoped<IOrganizationService, OrganizationService>();
|
||||||
|
services.AddScoped<ISubvaultService, SubvaultService>();
|
||||||
|
|
||||||
// Cors
|
// Cors
|
||||||
services.AddCors(config =>
|
services.AddCors(config =>
|
||||||
|
@ -35,7 +35,7 @@ namespace Bit.Core.Models.Api
|
|||||||
public class OrganizationUserDetailsResponseModel : OrganizationUserResponseModel
|
public class OrganizationUserDetailsResponseModel : OrganizationUserResponseModel
|
||||||
{
|
{
|
||||||
public OrganizationUserDetailsResponseModel(OrganizationUserUserDetails organizationUser,
|
public OrganizationUserDetailsResponseModel(OrganizationUserUserDetails organizationUser,
|
||||||
IEnumerable<SubvaultUserDetails> subvaults)
|
IEnumerable<SubvaultUserSubvaultDetails> subvaults)
|
||||||
: base(organizationUser, "organizationUserDetails")
|
: base(organizationUser, "organizationUserDetails")
|
||||||
{
|
{
|
||||||
Subvaults = new ListResponseModel<OrganizationUserSubvaultResponseModel>(
|
Subvaults = new ListResponseModel<OrganizationUserSubvaultResponseModel>(
|
||||||
|
@ -5,7 +5,7 @@ namespace Bit.Core.Models.Api
|
|||||||
{
|
{
|
||||||
public class OrganizationUserSubvaultResponseModel : ResponseModel
|
public class OrganizationUserSubvaultResponseModel : ResponseModel
|
||||||
{
|
{
|
||||||
public OrganizationUserSubvaultResponseModel(SubvaultUserDetails details,
|
public OrganizationUserSubvaultResponseModel(SubvaultUserSubvaultDetails details,
|
||||||
string obj = "organizationUserSubvault")
|
string obj = "organizationUserSubvault")
|
||||||
: base(obj)
|
: base(obj)
|
||||||
{
|
{
|
||||||
|
39
src/Core/Models/Api/Response/SubvaultUserResponseModel.cs
Normal file
39
src/Core/Models/Api/Response/SubvaultUserResponseModel.cs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
using System;
|
||||||
|
using Bit.Core.Models.Table;
|
||||||
|
using Bit.Core.Models.Data;
|
||||||
|
using Bit.Core.Enums;
|
||||||
|
|
||||||
|
namespace Bit.Core.Models.Api
|
||||||
|
{
|
||||||
|
public class SubvaultUserResponseModel : ResponseModel
|
||||||
|
{
|
||||||
|
public SubvaultUserResponseModel(SubvaultUserUserDetails subvaultUser)
|
||||||
|
: base("subvaultUser")
|
||||||
|
{
|
||||||
|
if(subvaultUser == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(subvaultUser));
|
||||||
|
}
|
||||||
|
|
||||||
|
Id = subvaultUser.Id.ToString();
|
||||||
|
OrganizationUserId = subvaultUser.OrganizationUserId.ToString();
|
||||||
|
SubvaultId = subvaultUser.SubvaultId.ToString();
|
||||||
|
Name = subvaultUser.Name;
|
||||||
|
Email = subvaultUser.Email;
|
||||||
|
Type = subvaultUser.Type;
|
||||||
|
Status = subvaultUser.Status;
|
||||||
|
ReadOnly = subvaultUser.ReadOnly;
|
||||||
|
Admin = subvaultUser.Admin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Id { get; set; }
|
||||||
|
public string OrganizationUserId { get; set; }
|
||||||
|
public string SubvaultId { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Email { get; set; }
|
||||||
|
public OrganizationUserType Type { get; set; }
|
||||||
|
public OrganizationUserStatusType Status { get; set; }
|
||||||
|
public bool ReadOnly { get; set; }
|
||||||
|
public bool Admin { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Bit.Core.Models.Data
|
namespace Bit.Core.Models.Data
|
||||||
{
|
{
|
||||||
public class SubvaultUserDetails
|
public class SubvaultUserSubvaultDetails
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public Guid OrganizationUserId { get; set; }
|
public Guid OrganizationUserId { get; set; }
|
17
src/Core/Models/Data/SubvaultUserUserDetails.cs
Normal file
17
src/Core/Models/Data/SubvaultUserUserDetails.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Bit.Core.Models.Data
|
||||||
|
{
|
||||||
|
public class SubvaultUserUserDetails
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public Guid OrganizationUserId { get; set; }
|
||||||
|
public Guid SubvaultId { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Email { get; set; }
|
||||||
|
public Enums.OrganizationUserStatusType Status { get; set; }
|
||||||
|
public Enums.OrganizationUserType Type { get; set; }
|
||||||
|
public bool ReadOnly { get; set; }
|
||||||
|
public bool Admin { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@ namespace Bit.Core.Repositories
|
|||||||
Task<OrganizationUser> GetByOrganizationAsync(Guid organizationId, Guid userId);
|
Task<OrganizationUser> GetByOrganizationAsync(Guid organizationId, 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<SubvaultUserDetails>>> GetDetailsByIdAsync(Guid id);
|
Task<Tuple<OrganizationUserUserDetails, ICollection<SubvaultUserSubvaultDetails>>> GetDetailsByIdAsync(Guid id);
|
||||||
Task<ICollection<OrganizationUserUserDetails>> GetManyDetailsByOrganizationAsync(Guid organizationId);
|
Task<ICollection<OrganizationUserUserDetails>> GetManyDetailsByOrganizationAsync(Guid organizationId);
|
||||||
Task<ICollection<OrganizationUserOrganizationDetails>> GetManyDetailsByUserAsync(Guid userId,
|
Task<ICollection<OrganizationUserOrganizationDetails>> GetManyDetailsByUserAsync(Guid userId,
|
||||||
OrganizationUserStatusType? status = null);
|
OrganizationUserStatusType? status = null);
|
||||||
|
@ -9,7 +9,8 @@ namespace Bit.Core.Repositories
|
|||||||
public interface ISubvaultUserRepository : IRepository<SubvaultUser, Guid>
|
public interface ISubvaultUserRepository : IRepository<SubvaultUser, Guid>
|
||||||
{
|
{
|
||||||
Task<ICollection<SubvaultUser>> GetManyByOrganizationUserIdAsync(Guid orgUserId);
|
Task<ICollection<SubvaultUser>> GetManyByOrganizationUserIdAsync(Guid orgUserId);
|
||||||
Task<ICollection<SubvaultUserDetails>> GetManyDetailsByUserIdAsync(Guid userId);
|
Task<ICollection<SubvaultUserSubvaultDetails>> GetManyDetailsByUserIdAsync(Guid userId);
|
||||||
|
Task<ICollection<SubvaultUserUserDetails>> GetManyDetailsBySubvaultIdAsync(Guid subvaultId);
|
||||||
Task<ICollection<SubvaultUserPermissions>> GetPermissionsByUserIdAsync(Guid userId, IEnumerable<Guid> subvaultIds,
|
Task<ICollection<SubvaultUserPermissions>> GetPermissionsByUserIdAsync(Guid userId, IEnumerable<Guid> subvaultIds,
|
||||||
Guid organizationId);
|
Guid organizationId);
|
||||||
Task<bool> GetCanEditByUserIdCipherIdAsync(Guid userId, Guid cipherId);
|
Task<bool> GetCanEditByUserIdCipherIdAsync(Guid userId, Guid cipherId);
|
||||||
|
@ -61,7 +61,7 @@ namespace Bit.Core.Repositories.SqlServer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Tuple<OrganizationUserUserDetails, ICollection<SubvaultUserDetails>>> GetDetailsByIdAsync(Guid id)
|
public async Task<Tuple<OrganizationUserUserDetails, ICollection<SubvaultUserSubvaultDetails>>> GetDetailsByIdAsync(Guid id)
|
||||||
{
|
{
|
||||||
using(var connection = new SqlConnection(ConnectionString))
|
using(var connection = new SqlConnection(ConnectionString))
|
||||||
{
|
{
|
||||||
@ -71,8 +71,8 @@ namespace Bit.Core.Repositories.SqlServer
|
|||||||
commandType: CommandType.StoredProcedure);
|
commandType: CommandType.StoredProcedure);
|
||||||
|
|
||||||
var user = (await results.ReadAsync<OrganizationUserUserDetails>()).SingleOrDefault();
|
var user = (await results.ReadAsync<OrganizationUserUserDetails>()).SingleOrDefault();
|
||||||
var subvaults = (await results.ReadAsync<SubvaultUserDetails>()).ToList();
|
var subvaults = (await results.ReadAsync<SubvaultUserSubvaultDetails>()).ToList();
|
||||||
return new Tuple<OrganizationUserUserDetails, ICollection<SubvaultUserDetails>>(user, subvaults);
|
return new Tuple<OrganizationUserUserDetails, ICollection<SubvaultUserSubvaultDetails>>(user, subvaults);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,12 +34,12 @@ namespace Bit.Core.Repositories.SqlServer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ICollection<SubvaultUserDetails>> GetManyDetailsByUserIdAsync(Guid userId)
|
public async Task<ICollection<SubvaultUserSubvaultDetails>> GetManyDetailsByUserIdAsync(Guid userId)
|
||||||
{
|
{
|
||||||
using(var connection = new SqlConnection(ConnectionString))
|
using(var connection = new SqlConnection(ConnectionString))
|
||||||
{
|
{
|
||||||
var results = await connection.QueryAsync<SubvaultUserDetails>(
|
var results = await connection.QueryAsync<SubvaultUserSubvaultDetails>(
|
||||||
$"[{Schema}].[SubvaultUserDetails_ReadByUserId]",
|
$"[{Schema}].[SubvaultUserSubvaultDetails_ReadByUserId]",
|
||||||
new { UserId = userId },
|
new { UserId = userId },
|
||||||
commandType: CommandType.StoredProcedure);
|
commandType: CommandType.StoredProcedure);
|
||||||
|
|
||||||
@ -47,6 +47,19 @@ namespace Bit.Core.Repositories.SqlServer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<SubvaultUserUserDetails>> GetManyDetailsBySubvaultIdAsync(Guid subvaultId)
|
||||||
|
{
|
||||||
|
using(var connection = new SqlConnection(ConnectionString))
|
||||||
|
{
|
||||||
|
var results = await connection.QueryAsync<SubvaultUserUserDetails>(
|
||||||
|
$"[{Schema}].[SubvaultUserUserDetails_ReadBySubvaultId]",
|
||||||
|
new { SubvaultId = subvaultId },
|
||||||
|
commandType: CommandType.StoredProcedure);
|
||||||
|
|
||||||
|
return results.ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<ICollection<SubvaultUserPermissions>> GetPermissionsByUserIdAsync(Guid userId,
|
public async Task<ICollection<SubvaultUserPermissions>> GetPermissionsByUserIdAsync(Guid userId,
|
||||||
IEnumerable<Guid> subvaultIds, Guid organizationId)
|
IEnumerable<Guid> subvaultIds, Guid organizationId)
|
||||||
{
|
{
|
||||||
|
13
src/Core/Services/ISubvaultService.cs
Normal file
13
src/Core/Services/ISubvaultService.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using Bit.Core.Models.Business;
|
||||||
|
using Bit.Core.Models.Table;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Bit.Core.Services
|
||||||
|
{
|
||||||
|
public interface ISubvaultService
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
40
src/Core/Services/Implementations/SubvaultService.cs
Normal file
40
src/Core/Services/Implementations/SubvaultService.cs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Bit.Core.Repositories;
|
||||||
|
using Bit.Core.Models.Business;
|
||||||
|
using Bit.Core.Models.Table;
|
||||||
|
using Bit.Core.Utilities;
|
||||||
|
using Bit.Core.Exceptions;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Bit.Core.Services
|
||||||
|
{
|
||||||
|
public class SubvaultService : ISubvaultService
|
||||||
|
{
|
||||||
|
private readonly IOrganizationRepository _organizationRepository;
|
||||||
|
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||||
|
private readonly ISubvaultRepository _subvaultRepository;
|
||||||
|
private readonly ISubvaultUserRepository _subvaultUserRepository;
|
||||||
|
private readonly IUserRepository _userRepository;
|
||||||
|
private readonly IMailService _mailService;
|
||||||
|
|
||||||
|
public SubvaultService(
|
||||||
|
IOrganizationRepository organizationRepository,
|
||||||
|
IOrganizationUserRepository organizationUserRepository,
|
||||||
|
ISubvaultRepository subvaultRepository,
|
||||||
|
ISubvaultUserRepository subvaultUserRepository,
|
||||||
|
IUserRepository userRepository,
|
||||||
|
IMailService mailService)
|
||||||
|
{
|
||||||
|
_organizationRepository = organizationRepository;
|
||||||
|
_organizationUserRepository = organizationUserRepository;
|
||||||
|
_subvaultRepository = subvaultRepository;
|
||||||
|
_subvaultUserRepository = subvaultUserRepository;
|
||||||
|
_userRepository = userRepository;
|
||||||
|
_mailService = mailService;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -84,7 +84,7 @@
|
|||||||
<Build Include="dbo\Tables\GroupUser.sql" />
|
<Build Include="dbo\Tables\GroupUser.sql" />
|
||||||
<Build Include="dbo\Tables\SubvaultGroup.sql" />
|
<Build Include="dbo\Tables\SubvaultGroup.sql" />
|
||||||
<Build Include="dbo\Views\SubvaultUserView.sql" />
|
<Build Include="dbo\Views\SubvaultUserView.sql" />
|
||||||
<Build Include="dbo\Views\SubvaultUserDetailsView.sql" />
|
<Build Include="dbo\Views\SubvaultUserSubvaultDetailsView.sql" />
|
||||||
<Build Include="dbo\Views\DeviceView.sql" />
|
<Build Include="dbo\Views\DeviceView.sql" />
|
||||||
<Build Include="dbo\Views\HistoryView.sql" />
|
<Build Include="dbo\Views\HistoryView.sql" />
|
||||||
<Build Include="dbo\Views\FolderView.sql" />
|
<Build Include="dbo\Views\FolderView.sql" />
|
||||||
@ -99,7 +99,7 @@
|
|||||||
<Build Include="dbo\Functions\CipherDetails.sql" />
|
<Build Include="dbo\Functions\CipherDetails.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\Subvault_ReadByOrganizationId.sql" />
|
<Build Include="dbo\Stored Procedures\Subvault_ReadByOrganizationId.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\SubvaultUser_ReadByOrganizationUserId.sql" />
|
<Build Include="dbo\Stored Procedures\SubvaultUser_ReadByOrganizationUserId.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\SubvaultUserDetails_ReadByUserId.sql" />
|
<Build Include="dbo\Stored Procedures\SubvaultUserSubvaultDetails_ReadByUserId.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\Cipher_Create.sql" />
|
<Build Include="dbo\Stored Procedures\Cipher_Create.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\Cipher_DeleteById.sql" />
|
<Build Include="dbo\Stored Procedures\Cipher_DeleteById.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\Favorite_Create.sql" />
|
<Build Include="dbo\Stored Procedures\Favorite_Create.sql" />
|
||||||
@ -180,5 +180,7 @@
|
|||||||
<Build Include="dbo\Stored Procedures\OrganizationUser_ReadByOrganizationIdEmail.sql" />
|
<Build Include="dbo\Stored Procedures\OrganizationUser_ReadByOrganizationIdEmail.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\OrganizationUser_ReadByOrganizationId.sql" />
|
<Build Include="dbo\Stored Procedures\OrganizationUser_ReadByOrganizationId.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\Subvault_ReadByIdAdminUserId.sql" />
|
<Build Include="dbo\Stored Procedures\Subvault_ReadByIdAdminUserId.sql" />
|
||||||
|
<Build Include="dbo\Views\SubvaultUserUserDetailsView.sql" />
|
||||||
|
<Build Include="dbo\Stored Procedures\SubvaultUserUserDetails_ReadBySubvaultId.sql" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -14,7 +14,7 @@ BEGIN
|
|||||||
SELECT
|
SELECT
|
||||||
*
|
*
|
||||||
FROM
|
FROM
|
||||||
[dbo].[SubvaultUserDetailsView]
|
[dbo].[SubvaultUserSubvaultDetailsView]
|
||||||
WHERE
|
WHERE
|
||||||
[OrganizationUserId] = @Id
|
[OrganizationUserId] = @Id
|
||||||
END
|
END
|
@ -1,4 +1,4 @@
|
|||||||
CREATE PROCEDURE [dbo].[SubvaultUserDetails_ReadByUserId]
|
CREATE PROCEDURE [dbo].[SubvaultUserSubvaultDetails_ReadByUserId]
|
||||||
@UserId UNIQUEIDENTIFIER
|
@UserId UNIQUEIDENTIFIER
|
||||||
AS
|
AS
|
||||||
BEGIN
|
BEGIN
|
||||||
@ -7,7 +7,7 @@ BEGIN
|
|||||||
SELECT
|
SELECT
|
||||||
SU.*
|
SU.*
|
||||||
FROM
|
FROM
|
||||||
[dbo].[SubvaultUserDetailsView] SU
|
[dbo].[SubvaultUserSubvaultDetailsView] SU
|
||||||
INNER JOIN
|
INNER JOIN
|
||||||
[OrganizationUser] OU ON SU.[OrganizationUserId] = OU.[Id]
|
[OrganizationUser] OU ON SU.[OrganizationUserId] = OU.[Id]
|
||||||
WHERE
|
WHERE
|
@ -0,0 +1,15 @@
|
|||||||
|
CREATE PROCEDURE [dbo].[SubvaultUserUserDetails_ReadBySubvaultId]
|
||||||
|
@SubvaultId UNIQUEIDENTIFIER
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
SU.*
|
||||||
|
FROM
|
||||||
|
[dbo].[SubvaultUserUserDetailsView] SU
|
||||||
|
INNER JOIN
|
||||||
|
[OrganizationUser] OU ON SU.[OrganizationUserId] = OU.[Id]
|
||||||
|
WHERE
|
||||||
|
SU.[SubvaultId] = @SubvaultId
|
||||||
|
END
|
@ -1,4 +1,4 @@
|
|||||||
CREATE VIEW [dbo].[SubvaultUserDetailsView]
|
CREATE VIEW [dbo].[SubvaultUserSubvaultDetailsView]
|
||||||
AS
|
AS
|
||||||
SELECT
|
SELECT
|
||||||
SU.[Id],
|
SU.[Id],
|
18
src/Sql/dbo/Views/SubvaultUserUserDetailsView.sql
Normal file
18
src/Sql/dbo/Views/SubvaultUserUserDetailsView.sql
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
CREATE VIEW [dbo].[SubvaultUserUserDetailsView]
|
||||||
|
AS
|
||||||
|
SELECT
|
||||||
|
SU.[Id],
|
||||||
|
SU.[OrganizationUserId],
|
||||||
|
SU.[SubvaultId],
|
||||||
|
U.[Name],
|
||||||
|
ISNULL(U.[Email], OU.[Email]) Email,
|
||||||
|
OU.[Status],
|
||||||
|
OU.[Type],
|
||||||
|
SU.[ReadOnly],
|
||||||
|
SU.[Admin]
|
||||||
|
FROM
|
||||||
|
[dbo].[SubvaultUser] SU
|
||||||
|
INNER JOIN
|
||||||
|
[dbo].[OrganizationUser] OU ON OU.[Id] = SU.[OrganizationUserId]
|
||||||
|
LEFT JOIN
|
||||||
|
[dbo].[User] U ON U.[Id] = OU.[UserId]
|
Loading…
x
Reference in New Issue
Block a user