package controllers
import (
"context"
"fmt"
"net/http"
"github.com/danielrhuynh/busybar/internal/auth"
"github.com/danielrhuynh/busybar/internal/models"
"github.com/danielrhuynh/busybar/internal/services"
"github.com/danielrhuynh/busybar/pkg/config"
"github.com/jackc/pgx/v5"
"github.com/labstack/echo/v4"
)
// func GetUserSession(c echo.Context) error {
// }
func GetAuthURL(c echo.Context) error {
providerName := c.Param("provider")
provider, ok := config.Config.OAuth[providerName]
if !ok {
return echo.NewHTTPError(http.StatusBadRequest, "bad provider")
}
authURL := provider.Config.AuthCodeURL("state")
return c.JSON(http.StatusOK, envelope{
"auth_url": authURL,
})
}
func AuthCallback(c echo.Context) error {
providerName := c.Param("provider")
provider, ok := config.Config.OAuth[providerName]
if !ok {
return echo.NewHTTPError(http.StatusBadRequest, "bad provider")
}
providerConfig := provider.Config
code := c.QueryParam("code")
if code == "" {
return echo.NewHTTPError(http.StatusBadRequest, "code is required")
}
token, err := providerConfig.Exchange(context.Background(), code)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "failed to exchange token")
}
accountInfo, err := services.FetchAccountInfoFromProvider(provider, token)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "failed to fetch account info")
}
var userSession *models.UserSession
userSession, err = services.AuthGetUserSessionFromProvider(providerName, accountInfo["id"].(string))
if err != nil && err != pgx.ErrNoRows {
fmt.Println(err)
return echo.NewHTTPError(http.StatusInternalServerError, "failed to get user session")
}
if userSession == nil {
userSession, err = services.AuthCreateUserSession(providerName, accountInfo["id"].(string), token)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "failed to create user session")
}
}
session, err := services.AuthCreateSession(userSession.ID)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "failed to create session")
}
redirectURL := fmt.Sprintf("busybar://auth?access_token=%s&refresh_token=%s", session.AccessToken, session.RefreshToken)
return c.Redirect(http.StatusTemporaryRedirect, redirectURL)
}
func AuthGetSession(c echo.Context) error {
user, err := auth.GetUser(c)
if err != nil {
return echo.NewHTTPError(http.StatusUnauthorized, "unauthorized")
}
return c.JSON(http.StatusOK, envelope{
"user": user,
})
}
func AuthLogout(c echo.Context) error {
user, err := auth.GetUser(c)
if err != nil {
return echo.NewHTTPError(http.StatusUnauthorized, "unauthorized")
}
err = services.AuthDeleteSession(user.ID)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "failed to delete session")
}
return c.NoContent(http.StatusNoContent)
}