1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-15 06:37:54 -05:00

[AC-1117] Add manage permission (#3126)

* Update sql files to add Manage permission

* Add migration script

* Rename collection manage migration file to remove duplicate migration date

* Migrations

* Add manage to models

* Add manage to repository

* Add constraint to Manage columns

* Migration lint fixes

* Add manage to OrganizationUserUserDetails_ReadWithCollectionsById

* Add missing manage fields

* Add 'Manage' to UserCollectionDetails

* Use CREATE OR ALTER where possible
This commit is contained in:
Robyn MacCallum
2023-08-11 14:50:34 -04:00
committed by GitHub
parent 5275f22f12
commit 4f08039756
44 changed files with 7787 additions and 52 deletions

View File

@ -9,6 +9,7 @@ public class SelectionReadOnlyRequestModel
public string Id { get; set; }
public bool ReadOnly { get; set; }
public bool HidePasswords { get; set; }
public bool Manage { get; set; }
public CollectionAccessSelection ToSelectionReadOnly()
{
@ -17,6 +18,7 @@ public class SelectionReadOnlyRequestModel
Id = new Guid(Id),
ReadOnly = ReadOnly,
HidePasswords = HidePasswords,
Manage = Manage,
};
}
}

View File

@ -33,10 +33,12 @@ public class CollectionDetailsResponseModel : CollectionResponseModel
{
ReadOnly = collectionDetails.ReadOnly;
HidePasswords = collectionDetails.HidePasswords;
Manage = collectionDetails.Manage;
}
public bool ReadOnly { get; set; }
public bool HidePasswords { get; set; }
public bool Manage { get; set; }
}
public class CollectionAccessDetailsResponseModel : CollectionResponseModel

View File

@ -14,9 +14,11 @@ public class SelectionReadOnlyResponseModel
Id = selection.Id;
ReadOnly = selection.ReadOnly;
HidePasswords = selection.HidePasswords;
Manage = selection.Manage;
}
public Guid Id { get; set; }
public bool ReadOnly { get; set; }
public bool HidePasswords { get; set; }
public bool Manage { get; set; }
}

View File

@ -6,4 +6,5 @@ public class CollectionGroup
public Guid GroupId { get; set; }
public bool ReadOnly { get; set; }
public bool HidePasswords { get; set; }
public bool Manage { get; set; }
}

View File

@ -6,4 +6,5 @@ public class CollectionUser
public Guid OrganizationUserId { get; set; }
public bool ReadOnly { get; set; }
public bool HidePasswords { get; set; }
public bool Manage { get; set; }
}

View File

@ -5,4 +5,5 @@ public class CollectionAccessSelection
public Guid Id { get; set; }
public bool ReadOnly { get; set; }
public bool HidePasswords { get; set; }
public bool Manage { get; set; }
}

View File

@ -6,4 +6,5 @@ public class CollectionDetails : Collection
{
public bool ReadOnly { get; set; }
public bool HidePasswords { get; set; }
public bool Manage { get; set; }
}

View File

@ -40,6 +40,8 @@ public static class DapperHelpers
table.Columns.Add(readOnlyColumn);
var hidePasswordsColumn = new DataColumn("HidePasswords", typeof(bool));
table.Columns.Add(hidePasswordsColumn);
var manageColumn = new DataColumn("Manage", typeof(bool));
table.Columns.Add(manageColumn);
if (values != null)
{
@ -49,6 +51,7 @@ public static class DapperHelpers
row[idColumn] = value.Id;
row[readOnlyColumn] = value.ReadOnly;
row[hidePasswordsColumn] = value.HidePasswords;
row[manageColumn] = value.Manage;
table.Rows.Add(row);
}
}

View File

