Skip to content

Commit 28570b4

Browse files
authored
Fix issues with removal of user logins on change to external login provider configuration (13) (#19511)
* Ensure to delete related tokens when removing logins for removed external login providers. Ensure to avoid removing logins for members. * Applied suggestions from code review. * Removed unnecessary <= check.
1 parent 1d6e7f1 commit 28570b4

File tree

1 file changed

+25
-11
lines changed

1 file changed

+25
-11
lines changed

src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ExternalLoginRepository.cs

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,17 @@ public void DeleteUserLogins(Guid userOrMemberKey) =>
5757
Database.Delete<ExternalLoginDto>("WHERE userOrMemberKey=@userOrMemberKey", new { userOrMemberKey });
5858

5959
/// <inheritdoc />
60-
public void DeleteUserLoginsForRemovedProviders(IEnumerable<string> currentLoginProviders) =>
61-
Database.Execute(Sql()
62-
.Delete<ExternalLoginDto>()
63-
.WhereNotIn<ExternalLoginDto>(x => x.LoginProvider, currentLoginProviders));
60+
public void DeleteUserLoginsForRemovedProviders(IEnumerable<string> currentLoginProviders)
61+
{
62+
Sql<ISqlContext> sql = Sql()
63+
.Select<ExternalLoginDto>(x => x.Id)
64+
.From<ExternalLoginDto>()
65+
.Where<ExternalLoginDto>(x => !x.LoginProvider.StartsWith(Constants.Security.MemberExternalAuthenticationTypePrefix)) // Only remove external logins relating to backoffice users, not members.
66+
.WhereNotIn<ExternalLoginDto>(x => x.LoginProvider, currentLoginProviders);
67+
68+
var toDelete = Database.Query<ExternalLoginDto>(sql).Select(x => x.Id).ToList();
69+
DeleteExternalLogins(toDelete);
70+
}
6471

6572
/// <inheritdoc />
6673
public void Save(Guid userOrMemberKey, IEnumerable<IExternalLogin> logins)
@@ -100,13 +107,7 @@ public void Save(Guid userOrMemberKey, IEnumerable<IExternalLogin> logins)
100107
}
101108

102109
// do the deletes, updates and inserts
103-
if (toDelete.Count > 0)
104-
{
105-
// Before we can remove the external login, we must remove the external login tokens associated with that external login,
106-
// otherwise we'll get foreign key constraint errors
107-
Database.DeleteMany<ExternalLoginTokenDto>().Where(x => toDelete.Contains(x.ExternalLoginId)).Execute();
108-
Database.DeleteMany<ExternalLoginDto>().Where(x => toDelete.Contains(x.Id)).Execute();
109-
}
110+
DeleteExternalLogins(toDelete);
110111

111112
foreach (KeyValuePair<int, IExternalLogin> u in toUpdate)
112113
{
@@ -116,6 +117,19 @@ public void Save(Guid userOrMemberKey, IEnumerable<IExternalLogin> logins)
116117
Database.InsertBulk(toInsert.Select(i => ExternalLoginFactory.BuildDto(userOrMemberKey, i)));
117118
}
118119

120+
private void DeleteExternalLogins(List<int> externalLoginIds)
121+
{
122+
if (externalLoginIds.Count == 0)
123+
{
124+
return;
125+
}
126+
127+
// Before we can remove the external login, we must remove the external login tokens associated with that external login,
128+
// otherwise we'll get foreign key constraint errors
129+
Database.DeleteMany<ExternalLoginTokenDto>().Where(x => externalLoginIds.Contains(x.ExternalLoginId)).Execute();
130+
Database.DeleteMany<ExternalLoginDto>().Where(x => externalLoginIds.Contains(x.Id)).Execute();
131+
}
132+
119133
/// <inheritdoc />
120134
public void Save(Guid userOrMemberKey, IEnumerable<IExternalLoginToken> tokens)
121135
{

0 commit comments

Comments
 (0)