fix: keep workbench user ids compatible
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
package httpapi
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type userID int64
|
||||
|
||||
func (id *userID) UnmarshalJSON(raw []byte) error {
|
||||
value, err := parseUserIDJSON(raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*id = userID(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
type optionalUserID struct {
|
||||
value int64
|
||||
set bool
|
||||
}
|
||||
|
||||
func (id *optionalUserID) UnmarshalJSON(raw []byte) error {
|
||||
if strings.TrimSpace(string(raw)) == "null" {
|
||||
id.set = true
|
||||
id.value = 0
|
||||
return nil
|
||||
}
|
||||
value, err := parseUserIDJSON(raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
id.set = true
|
||||
id.value = value
|
||||
return nil
|
||||
}
|
||||
|
||||
func (id optionalUserID) ptr() *int64 {
|
||||
if !id.set {
|
||||
return nil
|
||||
}
|
||||
return &id.value
|
||||
}
|
||||
|
||||
func parseUserIDJSON(raw []byte) (int64, error) {
|
||||
var text string
|
||||
if err := json.Unmarshal(raw, &text); err == nil {
|
||||
return parseUserID(text)
|
||||
}
|
||||
var number int64
|
||||
if err := json.Unmarshal(raw, &number); err == nil {
|
||||
return number, nil
|
||||
}
|
||||
return 0, fmt.Errorf("invalid user id")
|
||||
}
|
||||
|
||||
func parseUserID(value string) (int64, error) {
|
||||
value = strings.TrimSpace(value)
|
||||
if value == "" {
|
||||
return 0, fmt.Errorf("empty user id")
|
||||
}
|
||||
if strings.HasPrefix(value, "usr") {
|
||||
decoded, err := base64.URLEncoding.WithPadding(base64.NoPadding).DecodeString(strings.TrimPrefix(value, "usr"))
|
||||
if err != nil || len(decoded) < 8 {
|
||||
return 0, fmt.Errorf("invalid user id")
|
||||
}
|
||||
return int64(binary.LittleEndian.Uint64(decoded[:8])), nil
|
||||
}
|
||||
return strconv.ParseInt(value, 10, 64)
|
||||
}
|
||||
|
||||
func formatUserID(id int64) string {
|
||||
if id == 0 {
|
||||
return ""
|
||||
}
|
||||
src := make([]byte, 8)
|
||||
dst := make([]byte, base64.URLEncoding.WithPadding(base64.NoPadding).EncodedLen(8))
|
||||
binary.LittleEndian.PutUint64(src, uint64(id))
|
||||
base64.URLEncoding.WithPadding(base64.NoPadding).Encode(dst, src)
|
||||
return "usr" + string(dst)
|
||||
}
|
||||
|
||||
func parseUserIDList(values []userID) []int64 {
|
||||
items := make([]int64, 0, len(values))
|
||||
seen := make(map[int64]bool, len(values))
|
||||
for _, value := range values {
|
||||
id := int64(value)
|
||||
if id == 0 || seen[id] {
|
||||
continue
|
||||
}
|
||||
seen[id] = true
|
||||
items = append(items, id)
|
||||
}
|
||||
return items
|
||||
}
|
||||
Reference in New Issue
Block a user