diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index cdbf3d5..6876572 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,13 +4,40 @@
-
-
-
-
-
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -45,33 +72,33 @@
- {
- "keyToString": {
- "DefaultGoTemplateProperty": "Go File",
- "Go Build.Backend.executor": "Run",
- "Go 构建.Backend.executor": "Run",
- "RunOnceActivity.ShowReadmeOnStart": "true",
- "RunOnceActivity.go.formatter.settings.were.checked": "true",
- "RunOnceActivity.go.migrated.go.modules.settings": "true",
- "RunOnceActivity.go.modules.automatic.dependencies.download": "true",
- "RunOnceActivity.go.modules.go.list.on.any.changes.was.set": "true",
- "git-widget-placeholder": "features/consul",
- "go.import.settings.migrated": "true",
- "go.sdk.automatically.set": "true",
- "last_opened_file_path": "/Users/littlesheep",
- "node.js.detected.package.eslint": "true",
- "node.js.selected.package.eslint": "(autodetect)",
- "nodejs_package_manager_path": "npm",
- "run.code.analysis.last.selected.profile": "pProject Default",
- "settings.editor.selected.configurable": "preferences.pluginManager",
- "vue.rearranger.settings.migration": "true"
+
+}]]>
@@ -81,11 +108,11 @@
+
+
-
-
@@ -147,7 +174,6 @@
-
@@ -172,7 +198,8 @@
-
+
+
true
diff --git a/pkg/hyper/auth_adaptor.go b/pkg/hyper/auth_adaptor.go
index d224f15..f483560 100644
--- a/pkg/hyper/auth_adaptor.go
+++ b/pkg/hyper/auth_adaptor.go
@@ -12,7 +12,6 @@ const CookieAtk = "__hydrogen_atk"
const CookieRtk = "__hydrogen_rtk"
func (v *HyperConn) AuthMiddleware(c *fiber.Ctx) error {
- // Detect token
var atk string
if cookie := c.Cookies(CookieAtk); len(cookie) > 0 {
atk = cookie
@@ -42,7 +41,6 @@ func (v *HyperConn) AuthMiddleware(c *fiber.Ctx) error {
})
}
c.Locals("p_user", user)
- return nil
}
return c.Next()
diff --git a/pkg/internal/embed.go b/pkg/internal/embed.go
index 38dd3ff..7a0136b 100644
--- a/pkg/internal/embed.go
+++ b/pkg/internal/embed.go
@@ -2,5 +2,5 @@ package pkg
import "embed"
-//go:embed views/*
+//go:embed all:views/*
var FS embed.FS
diff --git a/pkg/internal/server/admin/badges_api.go b/pkg/internal/server/admin/badges_api.go
index bcfdc5b..4c7420a 100644
--- a/pkg/internal/server/admin/badges_api.go
+++ b/pkg/internal/server/admin/badges_api.go
@@ -2,16 +2,16 @@ package admin
import (
"fmt"
+ "git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
"git.solsynth.dev/hydrogen/passport/pkg/internal/database"
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
- "git.solsynth.dev/hydrogen/passport/pkg/internal/utils"
"github.com/gofiber/fiber/v2"
)
func grantBadge(c *fiber.Ctx) error {
- if err := utils.CheckPermissions(c, "AdminGrantBadges", true); err != nil {
+ if err := exts.EnsureGrantedPerm(c, "AdminGrantBadges", true); err != nil {
return err
}
@@ -21,7 +21,7 @@ func grantBadge(c *fiber.Ctx) error {
AccountID uint `json:"account_id"`
}
- if err := utils.BindAndValidate(c, &data); err != nil {
+ if err := exts.BindAndValidate(c, &data); err != nil {
return err
}
@@ -44,7 +44,7 @@ func grantBadge(c *fiber.Ctx) error {
}
func revokeBadge(c *fiber.Ctx) error {
- if err := utils.CheckPermissions(c, "AdminRevokeBadges", true); err != nil {
+ if err := exts.EnsureGrantedPerm(c, "AdminRevokeBadges", true); err != nil {
return err
}
diff --git a/pkg/internal/server/admin/index.go b/pkg/internal/server/admin/index.go
index ad11edc..099cb70 100644
--- a/pkg/internal/server/admin/index.go
+++ b/pkg/internal/server/admin/index.go
@@ -4,8 +4,8 @@ import (
"github.com/gofiber/fiber/v2"
)
-func MapAdminEndpoints(A *fiber.App, authMiddleware fiber.Handler) {
- admin := A.Group("/api/admin").Use(authMiddleware)
+func MapAdminEndpoints(A *fiber.App) {
+ admin := A.Group("/api/admin")
{
admin.Post("/badges", grantBadge)
admin.Delete("/badges/:badgeId", revokeBadge)
diff --git a/pkg/internal/server/accounts_api.go b/pkg/internal/server/api/accounts_api.go
similarity index 86%
rename from pkg/internal/server/accounts_api.go
rename to pkg/internal/server/api/accounts_api.go
index 4f64b82..8fbcc84 100644
--- a/pkg/internal/server/accounts_api.go
+++ b/pkg/internal/server/api/accounts_api.go
@@ -1,12 +1,11 @@
-package server
+package api
import (
"fmt"
+ "git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
"strconv"
"time"
- "git.solsynth.dev/hydrogen/passport/pkg/internal/utils"
-
"git.solsynth.dev/hydrogen/passport/pkg/internal/database"
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
@@ -16,7 +15,10 @@ import (
)
func getUserinfo(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
var data models.Account
if err := database.C.
@@ -47,7 +49,10 @@ func getUserinfo(c *fiber.Ctx) error {
}
func getEvents(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
take := c.QueryInt("take", 0)
offset := c.QueryInt("offset", 0)
@@ -76,7 +81,10 @@ func getEvents(c *fiber.Ctx) error {
}
func editUserinfo(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
var data struct {
Nick string `json:"nick" validate:"required,min=4,max=24"`
@@ -86,7 +94,7 @@ func editUserinfo(c *fiber.Ctx) error {
Birthday time.Time `json:"birthday"`
}
- if err := utils.BindAndValidate(c, &data); err != nil {
+ if err := exts.BindAndValidate(c, &data); err != nil {
return err
}
@@ -116,7 +124,10 @@ func editUserinfo(c *fiber.Ctx) error {
}
func killSession(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
id, _ := c.ParamsInt("ticketId", 0)
if err := database.C.Delete(&models.AuthTicket{}, &models.AuthTicket{
@@ -138,7 +149,7 @@ func doRegister(c *fiber.Ctx) error {
MagicToken string `json:"magic_token"`
}
- if err := utils.BindAndValidate(c, &data); err != nil {
+ if err := exts.BindAndValidate(c, &data); err != nil {
return err
} else if viper.GetBool("use_registration_magic_token") && len(data.MagicToken) <= 0 {
return fmt.Errorf("missing magic token in request")
@@ -167,7 +178,7 @@ func doRegisterConfirm(c *fiber.Ctx) error {
Code string `json:"code" validate:"required"`
}
- if err := utils.BindAndValidate(c, &data); err != nil {
+ if err := exts.BindAndValidate(c, &data); err != nil {
return err
}
diff --git a/pkg/internal/server/auth_api.go b/pkg/internal/server/api/auth_api.go
similarity index 93%
rename from pkg/internal/server/auth_api.go
rename to pkg/internal/server/api/auth_api.go
index 82722bd..4c8b24c 100644
--- a/pkg/internal/server/auth_api.go
+++ b/pkg/internal/server/api/auth_api.go
@@ -1,8 +1,8 @@
-package server
+package api
import (
"fmt"
- "git.solsynth.dev/hydrogen/passport/pkg/internal/utils"
+ "git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
"time"
"github.com/gofiber/fiber/v2"
@@ -16,7 +16,7 @@ func doAuthenticate(c *fiber.Ctx) error {
Password string `json:"password" validate:"required"`
}
- if err := utils.BindAndValidate(c, &data); err != nil {
+ if err := exts.BindAndValidate(c, &data); err != nil {
return err
}
@@ -48,7 +48,7 @@ func doMultiFactorAuthenticate(c *fiber.Ctx) error {
Code string `json:"code" validate:"required"`
}
- if err := utils.BindAndValidate(c, &data); err != nil {
+ if err := exts.BindAndValidate(c, &data); err != nil {
return err
}
@@ -85,7 +85,7 @@ func getToken(c *fiber.Ctx) error {
GrantType string `json:"grant_type" form:"grant_type"`
}
- if err := utils.BindAndValidate(c, &data); err != nil {
+ if err := exts.BindAndValidate(c, &data); err != nil {
return err
}
@@ -134,7 +134,7 @@ func getToken(c *fiber.Ctx) error {
return fiber.NewError(fiber.StatusBadRequest, "unsupported exchange token type")
}
- services.SetJwtCookieSet(c, access, refresh)
+ exts.SetAuthCookies(c, access, refresh)
return c.JSON(fiber.Map{
"id_token": access,
diff --git a/pkg/internal/server/avatar_api.go b/pkg/internal/server/api/avatar_api.go
similarity index 81%
rename from pkg/internal/server/avatar_api.go
rename to pkg/internal/server/api/avatar_api.go
index 8d1ce69..a650ad9 100644
--- a/pkg/internal/server/avatar_api.go
+++ b/pkg/internal/server/api/avatar_api.go
@@ -1,4 +1,4 @@
-package server
+package api
import (
"context"
@@ -7,20 +7,27 @@ import (
"git.solsynth.dev/hydrogen/passport/pkg/internal/database"
"git.solsynth.dev/hydrogen/passport/pkg/internal/gap"
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
+ "git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
- "git.solsynth.dev/hydrogen/passport/pkg/internal/utils"
"github.com/gofiber/fiber/v2"
"github.com/samber/lo"
)
func setAvatar(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
+
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
var data struct {
AttachmentID uint `json:"attachment" validate:"required"`
}
- if err := utils.BindAndValidate(c, &data); err != nil {
+ if err := exts.BindAndValidate(c, &data); err != nil {
return err
}
@@ -47,13 +54,16 @@ func setAvatar(c *fiber.Ctx) error {
}
func setBanner(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
var data struct {
AttachmentID uint `json:"attachment" validate:"required"`
}
- if err := utils.BindAndValidate(c, &data); err != nil {
+ if err := exts.BindAndValidate(c, &data); err != nil {
return err
}
diff --git a/pkg/internal/server/factors_api.go b/pkg/internal/server/api/factors_api.go
similarity index 97%
rename from pkg/internal/server/factors_api.go
rename to pkg/internal/server/api/factors_api.go
index 2bff580..98a7c46 100644
--- a/pkg/internal/server/factors_api.go
+++ b/pkg/internal/server/api/factors_api.go
@@ -1,4 +1,4 @@
-package server
+package api
import (
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
diff --git a/pkg/internal/server/friendships_api.go b/pkg/internal/server/api/friendships_api.go
similarity index 82%
rename from pkg/internal/server/friendships_api.go
rename to pkg/internal/server/api/friendships_api.go
index b7a87fb..d68482f 100644
--- a/pkg/internal/server/friendships_api.go
+++ b/pkg/internal/server/api/friendships_api.go
@@ -1,14 +1,17 @@
-package server
+package api
import (
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
+ "git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
- "git.solsynth.dev/hydrogen/passport/pkg/internal/utils"
"github.com/gofiber/fiber/v2"
)
func listFriendship(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
status := c.QueryInt("status", -1)
var err error
@@ -27,7 +30,10 @@ func listFriendship(c *fiber.Ctx) error {
}
func getFriendship(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
relatedId, _ := c.ParamsInt("relatedId", 0)
related, err := services.GetAccount(uint(relatedId))
@@ -43,7 +49,10 @@ func getFriendship(c *fiber.Ctx) error {
}
func makeFriendship(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
relatedName := c.Query("related")
relatedId, _ := c.ParamsInt("relatedId", 0)
@@ -72,14 +81,17 @@ func makeFriendship(c *fiber.Ctx) error {
}
func editFriendship(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
relatedId, _ := c.ParamsInt("relatedId", 0)
var data struct {
Status uint8 `json:"status"`
}
- if err := utils.BindAndValidate(c, &data); err != nil {
+ if err := exts.BindAndValidate(c, &data); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
@@ -103,7 +115,10 @@ func editFriendship(c *fiber.Ctx) error {
}
func deleteFriendship(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
relatedId, _ := c.ParamsInt("relatedId", 0)
related, err := services.GetAccount(uint(relatedId))
diff --git a/pkg/internal/server/api/index.go b/pkg/internal/server/api/index.go
new file mode 100644
index 0000000..64760a3
--- /dev/null
+++ b/pkg/internal/server/api/index.go
@@ -0,0 +1,90 @@
+package api
+
+import (
+ "git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
+ "github.com/gofiber/contrib/websocket"
+ "github.com/gofiber/fiber/v2"
+)
+
+func MapAPIs(app *fiber.App) {
+ app.Get("/.well-known", getMetadata)
+ app.Get("/.well-known/openid-configuration", getOidcConfiguration)
+
+ api := app.Group("/api").Name("API")
+ {
+ notify := api.Group("/notifications").Name("Notifications API")
+ {
+ notify.Get("/", getNotifications)
+ notify.Post("/subscribe", addNotifySubscriber)
+ notify.Put("/batch/read", markNotificationReadBatch)
+ notify.Put("/:notificationId/read", markNotificationRead)
+ }
+
+ me := api.Group("/users/me").Name("Myself Operations")
+ {
+
+ me.Put("/avatar", setAvatar)
+ me.Put("/banner", setBanner)
+
+ me.Get("/", getUserinfo)
+ me.Get("/page", getOwnPersonalPage)
+ me.Put("/", editUserinfo)
+ me.Put("/page", editPersonalPage)
+ me.Get("/events", getEvents)
+ me.Get("/tickets", getTickets)
+ me.Delete("/tickets/:ticketId", killSession)
+
+ me.Post("/confirm", doRegisterConfirm)
+
+ friends := me.Group("/friends").Name("Friends")
+ {
+ friends.Get("/", listFriendship)
+ friends.Get("/:relatedId", getFriendship)
+ friends.Post("/", makeFriendship)
+ friends.Post("/:relatedId", makeFriendship)
+ friends.Put("/:relatedId", editFriendship)
+ friends.Delete("/:relatedId", deleteFriendship)
+ }
+ }
+
+ directory := api.Group("/users/:alias").Name("User Directory")
+ {
+ directory.Get("/", getOtherUserinfo)
+ directory.Get("/page", getPersonalPage)
+ }
+
+ api.Post("/users", doRegister)
+
+ api.Post("/auth", doAuthenticate)
+ api.Post("/auth/token", getToken)
+ api.Post("/auth/factors/:factorId", requestFactorToken)
+
+ realms := api.Group("/realms").Name("Realms API")
+ {
+ realms.Get("/", listCommunityRealm)
+ realms.Get("/me", listOwnedRealm)
+ realms.Get("/me/available", listAvailableRealm)
+ realms.Get("/:realm", getRealm)
+ realms.Get("/:realm/members", listRealmMembers)
+ realms.Get("/:realm/members/me", getMyRealmMember)
+ realms.Post("/", createRealm)
+ realms.Put("/:realmId", editRealm)
+ realms.Delete("/:realmId", deleteRealm)
+ realms.Post("/:realm/members", addRealmMember)
+ realms.Delete("/:realm/members", removeRealmMember)
+ realms.Delete("/:realm/members/me", leaveRealm)
+ }
+
+ developers := api.Group("/dev").Name("Developers API")
+ {
+ developers.Post("/notify", notifyUser)
+ }
+
+ api.Use(func(c *fiber.Ctx) error {
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ return c.Next()
+ }).Get("/ws", websocket.New(listenWebsocket))
+ }
+}
diff --git a/pkg/internal/server/notifications_api.go b/pkg/internal/server/api/notifications_api.go
similarity index 79%
rename from pkg/internal/server/notifications_api.go
rename to pkg/internal/server/api/notifications_api.go
index b6ccc14..9c2bf6f 100644
--- a/pkg/internal/server/notifications_api.go
+++ b/pkg/internal/server/api/notifications_api.go
@@ -1,18 +1,22 @@
-package server
+package api
import (
"git.solsynth.dev/hydrogen/passport/pkg/internal/database"
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
+ "git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
- "git.solsynth.dev/hydrogen/passport/pkg/internal/utils"
"github.com/gofiber/fiber/v2"
)
func getNotifications(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
take := c.QueryInt("take", 0)
offset := c.QueryInt("offset", 0)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
+
tx := database.C.Where(&models.Notification{RecipientID: user.ID}).Model(&models.Notification{})
var count int64
@@ -36,9 +40,16 @@ func getNotifications(c *fiber.Ctx) error {
}
func markNotificationRead(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
id, _ := c.ParamsInt("notificationId", 0)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+
var notify models.Notification
if err := database.C.Where(&models.Notification{
BaseModel: models.BaseModel{ID: uint(id)},
@@ -55,13 +66,16 @@ func markNotificationRead(c *fiber.Ctx) error {
}
func markNotificationReadBatch(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
var data struct {
MessageIDs []uint `json:"messages"`
}
- if err := utils.BindAndValidate(c, &data); err != nil {
+ if err := exts.BindAndValidate(c, &data); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
}
@@ -75,7 +89,10 @@ func markNotificationReadBatch(c *fiber.Ctx) error {
}
func addNotifySubscriber(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
var data struct {
Provider string `json:"provider" validate:"required"`
@@ -83,7 +100,7 @@ func addNotifySubscriber(c *fiber.Ctx) error {
DeviceID string `json:"device_id" validate:"required"`
}
- if err := utils.BindAndValidate(c, &data); err != nil {
+ if err := exts.BindAndValidate(c, &data); err != nil {
return err
}
diff --git a/pkg/internal/server/notify_api.go b/pkg/internal/server/api/notify_api.go
similarity index 93%
rename from pkg/internal/server/notify_api.go
rename to pkg/internal/server/api/notify_api.go
index 24e18de..680b9d0 100644
--- a/pkg/internal/server/notify_api.go
+++ b/pkg/internal/server/api/notify_api.go
@@ -1,9 +1,9 @@
-package server
+package api
import (
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
+ "git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
- "git.solsynth.dev/hydrogen/passport/pkg/internal/utils"
"github.com/gofiber/fiber/v2"
)
@@ -21,7 +21,7 @@ func notifyUser(c *fiber.Ctx) error {
UserID uint `json:"user_id" validate:"required"`
}
- if err := utils.BindAndValidate(c, &data); err != nil {
+ if err := exts.BindAndValidate(c, &data); err != nil {
return err
}
diff --git a/pkg/internal/server/page_api.go b/pkg/internal/server/api/page_api.go
similarity index 81%
rename from pkg/internal/server/page_api.go
rename to pkg/internal/server/api/page_api.go
index b2b3958..77c7c43 100644
--- a/pkg/internal/server/page_api.go
+++ b/pkg/internal/server/api/page_api.go
@@ -1,9 +1,9 @@
-package server
+package api
import (
"git.solsynth.dev/hydrogen/passport/pkg/internal/database"
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
- "git.solsynth.dev/hydrogen/passport/pkg/internal/utils"
+ "git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
"github.com/gofiber/fiber/v2"
)
@@ -28,7 +28,10 @@ func getPersonalPage(c *fiber.Ctx) error {
}
func getOwnPersonalPage(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
var page models.AccountPage
if err := database.C.
@@ -41,14 +44,17 @@ func getOwnPersonalPage(c *fiber.Ctx) error {
}
func editPersonalPage(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
var data struct {
Content string `json:"content"`
Links []models.AccountPageLinks `json:"links"`
}
- if err := utils.BindAndValidate(c, &data); err != nil {
+ if err := exts.BindAndValidate(c, &data); err != nil {
return err
}
diff --git a/pkg/internal/server/realm_members_api.go b/pkg/internal/server/api/realm_members_api.go
similarity index 82%
rename from pkg/internal/server/realm_members_api.go
rename to pkg/internal/server/api/realm_members_api.go
index 2bed1f1..7c16361 100644
--- a/pkg/internal/server/realm_members_api.go
+++ b/pkg/internal/server/api/realm_members_api.go
@@ -1,10 +1,10 @@
-package server
+package api
import (
"git.solsynth.dev/hydrogen/passport/pkg/internal/database"
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
+ "git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
- "git.solsynth.dev/hydrogen/passport/pkg/internal/utils"
"github.com/gofiber/fiber/v2"
)
@@ -22,7 +22,10 @@ func listRealmMembers(c *fiber.Ctx) error {
func getMyRealmMember(c *fiber.Ctx) error {
alias := c.Params("realm")
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
if realm, err := services.GetRealmWithAlias(alias); err != nil {
return fiber.NewError(fiber.StatusNotFound, err.Error())
@@ -34,14 +37,17 @@ func getMyRealmMember(c *fiber.Ctx) error {
}
func addRealmMember(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
alias := c.Params("realm")
var data struct {
Target string `json:"target" validate:"required"`
}
- if err := utils.BindAndValidate(c, &data); err != nil {
+ if err := exts.BindAndValidate(c, &data); err != nil {
return err
}
@@ -65,14 +71,17 @@ func addRealmMember(c *fiber.Ctx) error {
}
func removeRealmMember(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
alias := c.Params("realm")
var data struct {
Target string `json:"target" validate:"required"`
}
- if err := utils.BindAndValidate(c, &data); err != nil {
+ if err := exts.BindAndValidate(c, &data); err != nil {
return err
}
@@ -96,7 +105,10 @@ func removeRealmMember(c *fiber.Ctx) error {
}
func leaveRealm(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
alias := c.Params("realm")
realm, err := services.GetRealmWithAlias(alias)
diff --git a/pkg/internal/server/realms_api.go b/pkg/internal/server/api/realms_api.go
similarity index 80%
rename from pkg/internal/server/realms_api.go
rename to pkg/internal/server/api/realms_api.go
index b4e5d8d..1a34a90 100644
--- a/pkg/internal/server/realms_api.go
+++ b/pkg/internal/server/api/realms_api.go
@@ -1,10 +1,10 @@
-package server
+package api
import (
"git.solsynth.dev/hydrogen/passport/pkg/internal/database"
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
+ "git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
- "git.solsynth.dev/hydrogen/passport/pkg/internal/utils"
"github.com/gofiber/fiber/v2"
)
@@ -27,7 +27,10 @@ func listCommunityRealm(c *fiber.Ctx) error {
}
func listOwnedRealm(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
if realms, err := services.ListOwnedRealm(user); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
} else {
@@ -36,7 +39,10 @@ func listOwnedRealm(c *fiber.Ctx) error {
}
func listAvailableRealm(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
if realms, err := services.ListAvailableRealm(user); err != nil {
return fiber.NewError(fiber.StatusBadRequest, err.Error())
} else {
@@ -45,10 +51,10 @@ func listAvailableRealm(c *fiber.Ctx) error {
}
func createRealm(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
- if err := utils.CheckPermissions(c, "CreateRealms", true); err != nil {
+ if err := exts.EnsureGrantedPerm(c, "CreateRealms", true); err != nil {
return err
}
+ user := c.Locals("user").(models.Account)
var data struct {
Alias string `json:"alias" validate:"required,lowercase,min=4,max=32"`
@@ -58,7 +64,7 @@ func createRealm(c *fiber.Ctx) error {
IsCommunity bool `json:"is_community"`
}
- if err := utils.BindAndValidate(c, &data); err != nil {
+ if err := exts.BindAndValidate(c, &data); err != nil {
return err
}
@@ -78,7 +84,10 @@ func createRealm(c *fiber.Ctx) error {
}
func editRealm(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
id, _ := c.ParamsInt("realmId", 0)
var data struct {
@@ -89,7 +98,7 @@ func editRealm(c *fiber.Ctx) error {
IsCommunity bool `json:"is_community"`
}
- if err := utils.BindAndValidate(c, &data); err != nil {
+ if err := exts.BindAndValidate(c, &data); err != nil {
return err
}
@@ -116,7 +125,10 @@ func editRealm(c *fiber.Ctx) error {
}
func deleteRealm(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
id, _ := c.ParamsInt("realmId", 0)
var realm models.Realm
diff --git a/pkg/internal/server/security_api.go b/pkg/internal/server/api/security_api.go
similarity index 81%
rename from pkg/internal/server/security_api.go
rename to pkg/internal/server/api/security_api.go
index 6b6a043..fba9867 100644
--- a/pkg/internal/server/security_api.go
+++ b/pkg/internal/server/api/security_api.go
@@ -1,13 +1,17 @@
-package server
+package api
import (
"git.solsynth.dev/hydrogen/passport/pkg/internal/database"
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
+ "git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
"github.com/gofiber/fiber/v2"
)
func getTickets(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
take := c.QueryInt("take", 0)
offset := c.QueryInt("offset", 0)
diff --git a/pkg/internal/server/userinfo_api.go b/pkg/internal/server/api/userinfo_api.go
similarity index 97%
rename from pkg/internal/server/userinfo_api.go
rename to pkg/internal/server/api/userinfo_api.go
index eb06de5..b200d8e 100644
--- a/pkg/internal/server/userinfo_api.go
+++ b/pkg/internal/server/api/userinfo_api.go
@@ -1,4 +1,4 @@
-package server
+package api
import (
"git.solsynth.dev/hydrogen/passport/pkg/internal/database"
diff --git a/pkg/internal/server/well_known_api.go b/pkg/internal/server/api/well_known_api.go
similarity index 98%
rename from pkg/internal/server/well_known_api.go
rename to pkg/internal/server/api/well_known_api.go
index 8580210..4384450 100644
--- a/pkg/internal/server/well_known_api.go
+++ b/pkg/internal/server/api/well_known_api.go
@@ -1,4 +1,4 @@
-package server
+package api
import (
"fmt"
diff --git a/pkg/internal/server/ws.go b/pkg/internal/server/api/ws.go
similarity index 97%
rename from pkg/internal/server/ws.go
rename to pkg/internal/server/api/ws.go
index 61d2d6c..4ecf40f 100644
--- a/pkg/internal/server/ws.go
+++ b/pkg/internal/server/api/ws.go
@@ -1,8 +1,7 @@
-package server
+package api
import (
"fmt"
-
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
"github.com/gofiber/contrib/websocket"
@@ -12,7 +11,7 @@ import (
)
func listenWebsocket(c *websocket.Conn) {
- user := c.Locals("principal").(models.Account)
+ user := c.Locals("user").(models.Account)
// Push connection
services.ClientRegister(user, c)
diff --git a/pkg/internal/server/auth_middleware.go b/pkg/internal/server/auth_middleware.go
deleted file mode 100644
index 91583aa..0000000
--- a/pkg/internal/server/auth_middleware.go
+++ /dev/null
@@ -1,55 +0,0 @@
-package server
-
-import (
- "strings"
-
- "git.solsynth.dev/hydrogen/passport/pkg/internal/services"
- "github.com/gofiber/fiber/v2"
-)
-
-func authMiddleware(c *fiber.Ctx) error {
- var token string
- if cookie := c.Cookies(services.CookieAccessKey); len(cookie) > 0 {
- token = cookie
- }
- if header := c.Get(fiber.HeaderAuthorization); len(header) > 0 {
- tk := strings.Replace(header, "Bearer", "", 1)
- token = strings.TrimSpace(tk)
- }
- if query := c.Query("tk"); len(query) > 0 {
- token = strings.TrimSpace(query)
- }
-
- c.Locals("token", token)
-
- if err := authFunc(c); err != nil {
- return err
- }
-
- return c.Next()
-}
-
-func authFunc(c *fiber.Ctx, overrides ...string) error {
- var token string
- if len(overrides) > 0 {
- token = overrides[0]
- } else {
- if tk, ok := c.Locals("token").(string); !ok {
- return fiber.NewError(fiber.StatusUnauthorized)
- } else {
- token = tk
- }
- }
-
- rtk := c.Cookies(services.CookieRefreshKey)
- if ctx, perms, atk, rtk, err := services.Authenticate(token, rtk, 0); err == nil {
- if atk != token {
- services.SetJwtCookieSet(c, atk, rtk)
- }
- c.Locals("permissions", perms)
- c.Locals("principal", ctx.Account)
- return nil
- } else {
- return err
- }
-}
diff --git a/pkg/internal/server/exts/auth.go b/pkg/internal/server/exts/auth.go
new file mode 100644
index 0000000..5ebc09c
--- /dev/null
+++ b/pkg/internal/server/exts/auth.go
@@ -0,0 +1,53 @@
+package exts
+
+import (
+ "fmt"
+ "git.solsynth.dev/hydrogen/passport/pkg/hyper"
+ "git.solsynth.dev/hydrogen/passport/pkg/internal/models"
+ "git.solsynth.dev/hydrogen/passport/pkg/internal/services"
+ "github.com/gofiber/fiber/v2"
+ "strings"
+)
+
+func AuthMiddleware(c *fiber.Ctx) error {
+ var atk string
+ if cookie := c.Cookies(hyper.CookieAtk); len(cookie) > 0 {
+ atk = cookie
+ }
+ if header := c.Get(fiber.HeaderAuthorization); len(header) > 0 {
+ tk := strings.Replace(header, "Bearer", "", 1)
+ atk = strings.TrimSpace(tk)
+ }
+
+ c.Locals("p_token", atk)
+
+ rtk := c.Cookies(hyper.CookieRtk)
+ if ctx, perms, newAtk, newRtk, err := services.Authenticate(atk, rtk, 0); err == nil {
+ if newAtk != atk {
+ SetAuthCookies(c, newAtk, newRtk)
+ }
+ c.Locals("permissions", perms)
+ c.Locals("user", ctx.Account)
+ }
+
+ return c.Next()
+}
+
+func EnsureAuthenticated(c *fiber.Ctx) error {
+ if _, ok := c.Locals("user").(models.Account); !ok {
+ return fiber.NewError(fiber.StatusUnauthorized)
+ }
+
+ return nil
+}
+
+func EnsureGrantedPerm(c *fiber.Ctx, key string, val any) error {
+ if err := EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ perms := c.Locals("permissions").(map[string]any)
+ if !services.HasPermNode(perms, key, val) {
+ return fiber.NewError(fiber.StatusForbidden, fmt.Sprintf("missing permission: %s", key))
+ }
+ return nil
+}
diff --git a/pkg/internal/server/exts/cookies.go b/pkg/internal/server/exts/cookies.go
new file mode 100644
index 0000000..32afd7c
--- /dev/null
+++ b/pkg/internal/server/exts/cookies.go
@@ -0,0 +1,27 @@
+package exts
+
+import (
+ "git.solsynth.dev/hydrogen/passport/pkg/hyper"
+ "github.com/gofiber/fiber/v2"
+ "github.com/spf13/viper"
+ "time"
+)
+
+func SetAuthCookies(c *fiber.Ctx, atk, rtk string) {
+ c.Cookie(&fiber.Cookie{
+ Name: hyper.CookieAtk,
+ Value: atk,
+ Domain: viper.GetString("security.cookie_domain"),
+ SameSite: viper.GetString("security.cookie_samesite"),
+ Expires: time.Now().Add(60 * time.Minute),
+ Path: "/",
+ })
+ c.Cookie(&fiber.Cookie{
+ Name: hyper.CookieRtk,
+ Value: rtk,
+ Domain: viper.GetString("security.cookie_domain"),
+ SameSite: viper.GetString("security.cookie_samesite"),
+ Expires: time.Now().Add(24 * 30 * time.Hour),
+ Path: "/",
+ })
+}
diff --git a/pkg/internal/utils/request.go b/pkg/internal/server/exts/request.go
similarity index 65%
rename from pkg/internal/utils/request.go
rename to pkg/internal/server/exts/request.go
index fd43caa..1e5a115 100644
--- a/pkg/internal/utils/request.go
+++ b/pkg/internal/server/exts/request.go
@@ -1,8 +1,6 @@
-package utils
+package exts
import (
- "fmt"
- "git.solsynth.dev/hydrogen/passport/pkg/internal/services"
"github.com/go-playground/validator/v10"
"github.com/gofiber/fiber/v2"
"github.com/samber/lo"
@@ -21,17 +19,6 @@ func BindAndValidate(c *fiber.Ctx, out any) error {
return nil
}
-func GetPermissions(c *fiber.Ctx) map[string]any {
- return c.Locals("permissions").(map[string]any)
-}
-
-func CheckPermissions(c *fiber.Ctx, key string, val any) error {
- if !services.HasPermNode(GetPermissions(c), key, val) {
- return fiber.NewError(fiber.StatusForbidden, fmt.Sprintf("requires permission: %s = %v", key, val))
- }
- return nil
-}
-
func GetRedirectUri(c *fiber.Ctx, fallback ...string) *string {
if len(c.Query("redirect_uri")) > 0 {
return lo.ToPtr(c.Query("redirect_uri"))
diff --git a/pkg/internal/server/server.go b/pkg/internal/server/server.go
index 17263e8..1f14ef0 100644
--- a/pkg/internal/server/server.go
+++ b/pkg/internal/server/server.go
@@ -1,11 +1,11 @@
package server
import (
+ "git.solsynth.dev/hydrogen/passport/pkg/internal/server/api"
+ "git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
"net/http"
"strings"
- "github.com/gofiber/contrib/websocket"
-
"git.solsynth.dev/hydrogen/passport/pkg/internal"
"git.solsynth.dev/hydrogen/passport/pkg/internal/i18n"
"git.solsynth.dev/hydrogen/passport/pkg/internal/server/admin"
@@ -61,92 +61,18 @@ func NewServer() {
Output: log.Logger,
}))
+ A.Use(exts.AuthMiddleware)
A.Use(i18n.I18nMiddleware)
- A.Get("/.well-known", getMetadata)
- A.Get("/.well-known/openid-configuration", getOidcConfiguration)
-
- api := A.Group("/api").Name("API")
- {
- notify := api.Group("/notifications").Name("Notifications API")
- {
- notify.Get("/", authMiddleware, getNotifications)
- notify.Post("/subscribe", authMiddleware, addNotifySubscriber)
- notify.Put("/batch/read", authMiddleware, markNotificationReadBatch)
- notify.Put("/:notificationId/read", authMiddleware, markNotificationRead)
- }
-
- me := api.Group("/users/me").Name("Myself Operations")
- {
-
- me.Put("/avatar", authMiddleware, setAvatar)
- me.Put("/banner", authMiddleware, setBanner)
-
- me.Get("/", authMiddleware, getUserinfo)
- me.Get("/page", authMiddleware, getOwnPersonalPage)
- me.Put("/", authMiddleware, editUserinfo)
- me.Put("/page", authMiddleware, editPersonalPage)
- me.Get("/events", authMiddleware, getEvents)
- me.Get("/tickets", authMiddleware, getTickets)
- me.Delete("/tickets/:ticketId", authMiddleware, killSession)
-
- me.Post("/confirm", doRegisterConfirm)
-
- friends := me.Group("/friends").Name("Friends")
- {
- friends.Get("/", authMiddleware, listFriendship)
- friends.Get("/:relatedId", authMiddleware, getFriendship)
- friends.Post("/", authMiddleware, makeFriendship)
- friends.Post("/:relatedId", authMiddleware, makeFriendship)
- friends.Put("/:relatedId", authMiddleware, editFriendship)
- friends.Delete("/:relatedId", authMiddleware, deleteFriendship)
- }
- }
-
- directory := api.Group("/users/:alias").Name("User Directory")
- {
- directory.Get("/", getOtherUserinfo)
- directory.Get("/page", getPersonalPage)
- }
-
- api.Post("/users", doRegister)
-
- api.Post("/auth", doAuthenticate)
- api.Post("/auth/token", getToken)
- api.Post("/auth/factors/:factorId", requestFactorToken)
-
- realms := api.Group("/realms").Name("Realms API")
- {
- realms.Get("/", listCommunityRealm)
- realms.Get("/me", authMiddleware, listOwnedRealm)
- realms.Get("/me/available", authMiddleware, listAvailableRealm)
- realms.Get("/:realm", getRealm)
- realms.Get("/:realm/members", listRealmMembers)
- realms.Get("/:realm/members/me", authMiddleware, getMyRealmMember)
- realms.Post("/", authMiddleware, createRealm)
- realms.Put("/:realmId", authMiddleware, editRealm)
- realms.Delete("/:realmId", authMiddleware, deleteRealm)
- realms.Post("/:realm/members", authMiddleware, addRealmMember)
- realms.Delete("/:realm/members", authMiddleware, removeRealmMember)
- realms.Delete("/:realm/members/me", authMiddleware, leaveRealm)
- }
-
- developers := api.Group("/dev").Name("Developers API")
- {
- developers.Post("/notify", notifyUser)
- }
-
- api.Get("/ws", authMiddleware, websocket.New(listenWebsocket))
- }
-
A.Use(favicon.New(favicon.Config{
FileSystem: http.FS(pkg.FS),
File: "views/favicon.png",
URL: "/favicon.png",
}))
- admin.MapAdminEndpoints(A, authMiddleware)
- ui.MapUserInterface(A, authFunc)
+ api.MapAPIs(A)
+ admin.MapAdminEndpoints(A)
+ ui.MapUserInterface(A)
}
func Listen() {
diff --git a/pkg/internal/server/ui/accounts.go b/pkg/internal/server/ui/accounts.go
index d8ecaa2..e4ec045 100644
--- a/pkg/internal/server/ui/accounts.go
+++ b/pkg/internal/server/ui/accounts.go
@@ -2,6 +2,7 @@ package ui
import (
"fmt"
+ "git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
"html/template"
"time"
@@ -15,7 +16,10 @@ import (
)
func selfUserinfoPage(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return DoAuthRedirect(c)
+ }
+ user := c.Locals("user").(models.Account)
var data models.Account
if err := database.C.
diff --git a/pkg/internal/server/ui/index.go b/pkg/internal/server/ui/index.go
index 11bc703..bd150b1 100644
--- a/pkg/internal/server/ui/index.go
+++ b/pkg/internal/server/ui/index.go
@@ -3,28 +3,15 @@ package ui
import (
"fmt"
- "git.solsynth.dev/hydrogen/passport/pkg/internal/services"
- "git.solsynth.dev/hydrogen/passport/pkg/internal/utils"
"github.com/gofiber/fiber/v2"
)
-func MapUserInterface(A *fiber.App, authFunc utils.AuthFunc) {
- authCheckWare := func(c *fiber.Ctx) error {
- var token string
- if cookie := c.Cookies(services.CookieAccessKey); len(cookie) > 0 {
- token = cookie
- }
-
- c.Locals("token", token)
-
- if err := authFunc(c); err != nil {
- uri := c.Request().URI().FullURI()
- return c.Redirect(fmt.Sprintf("/sign-in?redirect_uri=%s", string(uri)))
- } else {
- return c.Next()
- }
- }
+func DoAuthRedirect(c *fiber.Ctx) error {
+ uri := c.Request().URI().FullURI()
+ return c.Redirect(fmt.Sprintf("/sign-in?redirect_uri=%s", string(uri)))
+}
+func MapUserInterface(A *fiber.App) {
pages := A.Group("/").Name("Pages")
pages.Get("/", func(c *fiber.Ctx) error {
@@ -35,13 +22,13 @@ func MapUserInterface(A *fiber.App, authFunc utils.AuthFunc) {
pages.Get("/sign-in", signinPage)
pages.Get("/mfa", mfaRequestPage)
pages.Get("/mfa/apply", mfaApplyPage)
- pages.Get("/authorize", authCheckWare, authorizePage)
+ pages.Get("/authorize", authorizePage)
pages.Post("/sign-up", signupAction)
pages.Post("/sign-in", signinAction)
pages.Post("/mfa", mfaRequestAction)
pages.Post("/mfa/apply", mfaApplyAction)
- pages.Post("/authorize", authCheckWare, authorizeAction)
+ pages.Post("/authorize", authorizeAction)
- pages.Get("/users/me", authCheckWare, selfUserinfoPage)
+ pages.Get("/users/me", selfUserinfoPage)
}
diff --git a/pkg/internal/server/ui/mfa.go b/pkg/internal/server/ui/mfa.go
index 670f0f6..4fd8e24 100644
--- a/pkg/internal/server/ui/mfa.go
+++ b/pkg/internal/server/ui/mfa.go
@@ -3,8 +3,8 @@ package ui
import (
"fmt"
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
+ "git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
- "git.solsynth.dev/hydrogen/passport/pkg/internal/utils"
"github.com/gofiber/fiber/v2"
"github.com/nicksnyder/go-i18n/v2/i18n"
"github.com/samber/lo"
@@ -68,7 +68,7 @@ func mfaRequestAction(c *fiber.Ctx) error {
}
redirectBackUri := "/sign-in"
- err := utils.BindAndValidate(c, &data)
+ err := exts.BindAndValidate(c, &data)
if data.TicketID > 0 {
redirectBackUri = fmt.Sprintf("/mfa?ticket=%d", data.TicketID)
@@ -95,7 +95,7 @@ func mfaRequestAction(c *fiber.Ctx) error {
}
return flash.WithData(c, fiber.Map{
- "redirect_uri": utils.GetRedirectUri(c),
+ "redirect_uri": exts.GetRedirectUri(c),
}).Redirect(fmt.Sprintf("/mfa/apply?ticket=%d&factor=%d", data.TicketID, factor.ID))
}
@@ -145,7 +145,7 @@ func mfaApplyAction(c *fiber.Ctx) error {
}
redirectBackUri := "/sign-in"
- err := utils.BindAndValidate(c, &data)
+ err := exts.BindAndValidate(c, &data)
if data.TicketID > 0 {
redirectBackUri = fmt.Sprintf("/mfa/apply?ticket=%d&factor=%d", data.TicketID, data.FactorID)
@@ -187,8 +187,8 @@ func mfaApplyAction(c *fiber.Ctx) error {
"message": fmt.Sprintf("failed to exchange token: %v", err.Error()),
}).Redirect("/sign-in")
} else {
- services.SetJwtCookieSet(c, access, refresh)
+ exts.SetAuthCookies(c, access, refresh)
}
- return c.Redirect(lo.FromPtr(utils.GetRedirectUri(c, "/users/me")))
+ return c.Redirect(lo.FromPtr(exts.GetRedirectUri(c, "/users/me")))
}
diff --git a/pkg/internal/server/ui/oauth.go b/pkg/internal/server/ui/oauth.go
index 839eabf..946a17c 100644
--- a/pkg/internal/server/ui/oauth.go
+++ b/pkg/internal/server/ui/oauth.go
@@ -4,6 +4,7 @@ import (
"fmt"
"git.solsynth.dev/hydrogen/passport/pkg/internal/database"
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
+ "git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
"github.com/gofiber/fiber/v2"
"github.com/nicksnyder/go-i18n/v2/i18n"
@@ -16,7 +17,11 @@ import (
func authorizePage(c *fiber.Ctx) error {
localizer := c.Locals("localizer").(*i18n.Localizer)
- user := c.Locals("principal").(models.Account)
+
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return DoAuthRedirect(c)
+ }
+ user := c.Locals("user").(models.Account)
id := c.Query("client_id")
redirect := c.Query("redirect_uri")
@@ -81,12 +86,19 @@ func authorizePage(c *fiber.Ctx) error {
}
func authorizeAction(c *fiber.Ctx) error {
- user := c.Locals("principal").(models.Account)
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return err
+ }
+ user := c.Locals("user").(models.Account)
id := c.Query("client_id")
response := c.Query("response_type")
redirect := c.Query("redirect_uri")
scope := c.Query("scope")
+ if err := exts.EnsureAuthenticated(c); err != nil {
+ return DoAuthRedirect(c)
+ }
+
redirectBackUri := "/authorize?" + string(c.Request().URI().QueryString())
if len(scope) <= 0 {
diff --git a/pkg/internal/server/ui/signin.go b/pkg/internal/server/ui/signin.go
index 443101b..df87970 100644
--- a/pkg/internal/server/ui/signin.go
+++ b/pkg/internal/server/ui/signin.go
@@ -2,8 +2,8 @@ package ui
import (
"fmt"
+ "git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
- "git.solsynth.dev/hydrogen/passport/pkg/internal/utils"
"github.com/gofiber/fiber/v2"
"github.com/nicksnyder/go-i18n/v2/i18n"
"github.com/samber/lo"
@@ -47,7 +47,7 @@ func signinAction(c *fiber.Ctx) error {
Password string `form:"password" validate:"required"`
}
- if err := utils.BindAndValidate(c, &data); err != nil {
+ if err := exts.BindAndValidate(c, &data); err != nil {
return flash.WithInfo(c, fiber.Map{
"message": err.Error(),
}).Redirect("/sign-in")
@@ -76,7 +76,7 @@ func signinAction(c *fiber.Ctx) error {
if ticket.IsAvailable() != nil {
return flash.WithData(c, fiber.Map{
- "redirect_uri": utils.GetRedirectUri(c),
+ "redirect_uri": exts.GetRedirectUri(c),
}).Redirect(fmt.Sprintf("/mfa?ticket=%d", ticket.ID))
}
@@ -86,8 +86,8 @@ func signinAction(c *fiber.Ctx) error {
"message": fmt.Sprintf("failed to exchange token: %v", err.Error()),
}).Redirect("/sign-in")
} else {
- services.SetJwtCookieSet(c, access, refresh)
+ exts.SetAuthCookies(c, access, refresh)
}
- return c.Redirect(lo.FromPtr(utils.GetRedirectUri(c, "/users/me")))
+ return c.Redirect(lo.FromPtr(exts.GetRedirectUri(c, "/users/me")))
}
diff --git a/pkg/internal/server/ui/signup.go b/pkg/internal/server/ui/signup.go
index cf5bfa9..28867a2 100644
--- a/pkg/internal/server/ui/signup.go
+++ b/pkg/internal/server/ui/signup.go
@@ -4,8 +4,8 @@ import (
"fmt"
"git.solsynth.dev/hydrogen/passport/pkg/internal/database"
"git.solsynth.dev/hydrogen/passport/pkg/internal/models"
+ "git.solsynth.dev/hydrogen/passport/pkg/internal/server/exts"
"git.solsynth.dev/hydrogen/passport/pkg/internal/services"
- "git.solsynth.dev/hydrogen/passport/pkg/internal/utils"
"github.com/gofiber/fiber/v2"
"github.com/nicksnyder/go-i18n/v2/i18n"
"github.com/samber/lo"
@@ -52,7 +52,7 @@ func signupAction(c *fiber.Ctx) error {
MagicToken string `form:"magic_token"`
}
- if err := utils.BindAndValidate(c, &data); err != nil {
+ if err := exts.BindAndValidate(c, &data); err != nil {
return flash.WithInfo(c, fiber.Map{
"message": err.Error(),
}).Redirect("/sign-up")
@@ -82,6 +82,6 @@ func signupAction(c *fiber.Ctx) error {
} else {
return flash.WithInfo(c, fiber.Map{
"message": "account has been created. now you can sign in!",
- }).Redirect(lo.FromPtr(utils.GetRedirectUri(c, "/sign-in")))
+ }).Redirect(lo.FromPtr(exts.GetRedirectUri(c, "/sign-in")))
}
}
diff --git a/pkg/internal/services/auth.go b/pkg/internal/services/auth.go
index 9e40307..ffbaaeb 100644
--- a/pkg/internal/services/auth.go
+++ b/pkg/internal/services/auth.go
@@ -17,23 +17,23 @@ var (
authContextCache = make(map[string]models.AuthContext)
)
-func Authenticate(access, refresh string, depth int) (ctx models.AuthContext, perms map[string]any, newAccess, newRefresh string, err error) {
+func Authenticate(atk, rtk string, rty int) (ctx models.AuthContext, perms map[string]any, newAtk, newRtk string, err error) {
var claims PayloadClaims
- claims, err = DecodeJwt(access)
+ claims, err = DecodeJwt(atk)
if err != nil {
- if len(refresh) > 0 && depth < 1 {
+ if len(rtk) > 0 && rty < 1 {
// Auto refresh and retry
- newAccess, newRefresh, err = RefreshToken(refresh)
+ newAtk, newRtk, err = RefreshToken(rtk)
if err == nil {
- return Authenticate(newAccess, newRefresh, depth+1)
+ return Authenticate(newAtk, newRtk, rty+1)
}
}
err = fiber.NewError(fiber.StatusUnauthorized, fmt.Sprintf("invalid auth key: %v", err))
return
}
- newAccess = access
- newRefresh = refresh
+ newAtk = atk
+ newRtk = rtk
if ctx, err = GetAuthContext(claims.ID); err == nil {
var heldPerms map[string]any
diff --git a/pkg/internal/services/jwt.go b/pkg/internal/services/jwt.go
index de83bd5..a198b2f 100644
--- a/pkg/internal/services/jwt.go
+++ b/pkg/internal/services/jwt.go
@@ -2,16 +2,12 @@ package services
import (
"fmt"
- "github.com/gofiber/fiber/v2"
"time"
"github.com/golang-jwt/jwt/v5"
"github.com/spf13/viper"
)
-var CookieAccessKey = "passport_auth_key"
-var CookieRefreshKey = "passport_refresh_key"
-
type PayloadClaims struct {
jwt.RegisteredClaims
@@ -60,22 +56,3 @@ func DecodeJwt(str string) (PayloadClaims, error) {
return claims, fmt.Errorf("unexpected token payload: not payload claims type")
}
}
-
-func SetJwtCookieSet(c *fiber.Ctx, access, refresh string) {
- c.Cookie(&fiber.Cookie{
- Name: CookieAccessKey,
- Value: access,
- Domain: viper.GetString("security.cookie_domain"),
- SameSite: viper.GetString("security.cookie_samesite"),
- Expires: time.Now().Add(60 * time.Minute),
- Path: "/",
- })
- c.Cookie(&fiber.Cookie{
- Name: CookieRefreshKey,
- Value: refresh,
- Domain: viper.GetString("security.cookie_domain"),
- SameSite: viper.GetString("security.cookie_samesite"),
- Expires: time.Now().Add(24 * 30 * time.Hour),
- Path: "/",
- })
-}
diff --git a/pkg/internal/utils/auth.go b/pkg/internal/utils/auth.go
deleted file mode 100644
index b87ed7a..0000000
--- a/pkg/internal/utils/auth.go
+++ /dev/null
@@ -1,5 +0,0 @@
-package utils
-
-import "github.com/gofiber/fiber/v2"
-
-type AuthFunc func(c *fiber.Ctx, overrides ...string) error