github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/pvl/registers.go (about)

     1  // Copyright 2016 Keybase, Inc. All rights reserved. Use of
     2  // this source code is governed by the included BSD license.
     3  
     4  package pvl
     5  
     6  import (
     7  	"regexp"
     8  
     9  	"github.com/keybase/client/go/libkb"
    10  	"github.com/keybase/client/go/protocol/keybase1"
    11  )
    12  
    13  // A store of named immutable (set-once) registers.
    14  type namedRegsStore struct {
    15  	// Values of set registers
    16  	m map[string]string
    17  	// Registers that cannot be set or read
    18  	banned map[string]bool
    19  }
    20  
    21  func newNamedRegsStore() *namedRegsStore {
    22  	return &namedRegsStore{
    23  		m:      make(map[string]string),
    24  		banned: make(map[string]bool),
    25  	}
    26  }
    27  
    28  func (r *namedRegsStore) Get(key string) (string, libkb.ProofError) {
    29  	err := r.validateKey(key)
    30  	if err != nil {
    31  		return "", err
    32  	}
    33  	banned := r.banned[key]
    34  	if banned {
    35  		return "", libkb.NewProofError(keybase1.ProofStatus_INVALID_PVL, "banned key '%v'", key)
    36  	}
    37  	val, ok := r.m[key]
    38  	if !ok {
    39  		return "", libkb.NewProofError(keybase1.ProofStatus_INVALID_PVL, "register '%v' is not set", key)
    40  	}
    41  	return val, nil
    42  }
    43  
    44  func (r *namedRegsStore) Set(key string, val string) libkb.ProofError {
    45  	err := r.validateKey(key)
    46  	if err != nil {
    47  		return err
    48  	}
    49  	banned := r.banned[key]
    50  	if banned {
    51  		return libkb.NewProofError(keybase1.ProofStatus_INVALID_PVL, "banned key '%v'", key)
    52  	}
    53  	_, alreadySet := r.m[key]
    54  	if alreadySet {
    55  		return libkb.NewProofError(keybase1.ProofStatus_INVALID_PVL, "register '%v' was already set", key)
    56  	}
    57  	r.m[key] = val
    58  	return nil
    59  }
    60  
    61  // Mark a register as unuseable
    62  func (r *namedRegsStore) Ban(key string) libkb.ProofError {
    63  	err := r.validateKey(key)
    64  	if err != nil {
    65  		return err
    66  	}
    67  	_, banned := r.banned[key]
    68  	if banned {
    69  		return libkb.NewProofError(keybase1.ProofStatus_INVALID_PVL, "cannot ban already banned register '%v'", key)
    70  	}
    71  	_, set := r.m[key]
    72  	if set {
    73  		return libkb.NewProofError(keybase1.ProofStatus_INVALID_PVL, "cannot ban already set register '%v'", key)
    74  	}
    75  	r.banned[key] = true
    76  	return nil
    77  }
    78  
    79  var keyRE = regexp.MustCompile(`^[a-z0-9_]+$`)
    80  
    81  // Make sure a key is a simple snake case name.
    82  // Does not check whether it's banned.
    83  func (r *namedRegsStore) validateKey(key string) libkb.ProofError {
    84  	if !keyRE.MatchString(key) {
    85  		return libkb.NewProofError(keybase1.ProofStatus_INVALID_PVL, "invalid register name '%v'", key)
    86  	}
    87  	return nil
    88  }