We use the Statamic control panel with Google Workspace as our identity provider for a small internal team. We expected to create users in the CP and have them sign in with Google — but that is not how OAuth currently behaves, and I wanted to check whether making it possible is something you would consider.
Current behaviour. Provider::findUser() resolves users by the provider's numeric ID (User::findByOAuthId()). An admin-created user whose email exactly matches the Google account is not matched; they land on /auth/unauthorized until they first sign in with a password and connect the provider from their account page. create_user => true does not help either — createUser() throws OAuthEmailExistsException when the email already exists.
Why this is awkward. Every user still needs a password to bootstrap, and email_login_enabled has to stay on during onboarding. In practice people never do the manual connect step, which leaves a provider button on the login page that nobody can use. This is social-login semantics (link an account you already own) rather than SSO semantics (the identity provider asserts who you are). Both are legitimate; we just have no way to opt into the second.
Possible approaches. (a) An opt-in match_by_email => false flag: when enabled, findUser() falls back to User::findByEmail() and stores the provider ID on first login. Opt-in because it only makes sense when the operator trusts the provider's email claim — e.g. a Google Workspace app with an Internal consent screen. (b) A hook on the find path: v2 had a FindingUser event that allowed this in userland; v6 has no equivalent, since withUser and withUserData both run only on the create path. Today the only route is subclassing Statamic\OAuth\Manager and Provider, which is fragile across upgrades. Either works for us; (b) is arguably the smaller change.
Related: #1006 asked for OAuth to "only match with existing users rather than creating new ones". The creation half shipped as create_user; the matching half is what is still missing.
Thanks for considering it — and thanks for Statamic generally.
We use the Statamic control panel with Google Workspace as our identity provider for a small internal team. We expected to create users in the CP and have them sign in with Google — but that is not how OAuth currently behaves, and I wanted to check whether making it possible is something you would consider.
Current behaviour.
Provider::findUser()resolves users by the provider's numeric ID (User::findByOAuthId()). An admin-created user whose email exactly matches the Google account is not matched; they land on/auth/unauthorizeduntil they first sign in with a password and connect the provider from their account page.create_user => truedoes not help either —createUser()throwsOAuthEmailExistsExceptionwhen the email already exists.Why this is awkward. Every user still needs a password to bootstrap, and
email_login_enabledhas to stay on during onboarding. In practice people never do the manual connect step, which leaves a provider button on the login page that nobody can use. This is social-login semantics (link an account you already own) rather than SSO semantics (the identity provider asserts who you are). Both are legitimate; we just have no way to opt into the second.Possible approaches. (a) An opt-in
match_by_email => falseflag: when enabled,findUser()falls back toUser::findByEmail()and stores the provider ID on first login. Opt-in because it only makes sense when the operator trusts the provider's email claim — e.g. a Google Workspace app with anInternalconsent screen. (b) A hook on the find path: v2 had aFindingUserevent that allowed this in userland; v6 has no equivalent, sincewithUserandwithUserDataboth run only on the create path. Today the only route is subclassingStatamic\OAuth\ManagerandProvider, which is fragile across upgrades. Either works for us; (b) is arguably the smaller change.Related: #1006 asked for OAuth to "only match with existing users rather than creating new ones". The creation half shipped as
create_user; the matching half is what is still missing.Thanks for considering it — and thanks for Statamic generally.