mirror of
https://github.com/bitwarden/server
synced 2026-01-03 00:53:37 +00:00
PM-25576 made changes to member access query to use views and add avatar color.
This commit is contained in:
@@ -8,6 +8,7 @@ public class MemberAccessReportDetail
|
||||
public Guid? UserGuid { get; set; }
|
||||
public string UserName { get; set; }
|
||||
public string Email { get; set; }
|
||||
public string AvatarColor { get; set; }
|
||||
public bool TwoFactorEnabled { get; set; }
|
||||
public bool AccountRecoveryEnabled { get; set; }
|
||||
public bool UsesKeyConnector { get; set; }
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
// FIXME: Update this file to be null safe and then delete the line below
|
||||
#nullable disable
|
||||
|
||||
namespace Bit.Core.Dirt.Reports.Models.Data;
|
||||
namespace Bit.Core.Dirt.Models.Data;
|
||||
|
||||
public class OrganizationMemberBaseDetail
|
||||
{
|
||||
public Guid? UserGuid { get; set; }
|
||||
public string UserName { get; set; }
|
||||
public string Email { get; set; }
|
||||
public string AvatarColor { get; set; }
|
||||
public string TwoFactorProviders { get; set; }
|
||||
public bool UsesKeyConnector { get; set; }
|
||||
public string ResetPasswordKey { get; set; }
|
||||
@@ -18,5 +19,5 @@ public class OrganizationMemberBaseDetail
|
||||
public bool? ReadOnly { get; set; }
|
||||
public bool? HidePasswords { get; set; }
|
||||
public bool? Manage { get; set; }
|
||||
public Guid CipherId { get; set; }
|
||||
public Guid? CipherId { get; set; }
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ public class MemberAccessReportQuery(
|
||||
b.UserGuid,
|
||||
b.UserName,
|
||||
b.Email,
|
||||
b.AvatarColor,
|
||||
b.TwoFactorProviders,
|
||||
b.ResetPasswordKey,
|
||||
b.UsesKeyConnector,
|
||||
@@ -64,6 +65,7 @@ public class MemberAccessReportQuery(
|
||||
UserGuid = g.Key.UserGuid,
|
||||
UserName = g.Key.UserName,
|
||||
Email = g.Key.Email,
|
||||
AvatarColor = g.Key.AvatarColor,
|
||||
TwoFactorEnabled = orgUsersTwoFactorEnabled.FirstOrDefault(x => x.userId == g.Key.UserGuid).twoFactorIsEnabled,
|
||||
AccountRecoveryEnabled = !string.IsNullOrWhiteSpace(g.Key.ResetPasswordKey) && orgAbility.UseResetPassword,
|
||||
UsesKeyConnector = g.Key.UsesKeyConnector,
|
||||
@@ -74,7 +76,7 @@ public class MemberAccessReportQuery(
|
||||
ReadOnly = g.Key.ReadOnly,
|
||||
HidePasswords = g.Key.HidePasswords,
|
||||
Manage = g.Key.Manage,
|
||||
CipherIds = g.Select(c => c.CipherId)
|
||||
CipherIds = g.Select(c => c.CipherId).Where(id => id.HasValue).Select(id => id.Value)
|
||||
});
|
||||
|
||||
var accessDetailsCount = accessDetails.Count();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Bit.Core.Dirt.Reports.Models.Data;
|
||||
using Bit.Core.Dirt.Models.Data;
|
||||
|
||||
namespace Bit.Core.Dirt.Reports.Repositories;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using System.Data;
|
||||
using Bit.Core.Dirt.Reports.Models.Data;
|
||||
using Bit.Core.Dirt.Models.Data;
|
||||
using Bit.Core.Dirt.Reports.Repositories;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Infrastructure.Dapper.Repositories;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using AutoMapper;
|
||||
using Bit.Core.Dirt.Reports.Models.Data;
|
||||
using Bit.Core.Dirt.Models.Data;
|
||||
using Bit.Core.Dirt.Reports.Repositories;
|
||||
using Bit.Infrastructure.EntityFramework.Repositories;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Dirt;
|
||||
namespace Bit.Infrastructure.EntityFramework.Dirt.Repositories;
|
||||
|
||||
public class OrganizationMemberBaseDetailRepository : BaseEntityFrameworkRepository, IOrganizationMemberBaseDetailRepository
|
||||
{
|
||||
@@ -1,5 +1,5 @@
|
||||
using Bit.Core;
|
||||
using Bit.Core.Dirt.Reports.Models.Data;
|
||||
using Bit.Core.Dirt.Models.Data;
|
||||
using Bit.Infrastructure.EntityFramework.AdminConsole.Models;
|
||||
using Bit.Infrastructure.EntityFramework.AdminConsole.Models.Provider;
|
||||
using Bit.Infrastructure.EntityFramework.Auth.Models;
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
CREATE PROCEDURE dbo.MemberAccessReport_GetMemberAccessCipherDetailsByOrganizationId
|
||||
@OrganizationId UNIQUEIDENTIFIER
|
||||
AS
|
||||
SET NOCOUNT ON;
|
||||
|
||||
IF @OrganizationId IS NULL
|
||||
THROW 50000, 'OrganizationId cannot be null', 1;
|
||||
|
||||
-- Direct user-collection permissions
|
||||
SELECT
|
||||
OU.[Id] AS [UserGuid],
|
||||
OU.[Name] AS [UserName],
|
||||
OU.[Email],
|
||||
OU.[AvatarColor],
|
||||
OU.[TwoFactorProviders],
|
||||
OU.[UsesKeyConnector],
|
||||
OU.[ResetPasswordKey],
|
||||
CUP.[CollectionId],
|
||||
CUP.[CollectionName],
|
||||
NULL AS [GroupId],
|
||||
NULL AS [GroupName],
|
||||
CUP.[ReadOnly],
|
||||
CUP.[HidePasswords],
|
||||
CUP.[Manage],
|
||||
CCD.[CipherId]
|
||||
FROM
|
||||
[dbo].[OrganizationUserUserDetailsView] OU
|
||||
INNER JOIN
|
||||
[dbo].[Organization] O ON O.[Id] = OU.[OrganizationId]
|
||||
INNER JOIN
|
||||
[dbo].[CollectionUserPermissionsView] CUP ON CUP.[OrganizationUserId] = OU.[Id]
|
||||
INNER JOIN
|
||||
[dbo].[CollectionCipherDetailsView] CCD ON CCD.[CollectionId] = CUP.[CollectionId]
|
||||
WHERE
|
||||
O.[Id] = @OrganizationId
|
||||
AND O.[Enabled] = 1
|
||||
AND CUP.[OrganizationId] = @OrganizationId
|
||||
AND CCD.[CipherOrganizationId] = @OrganizationId
|
||||
AND OU.[Status] IN (0, 1, 2) -- Invited, Accepted, Confirmed
|
||||
AND CCD.[DeletedDate] IS NULL
|
||||
|
||||
UNION ALL
|
||||
|
||||
-- Group-based collection permissions
|
||||
SELECT
|
||||
OU.[Id] AS [UserGuid],
|
||||
OU.[Name] AS [UserName],
|
||||
OU.[Email],
|
||||
OU.[AvatarColor],
|
||||
OU.[TwoFactorProviders],
|
||||
OU.[UsesKeyConnector],
|
||||
OU.[ResetPasswordKey],
|
||||
CGP.[CollectionId],
|
||||
CGP.[CollectionName],
|
||||
CGP.[GroupId],
|
||||
CGP.[GroupName],
|
||||
CGP.[ReadOnly],
|
||||
CGP.[HidePasswords],
|
||||
CGP.[Manage],
|
||||
CCD.[CipherId]
|
||||
FROM
|
||||
[dbo].[OrganizationUserUserDetailsView] OU
|
||||
INNER JOIN
|
||||
[dbo].[Organization] O ON O.[Id] = OU.[OrganizationId]
|
||||
INNER JOIN
|
||||
[dbo].[CollectionGroupPermissionsView] CGP ON CGP.[OrganizationUserId] = OU.[Id]
|
||||
INNER JOIN
|
||||
[dbo].[CollectionCipherDetailsView] CCD ON CCD.[CollectionId] = CGP.[CollectionId]
|
||||
WHERE
|
||||
O.[Id] = @OrganizationId
|
||||
AND O.[Enabled] = 1
|
||||
AND CGP.[OrganizationId] = @OrganizationId
|
||||
AND CCD.[CipherOrganizationId] = @OrganizationId
|
||||
AND OU.[Status] IN (0, 1, 2) -- Invited, Accepted, Confirmed
|
||||
AND CCD.[DeletedDate] IS NULL
|
||||
|
||||
UNION ALL
|
||||
|
||||
-- Users without collection access
|
||||
SELECT
|
||||
OU.[Id] AS [UserGuid],
|
||||
OU.[Name] AS [UserName],
|
||||
OU.[Email],
|
||||
OU.[AvatarColor],
|
||||
OU.[TwoFactorProviders],
|
||||
OU.[UsesKeyConnector],
|
||||
OU.[ResetPasswordKey],
|
||||
NULL AS [CollectionId],
|
||||
NULL AS [CollectionName],
|
||||
NULL AS [GroupId],
|
||||
NULL AS [GroupName],
|
||||
NULL AS [ReadOnly],
|
||||
NULL AS [HidePasswords],
|
||||
NULL AS [Manage],
|
||||
NULL AS [CipherId]
|
||||
FROM
|
||||
[dbo].[OrganizationUserUserDetailsView] OU
|
||||
INNER JOIN
|
||||
[dbo].[Organization] O ON O.[Id] = OU.[OrganizationId]
|
||||
WHERE
|
||||
O.[Id] = @OrganizationId
|
||||
AND O.[Enabled] = 1
|
||||
AND OU.[Status] IN (0, 1, 2) -- Invited, Accepted, Confirmed
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM [dbo].[CollectionUserPermissionsView] CUP
|
||||
WHERE CUP.[OrganizationUserId] = OU.[Id]
|
||||
AND CUP.[OrganizationId] = @OrganizationId
|
||||
);
|
||||
@@ -1,92 +0,0 @@
|
||||
CREATE PROCEDURE dbo.MemberAccessReport_GetMemberAccessCipherDetailsByOrganizationId
|
||||
@OrganizationId UNIQUEIDENTIFIER
|
||||
AS
|
||||
SET NOCOUNT ON;
|
||||
|
||||
IF @OrganizationId IS NULL
|
||||
THROW 50000, 'OrganizationId cannot be null', 1;
|
||||
|
||||
SELECT
|
||||
OU.Id AS UserGuid,
|
||||
U.Name AS UserName,
|
||||
ISNULL(U.Email, OU.Email) as 'Email',
|
||||
U.TwoFactorProviders,
|
||||
U.UsesKeyConnector,
|
||||
OU.ResetPasswordKey,
|
||||
CC.CollectionId,
|
||||
C.Name AS CollectionName,
|
||||
NULL AS GroupId,
|
||||
NULL AS GroupName,
|
||||
CU.ReadOnly,
|
||||
CU.HidePasswords,
|
||||
CU.Manage,
|
||||
Cipher.Id AS CipherId
|
||||
FROM dbo.OrganizationUser OU
|
||||
LEFT JOIN dbo.[User] U ON U.Id = OU.UserId
|
||||
INNER JOIN dbo.Organization O ON O.Id = OU.OrganizationId
|
||||
AND O.Id = @OrganizationId
|
||||
AND O.Enabled = 1
|
||||
INNER JOIN dbo.CollectionUser CU ON CU.OrganizationUserId = OU.Id
|
||||
INNER JOIN dbo.Collection C ON C.Id = CU.CollectionId and C.OrganizationId = @OrganizationId
|
||||
INNER JOIN dbo.CollectionCipher CC ON CC.CollectionId = C.Id
|
||||
INNER JOIN dbo.Cipher Cipher ON Cipher.Id = CC.CipherId AND Cipher.OrganizationId = @OrganizationId
|
||||
WHERE OU.Status IN (0,1,2) -- Invited, Accepted and Confirmed Users
|
||||
AND Cipher.DeletedDate IS NULL
|
||||
UNION ALL
|
||||
-- Group-based collection permissions
|
||||
SELECT
|
||||
OU.Id AS UserGuid,
|
||||
U.Name AS UserName,
|
||||
ISNULL(U.Email, OU.Email) as 'Email',
|
||||
U.TwoFactorProviders,
|
||||
U.UsesKeyConnector,
|
||||
OU.ResetPasswordKey,
|
||||
CC.CollectionId,
|
||||
C.Name AS CollectionName,
|
||||
G.Id AS GroupId,
|
||||
G.Name AS GroupName,
|
||||
CG.ReadOnly,
|
||||
CG.HidePasswords,
|
||||
CG.Manage,
|
||||
Cipher.Id AS CipherId
|
||||
FROM dbo.OrganizationUser OU
|
||||
LEFT JOIN dbo.[User] U ON U.Id = OU.UserId
|
||||
INNER JOIN dbo.Organization O ON O.Id = OU.OrganizationId
|
||||
AND O.Id = @OrganizationId
|
||||
AND O.Enabled = 1
|
||||
INNER JOIN dbo.GroupUser GU ON GU.OrganizationUserId = OU.Id
|
||||
INNER JOIN dbo.[Group] G ON G.Id = GU.GroupId
|
||||
INNER JOIN dbo.CollectionGroup CG ON CG.GroupId = G.Id
|
||||
INNER JOIN dbo.Collection C ON C.Id = CG.CollectionId AND C.OrganizationId = @OrganizationId
|
||||
INNER JOIN dbo.CollectionCipher CC ON CC.CollectionId = C.Id
|
||||
INNER JOIN dbo.Cipher Cipher ON Cipher.Id = CC.CipherId and Cipher.OrganizationId = @OrganizationId
|
||||
WHERE OU.Status IN (0,1,2) -- Invited, Accepted and Confirmed Users
|
||||
AND Cipher.DeletedDate IS NULL
|
||||
UNION ALL
|
||||
-- Users without collection access (invited users)
|
||||
-- typically invited users who have not yet accepted the invitation
|
||||
-- and not yet assigned to any collection
|
||||
SELECT
|
||||
OU.Id AS UserGuid,
|
||||
U.Name AS UserName,
|
||||
ISNULL(U.Email, OU.Email) as 'Email',
|
||||
U.TwoFactorProviders,
|
||||
U.UsesKeyConnector,
|
||||
OU.ResetPasswordKey,
|
||||
null as CollectionId,
|
||||
null AS CollectionName,
|
||||
NULL AS GroupId,
|
||||
NULL AS GroupName,
|
||||
null as [ReadOnly],
|
||||
null as HidePasswords,
|
||||
null as Manage,
|
||||
null AS CipherId
|
||||
FROM dbo.OrganizationUser OU
|
||||
LEFT JOIN dbo.[User] U ON U.Id = OU.UserId
|
||||
INNER JOIN dbo.Organization O ON O.Id = OU.OrganizationId AND O.Id = @OrganizationId AND O.Enabled = 1
|
||||
WHERE OU.Status IN (0,1,2) -- Invited, Accepted and Confirmed Users
|
||||
AND OU.Id not in (
|
||||
select OU1.Id from dbo.OrganizationUser OU1
|
||||
inner join dbo.CollectionUser CU1 on CU1.OrganizationUserId = OU1.Id
|
||||
WHERE OU1.OrganizationId = @organizationId
|
||||
)
|
||||
15
src/Sql/dbo/Views/CollectionCipherDetailsView.sql
Normal file
15
src/Sql/dbo/Views/CollectionCipherDetailsView.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
CREATE OR ALTER VIEW [dbo].[CollectionCipherDetailsView]
|
||||
AS
|
||||
SELECT
|
||||
CC.[CollectionId],
|
||||
C.[OrganizationId] AS [CollectionOrganizationId],
|
||||
CC.[CipherId],
|
||||
Ci.[OrganizationId] AS [CipherOrganizationId],
|
||||
Ci.[DeletedDate]
|
||||
FROM
|
||||
[dbo].[CollectionCipher] CC
|
||||
INNER JOIN
|
||||
[dbo].[Collection] C ON C.[Id] = CC.[CollectionId]
|
||||
INNER JOIN
|
||||
[dbo].[Cipher] Ci ON Ci.[Id] = CC.[CipherId]
|
||||
GO
|
||||
21
src/Sql/dbo/Views/CollectionGroupPermissionsView.sql
Normal file
21
src/Sql/dbo/Views/CollectionGroupPermissionsView.sql
Normal file
@@ -0,0 +1,21 @@
|
||||
CREATE OR ALTER VIEW [dbo].[CollectionGroupPermissionsView]
|
||||
AS
|
||||
SELECT
|
||||
GU.[OrganizationUserId],
|
||||
G.[Id] AS [GroupId],
|
||||
G.[Name] AS [GroupName],
|
||||
G.[OrganizationId],
|
||||
CG.[CollectionId],
|
||||
C.[Name] AS [CollectionName],
|
||||
CG.[ReadOnly],
|
||||
CG.[HidePasswords],
|
||||
CG.[Manage]
|
||||
FROM
|
||||
[dbo].[GroupUser] GU
|
||||
INNER JOIN
|
||||
[dbo].[Group] G ON G.[Id] = GU.[GroupId]
|
||||
INNER JOIN
|
||||
[dbo].[CollectionGroup] CG ON CG.[GroupId] = G.[Id]
|
||||
INNER JOIN
|
||||
[dbo].[Collection] C ON C.[Id] = CG.[CollectionId]
|
||||
GO
|
||||
15
src/Sql/dbo/Views/CollectionUserPermissionsView.sql
Normal file
15
src/Sql/dbo/Views/CollectionUserPermissionsView.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
CREATE OR ALTER VIEW [dbo].[CollectionUserPermissionsView]
|
||||
AS
|
||||
SELECT
|
||||
CU.[OrganizationUserId],
|
||||
CU.[CollectionId],
|
||||
C.[OrganizationId],
|
||||
C.[Name] AS [CollectionName],
|
||||
CU.[ReadOnly],
|
||||
CU.[HidePasswords],
|
||||
CU.[Manage]
|
||||
FROM
|
||||
[dbo].[CollectionUser] CU
|
||||
INNER JOIN
|
||||
[dbo].[Collection] C ON C.[Id] = CU.[CollectionId]
|
||||
GO
|
||||
@@ -0,0 +1,166 @@
|
||||
CREATE OR ALTER VIEW [dbo].[CollectionCipherDetailsView]
|
||||
AS
|
||||
SELECT
|
||||
CC.[CollectionId],
|
||||
C.[OrganizationId] AS [CollectionOrganizationId],
|
||||
CC.[CipherId],
|
||||
Ci.[OrganizationId] AS [CipherOrganizationId],
|
||||
Ci.[DeletedDate]
|
||||
FROM
|
||||
[dbo].[CollectionCipher] CC
|
||||
INNER JOIN
|
||||
[dbo].[Collection] C ON C.[Id] = CC.[CollectionId]
|
||||
INNER JOIN
|
||||
[dbo].[Cipher] Ci ON Ci.[Id] = CC.[CipherId]
|
||||
GO
|
||||
|
||||
CREATE OR ALTER VIEW [dbo].[CollectionGroupPermissionsView]
|
||||
AS
|
||||
SELECT
|
||||
GU.[OrganizationUserId],
|
||||
G.[Id] AS [GroupId],
|
||||
G.[Name] AS [GroupName],
|
||||
G.[OrganizationId],
|
||||
CG.[CollectionId],
|
||||
C.[Name] AS [CollectionName],
|
||||
CG.[ReadOnly],
|
||||
CG.[HidePasswords],
|
||||
CG.[Manage]
|
||||
FROM
|
||||
[dbo].[GroupUser] GU
|
||||
INNER JOIN
|
||||
[dbo].[Group] G ON G.[Id] = GU.[GroupId]
|
||||
INNER JOIN
|
||||
[dbo].[CollectionGroup] CG ON CG.[GroupId] = G.[Id]
|
||||
INNER JOIN
|
||||
[dbo].[Collection] C ON C.[Id] = CG.[CollectionId]
|
||||
GO
|
||||
|
||||
CREATE OR ALTER VIEW [dbo].[CollectionUserPermissionsView]
|
||||
AS
|
||||
SELECT
|
||||
CU.[OrganizationUserId],
|
||||
CU.[CollectionId],
|
||||
C.[OrganizationId],
|
||||
C.[Name] AS [CollectionName],
|
||||
CU.[ReadOnly],
|
||||
CU.[HidePasswords],
|
||||
CU.[Manage]
|
||||
FROM
|
||||
[dbo].[CollectionUser] CU
|
||||
INNER JOIN
|
||||
[dbo].[Collection] C ON C.[Id] = CU.[CollectionId]
|
||||
GO
|
||||
|
||||
CREATE OR ALTER PROCEDURE [dbo].[MemberAccessReport_GetMemberAccessCipherDetailsByOrganizationId]
|
||||
@OrganizationId UNIQUEIDENTIFIER
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
|
||||
IF @OrganizationId IS NULL
|
||||
THROW 50000, 'OrganizationId cannot be null', 1;
|
||||
|
||||
-- Direct user-collection permissions
|
||||
SELECT
|
||||
OU.[Id] AS [UserGuid],
|
||||
OU.[Name] AS [UserName],
|
||||
OU.[Email],
|
||||
OU.[AvatarColor],
|
||||
OU.[TwoFactorProviders],
|
||||
OU.[UsesKeyConnector],
|
||||
OU.[ResetPasswordKey],
|
||||
CUP.[CollectionId],
|
||||
CUP.[CollectionName],
|
||||
NULL AS [GroupId],
|
||||
NULL AS [GroupName],
|
||||
CUP.[ReadOnly],
|
||||
CUP.[HidePasswords],
|
||||
CUP.[Manage],
|
||||
CCD.[CipherId]
|
||||
FROM
|
||||
[dbo].[OrganizationUserUserDetailsView] OU
|
||||
INNER JOIN
|
||||
[dbo].[Organization] O ON O.[Id] = OU.[OrganizationId]
|
||||
INNER JOIN
|
||||
[dbo].[CollectionUserPermissionsView] CUP ON CUP.[OrganizationUserId] = OU.[Id]
|
||||
INNER JOIN
|
||||
[dbo].[CollectionCipherDetailsView] CCD ON CCD.[CollectionId] = CUP.[CollectionId]
|
||||
WHERE
|
||||
O.[Id] = @OrganizationId
|
||||
AND O.[Enabled] = 1
|
||||
AND CUP.[OrganizationId] = @OrganizationId
|
||||
AND CCD.[CipherOrganizationId] = @OrganizationId
|
||||
AND OU.[Status] IN (0, 1, 2) -- Invited, Accepted, Confirmed
|
||||
AND CCD.[DeletedDate] IS NULL
|
||||
|
||||
UNION ALL
|
||||
|
||||
-- Group-based collection permissions
|
||||
SELECT
|
||||
OU.[Id] AS [UserGuid],
|
||||
OU.[Name] AS [UserName],
|
||||
OU.[Email],
|
||||
OU.[AvatarColor],
|
||||
OU.[TwoFactorProviders],
|
||||
OU.[UsesKeyConnector],
|
||||
OU.[ResetPasswordKey],
|
||||
CGP.[CollectionId],
|
||||
CGP.[CollectionName],
|
||||
CGP.[GroupId],
|
||||
CGP.[GroupName],
|
||||
CGP.[ReadOnly],
|
||||
CGP.[HidePasswords],
|
||||
CGP.[Manage],
|
||||
CCD.[CipherId]
|
||||
FROM
|
||||
[dbo].[OrganizationUserUserDetailsView] OU
|
||||
INNER JOIN
|
||||
[dbo].[Organization] O ON O.[Id] = OU.[OrganizationId]
|
||||
INNER JOIN
|
||||
[dbo].[CollectionGroupPermissionsView] CGP ON CGP.[OrganizationUserId] = OU.[Id]
|
||||
INNER JOIN
|
||||
[dbo].[CollectionCipherDetailsView] CCD ON CCD.[CollectionId] = CGP.[CollectionId]
|
||||
WHERE
|
||||
O.[Id] = @OrganizationId
|
||||
AND O.[Enabled] = 1
|
||||
AND CGP.[OrganizationId] = @OrganizationId
|
||||
AND CCD.[CipherOrganizationId] = @OrganizationId
|
||||
AND OU.[Status] IN (0, 1, 2) -- Invited, Accepted, Confirmed
|
||||
AND CCD.[DeletedDate] IS NULL
|
||||
|
||||
UNION ALL
|
||||
|
||||
-- Users without collection access
|
||||
SELECT
|
||||
OU.[Id] AS [UserGuid],
|
||||
OU.[Name] AS [UserName],
|
||||
OU.[Email],
|
||||
OU.[AvatarColor],
|
||||
OU.[TwoFactorProviders],
|
||||
OU.[UsesKeyConnector],
|
||||
OU.[ResetPasswordKey],
|
||||
NULL AS [CollectionId],
|
||||
NULL AS [CollectionName],
|
||||
NULL AS [GroupId],
|
||||
NULL AS [GroupName],
|
||||
NULL AS [ReadOnly],
|
||||
NULL AS [HidePasswords],
|
||||
NULL AS [Manage],
|
||||
NULL AS [CipherId]
|
||||
FROM
|
||||
[dbo].[OrganizationUserUserDetailsView] OU
|
||||
INNER JOIN
|
||||
[dbo].[Organization] O ON O.[Id] = OU.[OrganizationId]
|
||||
WHERE
|
||||
O.[Id] = @OrganizationId
|
||||
AND O.[Enabled] = 1
|
||||
AND OU.[Status] IN (0, 1, 2) -- Invited, Accepted, Confirmed
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM [dbo].[CollectionUserPermissionsView] CUP
|
||||
WHERE CUP.[OrganizationUserId] = OU.[Id]
|
||||
AND CUP.[OrganizationId] = @OrganizationId
|
||||
)
|
||||
END
|
||||
GO
|
||||
3443
util/MySqlMigrations/Migrations/20251119211526_2025-11-19_00_UpdateMemberAccessQuery.Designer.cs
generated
Normal file
3443
util/MySqlMigrations/Migrations/20251119211526_2025-11-19_00_UpdateMemberAccessQuery.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,50 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Bit.MySqlMigrations.Migrations;
|
||||
|
||||
/// <inheritdoc />
|
||||
public partial class _20251119_00_UpdateMemberAccessQuery : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<Guid>(
|
||||
name: "CipherId",
|
||||
table: "OrganizationMemberBaseDetails",
|
||||
type: "char(36)",
|
||||
nullable: true,
|
||||
collation: "ascii_general_ci",
|
||||
oldClrType: typeof(Guid),
|
||||
oldType: "char(36)")
|
||||
.OldAnnotation("Relational:Collation", "ascii_general_ci");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "AvatarColor",
|
||||
table: "OrganizationMemberBaseDetails",
|
||||
type: "longtext",
|
||||
nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AvatarColor",
|
||||
table: "OrganizationMemberBaseDetails");
|
||||
|
||||
migrationBuilder.AlterColumn<Guid>(
|
||||
name: "CipherId",
|
||||
table: "OrganizationMemberBaseDetails",
|
||||
type: "char(36)",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"),
|
||||
collation: "ascii_general_ci",
|
||||
oldClrType: typeof(Guid),
|
||||
oldType: "char(36)",
|
||||
oldNullable: true)
|
||||
.OldAnnotation("Relational:Collation", "ascii_general_ci");
|
||||
}
|
||||
}
|
||||
@@ -22,9 +22,12 @@ namespace Bit.MySqlMigrations.Migrations
|
||||
|
||||
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Bit.Core.Dirt.Reports.Models.Data.OrganizationMemberBaseDetail", b =>
|
||||
modelBuilder.Entity("Bit.Core.Dirt.Models.Data.OrganizationMemberBaseDetail", b =>
|
||||
{
|
||||
b.Property<Guid>("CipherId")
|
||||
b.Property<string>("AvatarColor")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<Guid?>("CipherId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.Property<Guid?>("CollectionId")
|
||||
|
||||
3449
util/PostgresMigrations/Migrations/20251119211516_2025-11-19_00_UpdateMemberAccessQuery.Designer.cs
generated
Normal file
3449
util/PostgresMigrations/Migrations/20251119211516_2025-11-19_00_UpdateMemberAccessQuery.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,45 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Bit.PostgresMigrations.Migrations;
|
||||
|
||||
/// <inheritdoc />
|
||||
public partial class _20251119_00_UpdateMemberAccessQuery : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<Guid>(
|
||||
name: "CipherId",
|
||||
table: "OrganizationMemberBaseDetails",
|
||||
type: "uuid",
|
||||
nullable: true,
|
||||
oldClrType: typeof(Guid),
|
||||
oldType: "uuid");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "AvatarColor",
|
||||
table: "OrganizationMemberBaseDetails",
|
||||
type: "text",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AvatarColor",
|
||||
table: "OrganizationMemberBaseDetails");
|
||||
|
||||
migrationBuilder.AlterColumn<Guid>(
|
||||
name: "CipherId",
|
||||
table: "OrganizationMemberBaseDetails",
|
||||
type: "uuid",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"),
|
||||
oldClrType: typeof(Guid),
|
||||
oldType: "uuid",
|
||||
oldNullable: true);
|
||||
}
|
||||
}
|
||||
@@ -23,9 +23,12 @@ namespace Bit.PostgresMigrations.Migrations
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Bit.Core.Dirt.Reports.Models.Data.OrganizationMemberBaseDetail", b =>
|
||||
modelBuilder.Entity("Bit.Core.Dirt.Models.Data.OrganizationMemberBaseDetail", b =>
|
||||
{
|
||||
b.Property<Guid>("CipherId")
|
||||
b.Property<string>("AvatarColor")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid?>("CipherId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid?>("CollectionId")
|
||||
|
||||
3432
util/SqliteMigrations/Migrations/20251119211521_2025-11-19_00_UpdateMemberAccessQuery.Designer.cs
generated
Normal file
3432
util/SqliteMigrations/Migrations/20251119211521_2025-11-19_00_UpdateMemberAccessQuery.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,45 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Bit.SqliteMigrations.Migrations;
|
||||
|
||||
/// <inheritdoc />
|
||||
public partial class _20251119_00_UpdateMemberAccessQuery : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<Guid>(
|
||||
name: "CipherId",
|
||||
table: "OrganizationMemberBaseDetails",
|
||||
type: "TEXT",
|
||||
nullable: true,
|
||||
oldClrType: typeof(Guid),
|
||||
oldType: "TEXT");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "AvatarColor",
|
||||
table: "OrganizationMemberBaseDetails",
|
||||
type: "TEXT",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AvatarColor",
|
||||
table: "OrganizationMemberBaseDetails");
|
||||
|
||||
migrationBuilder.AlterColumn<Guid>(
|
||||
name: "CipherId",
|
||||
table: "OrganizationMemberBaseDetails",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"),
|
||||
oldClrType: typeof(Guid),
|
||||
oldType: "TEXT",
|
||||
oldNullable: true);
|
||||
}
|
||||
}
|
||||
@@ -17,9 +17,12 @@ namespace Bit.SqliteMigrations.Migrations
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.8");
|
||||
|
||||
modelBuilder.Entity("Bit.Core.Dirt.Reports.Models.Data.OrganizationMemberBaseDetail", b =>
|
||||
modelBuilder.Entity("Bit.Core.Dirt.Models.Data.OrganizationMemberBaseDetail", b =>
|
||||
{
|
||||
b.Property<Guid>("CipherId")
|
||||
b.Property<string>("AvatarColor")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid?>("CipherId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<Guid?>("CollectionId")
|
||||
|
||||
Reference in New Issue
Block a user