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

     1  // Copyright 2019 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 idutil
     6  
     7  import (
     8  	"context"
     9  	"time"
    10  
    11  	"github.com/keybase/client/go/kbfs/kbfscrypto"
    12  	"github.com/keybase/client/go/kbfs/kbfsmd"
    13  	"github.com/keybase/client/go/kbfs/tlf"
    14  	kbname "github.com/keybase/client/go/kbun"
    15  	"github.com/keybase/client/go/protocol/keybase1"
    16  )
    17  
    18  // Resolver is an interface to be used to resolve assertions, implicit
    19  // teams and team TLF IDs.
    20  type Resolver interface {
    21  	// Resolve, given an assertion, resolves it to a username/UID
    22  	// pair. The username <-> UID mapping is trusted and
    23  	// immutable, so it can be cached. If the assertion is just
    24  	// the username or a UID assertion, then the resolution can
    25  	// also be trusted. If the returned pair is equal to that of
    26  	// the current session, then it can also be
    27  	// trusted. Otherwise, Identify() needs to be called on the
    28  	// assertion before the assertion -> (username, UserOrTeamID) mapping
    29  	// can be trusted.
    30  	//
    31  	//
    32  	// If the caller knows that the assertion needs to be resolvable
    33  	// while offline, they should pass in
    34  	// `keybase1.OfflineAvailability_BEST_EFFORT` as the `offline`
    35  	// parameter.  Otherwise `Resolve` might block on a network call.
    36  	//
    37  	// TODO: some of the above assumptions on cacheability aren't
    38  	// right for subteams, which can change their name, so this may
    39  	// need updating.
    40  	Resolve(ctx context.Context, assertion string,
    41  		offline keybase1.OfflineAvailability) (
    42  		kbname.NormalizedUsername, keybase1.UserOrTeamID, error)
    43  
    44  	// ResolveImplicitTeam resolves the given implicit team.
    45  	//
    46  	// If the caller knows that the team needs to be resolvable while
    47  	// offline, they should pass in
    48  	// `keybase1.OfflineAvailability_BEST_EFFORT` as the `offline`
    49  	// parameter.  Otherwise `ResolveImplicitTeam` might block on a
    50  	// network call.
    51  	ResolveImplicitTeam(
    52  		ctx context.Context, assertions, suffix string, tlfType tlf.Type,
    53  		offline keybase1.OfflineAvailability) (ImplicitTeamInfo, error)
    54  
    55  	// ResolveImplicitTeamByID resolves the given implicit team, given
    56  	// a team ID.
    57  	//
    58  	// If the caller knows that the team needs to be resolvable while
    59  	// offline, they should pass in
    60  	// `keybase1.OfflineAvailability_BEST_EFFORT` as the `offline`
    61  	// parameter.  Otherwise `ResolveImplicitTeamByID` might block on
    62  	// a network call.
    63  	ResolveImplicitTeamByID(
    64  		ctx context.Context, teamID keybase1.TeamID, tlfType tlf.Type,
    65  		offline keybase1.OfflineAvailability) (ImplicitTeamInfo, error)
    66  	// ResolveTeamTLFID returns the TLF ID associated with a given
    67  	// team ID, or tlf.NullID if no ID is yet associated with that
    68  	// team.
    69  	//
    70  	// If the caller knows that the ID needs to be resolved while
    71  	// offline, they should pass in
    72  	// `keybase1.OfflineAvailability_BEST_EFFORT` as the `offline`
    73  	// parameter.  Otherwise `ResolveTeamTLFID` might block on a
    74  	// network call.
    75  	ResolveTeamTLFID(
    76  		ctx context.Context, teamID keybase1.TeamID,
    77  		offline keybase1.OfflineAvailability) (tlf.ID, error)
    78  
    79  	// NormalizeSocialAssertion creates a SocialAssertion from its input and
    80  	// normalizes it.  The service name will be lowercased.  If the service is
    81  	// case-insensitive, then the username will also be lowercased.  Colon
    82  	// assertions (twitter:user) will be transformed to the user@twitter
    83  	// format.  Only registered services are allowed.
    84  	NormalizeSocialAssertion(
    85  		ctx context.Context, assertion string) (keybase1.SocialAssertion, error)
    86  }
    87  
    88  // NormalizedUsernameGetter is an interface that can get a normalized
    89  // username given an ID.
    90  type NormalizedUsernameGetter interface {
    91  	// GetNormalizedUsername returns the normalized username
    92  	// corresponding to the given UID.
    93  	//
    94  	// If the caller knows that the assertion needs to be resolvable
    95  	// while offline, they should pass in
    96  	// `keybase1.OfflineAvailability_BEST_EFFORT` as the `offline`
    97  	// parameter.  Otherwise `GetNormalizedUsername` might block on a
    98  	// network call.
    99  	GetNormalizedUsername(
   100  		ctx context.Context, id keybase1.UserOrTeamID,
   101  		offline keybase1.OfflineAvailability) (
   102  		kbname.NormalizedUsername, error)
   103  }
   104  
   105  // OfflineStatusGetter indicates whether a given TLF needs to be
   106  // available offline.
   107  type OfflineStatusGetter interface {
   108  	OfflineAvailabilityForPath(tlfPath string) keybase1.OfflineAvailability
   109  	OfflineAvailabilityForID(tlfID tlf.ID) keybase1.OfflineAvailability
   110  }
   111  
   112  // Identifier is an interface that can identify users and teams given
   113  // assertions.
   114  type Identifier interface {
   115  	// Identify resolves an assertion (which could also be a
   116  	// username) to a UserInfo struct, spawning tracker popups if
   117  	// necessary.  The reason string is displayed on any tracker
   118  	// popups spawned.
   119  	//
   120  	// If the caller knows that the assertion needs to be identifiable
   121  	// while offline, they should pass in
   122  	// `keybase1.OfflineAvailability_BEST_EFFORT` as the `offline`
   123  	// parameter.  Otherwise `Identify` might block on a network call.
   124  	Identify(ctx context.Context, assertion, reason string,
   125  		offline keybase1.OfflineAvailability) (
   126  		kbname.NormalizedUsername, keybase1.UserOrTeamID, error)
   127  	// IdentifyImplicitTeam identifies (and creates if necessary) the
   128  	// given implicit team.
   129  	//
   130  	// If the caller knows that the team needs to be identifiable
   131  	// while offline, they should pass in
   132  	// `keybase1.OfflineAvailability_BEST_EFFORT` as the `offline`
   133  	// parameter.  Otherwise `IdentifyImplicitTeam` might block on a
   134  	// network call.
   135  	IdentifyImplicitTeam(
   136  		ctx context.Context, assertions, suffix string, tlfType tlf.Type,
   137  		reason string, offline keybase1.OfflineAvailability) (
   138  		ImplicitTeamInfo, error)
   139  }
   140  
   141  // CurrentSessionGetter is an interface for objects that can return
   142  // session info.
   143  type CurrentSessionGetter interface {
   144  	// GetCurrentSession gets the current session info.
   145  	GetCurrentSession(ctx context.Context) (SessionInfo, error)
   146  }
   147  
   148  // KBPKI is an interface for something that can resolve, identify, get
   149  // user names, and get the current session.
   150  type KBPKI interface {
   151  	NormalizedUsernameGetter
   152  	Resolver
   153  	Identifier
   154  	CurrentSessionGetter
   155  }
   156  
   157  // Clock is an interface for getting the current time
   158  type Clock interface {
   159  	// Now returns the current time.
   160  	Now() time.Time
   161  }
   162  
   163  // MerkleRootGetter is an interface for getting and verifying global
   164  // Merkle roots.
   165  type MerkleRootGetter interface {
   166  	// GetCurrentMerkleRoot returns the current root of the global
   167  	// Keybase Merkle tree.
   168  	GetCurrentMerkleRoot(ctx context.Context) (
   169  		keybase1.MerkleRootV2, time.Time, error)
   170  	// VerifyMerkleRoot checks that the specified merkle root
   171  	// contains the given KBFS root; if not, it returns an error.
   172  	VerifyMerkleRoot(
   173  		ctx context.Context, root keybase1.MerkleRootV2,
   174  		kbfsRoot keybase1.KBFSRoot) error
   175  }
   176  
   177  // KeybaseService is a low-level interface for interacting with the
   178  // Keybase service process, for the purposes of resolving and
   179  // identifying users and teams.
   180  type KeybaseService interface {
   181  	MerkleRootGetter
   182  
   183  	// Resolve, given an assertion, resolves it to a username/UID
   184  	// pair. The username <-> UID mapping is trusted and
   185  	// immutable, so it can be cached. If the assertion is just
   186  	// the username or a UID assertion, then the resolution can
   187  	// also be trusted. If the returned pair is equal to that of
   188  	// the current session, then it can also be
   189  	// trusted. Otherwise, Identify() needs to be called on the
   190  	// assertion before the assertion -> (username, UID) mapping
   191  	// can be trusted.
   192  	//
   193  	// If the caller knows that the assertion needs to be resolvable
   194  	// while offline, they should pass in
   195  	// `keybase1.OfflineAvailability_BEST_EFFORT` as the `offline`
   196  	// parameter.  Otherwise `Resolve` might block on a network call.
   197  	Resolve(ctx context.Context, assertion string,
   198  		offline keybase1.OfflineAvailability) (
   199  		kbname.NormalizedUsername, keybase1.UserOrTeamID, error)
   200  
   201  	// Identify, given an assertion, returns a name and ID that
   202  	// matches that assertion, or an error otherwise. The reason
   203  	// string is displayed on any tracker popups spawned.
   204  	//
   205  	// If the caller knows that the assertion needs to be identifiable
   206  	// while offline, they should pass in
   207  	// `keybase1.OfflineAvailability_BEST_EFFORT` as the `offline`
   208  	// parameter.  Otherwise `Identify` might block on a network call.
   209  	Identify(ctx context.Context, assertion, reason string,
   210  		offline keybase1.OfflineAvailability) (
   211  		kbname.NormalizedUsername, keybase1.UserOrTeamID, error)
   212  
   213  	// NormalizeSocialAssertion creates a SocialAssertion from its input and
   214  	// normalizes it.  The service name will be lowercased.  If the service is
   215  	// case-insensitive, then the username will also be lowercased.  Colon
   216  	// assertions (twitter:user) will be transformed to the user@twitter
   217  	// format.  Only registered services are allowed.
   218  	NormalizeSocialAssertion(
   219  		ctx context.Context, assertion string) (keybase1.SocialAssertion, error)
   220  
   221  	// ResolveIdentifyImplicitTeam resolves, and optionally
   222  	// identifies, an implicit team.  If the implicit team doesn't yet
   223  	// exist, and doIdentifies is true, one is created.
   224  	//
   225  	// If the caller knows that the team needs to be resolvable while
   226  	// offline, they should pass in
   227  	// `keybase1.OfflineAvailability_BEST_EFFORT` as the `offline`
   228  	// parameter.  Otherwise `ResolveIdentifyImplicitTeam` might block
   229  	// on a network call.
   230  	ResolveIdentifyImplicitTeam(
   231  		ctx context.Context, assertions, suffix string, tlfType tlf.Type,
   232  		doIdentifies bool, reason string,
   233  		offline keybase1.OfflineAvailability) (ImplicitTeamInfo, error)
   234  
   235  	// ResolveImplicitTeamByID resolves an implicit team to a team
   236  	// name, given a team ID.
   237  	ResolveImplicitTeamByID(
   238  		ctx context.Context, teamID keybase1.TeamID) (string, error)
   239  
   240  	// CreateTeamTLF associates the given TLF ID with the team ID in
   241  	// the team's sigchain.  If the team already has a TLF ID
   242  	// associated with it, this overwrites it.
   243  	CreateTeamTLF(
   244  		ctx context.Context, teamID keybase1.TeamID, tlfID tlf.ID) error
   245  
   246  	// GetTeamSettings returns the KBFS settings for the given team.
   247  	//
   248  	// If the caller knows that the settings needs to be readable
   249  	// while offline, they should pass in
   250  	// `keybase1.OfflineAvailability_BEST_EFFORT` as the `offline`
   251  	// parameter.  Otherwise `GetTeamSettings` might block on a
   252  	// network call.
   253  	GetTeamSettings(
   254  		ctx context.Context, teamID keybase1.TeamID,
   255  		offline keybase1.OfflineAvailability) (keybase1.KBFSTeamSettings, error)
   256  
   257  	// LoadUserPlusKeys returns a UserInfo struct for a
   258  	// user with the specified UID.
   259  	// If you have the UID for a user and don't require Identify to
   260  	// validate an assertion or the identity of a user, use this to
   261  	// get UserInfo structs as it is much cheaper than Identify.
   262  	//
   263  	// pollForKID, if non empty, causes `PollForKID` field to be
   264  	// populated, which causes the service to poll for the given
   265  	// KID. This is useful during provisioning where the provisioner
   266  	// needs to get the MD revision that the provisionee has set the
   267  	// rekey bit on.
   268  	//
   269  	// If the caller knows that the user needs to be loadable while
   270  	// offline, they should pass in
   271  	// `keybase1.OfflineAvailability_BEST_EFFORT` as the `offline`
   272  	// parameter.  Otherwise `LoadUserPlusKeys` might block on a
   273  	// network call.
   274  	LoadUserPlusKeys(
   275  		ctx context.Context, uid keybase1.UID, pollForKID keybase1.KID,
   276  		offline keybase1.OfflineAvailability) (UserInfo, error)
   277  
   278  	// LoadTeamPlusKeys returns a TeamInfo struct for a team with the
   279  	// specified TeamID.  The caller can specify `desiredKeyGen` to
   280  	// force a server check if that particular key gen isn't yet
   281  	// known; it may be set to UnspecifiedKeyGen if no server check is
   282  	// required.  The caller can specify `desiredUID` and
   283  	// `desiredRole` to force a server check if that particular UID
   284  	// isn't a member of the team yet according to local caches; it
   285  	// may be set to "" if no server check is required.
   286  	//
   287  	// If the caller knows that the team needs to be loadable while
   288  	// offline, they should pass in
   289  	// `keybase1.OfflineAvailability_BEST_EFFORT` as the `offline`
   290  	// parameter.  Otherwise `LoadTeamPlusKeys` might block on a
   291  	// network call.
   292  	LoadTeamPlusKeys(ctx context.Context, tid keybase1.TeamID,
   293  		tlfType tlf.Type, desiredKeyGen kbfsmd.KeyGen,
   294  		desiredUser keybase1.UserVersion, desiredKey kbfscrypto.VerifyingKey,
   295  		desiredRole keybase1.TeamRole, offline keybase1.OfflineAvailability) (
   296  		TeamInfo, error)
   297  
   298  	// CurrentSession returns a SessionInfo struct with all the
   299  	// information for the current session, or an error otherwise.
   300  	CurrentSession(ctx context.Context, sessionID int) (
   301  		SessionInfo, error)
   302  }