feat(14.1-01): add OAuth identities table and empty-list Index
- Model golem15_user_oauth_identities with Encrypted tokens and empty Fillable
- gormigrate 202610050001 with both unique indexes, cascade FK, and jsonb profile_data
- OAuthIdentitiesIndex returns {"data":[]} for a signed-in caller with no rows
This commit is contained in:
67
controllers/oauth_identities.go
Normal file
67
controllers/oauth_identities.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"git.golem15.com/golem15/sm-user-plugin/models"
|
||||
"git.golem15.com/golem15/summercms/modules/backpack"
|
||||
"git.golem15.com/golem15/summercms/modules/bouncer"
|
||||
"git.golem15.com/golem15/summercms/modules/wire"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// OAuthIdentitiesOptions configures host-mounted list/unlink handlers.
|
||||
// Providers defaults to google, facebook, github when nil or empty.
|
||||
// WriteNotFound is injected by the host so 404 bodies match that app.
|
||||
type OAuthIdentitiesOptions struct {
|
||||
Providers []string
|
||||
WriteNotFound func(http.ResponseWriter, *http.Request)
|
||||
}
|
||||
|
||||
// OAuthIdentitiesIndex lists the caller's linked OAuth providers.
|
||||
func OAuthIdentitiesIndex(app *backpack.App) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
db, user, ok := oauthIdentityDeps(w, r, app)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var rows []models.OAuthIdentity
|
||||
if err := db.WithContext(r.Context()).
|
||||
Where("user_id = ?", user.ID).
|
||||
Order("provider").
|
||||
Find(&rows).Error; err != nil {
|
||||
writeOpaque500(w)
|
||||
return
|
||||
}
|
||||
data := make([]map[string]any, 0, len(rows))
|
||||
for i := range rows {
|
||||
item := map[string]any{
|
||||
"provider": rows[i].Provider,
|
||||
"linked_at": nil,
|
||||
}
|
||||
if rows[i].LinkedAt != nil {
|
||||
item["linked_at"] = &wire.Time{Time: rows[i].LinkedAt.UTC()}
|
||||
}
|
||||
data = append(data, item)
|
||||
}
|
||||
writeJSON(w, http.StatusOK, map[string]any{"data": wire.Slice(data)})
|
||||
}
|
||||
}
|
||||
|
||||
func oauthIdentityDeps(w http.ResponseWriter, r *http.Request, app *backpack.App) (*gorm.DB, *bouncer.Principal, bool) {
|
||||
if app == nil {
|
||||
writeOpaque500(w)
|
||||
return nil, nil, false
|
||||
}
|
||||
db, ok := app.Lookup[*gorm.DB]()
|
||||
if !ok || db == nil {
|
||||
writeOpaque500(w)
|
||||
return nil, nil, false
|
||||
}
|
||||
user, ok := bouncer.User(r.Context())
|
||||
if !ok || user == nil || user.ID == 0 {
|
||||
writeUnauthorized(w)
|
||||
return nil, nil, false
|
||||
}
|
||||
return db, user, true
|
||||
}
|
||||
Reference in New Issue
Block a user