feat(auth): replace hand-rolled auth with Ory Kratos — phase 2 backend
Delegates all credential management (login, register, password reset, email verification, social sign-in) to Ory Kratos. The Go API now acts as a resource server: the new KratosAuth middleware validates sessions against the Kratos whoami endpoint, writes the local User mirror into Echo context, and all existing domain handlers continue working unchanged. Hand-rolled token auth, AuthToken model, apple_auth/ google_auth services, and the auth refresh flow are removed. Tests are updated to use the fake-token middleware pattern so existing integration assertions require no rewrite. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,14 @@ import (
|
||||
"github.com/treytartt/honeydue-api/internal/validator"
|
||||
)
|
||||
|
||||
// authUserKey and authTokenKey mirror middleware.AuthUserKey / middleware.AuthTokenKey.
|
||||
// We duplicate the string constants here to avoid an import cycle
|
||||
// (testutil <- middleware <- repositories <- testutil).
|
||||
const (
|
||||
authUserKey = "auth_user"
|
||||
authTokenKey = "auth_token"
|
||||
)
|
||||
|
||||
var (
|
||||
i18nOnce sync.Once
|
||||
testDBCounter uint64
|
||||
@@ -52,9 +60,6 @@ func SetupTestDB(t *testing.T) *gorm.DB {
|
||||
err = db.AutoMigrate(
|
||||
&models.User{},
|
||||
&models.UserProfile{},
|
||||
&models.AuthToken{},
|
||||
&models.ConfirmationCode{},
|
||||
&models.PasswordResetCode{},
|
||||
&models.AdminUser{},
|
||||
&models.Residence{},
|
||||
&models.ResidenceType{},
|
||||
@@ -73,8 +78,6 @@ func SetupTestDB(t *testing.T) *gorm.DB {
|
||||
&models.NotificationPreference{},
|
||||
&models.APNSDevice{},
|
||||
&models.GCMDevice{},
|
||||
&models.AppleSocialAuth{},
|
||||
&models.GoogleSocialAuth{},
|
||||
&models.TaskReminderLog{},
|
||||
&models.UserSubscription{},
|
||||
&models.SubscriptionSettings{},
|
||||
@@ -177,29 +180,24 @@ func ParseJSONArray(t *testing.T, body []byte) []map[string]interface{} {
|
||||
return result
|
||||
}
|
||||
|
||||
// CreateTestUser creates a test user in the database
|
||||
func CreateTestUser(t *testing.T, db *gorm.DB, username, email, password string) *models.User {
|
||||
// CreateTestUser creates a test user in the database.
|
||||
// password is accepted for API compatibility but ignored — Kratos owns credentials.
|
||||
// A synthetic KratosID is generated so the user satisfies the unique-index constraint.
|
||||
func CreateTestUser(t *testing.T, db *gorm.DB, username, email, _ string) *models.User {
|
||||
t.Helper()
|
||||
user := &models.User{
|
||||
KratosID: "test-kratos-" + username,
|
||||
Username: username,
|
||||
Email: email,
|
||||
IsActive: true,
|
||||
}
|
||||
err := user.SetPassword(password)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = db.Create(user).Error
|
||||
err := db.Create(user).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
return user
|
||||
}
|
||||
|
||||
// CreateTestToken creates an auth token for a user
|
||||
func CreateTestToken(t *testing.T, db *gorm.DB, userID uint) *models.AuthToken {
|
||||
token, err := models.GetOrCreateToken(db, userID)
|
||||
require.NoError(t, err)
|
||||
return token
|
||||
}
|
||||
|
||||
// CreateTestResidenceType creates a test residence type
|
||||
func CreateTestResidenceType(t *testing.T, db *gorm.DB, name string) *models.ResidenceType {
|
||||
rt := &models.ResidenceType{Name: name}
|
||||
@@ -362,12 +360,15 @@ func AssertStatusCode(t *testing.T, w *httptest.ResponseRecorder, expected int)
|
||||
require.Equal(t, expected, w.Code, "unexpected status code: %s", w.Body.String())
|
||||
}
|
||||
|
||||
// MockAuthMiddleware creates middleware that sets a test user in context
|
||||
// MockAuthMiddleware creates middleware that sets a test user in context.
|
||||
// Uses the same context keys as KratosAuth (authUserKey / authTokenKey) so
|
||||
// handlers are unaware of the swap. The constants are duplicated here to
|
||||
// avoid an import cycle (testutil <- middleware <- repositories <- testutil).
|
||||
func MockAuthMiddleware(user *models.User) echo.MiddlewareFunc {
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
c.Set("auth_user", user)
|
||||
c.Set("auth_token", "test-token")
|
||||
c.Set(authUserKey, user)
|
||||
c.Set(authTokenKey, "test-token")
|
||||
return next(c)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user