131 lines
2.8 KiB
Go
131 lines
2.8 KiB
Go
package auth
|
|
|
|
import (
|
|
"net/url"
|
|
"nixcn-cms/data"
|
|
"nixcn-cms/pkgs/authcode"
|
|
"nixcn-cms/utils"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
func Redirect(c *gin.Context) {
|
|
clientId := c.Query("client_id")
|
|
if clientId == "" {
|
|
utils.HttpResponse(c, 400, "", "invalid request")
|
|
return
|
|
}
|
|
|
|
redirectUri := c.Query("redirect_uri")
|
|
if redirectUri == "" {
|
|
utils.HttpResponse(c, 400, "", "invalid request")
|
|
return
|
|
}
|
|
|
|
state := c.Query("state")
|
|
if state == "" {
|
|
utils.HttpResponse(c, 400, "", "invalid request")
|
|
return
|
|
}
|
|
|
|
code := c.Query("code")
|
|
if code == "" {
|
|
userIdOrig, ok := c.Get("user_id")
|
|
if !ok || userIdOrig == "" {
|
|
utils.HttpResponse(c, 401, "", "unauthorized")
|
|
return
|
|
}
|
|
|
|
userId, err := uuid.Parse(userIdOrig.(string))
|
|
if err != nil {
|
|
utils.HttpResponse(c, 500, "", "failed to parse uuid")
|
|
return
|
|
}
|
|
|
|
userData := new(data.User)
|
|
user, err := userData.GetByUserId(userId)
|
|
if err != nil {
|
|
utils.HttpResponse(c, 500, "", "failed to get user id")
|
|
return
|
|
}
|
|
|
|
code, err := authcode.NewAuthCode(clientId, user.Email)
|
|
if err != nil {
|
|
utils.HttpResponse(c, 500, "", "code gen failed")
|
|
return
|
|
}
|
|
|
|
url, err := url.Parse(redirectUri)
|
|
if err != nil {
|
|
utils.HttpResponse(c, 400, "", "invalid redirect uri")
|
|
return
|
|
}
|
|
query := url.Query()
|
|
query.Set("code", code)
|
|
url.RawQuery = query.Encode()
|
|
|
|
c.Redirect(302, url.String())
|
|
}
|
|
|
|
// Verify email token
|
|
authCode, ok := authcode.VerifyAuthCode(code)
|
|
if !ok {
|
|
utils.HttpResponse(c, 403, "", "invalid or expired token")
|
|
return
|
|
}
|
|
|
|
// Verify if user exists
|
|
userData := new(data.User)
|
|
user, err := userData.GetByEmail(authCode.Email)
|
|
|
|
if err != nil {
|
|
if err == gorm.ErrRecordNotFound {
|
|
// Create user
|
|
user.UUID = uuid.New()
|
|
user.UserId = uuid.New()
|
|
user.Email = authCode.Email
|
|
user.Username = user.UserId.String()
|
|
user.PermissionLevel = 10
|
|
if err := user.Create(); err != nil {
|
|
utils.HttpResponse(c, 500, "", "internal server error")
|
|
return
|
|
}
|
|
} else {
|
|
utils.HttpResponse(c, 500, "", "internal server error")
|
|
return
|
|
}
|
|
}
|
|
|
|
clientData := new(data.Client)
|
|
client, err := clientData.GetClientByClientId(clientId)
|
|
if err != nil {
|
|
utils.HttpResponse(c, 400, "", "client not found")
|
|
return
|
|
}
|
|
|
|
err = client.ValidateRedirectURI(redirectUri)
|
|
if err != nil {
|
|
utils.HttpResponse(c, 400, "", "redirect uri not match")
|
|
return
|
|
}
|
|
|
|
newCode, err := authcode.NewAuthCode(clientId, authCode.Email)
|
|
if err != nil {
|
|
utils.HttpResponse(c, 500, "", "internal server error")
|
|
return
|
|
}
|
|
|
|
url, err := url.Parse(redirectUri)
|
|
if err != nil {
|
|
utils.HttpResponse(c, 400, "", "invalid redirect uri")
|
|
return
|
|
}
|
|
query := url.Query()
|
|
query.Set("code", newCode)
|
|
url.RawQuery = query.Encode()
|
|
|
|
c.Redirect(302, url.String())
|
|
}
|