I'm stuck in deleting ThirdPartyAccountLink record in RegistrationHandler apex class for SSO. After contacting salesforce support I got delete access on ThirdPartyAccountLink object.
My class is working as expected when user login first time but when I change the user id for that user and try to login it gave me below error: "Delete failed. First exception on row 0 with id 0Jr0v00000000FQCAY; first error: UNKNOWN_EXCEPTION, An unexpected error occurred. Please include this ErrorId if you contact support: 788178633-264969 (188355293): []"
After changing Id of User A from xxx to yyy, then User A should land on profile of user having YYY id. Currently even after changing Id User A still landing on profile of xxx id.
Please let me know if any confusion is there.
Code :
global class RegistrationHandlerSSO implements Auth.RegistrationHandler {
global User createUser(Id portalId, Auth.UserData data) {
//Querying all users
List<User> userList = new List<User>([
SELECT Id
FROM User
WHERE Id =: data.attributeMap.get('alt_username') AND
IsActive = true and
SFDC_License_Type__c = 'Customer Community Plus Login'
]);
User uId;
boolean generateUser = true;
for (User u:userList) {
//Checking that current user is already there in system or not.
//If yes, performing below operations
if (u.Id == data.attributeMap.get('alt_username')) {
Id userIds= u.Id;
//Fetch ThirdPartyAccountLink records associated with this user and delete it using
// Auth.AuthToken.revokeAccess() method
List<ThirdPartyAccountLink> thirdPartyActLink = new List<ThirdPartyAccountLink>(
[SELECT Handle, Provider, SsoProviderName, UserId, ThirdPartyAccountLinkKey,
user.contact.Account.Id, remoteIdentifier, SsoProvider.id
FROM ThirdPartyAccountLink
WHERE UserId =: userIds
LIMIT 1]);
if(!thirdPartyActLink.isEmpty())
Auth.AuthToken.revokeAccess(
thirdPartyActLink[0].SsoProvider.id,
thirdPartyActLink[0].Provider,
thirdPartyActLink[0].UserId,
thirdPartyActLink[0].remoteIdentifier
);
//Marking this boolean as false to avoid creating new user
generateUser = false;
//if user is aleadythere in system paas it to updateUser() method to avoid linking
// Id change
updateUser(u.Id, portalId, data);
uId = u;
}
}
return(uId);
}
global void updateUser(Id userId, Id portalId, Auth.UserData data) {
// checking for ID whether it same as logged in community user. if not then update it
if(userId != data.attributeMap.get('alt_username')) {
userId = data.attributeMap.get('alt_username');
}
List<User> userList = new List<User>([
SELECT Id
FROM User
WHERE Id =: userId
]);
for (User u:userList) {
List<ThirdPartyAccountLink> thirdPartyActLink = new List<ThirdPartyAccountLink>(
[SELECT Handle, Provider, SsoProviderName, UserId, ThirdPartyAccountLinkKey,
user.contact.Account.Id, remoteIdentifier, SsoProvider.id
FROM ThirdPartyAccountLink
WHERE UserId =: u.Id
LIMIT 1]);
if(!thirdPartyActLink.isEmpty()) {
try {
Auth.AuthToken.revokeAccess(
thirdPartyActLink[0].SsoProvider.id,
thirdPartyActLink[0].Provider,
thirdPartyActLink[0].UserId,
thirdPartyActLink[0].remoteIdentifier
);
} catch (System.DmlException e) {
System.debug('@@@Error while deleteImmediate::'+e);
System.Debug('Cause: ' + e.getCause());
System.Debug('TypeName: ' + e.getTypeName());
System.Debug('getDmlFieldNames: ' + e.getDmlFieldNames(0));
System.Debug('getDmlFields: ' + e.getDmlFields(0));
System.Debug('getDmlId: ' + e.getDmlId(0));
System.Debug('getDmlMessage: ' + e.getDmlMessage(0));
System.Debug('getDmlType: ' + e.getDmlType(0));
System.Debug('getNumDml: ' + e.getNumDml());
System.Debug('Message: ' + e.getMessage());
}
}
User u2 = new User(id=u.Id);
update(u2);
}
}
}
Can someone please help me on this? Any help will be appreciated.
createUser(...)
. If the User record already exists and you want to use that record instead of creating a new one, locate that record and return it.