feat(authentication): [DRAFT] Refactor Authentication and add Facebook Login#6720
feat(authentication): [DRAFT] Refactor Authentication and add Facebook Login#6720Neilk1021 wants to merge 25 commits into
Conversation
…lusion of front end components I forgot to add to the VCS.
# Conflicts: # config-service/src/test/scala/org/apache/texera/service/resource/ConfigResourceAuthSpec.scala # sql/changelog.xml
Automated Reviewer SuggestionsBased on the
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #6720 +/- ##
============================================
+ Coverage 74.65% 76.42% +1.76%
+ Complexity 3438 3435 -3
============================================
Files 1160 1166 +6
Lines 45793 46094 +301
Branches 5069 5116 +47
============================================
+ Hits 34189 35228 +1039
+ Misses 9953 9322 -631
+ Partials 1651 1544 -107
*This pull request uses carry forward flags. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
📊 Arrow Flight E2E bench(no arrow-flight-e2e.csv in artifact) |
|
Please separate the consolidated login page, the authentication refactor, and the Facebook Login implementation into three separate PRs. These changes are independent and can be developed and reviewed separately without any dependencies on one another. |
What changes were proposed in this PR?
Refactors authentication to decouple identity from credentials: all auth material moves out of the
"user"table into a dedicatedauth_providertable, external-provider login (Google, Facebook) is unified behind a single provisioning path, and Facebook OAuth is added as a new login option.Schema split — new
auth_providertable. The"user"table dropspassword,google_id,google_avatar, and the oldck_nulltestCHECK, and gains a provider-neutralavatarcolumn. A newprovider_type_enum ('LOCAL','GOOGLE','FACEBOOK')andauth_provider (uid, provider_type, provider_id, password, created_at)table are added, withPRIMARY KEY (uid, provider_type), an FK to"user"(uid) ON DELETE CASCADE,uq_provider_identity UNIQUE (provider_type, provider_id), andck_provider_credential(LOCAL ⇒ password set / provider_id null; non-LOCAL ⇒ provider_id set / password null) replacingck_nulltest. Liquibase migrationsql/updates/29.sql(registered insql/changelog.xml) creates the enum + table and backfillsLOCALrows fromuser.passwordandGOOGLErows fromuser.google_id. The jOOQAuthProvidertable/dao/pojo andProviderTypeEnumare regenerated from the new DDL.Shared
ExternalAuthProvisionerabstraction. Newobject ExternalAuthProvisionerthat both Google and Facebook login route through. Given anExternalProfile(providerType, providerId, name, email, avatar: Option[String]),loginOrProvisionruns a single transaction that resolves the user by provider identity → else by email → else creates anINACTIVEuser, then upserts the provider row (guarding the(uid, provider_type)PK against collision) and refreshesname/email/avatar.avataris optional so a Facebook login (no avatar) never clobbers an avatar set by Google.Facebook OAuth (new).
FacebookAuthResourceat/auth/facebook(GET /clientid,POST /login) verifies the access token via the Graph APIdebug_token+/meendpoints, falling back to{id}@facebook.localwhen Facebook returns no email. Config gainsfacebook.clientId/facebook.appSecret(envsUSER_SYS_FACEBOOK_CLIENT_ID/USER_SYS_FACEBOOK_APP_SECRET) with matchingUserSystemConfigaccessors.Google + local login retargeted to the new schema.
GoogleAuthResourcedrops its inline DAO logic and delegates toExternalAuthProvisioner. Local login (AuthResource) now joinsauth_provideronPROVIDER_TYPE = LOCALand checks the hashed password there; registration and admin bootstrap write theuserrow + aLOCALprovider row atomically via a new privateInsertUser.AdminUserResource/UserResourceand related resources rebindavatarontouser.JWT claims simplified.
JwtAuth.jwtClaimsemits a singleavatarclaim instead ofgoogleId/googleAvatar;JwtParserandSessionUserare updated to match (SessionUser.getGoogleIdremoved), constructingUservia setters rather than the old positional constructor.Frontend. New consolidated login page (
texera-login.component) with tabbed local sign-in/sign-up plus Google and Facebook buttons; newFacebookAuthService; theUsertype andauth.serviceJWT decode swapgoogleId/googleAvatarforavatar;app.moduleregisters aFacebookLoginProvideralongside Google, resolving both client ids in parallel.Tests. New:
ExternalAuthProvisionerSpec(embedded-Postgres integration over the full provisioning matrix),facebook-auth.service.spec.ts,texera-login.component.spec.ts. Updated:JwtAuth/JwtParser/SessionUser/UserAuthenticatorspecs for the avatar-claim change, plus a repo-wide sweep droppinguser.setPassword(...)from existing specs to match the new schema.Any related issues, documentation, discussions?
Closes #6718. The design rationale and coupling points that drove this split (the
jwtClaimsprovider fields, theck_nulltestCHECK, the DAO-per-resource pattern, and the frontendUsershape) are documented inauth-split-notes.md. No other tracked issues.How was this PR tested?
Auth-specific suites were run and are green:
sbt, ScalaTest):ExternalAuthProvisionerSpecruns against embedded Postgres (MockTexeraDBloads the realsql/texera_ddl.sql, so theauth_providerconstraints are live) — 7/7, covering new-identity provisioning, returning-identity idempotency, profile refresh, the Facebook-avatar-not-clobbered case, email-match linking, and provider-id upsert.JwtAuthSpec— 5/5, including the newavatarclaim.ng test/ Vitest):facebook-auth.service.spec.ts+texera-login.component.spec.ts— 22/22, covering local login/register validation and navigation, social sign-in routing (Google vs Facebook), the confirm-password validator, and error paths.Commands:
A full
sbt clean compile test+ complete frontend suite run is still recommended before merge (the schema-matching spec sweep touches many modules).Was this PR authored or co-authored using generative AI tooling?
Yes. This PR was co-authored with Claude Opus 4.8. The overall architecture and design decisions were the author's; Claude assisted with implementing much of the code and the accompanying tests.