83 lines
1.9 KiB
Go
83 lines
1.9 KiB
Go
package machine
|
|
|
|
import (
|
|
"crypto/hmac"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/denisbrodbeck/machineid"
|
|
"github.com/evcc-io/evcc/core/keys"
|
|
"github.com/evcc-io/evcc/server/db/settings"
|
|
"github.com/samber/lo"
|
|
)
|
|
|
|
var (
|
|
id string
|
|
getMachineID = machineid.ID
|
|
)
|
|
|
|
// CustomID sets the machine id to a custom value
|
|
func CustomID(cid string) error {
|
|
if id != "" {
|
|
panic("machine id already generated")
|
|
}
|
|
|
|
cid = strings.TrimSpace(cid)
|
|
if l := len(cid); l != 32 && l != 64 {
|
|
return fmt.Errorf("expected 32 or 64 characters machine id, got %d", l)
|
|
}
|
|
|
|
id = cid
|
|
|
|
return nil
|
|
}
|
|
|
|
// RandomID creates a random id
|
|
func RandomID() string {
|
|
rnd := lo.RandomString(512, lo.LettersCharset)
|
|
mac := hmac.New(sha256.New, []byte(rnd))
|
|
return hex.EncodeToString(mac.Sum(nil))
|
|
}
|
|
|
|
// ID returns the platform specific machine id of the current host OS.
|
|
// If ID cannot be generated, a random one from settings will be used (generated on demand)
|
|
func ID() string {
|
|
if id == "" {
|
|
var err error
|
|
if id, err = getMachineID(); err == nil && id != "" {
|
|
return id
|
|
}
|
|
|
|
// no machine id found, use is from settings
|
|
return getOrCreateIDFromSettings()
|
|
}
|
|
|
|
return id
|
|
}
|
|
|
|
// getOrCreateIDFromSettings return instance id from settings if exists, otherwise creates and stores a new one
|
|
func getOrCreateIDFromSettings() string {
|
|
if id, err := settings.String(keys.Plant); err == nil && id != "" {
|
|
return id
|
|
}
|
|
|
|
id := RandomID()
|
|
settings.SetString(keys.Plant, id)
|
|
|
|
return id
|
|
}
|
|
|
|
// ProtectedID returns a hashed version of the machine id
|
|
// using a fixed, application-specific key.
|
|
func ProtectedID(key string) string {
|
|
return protect(key, ID())
|
|
}
|
|
|
|
// protect calculates HMAC-SHA256 of the id, keyed by key and returns a hex-encoded string
|
|
func protect(key, id string) string {
|
|
mac := hmac.New(sha256.New, []byte(id))
|
|
mac.Write([]byte(key))
|
|
return hex.EncodeToString(mac.Sum(nil))
|
|
}
|