You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tailscale-android/libtailscale/store.go

95 lines
1.9 KiB
Go

// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
package libtailscale
import (
"encoding/base64"
"tailscale.com/ipn"
)
// stateStore is the Go interface for a persistent storage
// backend by androidx.security.crypto.EncryptedSharedPreferences (see
// App.java).
type stateStore struct {
// appCtx is the global Android app context.
appCtx AppContext
}
func newStateStore(appCtx AppContext) *stateStore {
return &stateStore{
appCtx: appCtx,
}
}
func prefKeyFor(id ipn.StateKey) string {
return "statestore-" + string(id)
}
func (s *stateStore) ReadString(key string, def string) (string, error) {
data, err := s.read(key)
if err != nil {
return def, err
}
if data == nil {
return def, nil
}
return string(data), nil
}
func (s *stateStore) WriteString(key string, val string) error {
return s.write(key, []byte(val))
}
func (s *stateStore) ReadBool(key string, def bool) (bool, error) {
data, err := s.read(key)
if err != nil {
return def, err
}
if data == nil {
return def, nil
}
return string(data) == "true", nil
}
func (s *stateStore) WriteBool(key string, val bool) error {
data := []byte("false")
if val {
data = []byte("true")
}
return s.write(key, data)
}
func (s *stateStore) ReadState(id ipn.StateKey) ([]byte, error) {
state, err := s.read(prefKeyFor(id))
if err != nil {
return nil, err
}
if state == nil {
return nil, ipn.ErrStateNotExist
}
return state, nil
}
func (s *stateStore) WriteState(id ipn.StateKey, bs []byte) error {
prefKey := prefKeyFor(id)
return s.write(prefKey, bs)
}
func (s *stateStore) read(key string) ([]byte, error) {
b64, err := s.appCtx.DecryptFromPref(key)
if err != nil {
return nil, err
}
if b64 == "" {
return nil, nil
}
return base64.RawStdEncoding.DecodeString(b64)
}
func (s *stateStore) write(key string, value []byte) error {
bs64 := base64.RawStdEncoding.EncodeToString(value)
return s.appCtx.EncryptToPref(key, bs64)
}