@ -121,7 +121,8 @@ public class CollectionRepository : Repository<Collection, Guid>, ICollectionRep
{
Id = g.GroupId,
HidePasswords = g.HidePasswords,
ReadOnly = g.ReadOnly
ReadOnly = g.ReadOnly,
Manage = g.Manage
}).ToList() ?? new List<CollectionAccessSelection>(),
Users = users
.FirstOrDefault(u => u.Key == collection.Id)?
@ -129,7 +130,8 @@ public class CollectionRepository : Repository<Collection, Guid>, ICollectionRep
{
Id = c.OrganizationUserId,
HidePasswords = c.HidePasswords,
ReadOnly = c.ReadOnly
ReadOnly = c.ReadOnly,
Manage = c.Manage
}).ToList() ?? new List<CollectionAccessSelection>()
}
)
@ -163,7 +165,8 @@ public class CollectionRepository : Repository<Collection, Guid>, ICollectionRep
{
Id = g.GroupId,
HidePasswords = g.HidePasswords,
ReadOnly = g.ReadOnly
ReadOnly = g.ReadOnly,
Manage = g.Manage
}).ToList() ?? new List<CollectionAccessSelection>(),
Users = users
.FirstOrDefault(u => u.Key == collection.Id)?
@ -171,7 +174,8 @@ public class CollectionRepository : Repository<Collection, Guid>, ICollectionRep
{
Id = c.OrganizationUserId,
HidePasswords = c.HidePasswords,
ReadOnly = c.ReadOnly
ReadOnly = c.ReadOnly,
Manage = c.Manage
}).ToList() ?? new List<CollectionAccessSelection>()
}
)

View File

@ -70,7 +70,8 @@ public class GroupRepository : Repository<Group, Guid>, IGroupRepository
{
Id = c.CollectionId,
HidePasswords = c.HidePasswords,
ReadOnly = c.ReadOnly
ReadOnly = c.ReadOnly,
Manage = c.Manage
}
).ToList() ?? new List<CollectionAccessSelection>())
).ToList();

View File

@ -266,7 +266,8 @@ public class OrganizationUserRepository : Repository<OrganizationUser, Guid>, IO
{
Id = uc.CollectionId,
ReadOnly = uc.ReadOnly,
HidePasswords = uc.HidePasswords
HidePasswords = uc.HidePasswords,
Manage = uc.Manage
}).ToList() ?? new List<CollectionAccessSelection>();
}
}

View File

