github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libkbfs/rekey_queue_test.go (about)

     1  // Copyright 2016 Keybase Inc. All rights reserved.
     2  // Use of this source code is governed by a BSD
     3  // license that can be found in the LICENSE file.
     4  
     5  package libkbfs
     6  
     7  import (
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/keybase/client/go/kbfs/tlf"
    12  	kbname "github.com/keybase/client/go/kbun"
    13  	"golang.org/x/net/context"
    14  )
    15  
    16  func TestRekeyQueueBasic(t *testing.T) {
    17  	var u1, u2, u3, u4 kbname.NormalizedUsername = "u1", "u2", "u3", "u4"
    18  	config1, _, ctx, cancel := kbfsOpsConcurInit(t, u1, u2, u3, u4)
    19  	defer kbfsConcurTestShutdown(ctx, t, config1, cancel)
    20  
    21  	config2 := ConfigAsUser(config1, u2)
    22  	defer CheckConfigAndShutdown(ctx, t, config2)
    23  	session2, err := config2.KBPKI().GetCurrentSession(context.Background())
    24  	if err != nil {
    25  		t.Fatal(err)
    26  	}
    27  	uid2 := session2.UID
    28  
    29  	config3 := ConfigAsUser(config1, u3)
    30  	defer CheckConfigAndShutdown(ctx, t, config3)
    31  	_, err = config3.KBPKI().GetCurrentSession(context.Background())
    32  	if err != nil {
    33  		t.Fatal(err)
    34  	}
    35  
    36  	config4 := ConfigAsUser(config1, u4)
    37  	defer CheckConfigAndShutdown(ctx, t, config4)
    38  	_, err = config4.KBPKI().GetCurrentSession(context.Background())
    39  	if err != nil {
    40  		t.Fatal(err)
    41  	}
    42  
    43  	kbfsOps1 := config1.KBFSOps()
    44  	var names []string
    45  
    46  	// Create a few shared folders
    47  	for i := 0; i < 3; i++ {
    48  		writers := []string{u1.String(), u2.String()}
    49  		if i > 0 {
    50  			writers = append(writers, u3.String())
    51  		}
    52  		if i > 1 {
    53  			writers = append(writers, u4.String())
    54  		}
    55  		name := strings.Join(writers, ",")
    56  		names = append(names, name)
    57  		// user 1 creates the directory
    58  		rootNode1 := GetRootNodeOrBust(ctx, t, config1, name, tlf.Private)
    59  		// user 1 creates a file
    60  		_, _, err = kbfsOps1.CreateFile(
    61  			ctx, rootNode1, testPPS("a"), false, NoExcl)
    62  		if err != nil {
    63  			t.Fatalf("Couldn't create file: %v", err)
    64  		}
    65  		err = kbfsOps1.SyncAll(ctx, rootNode1.GetFolderBranch())
    66  		if err != nil {
    67  			t.Fatalf("Couldn't sync all: %v", err)
    68  		}
    69  	}
    70  
    71  	// Create a new device for user 2
    72  	config2Dev2 := ConfigAsUser(config1, u2)
    73  	defer CheckConfigAndShutdown(ctx, t, config2Dev2)
    74  	AddDeviceForLocalUserOrBust(t, config1, uid2)
    75  	AddDeviceForLocalUserOrBust(t, config2, uid2)
    76  	devIndex := AddDeviceForLocalUserOrBust(t, config2Dev2, uid2)
    77  	SwitchDeviceForLocalUserOrBust(t, config2Dev2, devIndex)
    78  
    79  	// user 2 should be unable to read the data now since its device
    80  	// wasn't registered when the folder was originally created.
    81  	for _, name := range names {
    82  		_, err := GetRootNodeForTest(ctx, config2Dev2, name, tlf.Private)
    83  		if _, ok := err.(NeedSelfRekeyError); !ok {
    84  			t.Fatalf("Got unexpected error when reading with new key: %v", err)
    85  		}
    86  	}
    87  
    88  	fch := make(chan error, len(names))
    89  
    90  	// now user 1 should rekey via its rekey worker
    91  	for _, name := range names {
    92  		rootNode1 := GetRootNodeOrBust(ctx, t, config1, name, tlf.Private)
    93  		getRekeyFSM(ctx, config1.KBFSOps(), rootNode1.GetFolderBranch().Tlf).
    94  			listenOnEvent(rekeyFinishedEvent, func(e RekeyEvent) {
    95  				fch <- e.finished.err
    96  			}, false)
    97  		// queue it for rekey
    98  		config1.RekeyQueue().Enqueue(rootNode1.GetFolderBranch().Tlf)
    99  	}
   100  
   101  	// listen for all of the rekey results
   102  	for range names {
   103  		if err := <-fch; err != nil {
   104  			t.Fatal(err)
   105  		}
   106  	}
   107  
   108  	// user 2's new device should be able to read now
   109  	for _, name := range names {
   110  		_ = GetRootNodeOrBust(ctx, t, config2Dev2, name, tlf.Private)
   111  	}
   112  }