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

     1  // Copyright 2017 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 libfs
     6  
     7  import (
     8  	"context"
     9  	"os"
    10  
    11  	"github.com/keybase/client/go/kbfs/idutil"
    12  	"github.com/keybase/client/go/kbfs/libkbfs"
    13  	"github.com/keybase/client/go/kbfs/tlf"
    14  	"github.com/keybase/client/go/kbfs/tlfhandle"
    15  	"github.com/keybase/client/go/protocol/keybase1"
    16  )
    17  
    18  // IsWriter returns whether or not the currently logged-in user is a
    19  // valid writer for the folder described by `h`.
    20  func IsWriter(ctx context.Context, kbpki libkbfs.KBPKI,
    21  	osg idutil.OfflineStatusGetter, h *tlfhandle.Handle) (bool, error) {
    22  	session, err := idutil.GetCurrentSessionIfPossible(
    23  		ctx, kbpki, h.Type() == tlf.Public)
    24  	// We are using GetCurrentUserInfoIfPossible here so err is only non-nil if
    25  	// a real problem happened. If the user is logged out, we will get an empty
    26  	// username and uid, with a nil error.
    27  	if err != nil {
    28  		return false, err
    29  	}
    30  	if h.TypeForKeying() == tlf.TeamKeying {
    31  		tid, err := h.FirstResolvedWriter().AsTeam()
    32  		if err != nil {
    33  			return false, err
    34  		}
    35  		offline := keybase1.OfflineAvailability_NONE
    36  		if osg != nil {
    37  			offline = osg.OfflineAvailabilityForID(h.TlfID())
    38  		}
    39  		isWriter, err := kbpki.IsTeamWriter(
    40  			ctx, tid, session.UID, session.VerifyingKey, offline)
    41  		if err != nil {
    42  			return false, err
    43  		}
    44  		return isWriter, nil
    45  	}
    46  	return h.IsWriter(session.UID), nil
    47  }
    48  
    49  // WritePermMode fills in original based on whether or not the
    50  // currently logged-in user is a valid writer for the folder described
    51  // by `h`.
    52  func WritePermMode(
    53  	ctx context.Context, node libkbfs.Node, original os.FileMode,
    54  	kbpki libkbfs.KBPKI, osg idutil.OfflineStatusGetter,
    55  	h *tlfhandle.Handle) (os.FileMode, error) {
    56  	original &^= os.FileMode(0222) // clear write perm bits
    57  
    58  	if node != nil && node.Readonly(ctx) {
    59  		return original, nil
    60  	}
    61  
    62  	isWriter, err := IsWriter(ctx, kbpki, osg, h)
    63  	if err != nil {
    64  		return 0, err
    65  	}
    66  	if isWriter {
    67  		original |= 0200
    68  	}
    69  
    70  	return original, nil
    71  }