@ -68,6 +68,7 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
GroupId = g.Id,
ReadOnly = g.ReadOnly,
HidePasswords = g.HidePasswords,
Manage = g.Manage
});
await dbContext.AddRangeAsync(collectionGroups);
}
@ -85,6 +86,7 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
OrganizationUserId = u.Id,
ReadOnly = u.ReadOnly,
HidePasswords = u.HidePasswords,
Manage = u.Manage
});
await dbContext.AddRangeAsync(collectionUsers);
}
@ -130,6 +132,7 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
Id = cg.GroupId,
ReadOnly = cg.ReadOnly,
HidePasswords = cg.HidePasswords,
Manage = cg.Manage
};
var groups = await groupQuery.ToArrayAsync();
@ -140,6 +143,7 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
Id = cg.OrganizationUserId,
ReadOnly = cg.ReadOnly,
HidePasswords = cg.HidePasswords,
Manage = cg.Manage
};
var users = await userQuery.ToArrayAsync();
var access = new CollectionAccessDetails { Users = users, Groups = groups };
@ -161,6 +165,7 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
Id = cg.GroupId,
ReadOnly = cg.ReadOnly,
HidePasswords = cg.HidePasswords,
Manage = cg.Manage
};
var groups = await groupQuery.ToArrayAsync();
@ -171,6 +176,7 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
Id = cg.OrganizationUserId,
ReadOnly = cg.ReadOnly,
HidePasswords = cg.HidePasswords,
Manage = cg.Manage,
};
var users = await userQuery.ToArrayAsync();
var access = new CollectionAccessDetails { Users = users, Groups = groups };
@ -207,7 +213,8 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
{
Id = g.GroupId,
HidePasswords = g.HidePasswords,
ReadOnly = g.ReadOnly
ReadOnly = g.ReadOnly,
Manage = g.Manage
}).ToList() ?? new List<CollectionAccessSelection>(),
Users = users
.FirstOrDefault(u => u.Key == collection.Id)?
@ -215,7 +222,8 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
{
Id = c.OrganizationUserId,
HidePasswords = c.HidePasswords,
ReadOnly = c.ReadOnly
ReadOnly = c.ReadOnly,
Manage = c.Manage
}).ToList() ?? new List<CollectionAccessSelection>()
}
)
@ -251,7 +259,8 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
{
Id = g.GroupId,
HidePasswords = g.HidePasswords,
ReadOnly = g.ReadOnly
ReadOnly = g.ReadOnly,
Manage = g.Manage
}).ToList() ?? new List<CollectionAccessSelection>(),
Users = users
.FirstOrDefault(u => u.Key == collection.Id)?
@ -259,7 +268,8 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
{
Id = c.OrganizationUserId,
HidePasswords = c.HidePasswords,
ReadOnly = c.ReadOnly
ReadOnly = c.ReadOnly,
Manage = c.Manage
}).ToList() ?? new List<CollectionAccessSelection>()
}
)
@ -329,6 +339,7 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
ExternalId = collectionGroup.Key.ExternalId,
ReadOnly = Convert.ToBoolean(collectionGroup.Min(c => Convert.ToInt32(c.ReadOnly))),
HidePasswords = Convert.ToBoolean(collectionGroup.Min(c => Convert.ToInt32(c.HidePasswords))),
Manage = Convert.ToBoolean(collectionGroup.Min(c => Convert.ToInt32(c.Manage))),
})
.ToList();
}
@ -353,6 +364,7 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
ExternalId = collectionGroup.Key.ExternalId,
ReadOnly = Convert.ToBoolean(collectionGroup.Min(c => Convert.ToInt32(c.ReadOnly))),
HidePasswords = Convert.ToBoolean(collectionGroup.Min(c => Convert.ToInt32(c.HidePasswords))),
Manage = Convert.ToBoolean(collectionGroup.Min(c => Convert.ToInt32(c.Manage))),
}).ToListAsync();
}
}
@ -371,6 +383,7 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
Id = cu.OrganizationUserId,
ReadOnly = cu.ReadOnly,
HidePasswords = cu.HidePasswords,
Manage = cu.Manage
}).ToArray();
}
}
@ -415,6 +428,7 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
OrganizationUserId = requestedUser.Id,
HidePasswords = requestedUser.HidePasswords,
ReadOnly = requestedUser.ReadOnly,
Manage = requestedUser.Manage
});
continue;
}
@ -422,6 +436,7 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
// It already exists, update it
existingCollectionUser.HidePasswords = requestedUser.HidePasswords;
existingCollectionUser.ReadOnly = requestedUser.ReadOnly;
existingCollectionUser.Manage = requestedUser.Manage;
dbContext.CollectionUsers.Update(existingCollectionUser);
}
@ -487,13 +502,15 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
GroupId = x.g.Id,
ReadOnly = groups.FirstOrDefault(g => g.Id == x.g.Id).ReadOnly,
HidePasswords = groups.FirstOrDefault(g => g.Id == x.g.Id).HidePasswords,
Manage = groups.FirstOrDefault(g => g.Id == x.g.Id).Manage
}).ToList();
var update = union
.Where(
x => x.g != null &&
x.cg != null &&
(x.cg.ReadOnly != groups.FirstOrDefault(g => g.Id == x.g.Id).ReadOnly ||
x.cg.HidePasswords != groups.FirstOrDefault(g => g.Id == x.g.Id).HidePasswords)
x.cg.HidePasswords != groups.FirstOrDefault(g => g.Id == x.g.Id).HidePasswords ||
x.cg.Manage != groups.FirstOrDefault(g => g.Id == x.g.Id).Manage)
)
.Select(x => new CollectionGroup
{
@ -501,6 +518,7 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
GroupId = x.g.Id,
ReadOnly = groups.FirstOrDefault(g => g.Id == x.g.Id).ReadOnly,
HidePasswords = groups.FirstOrDefault(g => g.Id == x.g.Id).HidePasswords,
Manage = groups.FirstOrDefault(g => g.Id == x.g.Id).Manage,
});
var delete = union
.Where(
@ -549,13 +567,15 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
OrganizationUserId = x.u.Id,
ReadOnly = users.FirstOrDefault(u => u.Id == x.u.Id).ReadOnly,
HidePasswords = users.FirstOrDefault(u => u.Id == x.u.Id).HidePasswords,
Manage = users.FirstOrDefault(u => u.Id == x.u.Id).Manage,
}).ToList();
var update = union
.Where(
x => x.u != null &&
x.cu != null &&
(x.cu.ReadOnly != users.FirstOrDefault(u => u.Id == x.u.Id).ReadOnly ||
x.cu.HidePasswords != users.FirstOrDefault(u => u.Id == x.u.Id).HidePasswords)
x.cu.HidePasswords != users.FirstOrDefault(u => u.Id == x.u.Id).HidePasswords ||
x.cu.Manage != users.FirstOrDefault(u => u.Id == x.u.Id).Manage)
)
.Select(x => new CollectionUser
{
@ -563,6 +583,7 @@ public class CollectionRepository : Repository<Core.Entities.Collection, Collect
OrganizationUserId = x.u.Id,
ReadOnly = users.FirstOrDefault(u => u.Id == x.u.Id).ReadOnly,
HidePasswords = users.FirstOrDefault(u => u.Id == x.u.Id).HidePasswords,
Manage = users.FirstOrDefault(u => u.Id == x.u.Id).Manage,
});
var delete = union
.Where(

View File

@ -30,6 +30,7 @@ public class GroupRepository : Repository<Core.Entities.Group, Group, Guid>, IGr
GroupId = grp.Id,
ReadOnly = y.ReadOnly,
HidePasswords = y.HidePasswords,
Manage = y.Manage,
});
await dbContext.CollectionGroups.AddRangeAsync(collectionGroups);
await dbContext.SaveChangesAsync();
@ -66,6 +67,7 @@ public class GroupRepository : Repository<Core.Entities.Group, Group, Guid>, IGr
Id = c.CollectionId,
ReadOnly = c.ReadOnly,
HidePasswords = c.HidePasswords,
Manage = c.Manage,
}).ToList();
return new Tuple<Core.Entities.Group, ICollection<CollectionAccessSelection>>(
grp, collections);
@ -108,7 +110,8 @@ public class GroupRepository : Repository<Core.Entities.Group, Group, Guid>, IGr
{
Id = c.CollectionId,
HidePasswords = c.HidePasswords,
ReadOnly = c.ReadOnly
ReadOnly = c.ReadOnly,
Manage = c.Manage
}
).ToList() ?? new List<CollectionAccessSelection>())
).ToList();
@ -202,12 +205,14 @@ public class GroupRepository : Repository<Core.Entities.Group, Group, Guid>, IGr
GroupId = group.Id,
ReadOnly = requestedCollection.ReadOnly,
HidePasswords = requestedCollection.HidePasswords,
Manage = requestedCollection.Manage
});
continue;
}
existingCollectionGroup.ReadOnly = requestedCollection.ReadOnly;
existingCollectionGroup.HidePasswords = requestedCollection.HidePasswords;
existingCollectionGroup.Manage = requestedCollection.Manage;
}
var requestedCollectionIds = requestedCollections.Select(c => c.Id);

