163 lines
4.4 KiB
Go
163 lines
4.4 KiB
Go
package github_auth
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"github.com/gofrs/uuid"
|
|
"github.com/gomodule/redigo/redis"
|
|
"ripper/internal/cache"
|
|
"strings"
|
|
)
|
|
|
|
type ClientAuthInfo struct {
|
|
ClientId string `json:"client_id"`
|
|
DisplayUserName string `json:"display_user_name,omitempty"`
|
|
DeviceCode string `json:"device_code"`
|
|
UserCode string `json:"user_code"`
|
|
CardCode string `json:"card_code"`
|
|
}
|
|
|
|
type ClientOAuthInfo struct {
|
|
ClientId string `json:"client_id" form:"client_id"`
|
|
Code string `json:"code" form:"code"`
|
|
ClientSecret string `json:"client_secret" form:"client_secret"`
|
|
Scope string `json:"scope" form:"scope"`
|
|
}
|
|
|
|
// BindClientToCode 绑定客户端到代码
|
|
// clientId 客户端ID
|
|
// exp 过期时间
|
|
// return 用户代码, 设备代码, 错误
|
|
func BindClientToCode(clientId string, exp int) (string, string, error) {
|
|
genCode := func() string {
|
|
newUUID, _ := uuid.NewV4()
|
|
uuidStr := strings.Replace(newUUID.String(), "-", "", -1)
|
|
return uuidStr[:6]
|
|
}
|
|
formattedUUID := genCode()
|
|
rep := 0
|
|
redisKey := fmt.Sprintf("copilot.proxy.%s", formattedUUID)
|
|
repeat, _ := cache.Exist(redisKey)
|
|
for repeat {
|
|
if rep > 5 {
|
|
return "", "", fmt.Errorf("gen code error")
|
|
}
|
|
formattedUUID = genCode()
|
|
redisKey = fmt.Sprintf("copilot.proxy.%s", formattedUUID)
|
|
repeat, _ = cache.Exist(redisKey)
|
|
rep++
|
|
}
|
|
devId := GenDevicesCode(40)
|
|
authInfo := ClientAuthInfo{
|
|
ClientId: clientId,
|
|
DeviceCode: devId,
|
|
UserCode: formattedUUID,
|
|
}
|
|
authInfoData, _ := json.Marshal(authInfo)
|
|
err := cache.Set(redisKey, authInfoData, exp)
|
|
if err != nil {
|
|
return "", "", err
|
|
}
|
|
redisKey = fmt.Sprintf("copilot.proxy.map.%s", devId)
|
|
err = cache.Set(redisKey, formattedUUID, exp)
|
|
return formattedUUID, devId, err
|
|
}
|
|
|
|
// GetClientAuthInfoByDeviceCode 通过设备代码获取客户端授权信息
|
|
func GetClientAuthInfoByDeviceCode(deviceCode string) (*ClientAuthInfo, error) {
|
|
redisKey := fmt.Sprintf("copilot.proxy.map.%s", deviceCode)
|
|
userCode, err := cache.Get(redisKey)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
redisKey = fmt.Sprintf("copilot.proxy.%s", userCode)
|
|
authInfoData, err := redis.Bytes(cache.Get(redisKey))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
authInfo := &ClientAuthInfo{}
|
|
err = json.Unmarshal(authInfoData, &authInfo)
|
|
return authInfo, err
|
|
}
|
|
|
|
func GetOAuthCodeInfoByClientIdAndCode(clientId string, code string) (*ClientOAuthInfo, error) {
|
|
cacheKey := "oauth2_authorize_" + clientId
|
|
oauthCodeData, err := redis.Bytes(cache.Get(cacheKey))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var oauthCode ClientOAuthInfo
|
|
err = json.Unmarshal(oauthCodeData, &oauthCode)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if oauthCode.Code != code {
|
|
return nil, fmt.Errorf("invalid oauth code")
|
|
}
|
|
return &oauthCode, nil
|
|
}
|
|
|
|
func GetClientAuthInfo(code string) (ClientAuthInfo, error) {
|
|
redisKey := fmt.Sprintf("copilot.proxy.%s", code)
|
|
authInfoData, err := redis.Bytes(cache.Get(redisKey))
|
|
if err != nil {
|
|
return ClientAuthInfo{}, err
|
|
}
|
|
var authInfo ClientAuthInfo
|
|
err = json.Unmarshal(authInfoData, &authInfo)
|
|
return authInfo, err
|
|
}
|
|
|
|
// GenDevicesCode 生成设备代码
|
|
func GenDevicesCode(codeLen int) string {
|
|
var newUUID string
|
|
for len(newUUID) < 64 {
|
|
ud, _ := uuid.NewV4()
|
|
newUUID += strings.Replace(ud.String(), "-", "", -1)
|
|
}
|
|
return newUUID[:codeLen]
|
|
}
|
|
|
|
// UpdateClientAuthStatusByDeviceCode 更新客户端授权码通过设备代码
|
|
func UpdateClientAuthStatusByDeviceCode(deviceCode string, cardCode string, displayUserName string) error {
|
|
redisKey := fmt.Sprintf("copilot.proxy.map.%s", deviceCode)
|
|
uCode, err := cache.Get(redisKey)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
redisKey = fmt.Sprintf("copilot.proxy.%s", uCode)
|
|
authInfoData, err := redis.Bytes(cache.Get(redisKey))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
authInfo := &ClientAuthInfo{}
|
|
err = json.Unmarshal(authInfoData, &authInfo)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
authInfo.CardCode = cardCode
|
|
if displayUserName != "" {
|
|
authInfo.DisplayUserName = displayUserName
|
|
}
|
|
authInfoData, _ = json.Marshal(authInfo)
|
|
err = cache.Set(redisKey, authInfoData, -1)
|
|
return err
|
|
}
|
|
|
|
func RemoveClientAuthInfoByDeviceCode(deviceCode string) error {
|
|
redisKey := fmt.Sprintf("copilot.proxy.map.%s", deviceCode)
|
|
uCode, err := cache.Get(redisKey)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
redisKey = fmt.Sprintf("copilot.proxy.%s", uCode)
|
|
err = cache.Del(redisKey)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
redisKey = fmt.Sprintf("copilot.proxy.map.%s", deviceCode)
|
|
err = cache.Del(redisKey)
|
|
return err
|
|
}
|