github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/teams/conflicts.go (about)

     1  package teams
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/keybase/client/go/libkb"
     7  	"github.com/keybase/client/go/lru"
     8  	"github.com/keybase/client/go/protocol/keybase1"
     9  	"golang.org/x/net/context"
    10  )
    11  
    12  // Increment to invalidate the disk cache.
    13  const diskStorageVersionConflictInfo = 1
    14  
    15  type conflictID struct {
    16  	isPublic bool
    17  	id       keybase1.TeamID
    18  }
    19  
    20  func (i conflictID) MemKey() string {
    21  	prefix := "r"
    22  	if i.isPublic {
    23  		prefix = "u"
    24  	}
    25  	return fmt.Sprintf("%s%s", prefix, i.id)
    26  }
    27  
    28  func (i conflictID) DbKey() libkb.DbKey {
    29  	return libkb.DbKey{
    30  		Typ: libkb.ObjType(libkb.DBImplicitTeamConflictInfo),
    31  		Key: i.MemKey(),
    32  	}
    33  }
    34  
    35  var _ libkb.LRUKeyer = conflictID{}
    36  
    37  type rawGetConflictInfo struct {
    38  	Status       libkb.AppStatus                    `json:"status"`
    39  	ConflictInfo *keybase1.ImplicitTeamConflictInfo `json:"conflict_info"`
    40  }
    41  
    42  func (r *rawGetConflictInfo) GetAppStatus() *libkb.AppStatus {
    43  	return &r.Status
    44  }
    45  
    46  func GetConflictInfo(ctx context.Context, g *libkb.GlobalContext, id keybase1.TeamID, isFullyResolved bool, name keybase1.ImplicitTeamDisplayName) (ret keybase1.ImplicitTeamDisplayName, err error) {
    47  	mctx := libkb.NewMetaContext(ctx, g)
    48  	defer mctx.Trace(fmt.Sprintf("GetConflictInfo(%s,%v)", id, name), &err)()
    49  
    50  	ret = name.DeepCopy()
    51  
    52  	key := conflictID{name.IsPublic, id}
    53  	cv, err := g.GetImplicitTeamConflictInfoCacher().Get(ctx, g, key)
    54  	if err != nil {
    55  		mctx.Debug("In fetching from cache: %s", err.Error())
    56  	}
    57  	if cv != nil {
    58  		if p, ok := cv.(*keybase1.ImplicitTeamConflictInfo); ok {
    59  			if p.IsConflict() {
    60  				ret.ConflictInfo = p
    61  			}
    62  			return ret, nil
    63  		}
    64  		mctx.Debug("Bad element of wrong type from cache: %T", cv)
    65  	}
    66  
    67  	displayName, err := FormatImplicitTeamDisplayName(ctx, g, name)
    68  	if err != nil {
    69  		return ret, err
    70  	}
    71  
    72  	arg := libkb.NewAPIArg("team/conflict_info")
    73  	arg.SessionType = libkb.APISessionTypeREQUIRED
    74  	if name.IsPublic {
    75  		arg.SessionType = libkb.APISessionTypeOPTIONAL
    76  	}
    77  	arg.Args = libkb.HTTPArgs{
    78  		"tid":          libkb.S{Val: string(id)},
    79  		"display_name": libkb.S{Val: displayName},
    80  		"public":       libkb.B{Val: name.IsPublic},
    81  	}
    82  	var raw rawGetConflictInfo
    83  	if err = mctx.G().API.GetDecode(mctx, arg, &raw); err != nil {
    84  		return ret, err
    85  	}
    86  
    87  	ci := raw.ConflictInfo
    88  	ret.ConflictInfo = ci
    89  
    90  	// If the team is not fully resolved, and there isn't a conflict, there might
    91  	// still become a conflict in the future, so we decide not to cache it.
    92  	// Otherwise, the answer stays true indefinitely, so we can cache the value
    93  	// without fear of staleness.
    94  	if isFullyResolved || ci.IsConflict() {
    95  		tmpErr := mctx.G().GetImplicitTeamConflictInfoCacher().Put(ctx, g, key, ci)
    96  		if tmpErr != nil {
    97  			mctx.Debug("Failed to cached implicit team conflict info: %s", tmpErr.Error())
    98  		}
    99  	}
   100  
   101  	return ret, nil
   102  }
   103  
   104  func NewImplicitTeamConflictInfoCache(g *libkb.GlobalContext) *lru.Cache {
   105  	return lru.NewLRU(g, libkb.ImplicitTeamConflictInfoCacheSize, diskStorageVersionConflictInfo, keybase1.ImplicitTeamConflictInfo{})
   106  }
   107  
   108  func NewImplicitTeamConflictInfoCacheAndInstall(g *libkb.GlobalContext) {
   109  	cache := NewImplicitTeamConflictInfoCache(g)
   110  	g.SetImplicitTeamConflictInfoCacher(cache)
   111  	g.AddLogoutHook(cache, "implicitTeamConflictInfoCache")
   112  	g.AddDbNukeHook(cache, "implicitTeamConflictInfoCache")
   113  }