ai-gateway/controller/auth/lark.go

201 lines
4.6 KiB
Go
Raw Normal View History

2024-04-05 04:10:43 +00:00
package auth
2023-04-22 12:39:27 +00:00
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
2024-01-28 11:38:58 +00:00
"github.com/songquanpeng/one-api/common/config"
"github.com/songquanpeng/one-api/common/logger"
2024-04-05 04:10:43 +00:00
"github.com/songquanpeng/one-api/controller"
2024-01-28 11:38:58 +00:00
"github.com/songquanpeng/one-api/model"
2023-04-22 12:39:27 +00:00
"net/http"
"strconv"
"time"
)
2024-04-05 04:10:43 +00:00
type LarkOAuthResponse struct {
2023-04-22 12:39:27 +00:00
AccessToken string `json:"access_token"`
}
2024-04-05 04:10:43 +00:00
type LarkUser struct {
Name string `json:"name"`
OpenID string `json:"open_id"`
2023-04-22 12:39:27 +00:00
}
2024-04-05 04:10:43 +00:00
func getLarkUserInfoByCode(code string) (*LarkUser, error) {
2023-04-22 12:39:27 +00:00
if code == "" {
return nil, errors.New("无效的参数")
}
2024-04-05 04:10:43 +00:00
values := map[string]string{
"client_id": config.LarkClientId,
"client_secret": config.LarkClientSecret,
"code": code,
"grant_type": "authorization_code",
"redirect_uri": fmt.Sprintf("%s/oauth/lark", config.ServerAddress),
}
2023-04-22 12:39:27 +00:00
jsonData, err := json.Marshal(values)
if err != nil {
return nil, err
}
2024-04-05 04:10:43 +00:00
req, err := http.NewRequest("POST", "https://passport.feishu.cn/suite/passport/oauth/token", bytes.NewBuffer(jsonData))
2023-04-22 12:39:27 +00:00
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
client := http.Client{
Timeout: 5 * time.Second,
}
res, err := client.Do(req)
if err != nil {
logger.SysLog(err.Error())
2024-04-05 04:10:43 +00:00
return nil, errors.New("无法连接至飞书服务器,请稍后重试!")
2023-04-22 12:39:27 +00:00
}
defer res.Body.Close()
2024-04-05 04:10:43 +00:00
var oAuthResponse LarkOAuthResponse
2023-04-22 12:39:27 +00:00
err = json.NewDecoder(res.Body).Decode(&oAuthResponse)
if err != nil {
return nil, err
}
2024-04-05 04:10:43 +00:00
req, err = http.NewRequest("GET", "https://passport.feishu.cn/suite/passport/oauth/userinfo", nil)
2023-04-22 12:39:27 +00:00
if err != nil {
return nil, err
}
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", oAuthResponse.AccessToken))
res2, err := client.Do(req)
if err != nil {
logger.SysLog(err.Error())
2024-04-05 04:10:43 +00:00
return nil, errors.New("无法连接至飞书服务器,请稍后重试!")
2023-04-22 12:39:27 +00:00
}
2024-04-05 04:10:43 +00:00
var larkUser LarkUser
err = json.NewDecoder(res2.Body).Decode(&larkUser)
2023-04-22 12:39:27 +00:00
if err != nil {
return nil, err
}
2024-04-05 04:10:43 +00:00
return &larkUser, nil
2023-04-22 12:39:27 +00:00
}
2024-04-05 04:10:43 +00:00
func LarkOAuth(c *gin.Context) {
2023-04-22 12:39:27 +00:00
session := sessions.Default(c)
2023-09-14 16:24:20 +00:00
state := c.Query("state")
if state == "" || session.Get("oauth_state") == nil || state != session.Get("oauth_state").(string) {
c.JSON(http.StatusForbidden, gin.H{
"success": false,
"message": "state is empty or not same",
})
return
}
2023-04-22 12:39:27 +00:00
username := session.Get("username")
if username != nil {
2024-04-05 04:10:43 +00:00
LarkBind(c)
2023-04-22 12:39:27 +00:00
return
}
code := c.Query("code")
2024-04-05 04:10:43 +00:00
larkUser, err := getLarkUserInfoByCode(code)
2023-04-22 12:39:27 +00:00
if err != nil {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": err.Error(),
})
return
}
user := model.User{
2024-04-05 04:10:43 +00:00
LarkId: larkUser.OpenID,
2023-04-22 12:39:27 +00:00
}
2024-04-05 04:10:43 +00:00
if model.IsLarkIdAlreadyTaken(user.LarkId) {
err := user.FillUserByLarkId()
2023-04-22 12:39:27 +00:00
if err != nil {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": err.Error(),
})
return
}
} else {
if config.RegisterEnabled {
2024-04-05 04:10:43 +00:00
user.Username = "lark_" + strconv.Itoa(model.GetMaxUserId()+1)
if larkUser.Name != "" {
user.DisplayName = larkUser.Name
2023-04-22 12:39:27 +00:00
} else {
2024-04-05 04:10:43 +00:00
user.DisplayName = "Lark User"
2023-04-22 12:39:27 +00:00
}
2024-04-05 18:03:59 +00:00
user.Role = model.RoleCommonUser
user.Status = model.UserStatusEnabled
2023-04-22 12:39:27 +00:00
2023-06-17 10:12:58 +00:00
if err := user.Insert(0); err != nil {
2023-04-22 12:39:27 +00:00
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": err.Error(),
})
return
}
} else {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": "管理员关闭了新用户注册",
})
return
}
}
2024-04-05 18:03:59 +00:00
if user.Status != model.UserStatusEnabled {
2023-04-22 12:39:27 +00:00
c.JSON(http.StatusOK, gin.H{
"message": "用户已被封禁",
"success": false,
})
return
}
2024-04-05 04:10:43 +00:00
controller.SetupLogin(&user, c)
2023-04-22 12:39:27 +00:00
}
2024-04-05 04:10:43 +00:00
func LarkBind(c *gin.Context) {
2023-04-22 12:39:27 +00:00
code := c.Query("code")
2024-04-05 04:10:43 +00:00
larkUser, err := getLarkUserInfoByCode(code)
2023-04-22 12:39:27 +00:00
if err != nil {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": err.Error(),
})
return
}
user := model.User{
2024-04-05 04:10:43 +00:00
LarkId: larkUser.OpenID,
2023-04-22 12:39:27 +00:00
}
2024-04-05 04:10:43 +00:00
if model.IsLarkIdAlreadyTaken(user.LarkId) {
2023-04-22 12:39:27 +00:00
c.JSON(http.StatusOK, gin.H{
"success": false,
2024-04-05 04:10:43 +00:00
"message": "该飞书账户已被绑定",
2023-04-22 12:39:27 +00:00
})
return
}
session := sessions.Default(c)
id := session.Get("id")
// id := c.GetInt("id") // critical bug!
user.Id = id.(int)
err = user.FillUserById()
if err != nil {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": err.Error(),
})
return
}
2024-04-05 04:10:43 +00:00
user.LarkId = larkUser.OpenID
2023-04-22 12:39:27 +00:00
err = user.Update(false)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": err.Error(),
})
return
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"message": "bind",
})
return
}