View File

@ -33,6 +33,7 @@ public class OrganizationUserRepository : Repository<Core.Entities.OrganizationU
OrganizationUserId = organizationUser.Id,
ReadOnly = y.ReadOnly,
HidePasswords = y.HidePasswords,
Manage = y.Manage
});
await dbContext.CollectionUsers.AddRangeAsync(collectionUsers);
await dbContext.SaveChangesAsync();
@ -141,6 +142,7 @@ public class OrganizationUserRepository : Repository<Core.Entities.OrganizationU
Id = cu.CollectionId,
ReadOnly = cu.ReadOnly,
HidePasswords = cu.HidePasswords,
Manage = cu.Manage,
});
return new Tuple<Core.Entities.OrganizationUser, ICollection<CollectionAccessSelection>>(
organizationUser, collections.ToList());
@ -235,6 +237,7 @@ public class OrganizationUserRepository : Repository<Core.Entities.OrganizationU
Id = cu.CollectionId,
ReadOnly = cu.ReadOnly,
HidePasswords = cu.HidePasswords,
Manage = cu.Manage
}).ToListAsync();
return new Tuple<OrganizationUserUserDetails, ICollection<CollectionAccessSelection>>(organizationUserUserDetails, collections);
}
@ -360,7 +363,8 @@ public class OrganizationUserRepository : Repository<Core.Entities.OrganizationU
{
Id = cu.CollectionId,
ReadOnly = cu.ReadOnly,
HidePasswords = cu.HidePasswords
HidePasswords = cu.HidePasswords,
Manage = cu.Manage,
}).ToList() ?? new List<CollectionAccessSelection>();
}
}
@ -440,6 +444,7 @@ public class OrganizationUserRepository : Repository<Core.Entities.OrganizationU
OrganizationUserId = obj.Id,
HidePasswords = requestedCollection.HidePasswords,
ReadOnly = requestedCollection.ReadOnly,
Manage = requestedCollection.Manage
});
continue;
}
@ -447,6 +452,7 @@ public class OrganizationUserRepository : Repository<Core.Entities.OrganizationU
// It already exists, update it
existingCollectionUser.HidePasswords = requestedCollection.HidePasswords;
existingCollectionUser.ReadOnly = requestedCollection.ReadOnly;
existingCollectionUser.Manage = requestedCollection.Manage;
dbContext.CollectionUsers.Update(existingCollectionUser);
}

