Skip to content

Commit

Permalink
fix: upgrade to feishu oauth v2
Browse files Browse the repository at this point in the history
  • Loading branch information
ChocoLZS authored and Makiras committed Oct 28, 2024
1 parent c52b435 commit 0e6e94e
Showing 1 changed file with 71 additions and 19 deletions.
90 changes: 71 additions & 19 deletions utils/auth.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package utils

import (
"strings"

"domain0/config"
"encoding/json"
"errors"
Expand All @@ -16,6 +18,7 @@ type AccessTokenInfo struct {
ExpiresIn int `json:"expires_in"`
RefreshToken string `json:"refresh_token"`
RefreshExpiresIn int `json:"refresh_expires_in"`
Scope string `json:"scope"`
}

type AuthInfo struct {
Expand All @@ -36,56 +39,106 @@ type AuthInfo struct {
// Mobile string `json:"mobile"`
}

type FeishuAuthInfoResponse struct {
Code int `json:"code"`
Message string `json:"msg"`
Data AuthInfo `json:"data"`
// enterprise email
var AuthScope = strings.Join([]string{"mail:user_mailbox:readonly"}, " ")

type FeishuGenericResponse[T any] struct {
Code int `json:"code"`
Message string `json:"msg"`
Data T `json:"data"`
}

type FeishuAccessTokenInfoResponse = FeishuGenericResponse[AccessTokenInfo]

type FeishuAuthInfoResponse = FeishuGenericResponse[AuthInfo]

type FeishuAppAccessTokenInfoResponse struct {
AppAccessToken string `json:"app_access_token"`
Code int `json:"code"`
Expire int `json:"expire"`
Msg string `json:"msg"`
TenantAccessToken string `json:"tenant_access_token"`
}

func FeishuRedirectToCodeURL() string {
return "https://passport.feishu.cn/suite/passport/oauth/authorize?client_id=" + config.CONFIG.Feishu.AppID +
return "https://open.feishu.cn/open-apis/authen/v1/authorize?app_id=" + config.CONFIG.Feishu.AppID +
"&redirect_uri=" + url.QueryEscape(config.CONFIG.Feishu.RedirectURL) +
"&response_type=code" +
"&scope=" + url.QueryEscape(AuthScope) +
"&state=feishu"
}

func feishuAppAccessTokenURL() string {
return "https://open.feishu.cn/open-apis/auth/v3/app_access_token/internal?app_id=" + config.CONFIG.Feishu.AppID +
"&app_secret=" + config.CONFIG.Feishu.AppSecret
}

func feishuRedirectToTokenURL(code string) string {
return "https://passport.feishu.cn/suite/passport/oauth/token?grant_type=authorization_code&client_id=" + config.CONFIG.Feishu.AppID +
"&client_secret=" + config.CONFIG.Feishu.AppSecret +
"&code=" + code +
"&redirect_uri=" + url.QueryEscape(config.CONFIG.Feishu.RedirectURL)
return "https://open.feishu.cn/open-apis/authen/v1/oidc/access_token?grant_type=authorization_code&code=" + code
}

func feishuGetUserInfoURL() string {
return "https://open.feishu.cn/open-apis/authen/v1/user_info"
}

func FeishuGetUserInfo(code string) (AuthInfo, error) {
// Query App access token
t := fiber.AcquireAgent()
defer fiber.ReleaseAgent(t)

app_req := t.Request()
app_req.Header.SetMethod("POST")
app_req.SetRequestURI(feishuAppAccessTokenURL())
if err := t.Parse(); err != nil {
logrus.Error(err)
return AuthInfo{}, err
}

hcode, body, errs := t.Bytes()
if len(errs) != 0 || hcode != 200 {
logrus.Error("fetch app token failed : ", string(body), errs)
return AuthInfo{}, errors.New("feishu auth failed")
}

var feishuAppAccessTokenInfo FeishuAppAccessTokenInfoResponse
err := json.Unmarshal(body, &feishuAppAccessTokenInfo)
if err != nil {
logrus.Error(err)
return AuthInfo{}, err
}
if feishuAppAccessTokenInfo.Code != 0 {
logrus.Error("fetch app token failed : ", feishuAppAccessTokenInfo.Msg)
return AuthInfo{}, errors.New("feishu auth failed")
}

// Query Access token
a := fiber.AcquireAgent()
defer fiber.ReleaseAgent(a)

act_req := a.Request()
act_req.Header.SetMethod("POST")
act_req.SetRequestURI(feishuRedirectToTokenURL(code))

act_req.Header.Set("Authorization", "Bearer "+feishuAppAccessTokenInfo.AppAccessToken)
if err := a.Parse(); err != nil {
logrus.Error(err)
return AuthInfo{}, err
}

hcode, body, errs := a.Bytes()
hcode, body, errs = a.Bytes()
if len(errs) != 0 || hcode != 200 {
logrus.Error(errs)
logrus.Error("fetch auth token failed : ", string(body), errs)
return AuthInfo{}, errors.New("feishu auth failed")
}

var accessTokenInfo AccessTokenInfo
err := json.Unmarshal(body, &accessTokenInfo)
var accessTokenInfo FeishuAccessTokenInfoResponse
err = json.Unmarshal(body, &accessTokenInfo)
if err != nil {
logrus.Error(err)
return AuthInfo{}, err
}
if accessTokenInfo.Code != 0 {
logrus.Error("fetch user info failed : ", accessTokenInfo.Message)
return AuthInfo{}, errors.New("feishu auth failed")
}

// Query User info
u := fiber.AcquireAgent()
Expand All @@ -94,10 +147,10 @@ func FeishuGetUserInfo(code string) (AuthInfo, error) {
user_req := u.Request()
user_req.Header.SetMethod("GET")
user_req.SetRequestURI(feishuGetUserInfoURL())
user_req.Header.Set("Authorization", "Bearer "+accessTokenInfo.AccessToken)
user_req.Header.Set("Authorization", "Bearer "+accessTokenInfo.Data.AccessToken)

if err := u.Parse(); err != nil {
logrus.Error(err)
logrus.Error("fetch user info failed : ", string(body), err)
return AuthInfo{}, err
}

Expand All @@ -114,9 +167,8 @@ func FeishuGetUserInfo(code string) (AuthInfo, error) {
return AuthInfo{}, err
}
if feishuInfoResponse.Code != 0 {
logrus.Error(feishuInfoResponse.Message)
logrus.Error("fetch user info failed : ", feishuInfoResponse.Message)
return AuthInfo{}, errors.New("feishu auth failed")
}

return feishuInfoResponse.Data, nil
}

0 comments on commit 0e6e94e

Please sign in to comment.