Clear conflicting external_id when enrolling manual profile into SCIM
When a SCIM provider sends CreateUser for a user whose email matches an existing manual profile, but another profile already holds that external_id (e.g. created by a prior CreateUser with a different email), clear the conflicting external_id before enrolling the manual profile. Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
@@ -1396,6 +1396,42 @@ WHERE
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *MembershipProfile) ClearExternalID(
|
||||||
|
ctx context.Context,
|
||||||
|
conn pg.Conn,
|
||||||
|
scope Scoper,
|
||||||
|
externalID string,
|
||||||
|
organizationID gid.GID,
|
||||||
|
) error {
|
||||||
|
q := `
|
||||||
|
UPDATE iam_membership_profiles
|
||||||
|
SET
|
||||||
|
external_id = NULL,
|
||||||
|
updated_at = @updated_at
|
||||||
|
WHERE
|
||||||
|
%s
|
||||||
|
AND external_id = @external_id
|
||||||
|
AND organization_id = @organization_id
|
||||||
|
AND id != @exclude_id
|
||||||
|
`
|
||||||
|
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||||
|
|
||||||
|
args := pgx.NamedArgs{
|
||||||
|
"external_id": externalID,
|
||||||
|
"organization_id": organizationID,
|
||||||
|
"exclude_id": p.ID,
|
||||||
|
"updated_at": time.Now(),
|
||||||
|
}
|
||||||
|
maps.Copy(args, scope.SQLArguments())
|
||||||
|
|
||||||
|
_, err := conn.Exec(ctx, q, args)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot clear external id: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (p *MembershipProfile) Delete(
|
func (p *MembershipProfile) Delete(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
conn pg.Conn,
|
conn pg.Conn,
|
||||||
|
|||||||
@@ -244,6 +244,18 @@ func (s *Service) CreateUser(
|
|||||||
return scimerrors.ScimErrorUniqueness
|
return scimerrors.ScimErrorUniqueness
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if externalIdPtr != nil {
|
||||||
|
if err := profile.ClearExternalID(
|
||||||
|
ctx,
|
||||||
|
tx,
|
||||||
|
scope,
|
||||||
|
*externalIdPtr,
|
||||||
|
config.OrganizationID,
|
||||||
|
); err != nil {
|
||||||
|
return fmt.Errorf("cannot clear conflicting external id: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
profile.Source = coredata.ProfileSourceSCIM
|
profile.Source = coredata.ProfileSourceSCIM
|
||||||
profile.State = profileState
|
profile.State = profileState
|
||||||
profile.FullName = attrs.FullName
|
profile.FullName = attrs.FullName
|
||||||
|
|||||||
Reference in New Issue
Block a user