View File

@ -58,6 +58,8 @@ public class UserCollectionDetailsQuery : IQuery<CollectionDetails>
!((bool?)x.cu.ReadOnly ?? (bool?)x.cg.ReadOnly ?? false) ? false : true,
HidePasswords = x.ou.AccessAll || x.g.AccessAll ||
!((bool?)x.cu.HidePasswords ?? (bool?)x.cg.HidePasswords ?? false) ? false : true,
Manage = x.ou.AccessAll || x.g.AccessAll ||
!((bool?)x.cu.Manage ?? (bool?)x.cg.Manage ?? false) ? false : true,
});
}
}

View File

@ -18,7 +18,15 @@ SELECT
OR COALESCE(CU.[HidePasswords], CG.[HidePasswords], 0) = 0
THEN 0
ELSE 1
END [HidePasswords]
END [HidePasswords],
CASE
WHEN
OU.[AccessAll] = 1
OR G.[AccessAll] = 1
OR COALESCE(CU.[Manage], CG.[Manage], 0) = 0
THEN 0
ELSE 1
END [Manage]
FROM
[dbo].[CollectionView] C
INNER JOIN

View File

@ -7,9 +7,10 @@ BEGIN
SELECT
[GroupId] [Id],
[ReadOnly],
[HidePasswords]
[HidePasswords],
[Manage]
FROM
[dbo].[CollectionGroup]
WHERE
[CollectionId] = @CollectionId
END
END

View File

@ -7,9 +7,10 @@ BEGIN
SELECT
[OrganizationUserId] [Id],
[ReadOnly],
[HidePasswords]
[HidePasswords],
[Manage]
FROM
[dbo].[CollectionUser]
WHERE
[CollectionId] = @CollectionId
END
END

View File

@ -19,7 +19,8 @@ BEGIN
[Target]
SET
[Target].[ReadOnly] = [Source].[ReadOnly],
[Target].[HidePasswords] = [Source].[HidePasswords]
[Target].[HidePasswords] = [Source].[HidePasswords],
[Target].[Manage] = [Source].[Manage]
FROM
[dbo].[CollectionUser] [Target]
INNER JOIN
@ -29,6 +30,7 @@ BEGIN
AND (
[Target].[ReadOnly] != [Source].[ReadOnly]
OR [Target].[HidePasswords] != [Source].[HidePasswords]
OR [Target].[Manage] != [Source].[Manage]
)
-- Insert
@ -38,7 +40,8 @@ BEGIN
@CollectionId,
[Source].[Id],
[Source].[ReadOnly],
[Source].[HidePasswords]
[Source].[HidePasswords],
[Source].[Manage]
FROM
@Users [Source]
INNER JOIN
@ -71,4 +74,4 @@ BEGIN
)
EXEC [dbo].[User_BumpAccountRevisionDateByCollectionId] @CollectionId, @OrgId
END
END

View File

@ -27,13 +27,15 @@ BEGIN
[CollectionId],
[GroupId],
[ReadOnly],
[HidePasswords]
[HidePasswords],
[Manage]
)
SELECT
@Id,
[Id],
[ReadOnly],
[HidePasswords]
[HidePasswords],
[Manage]
FROM
@Groups
WHERE
@ -53,17 +55,19 @@ BEGIN
[CollectionId],
[OrganizationUserId],
[ReadOnly],
[HidePasswords]
[HidePasswords],
[Manage]
)
SELECT
@Id,
[Id],
[ReadOnly],
[HidePasswords]
[HidePasswords],
[Manage]
FROM
@Users
WHERE
[Id] IN (SELECT [Id] FROM [AvailableUsersCTE])
EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId
END
END

View File

