Passport/pkg/server/oauth_api.go

122 lines
3.3 KiB
Go
Raw Normal View History

2024-01-30 07:57:49 +00:00
package server
import (
"code.smartsheep.studio/hydrogen/passport/pkg/database"
"code.smartsheep.studio/hydrogen/passport/pkg/models"
"code.smartsheep.studio/hydrogen/passport/pkg/security"
2024-01-30 09:57:23 +00:00
"code.smartsheep.studio/hydrogen/passport/pkg/services"
2024-01-30 07:57:49 +00:00
"github.com/gofiber/fiber/v2"
"github.com/samber/lo"
"strings"
"time"
)
func preConnect(c *fiber.Ctx) error {
id := c.Query("client_id")
redirect := c.Query("redirect_uri")
var client models.ThirdClient
if err := database.C.Where(&models.ThirdClient{Alias: id}).First(&client).Error; err != nil {
return fiber.NewError(fiber.StatusNotFound, err.Error())
} else if !client.IsDraft && !lo.Contains(client.Callbacks, strings.Split(redirect, "?")[0]) {
return fiber.NewError(fiber.StatusBadRequest, "invalid callback url")
2024-01-30 07:57:49 +00:00
}
user := c.Locals("principal").(models.Account)
var session models.AuthSession
if err := database.C.Where(&models.AuthSession{
2024-01-30 13:01:00 +00:00
AccountID: user.ID,
ClientID: &client.ID,
LastGrantAt: nil,
2024-01-30 07:57:49 +00:00
}).First(&session).Error; err == nil {
if session.ExpiredAt != nil && session.ExpiredAt.Unix() < time.Now().Unix() {
return c.JSON(fiber.Map{
"client": client,
"session": nil,
})
} else {
session, err = security.RegenSession(session)
}
return c.JSON(fiber.Map{
"client": client,
"session": session,
})
}
return c.JSON(fiber.Map{
"client": client,
"session": nil,
})
}
func doConnect(c *fiber.Ctx) error {
user := c.Locals("principal").(models.Account)
id := c.Query("client_id")
response := c.Query("response_type")
redirect := c.Query("redirect_uri")
scope := c.Query("scope")
if len(scope) <= 0 {
return fiber.NewError(fiber.StatusBadRequest, "invalid request params")
}
var client models.ThirdClient
if err := database.C.Where(&models.ThirdClient{Alias: id}).First(&client).Error; err != nil {
return fiber.NewError(fiber.StatusNotFound, err.Error())
}
switch response {
case "code":
// OAuth Authorization Mode
session, err := security.GrantOauthSession(
user,
client,
strings.Split(scope, " "),
2024-01-30 13:24:54 +00:00
[]string{"passport", client.Alias},
2024-01-30 09:57:23 +00:00
nil,
2024-01-30 07:57:49 +00:00
lo.ToPtr(time.Now()),
c.IP(),
c.Get(fiber.HeaderUserAgent),
)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
} else {
2024-01-30 09:57:23 +00:00
services.AddEvent(user, "oauth.connect", client.Alias, c.IP(), c.Get(fiber.HeaderUserAgent))
2024-01-30 07:57:49 +00:00
return c.JSON(fiber.Map{
"session": session,
"redirect_uri": redirect,
})
}
case "token":
// OAuth Implicit Mode
session, err := security.GrantOauthSession(
user,
client,
strings.Split(scope, " "),
2024-01-30 13:24:54 +00:00
[]string{"passport", client.Alias},
2024-01-30 09:57:23 +00:00
nil,
2024-01-30 07:57:49 +00:00
lo.ToPtr(time.Now()),
c.IP(),
c.Get(fiber.HeaderUserAgent),
)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
} else if access, refresh, err := security.GetToken(session); err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
} else {
2024-01-30 09:57:23 +00:00
services.AddEvent(user, "oauth.connect", client.Alias, c.IP(), c.Get(fiber.HeaderUserAgent))
2024-01-30 07:57:49 +00:00
return c.JSON(fiber.Map{
"access_token": access,
"refresh_token": refresh,
"redirect_uri": redirect,
"session": session,
})
}
default:
return fiber.NewError(fiber.StatusBadRequest, "unsupported response type")
}
}