92 lines
2.3 KiB
Go
92 lines
2.3 KiB
Go
package data
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"errors"
|
|
"nixcn-cms/internal/cryptography"
|
|
"strings"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/spf13/viper"
|
|
"gorm.io/datatypes"
|
|
)
|
|
|
|
type Client struct {
|
|
Id uint `json:"id" gorm:"primaryKey;autoIncrement"`
|
|
UUID uuid.UUID `json:"uuid" gorm:"type:uuid;uniqueIndex;not null"`
|
|
ClientId string `json:"client_id" gorm:"type:varchar(255);uniqueIndex;not null"`
|
|
ClientSecret string `json:"client_secret" gorm:"type:varchar(255);not null"`
|
|
ClientName string `json:"client_name" gorm:"type:varchar(255);uniqueIndex;not null"`
|
|
RedirectUri datatypes.JSON `json:"redirect_uri" gorm:"type:json;not null"`
|
|
}
|
|
|
|
func (self *Client) GetClientByClientId(clientId string) (*Client, error) {
|
|
var client Client
|
|
if err := Database.
|
|
Where("client_id = ?", clientId).
|
|
First(&client).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return &client, nil
|
|
}
|
|
|
|
func (self *Client) GetDecryptedSecret() (string, error) {
|
|
secretKey := viper.GetString("secrets.client_secret_key")
|
|
secret, err := cryptography.AESCBCDecrypt(self.ClientSecret, []byte(secretKey))
|
|
return string(secret), err
|
|
}
|
|
|
|
type ClientParams struct {
|
|
ClientId string
|
|
ClientName string
|
|
RedirectUri []string
|
|
}
|
|
|
|
func (self *Client) Create(params *ClientParams) (*Client, error) {
|
|
jsonRedirectUri, err := json.Marshal(params.RedirectUri)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
encKey := viper.GetString("secrets.client_secret_key")
|
|
b := make([]byte, 32)
|
|
if _, err := rand.Read(b); err != nil {
|
|
return nil, err
|
|
}
|
|
clientSecret := base64.RawURLEncoding.EncodeToString(b)
|
|
encryptedSecret, err := cryptography.AESCBCEncrypt([]byte(clientSecret), []byte(encKey))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
client := &Client{
|
|
UUID: uuid.New(),
|
|
ClientId: params.ClientId,
|
|
ClientSecret: encryptedSecret,
|
|
ClientName: params.ClientName,
|
|
RedirectUri: jsonRedirectUri,
|
|
}
|
|
|
|
if err := Database.Create(&client).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return client, nil
|
|
}
|
|
|
|
func (self *Client) ValidateRedirectURI(redirectURI string) error {
|
|
var uris []string
|
|
if err := json.Unmarshal(self.RedirectUri, &uris); err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, prefix := range uris {
|
|
if strings.HasPrefix(redirectURI, prefix) {
|
|
return nil
|
|
}
|
|
}
|
|
return errors.New("redirect uri not match")
|
|
}
|