@ -12,7 +12,8 @@ BEGIN
RevisionDate,
ExternalId,
MIN([ReadOnly]) AS [ReadOnly],
MIN([HidePasswords]) AS [HidePasswords]
MIN([HidePasswords]) AS [HidePasswords],
MIN([Manage]) AS [Manage]
FROM
[dbo].[UserCollectionDetails](@UserId)
WHERE

View File

@ -12,7 +12,8 @@ BEGIN
RevisionDate,
ExternalId,
MIN([ReadOnly]) AS [ReadOnly],
MIN([HidePasswords]) AS [HidePasswords]
MIN([HidePasswords]) AS [HidePasswords],
MIN([Manage]) AS [Manage]
FROM
[dbo].[UserCollectionDetails](@UserId)
GROUP BY

View File

@ -12,7 +12,8 @@ BEGIN
RevisionDate DATETIME2(7),
ExternalId NVARCHAR(300),
ReadOnly BIT,
HidePasswords BIT)
HidePasswords BIT,
Manage BIT)
INSERT INTO @TempUserCollections EXEC [dbo].[Collection_ReadByUserId] @UserId
@ -35,4 +36,4 @@ BEGIN
INNER JOIN
@TempUserCollections C ON C.[Id] = CU.[CollectionId]
END
END

View File

@ -36,14 +36,17 @@ BEGIN
@Id,
[Source].[Id],
[Source].[ReadOnly],
[Source].[HidePasswords]
[Source].[HidePasswords],
[Source].[Manage]
)
WHEN MATCHED AND (
[Target].[ReadOnly] != [Source].[ReadOnly]
OR [Target].[HidePasswords] != [Source].[HidePasswords]
OR [Target].[Manage] != [Source].[Manage]
) THEN
UPDATE SET [Target].[ReadOnly] = [Source].[ReadOnly],
[Target].[HidePasswords] = [Source].[HidePasswords]
[Target].[HidePasswords] = [Source].[HidePasswords],
[Target].[Manage] = [Source].[Manage]
WHEN NOT MATCHED BY SOURCE
AND [Target].[CollectionId] = @Id THEN
DELETE
@ -72,18 +75,21 @@ BEGIN
@Id,
[Source].[Id],
[Source].[ReadOnly],
[Source].[HidePasswords]
[Source].[HidePasswords],
[Source].[Manage]
)
WHEN MATCHED AND (
[Target].[ReadOnly] != [Source].[ReadOnly]
OR [Target].[HidePasswords] != [Source].[HidePasswords]
OR [Target].[Manage] != [Source].[Manage]
) THEN
UPDATE SET [Target].[ReadOnly] = [Source].[ReadOnly],
[Target].[HidePasswords] = [Source].[HidePasswords]
[Target].[HidePasswords] = [Source].[HidePasswords],
[Target].[Manage] = [Source].[Manage]
WHEN NOT MATCHED BY SOURCE
AND [Target].[CollectionId] = @Id THEN
DELETE
;
EXEC [dbo].[User_BumpAccountRevisionDateByCollectionId] @Id, @OrganizationId
END
END

View File

@ -26,17 +26,19 @@ BEGIN
[CollectionId],
[GroupId],
[ReadOnly],
[HidePasswords]
[HidePasswords],
[Manage]
)
SELECT
[Id],
@Id,
[ReadOnly],
[HidePasswords]
[HidePasswords],
[Manage]
FROM
@Collections
WHERE
[Id] IN (SELECT [Id] FROM [AvailableCollectionsCTE])
EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId
END
END

View File

@ -9,9 +9,10 @@ BEGIN
SELECT
[CollectionId] [Id],
[ReadOnly],
[HidePasswords]
[HidePasswords],
[Manage]
FROM
[dbo].[CollectionGroup]
WHERE
[GroupId] = @Id
END
END

View File

@ -35,18 +35,21 @@ BEGIN
[Source].[Id],
@Id,
[Source].[ReadOnly],
[Source].[HidePasswords]
[Source].[HidePasswords],
[Source].[Manage]
)
WHEN MATCHED AND (
[Target].[ReadOnly] != [Source].[ReadOnly]
OR [Target].[HidePasswords] != [Source].[HidePasswords]
OR [Target].[Manage] != [Source].[Manage]
) THEN
UPDATE SET [Target].[ReadOnly] = [Source].[ReadOnly],
[Target].[HidePasswords] = [Source].[HidePasswords]
[Target].[HidePasswords] = [Source].[HidePasswords],
[Target].[Manage] = [Source].[Manage]
WHEN NOT MATCHED BY SOURCE
AND [Target].[GroupId] = @Id THEN
DELETE
;
EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId
END
END

