build spotify-to-navidrome migrator with recovery flow
This commit is contained in:
101
internal/qobuz/signer.go
Normal file
101
internal/qobuz/signer.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package qobuz
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func signGet(path, appSecret string, query url.Values) (requestTS, requestSig string) {
|
||||
ts := nowTS()
|
||||
method := methodName(path)
|
||||
|
||||
keys := make([]string, 0, len(query))
|
||||
for k := range query {
|
||||
if k == "app_id" || k == "request_ts" || k == "request_sig" {
|
||||
continue
|
||||
}
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
b := strings.Builder{}
|
||||
b.WriteString(method)
|
||||
for _, k := range keys {
|
||||
vals := query[k]
|
||||
if len(vals) == 0 {
|
||||
continue
|
||||
}
|
||||
b.WriteString(k)
|
||||
b.WriteString(vals[0])
|
||||
}
|
||||
b.WriteString(ts)
|
||||
b.WriteString(appSecret)
|
||||
|
||||
h := md5.Sum([]byte(b.String()))
|
||||
return ts, hex.EncodeToString(h[:])
|
||||
}
|
||||
|
||||
func signPost(path, appSecret string, form url.Values, includeValues bool) (requestTS, requestSig string) {
|
||||
ts := nowTS()
|
||||
method := methodName(path)
|
||||
|
||||
keys := make([]string, 0, len(form))
|
||||
for k := range form {
|
||||
if k == "app_id" || k == "request_ts" || k == "request_sig" {
|
||||
continue
|
||||
}
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
b := strings.Builder{}
|
||||
b.WriteString(method)
|
||||
for _, k := range keys {
|
||||
b.WriteString(k)
|
||||
if includeValues {
|
||||
vals := form[k]
|
||||
if len(vals) > 0 {
|
||||
b.WriteString(vals[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
b.WriteString(ts)
|
||||
b.WriteString(appSecret)
|
||||
|
||||
h := md5.Sum([]byte(b.String()))
|
||||
return ts, hex.EncodeToString(h[:])
|
||||
}
|
||||
|
||||
func methodName(path string) string {
|
||||
return strings.ReplaceAll(strings.Trim(path, "/"), "/", "")
|
||||
}
|
||||
|
||||
func nowTS() string {
|
||||
return strconvI64(time.Now().Unix())
|
||||
}
|
||||
|
||||
func strconvI64(v int64) string {
|
||||
if v == 0 {
|
||||
return "0"
|
||||
}
|
||||
neg := v < 0
|
||||
if neg {
|
||||
v = -v
|
||||
}
|
||||
buf := [20]byte{}
|
||||
i := len(buf)
|
||||
for v > 0 {
|
||||
i--
|
||||
buf[i] = byte('0' + v%10)
|
||||
v /= 10
|
||||
}
|
||||
if neg {
|
||||
i--
|
||||
buf[i] = '-'
|
||||
}
|
||||
return string(buf[i:])
|
||||
}
|
||||
Reference in New Issue
Block a user