We are currently in the process of migrating a large project from Concrete CMS 8.5.20 to 9.3.7. It has been a complex journey due to many custom tools we’ve developed, but we are almost there.
We are facing a challenge with Authentication Types. In version 8, we used an add-on for LDAP authentication. In version 9, we have switched to the native Google Authentication.
The issue:
New users can log in via Google without any problems.
However, for users migrated from v8 (who previously used LDAP), when they try to log in via Google, they get the following error:
“A user account already exists for this email, please log in and attach from your account page.”
It seems Concrete is attempting to register them as new users because it doesn’t find a link between the Google identity and the existing row in the Users table. Since we have a large number of users, asking them to log in manually and “attach” the account is not a viable option.
My questions:
Is there a specific table in v9 where these external identity mappings are stored? (We want to check if there are leftovers from the LDAP add-on or if we can pre-populate the mapping).
Is there a configuration flag (via concrete.php) to allow “auto-linking” based on email address during the first Google login?
Any guidance on which table or service handles this link in v9 would be greatly appreciated.
From what I understand, they were already working on that addon before I was trying to seek a solution. But yeah, the whole LDAP/AD v8 to v9 situation is… less than ideal, argh.
As for translating v8 LDAP user accounts to v9 Google (Workspace) Auth, that’s probably something @andrew can be more suited to answering. Sounds like a tricky one!
@mhawke: Thanks for the link to the Macareux addon. For now, I want to exhaust all possibilities with Google Authentication first, as it’s our preferred path. If we hit a dead end, I’ll definitely look into the LDAP addon as a plan B.
@BloodyIron: You nailed it—the transition is indeed “less than ideal” due to those existing records. I’m glad you mentioned @andrew, as some insight into the core logic would be gold right now.
In the meantime, I’ve been digging into the database and I’d like to share what I’ve found, in case it helps others:
The mapping between a Concrete user and the external service happens in the OauthUserMap table. It has three key fields:
user_id: Corresponds to the uID in the Users table.
namespace: Corresponds to the authTypeHandle (in this case, ‘google’).
binding: This is the unique Google internal ID (a string of about 21 digits).
Since this ID is immutable (unlike the email address), Concrete uses it to ensure the identity match.
Our next step is to explore if we can pre-populate this table via script.
Does anyone see any potential side effects or “gotchas” by manually populating this table?