Update config to support OIDC and oauth2
This commit is contained in:
parent
430f46ffee
commit
4c1b402137
8 changed files with 92 additions and 42 deletions
|
@ -44,13 +44,12 @@ func (i *IdentityProvider) ExchangeToken(ctx context.Context, code string) (stri
|
|||
TokenURL: i.config.TokenURL,
|
||||
},
|
||||
}
|
||||
|
||||
token, err := conf.Exchange(ctx, code)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
accessToken, ok := token.Extra("access_token").(string)
|
||||
accessToken, ok := token.AccessToken, token.Valid()
|
||||
if !ok {
|
||||
return "", errors.New("access token not found")
|
||||
}
|
||||
|
|
54
internal/resource/handler.go
Normal file
54
internal/resource/handler.go
Normal file
|
@ -0,0 +1,54 @@
|
|||
package resource
|
||||
|
||||
import (
|
||||
"donetick.com/core/config"
|
||||
jwt "github.com/appleboy/gin-jwt/v2"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type Resource struct {
|
||||
Idp identityProvider `json:"identity_provider" binding:"omitempty"`
|
||||
}
|
||||
type identityProvider struct {
|
||||
Auth_url string `json:"auth_url" binding:"omitempty"`
|
||||
Client_ID string `json:"client_id" binding:"omitempty"`
|
||||
Name string `json:"name" binding:"omitempty"`
|
||||
}
|
||||
|
||||
type Handler struct {
|
||||
config config.Config
|
||||
}
|
||||
|
||||
func NewHandler(cfg *config.Config) *Handler {
|
||||
return &Handler{
|
||||
config: *cfg,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) getResource(c *gin.Context) {
|
||||
c.JSON(200, &Resource{
|
||||
Idp: identityProvider{
|
||||
Auth_url: h.config.OAuth2Config.AuthURL,
|
||||
Client_ID: h.config.OAuth2Config.ClientID,
|
||||
Name: h.config.OAuth2Config.Name,
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func Routes(r *gin.Engine, h *Handler, auth *jwt.GinJWTMiddleware, cfg *config.Config) {
|
||||
resourceRoutes := r.Group("api/v1/resource")
|
||||
|
||||
if cfg.IsDoneTickDotCom {
|
||||
// skip resource endpoint for donetick.com
|
||||
resourceRoutes.GET("", func(c *gin.Context) {
|
||||
c.JSON(200, gin.H{})
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
{
|
||||
resourceRoutes.GET("", h.getResource)
|
||||
}
|
||||
|
||||
}
|
|
@ -294,14 +294,16 @@ func (h *Handler) thirdPartyAuthCallback(c *gin.Context) {
|
|||
}
|
||||
|
||||
token, err := h.identityProvider.ExchangeToken(c, req.Code)
|
||||
|
||||
if err != nil {
|
||||
logger.Errorw("account.handler.thirdPartyAuthCallback (oauth2) failed to exchange token", "err", err)
|
||||
logger.Error("account.handler.thirdPartyAuthCallback (oauth2) failed to exchange token", "err", err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to exchange token"})
|
||||
return
|
||||
}
|
||||
|
||||
claims, err := h.identityProvider.GetUserInfo(c, token)
|
||||
if err != nil {
|
||||
logger.Errorw("account.handler.thirdPartyAuthCallback (oauth2) failed to get claims", "err", err)
|
||||
logger.Error("account.handler.thirdPartyAuthCallback (oauth2) failed to get claims", "err", err)
|
||||
}
|
||||
|
||||
acc, err := h.userRepo.FindByEmail(c, claims.Email)
|
||||
|
@ -310,7 +312,7 @@ func (h *Handler) thirdPartyAuthCallback(c *gin.Context) {
|
|||
password := auth.GenerateRandomPassword(12)
|
||||
encodedPassword, err := auth.EncodePassword(password)
|
||||
if err != nil {
|
||||
logger.Errorw("account.handler.thirdPartyAuthCallback (oauth2) password encoding failed", "err", err)
|
||||
logger.Error("account.handler.thirdPartyAuthCallback (oauth2) password encoding failed", "err", err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Password encoding failed"})
|
||||
return
|
||||
}
|
||||
|
@ -370,7 +372,7 @@ func (h *Handler) thirdPartyAuthCallback(c *gin.Context) {
|
|||
h.jwtAuth.Authenticator(c)
|
||||
tokenString, expire, err := h.jwtAuth.TokenGenerator(acc)
|
||||
if err != nil {
|
||||
logger.Errorw("Unable to Generate a Token")
|
||||
logger.Error("Unable to Generate a Token")
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": "Unable to Generate a Token",
|
||||
})
|
||||
|
@ -378,9 +380,6 @@ func (h *Handler) thirdPartyAuthCallback(c *gin.Context) {
|
|||
}
|
||||
c.JSON(http.StatusOK, gin.H{"token": tokenString, "expire": expire})
|
||||
return
|
||||
default:
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid provider"})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -713,13 +712,4 @@ func Routes(router *gin.Engine, h *Handler, auth *jwt.GinJWTMiddleware, limiter
|
|||
authRoutes.POST("reset", h.resetPassword)
|
||||
authRoutes.POST("password", h.updateUserPassword)
|
||||
}
|
||||
pingRoutes := router.Group("api/v1/ping")
|
||||
pingRoutes.Use(utils.RateLimitMiddleware(limiter))
|
||||
{
|
||||
pingRoutes.GET("/", func(c *gin.Context) {
|
||||
c.JSON(200, gin.H{
|
||||
"message": "pong",
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,18 +7,18 @@ import (
|
|||
)
|
||||
|
||||
type User struct {
|
||||
ID int `json:"id" gorm:"primary_key"` // Unique identifier
|
||||
DisplayName string `json:"displayName" gorm:"column:display_name"` // Display name
|
||||
Username string `json:"username" gorm:"column:username;unique"` // Username (unique)
|
||||
Email string `json:"email" gorm:"column:email;unique"` // Email (unique)
|
||||
Provider AuthProvider `json:"provider" gorm:"column:provider"` // Provider
|
||||
Password string `json:"-" gorm:"column:password"` // Password
|
||||
CircleID int `json:"circleID" gorm:"column:circle_id"` // Circle ID
|
||||
ChatID int64 `json:"chatID" gorm:"column:chat_id"` // Telegram chat ID
|
||||
Image string `json:"image" gorm:"column:image"` // Image
|
||||
CreatedAt time.Time `json:"created_at" gorm:"column:created_at"` // Created at
|
||||
UpdatedAt time.Time `json:"updated_at" gorm:"column:updated_at"` // Updated at
|
||||
Disabled bool `json:"disabled" gorm:"column:disabled"` // Disabled
|
||||
ID int `json:"id" gorm:"primary_key"` // Unique identifier
|
||||
DisplayName string `json:"displayName" gorm:"column:display_name"` // Display name
|
||||
Username string `json:"username" gorm:"column:username;unique"` // Username (unique)
|
||||
Email string `json:"email" gorm:"column:email;unique"` // Email (unique)
|
||||
Provider AuthProviderType `json:"provider" gorm:"column:provider"` // Provider
|
||||
Password string `json:"-" gorm:"column:password"` // Password
|
||||
CircleID int `json:"circleID" gorm:"column:circle_id"` // Circle ID
|
||||
ChatID int64 `json:"chatID" gorm:"column:chat_id"` // Telegram chat ID
|
||||
Image string `json:"image" gorm:"column:image"` // Image
|
||||
CreatedAt time.Time `json:"created_at" gorm:"column:created_at"` // Created at
|
||||
UpdatedAt time.Time `json:"updated_at" gorm:"column:updated_at"` // Updated at
|
||||
Disabled bool `json:"disabled" gorm:"column:disabled"` // Disabled
|
||||
// Email string `json:"email" gorm:"column:email"` // Email
|
||||
CustomerID *string `gorm:"column:customer_id;<-:false"` // read only column
|
||||
Subscription *string `json:"subscription" gorm:"column:subscription;<-:false"` // read only column
|
||||
|
@ -48,10 +48,10 @@ type UserNotificationTarget struct {
|
|||
TargetID string `json:"target_id" gorm:"column:target_id"` // Target ID
|
||||
CreatedAt time.Time `json:"-" gorm:"column:created_at"`
|
||||
}
|
||||
type AuthProvider int
|
||||
type AuthProviderType int
|
||||
|
||||
const (
|
||||
AuthProviderDonetick AuthProvider = iota
|
||||
AuthProviderDonetick AuthProviderType = iota
|
||||
AuthProviderOAuth2
|
||||
AuthProviderGoogle
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue