feat(github): support GPG verification (#7996 close #7986)

* feat(github): support GPG verification

* chore
This commit is contained in:
KirCute
2025-02-24 23:12:23 +08:00
committed by GitHub
parent 79bef0be9e
commit cdc41595bc
6 changed files with 193 additions and 69 deletions

View File

@ -1,14 +1,20 @@
package github
import (
"bytes"
"context"
"errors"
"fmt"
"io"
"strings"
"text/template"
"time"
"github.com/ProtonMail/go-crypto/openpgp"
"github.com/ProtonMail/go-crypto/openpgp/armor"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/pkg/utils"
"github.com/go-resty/resty/v2"
"strings"
"text/template"
)
type MessageTemplateVars struct {
@ -97,3 +103,65 @@ func getUsername(ctx context.Context) string {
}
return user.Username
}
func loadPrivateKey(key, passphrase string) (*openpgp.Entity, error) {
entityList, err := openpgp.ReadArmoredKeyRing(strings.NewReader(key))
if err != nil {
return nil, err
}
if len(entityList) < 1 {
return nil, fmt.Errorf("no keys found in key ring")
}
entity := entityList[0]
pass := []byte(passphrase)
if entity.PrivateKey != nil && entity.PrivateKey.Encrypted {
if err = entity.PrivateKey.Decrypt(pass); err != nil {
return nil, fmt.Errorf("password incorrect: %+v", err)
}
}
for _, subKey := range entity.Subkeys {
if subKey.PrivateKey != nil && subKey.PrivateKey.Encrypted {
if err = subKey.PrivateKey.Decrypt(pass); err != nil {
return nil, fmt.Errorf("password incorrect: %+v", err)
}
}
}
return entity, nil
}
func signCommit(m *map[string]interface{}, entity *openpgp.Entity) (string, error) {
var commit strings.Builder
commit.WriteString(fmt.Sprintf("tree %s\n", (*m)["tree"].(string)))
parents := (*m)["parents"].([]string)
for _, p := range parents {
commit.WriteString(fmt.Sprintf("parent %s\n", p))
}
now := time.Now()
_, offset := now.Zone()
hour := offset / 3600
author := (*m)["author"].(map[string]string)
commit.WriteString(fmt.Sprintf("author %s <%s> %d %+03d00\n", author["name"], author["email"], now.Unix(), hour))
author["date"] = now.Format(time.RFC3339)
committer := (*m)["committer"].(map[string]string)
commit.WriteString(fmt.Sprintf("committer %s <%s> %d %+03d00\n", committer["name"], committer["email"], now.Unix(), hour))
committer["date"] = now.Format(time.RFC3339)
commit.WriteString(fmt.Sprintf("\n%s", (*m)["message"].(string)))
data := commit.String()
var sigBuffer bytes.Buffer
err := openpgp.DetachSign(&sigBuffer, entity, strings.NewReader(data), nil)
if err != nil {
return "", fmt.Errorf("signing failed: %v", err)
}
var armoredSig bytes.Buffer
armorWriter, err := armor.Encode(&armoredSig, "PGP SIGNATURE", nil)
if err != nil {
return "", err
}
if _, err = io.Copy(armorWriter, &sigBuffer); err != nil {
return "", err
}
_ = armorWriter.Close()
return armoredSig.String(), nil
}