fix(tenant): reuse existing Logto users and clean up on delete
Create: if admin email matches an existing Logto user, add them to the tenant org instead of creating a duplicate account. Only creates a new user when no match is found and a password is provided. Delete: before deleting the Logto org, list its members. After org deletion, delete tenant-only users (those with no remaining org memberships). Users who belong to other orgs are preserved. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -104,18 +104,34 @@ public class VendorTenantService {
|
||||
if (tenant.getLogtoOrgId() != null && logtoClient.isAvailable()) {
|
||||
String ownerRoleId = logtoClient.findOrgRoleIdByName("owner");
|
||||
|
||||
// Create tenant admin (email is the primary identity)
|
||||
if (request.adminEmail() != null && request.adminPassword() != null) {
|
||||
// Create or find tenant admin (email is the primary identity)
|
||||
if (request.adminEmail() != null) {
|
||||
try {
|
||||
String email = request.adminEmail();
|
||||
// Check if user already exists in Logto (e.g., platform admin or self-registered user)
|
||||
var existingUser = logtoClient.findUserByEmail(email);
|
||||
String userId;
|
||||
if (existingUser != null) {
|
||||
userId = String.valueOf(existingUser.get("id"));
|
||||
log.info("User '{}' already exists ({}), adding to tenant org", email, userId);
|
||||
} else if (request.adminPassword() != null) {
|
||||
String username = request.adminUsername();
|
||||
if (username == null || username.isBlank()) {
|
||||
username = email.substring(0, email.indexOf('@'));
|
||||
}
|
||||
String userId = logtoClient.createUserWithPassword(
|
||||
userId = logtoClient.createUserWithPassword(
|
||||
username, request.adminPassword(),
|
||||
tenant.getLogtoOrgId(), ownerRoleId);
|
||||
null, null);
|
||||
logtoClient.updateUserProfile(userId, Map.of("primaryEmail", email));
|
||||
} else {
|
||||
userId = null;
|
||||
}
|
||||
if (userId != null) {
|
||||
logtoClient.addUserToOrganization(tenant.getLogtoOrgId(), userId);
|
||||
if (ownerRoleId != null) {
|
||||
logtoClient.assignOrganizationRole(tenant.getLogtoOrgId(), userId, ownerRoleId);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("Failed to create admin user for tenant {}: {}", tenant.getSlug(), e.getMessage());
|
||||
}
|
||||
@@ -364,10 +380,26 @@ public class VendorTenantService {
|
||||
// Revoke license
|
||||
licenseService.revokeLicense(tenantId, actorId);
|
||||
|
||||
// Delete Logto org
|
||||
// Delete Logto org and clean up tenant-only users
|
||||
if (logtoClient.isAvailable() && tenant.getLogtoOrgId() != null) {
|
||||
try {
|
||||
// List org members before deleting the org
|
||||
var members = logtoClient.listOrganizationMembers(tenant.getLogtoOrgId());
|
||||
logtoClient.deleteOrganization(tenant.getLogtoOrgId());
|
||||
|
||||
// Delete users that have no other org memberships (tenant-only users)
|
||||
for (var member : members) {
|
||||
String userId = String.valueOf(member.get("id"));
|
||||
try {
|
||||
var orgs = logtoClient.getUserOrganizations(userId);
|
||||
if (orgs.isEmpty()) {
|
||||
logtoClient.deleteUser(userId);
|
||||
log.info("Deleted tenant-only Logto user {} for tenant {}", userId, tenant.getSlug());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("Failed to clean up Logto user {} for tenant {}: {}", userId, tenant.getSlug(), e.getMessage());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("Failed to delete Logto org for tenant {}: {}", tenant.getSlug(), e.getMessage());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user