View File

@ -9,11 +9,12 @@ BEGIN
SELECT
CU.[CollectionId] Id,
CU.[ReadOnly],
CU.[HidePasswords]
CU.[HidePasswords],
CU.[Manage]
FROM
[dbo].[OrganizationUser] OU
INNER JOIN
[dbo].[CollectionUser] CU ON OU.[AccessAll] = 0 AND CU.[OrganizationUserId] = [OU].[Id]
WHERE
[OrganizationUserId] = @Id
END
END

View File

@ -33,13 +33,15 @@ BEGIN
[CollectionId],
[OrganizationUserId],
[ReadOnly],
[HidePasswords]
[HidePasswords],
[Manage]
)
SELECT
[Id],
@Id,
[ReadOnly],
[HidePasswords]
[HidePasswords],
[Manage]
FROM
@Collections
WHERE

View File

@ -24,7 +24,8 @@ BEGIN
[Target]
SET
[Target].[ReadOnly] = [Source].[ReadOnly],
[Target].[HidePasswords] = [Source].[HidePasswords]
[Target].[HidePasswords] = [Source].[HidePasswords],
[Target].[Manage] = [Source].[Manage]
FROM
[dbo].[CollectionUser] AS [Target]
INNER JOIN
@ -34,6 +35,7 @@ BEGIN
AND (
[Target].[ReadOnly] != [Source].[ReadOnly]
OR [Target].[HidePasswords] != [Source].[HidePasswords]
OR [Target].[Manage] != [Source].[Manage]
)
-- Insert
@ -43,7 +45,8 @@ BEGIN
[Source].[Id],
@Id,
[Source].[ReadOnly],
[Source].[HidePasswords]
[Source].[HidePasswords],
[Source].[Manage]
FROM
@Collections AS [Source]
INNER JOIN
@ -58,7 +61,7 @@ BEGIN
[CollectionId] = [Source].[Id]
AND [OrganizationUserId] = @Id
)
-- Delete
DELETE
CU

View File

@ -3,6 +3,7 @@
[GroupId] UNIQUEIDENTIFIER NOT NULL,
[ReadOnly] BIT NOT NULL,
[HidePasswords] BIT NOT NULL,
[Manage] BIT NOT NULL CONSTRAINT D_CollectionGroup_Manage DEFAULT (0),
CONSTRAINT [PK_CollectionGroup] PRIMARY KEY CLUSTERED ([CollectionId] ASC, [GroupId] ASC),
CONSTRAINT [FK_CollectionGroup_Collection] FOREIGN KEY ([CollectionId]) REFERENCES [dbo].[Collection] ([Id]),
CONSTRAINT [FK_CollectionGroup_Group] FOREIGN KEY ([GroupId]) REFERENCES [dbo].[Group] ([Id]) ON DELETE CASCADE

View File

@ -3,6 +3,7 @@
[OrganizationUserId] UNIQUEIDENTIFIER NOT NULL,
[ReadOnly] BIT NOT NULL,
[HidePasswords] BIT NOT NULL,
[Manage] BIT NOT NULL CONSTRAINT D_CollectionUser_Manage DEFAULT (0),
CONSTRAINT [PK_CollectionUser] PRIMARY KEY CLUSTERED ([CollectionId] ASC, [OrganizationUserId] ASC),
CONSTRAINT [FK_CollectionUser_Collection] FOREIGN KEY ([CollectionId]) REFERENCES [dbo].[Collection] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_CollectionUser_OrganizationUser] FOREIGN KEY ([OrganizationUserId]) REFERENCES [dbo].[OrganizationUser] ([Id])

View File

@ -1,5 +1,6 @@
CREATE TYPE [dbo].[SelectionReadOnlyArray] AS TABLE (
[Id] UNIQUEIDENTIFIER NOT NULL,
[ReadOnly] BIT NOT NULL,
[HidePasswords] BIT NOT NULL);
[HidePasswords] BIT NOT NULL,
[Manage] BIT NOT NULL);