github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/service/teams.go (about) 1 // Copyright 2017 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 4 // RPC handlers for team operations 5 6 package service 7 8 import ( 9 "fmt" 10 "time" 11 12 "github.com/go-errors/errors" 13 "github.com/keybase/client/go/protocol/gregor1" 14 15 "github.com/keybase/client/go/kbtime" 16 17 "github.com/keybase/client/go/chat/globals" 18 "github.com/keybase/client/go/externals" 19 "github.com/keybase/client/go/libkb" 20 "github.com/keybase/client/go/offline" 21 "github.com/keybase/client/go/protocol/chat1" 22 keybase1 "github.com/keybase/client/go/protocol/keybase1" 23 "github.com/keybase/client/go/teams" 24 "github.com/keybase/go-framed-msgpack-rpc/rpc" 25 "golang.org/x/net/context" 26 ) 27 28 type TeamsHandler struct { 29 *BaseHandler 30 globals.Contextified 31 connID libkb.ConnectionID 32 service *Service 33 } 34 35 var _ keybase1.TeamsInterface = (*TeamsHandler)(nil) 36 37 func NewTeamsHandler(xp rpc.Transporter, id libkb.ConnectionID, g *globals.Context, service *Service) *TeamsHandler { 38 return &TeamsHandler{ 39 BaseHandler: NewBaseHandler(g.ExternalG(), xp), 40 Contextified: globals.NewContextified(g), 41 connID: id, 42 service: service, 43 } 44 } 45 46 func (h *TeamsHandler) UntrustedTeamExists(ctx context.Context, teamName keybase1.TeamName) (res keybase1.UntrustedTeamExistsResult, err error) { 47 ctx = libkb.WithLogTag(ctx, "TM") 48 defer h.G().CTrace(ctx, fmt.Sprintf("UntrustedTeamExists(%s)", teamName), &err)() 49 mctx := libkb.NewMetaContext(ctx, h.G().ExternalG()) 50 return teams.GetUntrustedTeamExists(mctx, teamName) 51 } 52 53 func (h *TeamsHandler) TeamCreate(ctx context.Context, arg keybase1.TeamCreateArg) (res keybase1.TeamCreateResult, err error) { 54 ctx = libkb.WithLogTag(ctx, "TM") 55 arg2 := keybase1.TeamCreateWithSettingsArg{ 56 SessionID: arg.SessionID, 57 Name: arg.Name, 58 JoinSubteam: arg.JoinSubteam, 59 } 60 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 61 return res, err 62 } 63 return h.TeamCreateWithSettings(ctx, arg2) 64 } 65 66 func (h *TeamsHandler) TeamCreateFancy(ctx context.Context, arg keybase1.TeamCreateFancyArg) (teamID keybase1.TeamID, 67 err error) { 68 ctx = libkb.WithLogTag(ctx, "TM") 69 mctx := h.MetaContext(ctx) 70 teamInfo := arg.TeamInfo 71 defer h.G().CTrace(ctx, fmt.Sprintf("TeamCreateFancy(%s)", teamInfo.Name), &err)() 72 73 arg2 := keybase1.TeamCreateWithSettingsArg{ 74 Name: teamInfo.Name, 75 SessionID: arg.SessionID, 76 Settings: teamInfo.OpenSettings, 77 JoinSubteam: teamInfo.JoinSubteam, 78 } 79 teamCreateRes, err := h.TeamCreateWithSettings(ctx, arg2) 80 if err != nil { 81 return teamID, err 82 } 83 teamID = teamCreateRes.TeamID 84 85 var errs []error 86 if teamInfo.Description != "" { 87 err = teams.SetTeamShowcase(ctx, h.G().ExternalG(), teamID, nil, /* showcase */ 88 &teamInfo.Description, nil /* anyMemberShowcase */) 89 if err != nil { 90 errs = append(errs, err) 91 mctx.Error("SetTeamShowcase failed with: %s", err) 92 } 93 } 94 if teamInfo.ProfileShowcase { 95 err = teams.SetTeamMemberShowcase(ctx, h.G().ExternalG(), teamID, true /* isShowcased */) 96 if err != nil { 97 errs = append(errs, err) 98 mctx.Error("SetTeamMemberShowcase failed with: %s", err) 99 } 100 } 101 if teamInfo.Avatar != nil { 102 avatar := teamInfo.Avatar 103 arg3 := keybase1.UploadTeamAvatarArg{Teamname: teamInfo.Name, Filename: avatar.AvatarFilename, 104 Crop: avatar.Crop, SendChatNotification: false} 105 err = teams.ChangeTeamAvatar(mctx, arg3) 106 if err != nil { 107 errs = append(errs, err) 108 } 109 } 110 uid := gregor1.UID(h.G().GetMyUID().ToBytes()) 111 for _, topicName := range teamInfo.ChatChannels { 112 _, _, err = h.G().ChatHelper.NewConversation(ctx, uid, teamInfo.Name, 113 &topicName, chat1.TopicType_CHAT, chat1.ConversationMembersType_TEAM, keybase1.TLFVisibility_PRIVATE) 114 if err != nil { 115 errs = append(errs, err) 116 } 117 } 118 for _, subteamName := range teamInfo.Subteams { 119 name := teamInfo.Name + "." + subteamName 120 _, err = h.TeamCreate(ctx, keybase1.TeamCreateArg{SessionID: arg.SessionID, Name: name}) 121 if err != nil { 122 errs = append(errs, err) 123 } 124 } 125 126 if len(teamInfo.Users) > 0 { 127 arg4 := keybase1.TeamAddMembersMultiRoleArg{ 128 SessionID: arg.SessionID, 129 TeamID: teamID, 130 Users: teamInfo.Users, 131 SendChatNotification: false, 132 EmailInviteMessage: teamInfo.EmailInviteMessage, 133 // Add users to the default channels. 134 AddToChannels: nil, 135 } 136 137 unaddedUsers, err := h.TeamAddMembersMultiRole(ctx, arg4) 138 if err != nil { 139 errs = append(errs, err) 140 } 141 if len(unaddedUsers.NotAdded) > 0 { 142 errs = append(errs, fmt.Errorf("could not add members to team: %v", unaddedUsers.NotAdded)) 143 } 144 } 145 146 if errs == nil { 147 return teamID, nil 148 } 149 return teamID, libkb.CombineErrors(errs...) 150 } 151 152 func (h *TeamsHandler) TeamCreateWithSettings(ctx context.Context, arg keybase1.TeamCreateWithSettingsArg) (res keybase1.TeamCreateResult, err error) { 153 ctx = libkb.WithLogTag(ctx, "TM") 154 defer h.G().CTrace(ctx, fmt.Sprintf("TeamCreate(%s)", arg.Name), &err)() 155 156 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 157 return res, err 158 } 159 160 teamName, err := keybase1.TeamNameFromString(arg.Name) 161 if err != nil { 162 return res, err 163 } 164 if teamName.Depth() == 0 { 165 return res, fmt.Errorf("empty team name") 166 } 167 if !teamName.IsRootTeam() { 168 h.G().Log.CDebugf(ctx, "TeamCreate: creating a new subteam: %s", arg.Name) 169 parentName, err := teamName.Parent() 170 if err != nil { 171 return res, err 172 } 173 addSelfAs := keybase1.TeamRole_WRITER // writer is enough to init chat channel 174 if arg.JoinSubteam { 175 // but if user wants to stay in team, add as admin. 176 addSelfAs = keybase1.TeamRole_ADMIN 177 } 178 179 teamID, err := teams.CreateSubteam(ctx, h.G().ExternalG(), string(teamName.LastPart()), 180 parentName, addSelfAs) 181 if err != nil { 182 return res, err 183 } 184 res.TeamID = *teamID 185 186 // join the team to send the Create message 187 h.G().Log.CDebugf(ctx, "TeamCreate: created subteam %s with self in as %v", arg.Name, addSelfAs) 188 username := h.G().Env.GetUsername().String() 189 res.ChatSent = teams.SendTeamChatCreateMessage(ctx, h.G().ExternalG(), teamName.String(), username) 190 res.CreatorAdded = true 191 192 if !arg.JoinSubteam { 193 h.G().Log.CDebugf(ctx, "TeamCreate: leaving just-created subteam %s", arg.Name) 194 if err := teams.Leave(ctx, h.G().ExternalG(), teamName.String(), false); err != nil { 195 h.G().Log.CDebugf(ctx, "TeamCreate: error leaving new subteam %s: %s", arg.Name, err) 196 return res, err 197 } 198 h.G().Log.CDebugf(ctx, "TeamCreate: left just-created subteam %s", arg.Name) 199 res.CreatorAdded = false 200 } 201 } else { 202 teamID, err := teams.CreateRootTeam(ctx, h.G().ExternalG(), teamName.String(), arg.Settings) 203 if err != nil { 204 return res, err 205 } 206 res.TeamID = *teamID 207 res.CreatorAdded = true 208 // send system message that team was created 209 res.ChatSent = teams.SendTeamChatCreateMessage(ctx, h.G().ExternalG(), teamName.String(), h.G().Env.GetUsername().String()) 210 } 211 212 return res, nil 213 } 214 215 func (h *TeamsHandler) TeamGet(ctx context.Context, arg keybase1.TeamGetArg) (res keybase1.TeamDetails, err error) { 216 ctx = libkb.WithLogTag(ctx, "TM") 217 defer h.G().CTrace(ctx, fmt.Sprintf("TeamGet(%s)", arg.Name), &err)() 218 219 t, err := teams.GetAnnotatedTeamByName(ctx, h.G().ExternalG(), arg.Name) 220 if err != nil { 221 return res, err 222 } 223 return t.ToLegacyTeamDetails(), nil 224 } 225 226 func (h *TeamsHandler) TeamGetByID(ctx context.Context, arg keybase1.TeamGetByIDArg) (res keybase1.TeamDetails, err error) { 227 ctx = libkb.WithLogTag(ctx, "TM") 228 defer h.G().CTrace(ctx, fmt.Sprintf("TeamGetByID(%s)", arg.Id), &err)() 229 230 t, err := teams.GetAnnotatedTeam(ctx, h.G().ExternalG(), arg.Id) 231 if err != nil { 232 return res, err 233 } 234 return t.ToLegacyTeamDetails(), nil 235 } 236 237 func (h *TeamsHandler) GetAnnotatedTeam(ctx context.Context, arg keybase1.TeamID) (res keybase1.AnnotatedTeam, err error) { 238 ctx = libkb.WithLogTag(ctx, "TM") 239 defer h.G().CTrace(ctx, fmt.Sprintf("GetAnnotatedTeam(%s)", arg), &err)() 240 241 return teams.GetAnnotatedTeam(ctx, h.G().ExternalG(), arg) 242 } 243 244 func (h *TeamsHandler) GetAnnotatedTeamByName(ctx context.Context, arg string) (res keybase1.AnnotatedTeam, err error) { 245 ctx = libkb.WithLogTag(ctx, "TM") 246 defer h.G().CTrace(ctx, fmt.Sprintf("GetAnnotatedTeam(%s)", arg), &err)() 247 248 return teams.GetAnnotatedTeamByName(ctx, h.G().ExternalG(), arg) 249 } 250 251 func (h *TeamsHandler) TeamGetMembersByID(ctx context.Context, arg keybase1.TeamGetMembersByIDArg) (res []keybase1.TeamMemberDetails, err error) { 252 ctx = libkb.WithLogTag(ctx, "TM") 253 defer h.G().CTrace(ctx, fmt.Sprintf("TeamGetMembersByID(%s)", arg.Id), &err)() 254 255 t, err := teams.GetAnnotatedTeam(ctx, h.G().ExternalG(), arg.Id) 256 if err != nil { 257 return res, err 258 } 259 return t.Members, nil 260 } 261 262 func (h *TeamsHandler) TeamListUnverified(ctx context.Context, arg keybase1.TeamListUnverifiedArg) (res keybase1.AnnotatedTeamList, err error) { 263 ctx = libkb.WithLogTag(ctx, "TM") 264 defer h.G().CTrace(ctx, fmt.Sprintf("TeamList(%s)", arg.UserAssertion), &err)() 265 x, err := teams.ListTeamsUnverified(ctx, h.G().ExternalG(), arg) 266 if err != nil { 267 return keybase1.AnnotatedTeamList{}, err 268 } 269 return *x, nil 270 } 271 272 func (h *TeamsHandler) TeamListTeammates(ctx context.Context, arg keybase1.TeamListTeammatesArg) (res keybase1.AnnotatedTeamList, err error) { 273 ctx = libkb.WithLogTag(ctx, "TM") 274 defer h.G().CTrace(ctx, fmt.Sprintf("TeamListTeammates(%t)", arg.IncludeImplicitTeams), &err)() 275 x, err := teams.ListAll(ctx, h.G().ExternalG(), arg) 276 if err != nil { 277 return keybase1.AnnotatedTeamList{}, err 278 } 279 return *x, nil 280 } 281 282 func (h *TeamsHandler) TeamListVerified(ctx context.Context, arg keybase1.TeamListVerifiedArg) (res keybase1.AnnotatedTeamList, err error) { 283 ctx = libkb.WithLogTag(ctx, "TM") 284 defer h.G().CTrace(ctx, fmt.Sprintf("TeamListVerified(%s)", arg.UserAssertion), &err)() 285 x, err := teams.ListTeamsVerified(ctx, h.G().ExternalG(), arg) 286 if err != nil { 287 return keybase1.AnnotatedTeamList{}, err 288 } 289 return *x, nil 290 } 291 292 func (h *TeamsHandler) TeamGetSubteamsUnverified(ctx context.Context, arg keybase1.TeamGetSubteamsUnverifiedArg) (res keybase1.SubteamListResult, err error) { 293 ctx = libkb.WithLogTag(ctx, "TM") 294 defer h.G().CTrace(ctx, fmt.Sprintf("TeamGetSubteamsUnverified(%s)", arg.Name), &err)() 295 mctx := libkb.NewMetaContext(ctx, h.G().ExternalG()) 296 return teams.ListSubteamsUnverified(mctx, arg.Name) 297 } 298 299 func (h *TeamsHandler) TeamListSubteamsRecursive(ctx context.Context, arg keybase1.TeamListSubteamsRecursiveArg) (res []keybase1.TeamIDAndName, err error) { 300 ctx = libkb.WithLogTag(ctx, "TM") 301 defer h.G().CTrace(ctx, fmt.Sprintf("TeamListSubteamsRecursive(%s)", arg.ParentTeamName), &err)() 302 return teams.ListSubteamsRecursive(ctx, h.G().ExternalG(), arg.ParentTeamName, arg.ForceRepoll) 303 } 304 305 func (h *TeamsHandler) TeamAddMember(ctx context.Context, arg keybase1.TeamAddMemberArg) (res keybase1.TeamAddMemberResult, err error) { 306 ctx = libkb.WithLogTag(ctx, "TM") 307 defer h.G().CTrace(ctx, fmt.Sprintf("TeamAddMember(%s,username=%q,email=%q,phone=%q)", arg.TeamID, arg.Username, arg.Email, arg.Phone), 308 &err)() 309 310 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 311 return res, err 312 } 313 314 assertion := arg.Username 315 if arg.Email != "" || arg.Phone != "" { 316 var assertionURL libkb.AssertionURL 317 var err error 318 if arg.Email != "" { 319 assertionURL, err = libkb.ParseAssertionURLKeyValue(externals.MakeStaticAssertionContext(ctx), "email", arg.Email, true) 320 } else { 321 assertionURL, err = libkb.ParseAssertionURLKeyValue(externals.MakeStaticAssertionContext(ctx), "phone", arg.Phone, true) 322 } 323 if err != nil { 324 return res, err 325 } 326 assertion = assertionURL.String() 327 } 328 329 result, err := teams.AddMemberByID(ctx, h.G().ExternalG(), arg.TeamID, assertion, arg.Role, arg.BotSettings, arg.EmailInviteMessage) 330 if err != nil { 331 return res, err 332 } 333 334 if !arg.SendChatNotification { 335 return result, nil 336 } 337 338 if result.Invited { 339 return result, nil 340 } 341 342 result.ChatSending = true 343 go func() { 344 ctx := libkb.WithLogTag(context.Background(), "BG") 345 err := teams.SendTeamChatWelcomeMessage(ctx, h.G().ExternalG(), arg.TeamID, "", 346 result.User.Username, chat1.ConversationMembersType_TEAM, arg.Role) 347 if err != nil { 348 h.G().Log.CDebugf(ctx, "send team welcome message: error: %v", err) 349 } else { 350 h.G().Log.CDebugf(ctx, "send team welcome message: success") 351 } 352 }() 353 return result, nil 354 } 355 356 // TeamAddMembers returns err if adding members to team failed. 357 // Adding members is "all-or-nothing", except in the case that the 1st attempt 358 // fails due to some users having restrictive contact settings. In this 359 // situation, we retry adding just the non-restricted members. If this 2nd attempt 360 // succeeds, err=nil and TeamAddMembersResult contains a list of the users that 361 // weren't added. If the 2nd attempt fails, then an err is returned as usual. 362 func (h *TeamsHandler) TeamAddMembers(ctx context.Context, arg keybase1.TeamAddMembersArg) (res keybase1.TeamAddMembersResult, err error) { 363 ctx = libkb.WithLogTag(ctx, "TM") 364 defer h.G().CTrace(ctx, fmt.Sprintf("TeamAddMembers(%+v", arg), &err)() 365 366 var users []keybase1.UserRolePair 367 for _, a := range arg.Assertions { 368 users = append(users, keybase1.UserRolePair{Assertion: a, Role: arg.Role}) 369 } 370 arg2 := keybase1.TeamAddMembersMultiRoleArg{ 371 TeamID: arg.TeamID, 372 Users: users, 373 SendChatNotification: arg.SendChatNotification, 374 EmailInviteMessage: arg.EmailInviteMessage, 375 } 376 return h.TeamAddMembersMultiRole(ctx, arg2) 377 } 378 379 func (h *TeamsHandler) TeamAddMembersMultiRole(ctx context.Context, arg keybase1.TeamAddMembersMultiRoleArg) (res keybase1.TeamAddMembersResult, err error) { 380 ctx = libkb.WithLogTag(ctx, "TM") 381 382 debugString := "0" 383 if len(arg.Users) > 0 { 384 debugString = fmt.Sprintf("'%v'", arg.Users[0].Assertion) 385 if len(arg.Users) > 1 { 386 debugString = fmt.Sprintf("'%v' + %v more", arg.Users[0].Assertion, len(arg.Users)-1) 387 } 388 } 389 390 defer h.G().CTrace(ctx, fmt.Sprintf("TeamAddMembers(%s, %s)", arg.TeamID, debugString), 391 &err)() 392 if len(arg.Users) == 0 { 393 return res, fmt.Errorf("attempted to add 0 users to a team") 394 } 395 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 396 return res, err 397 } 398 399 added, notAdded, err := teams.AddMembers(ctx, h.G().ExternalG(), arg.TeamID, arg.Users, arg.EmailInviteMessage) 400 switch err := err.(type) { 401 case nil: 402 case teams.AddMembersError: 403 switch e := err.Err.(type) { 404 case libkb.IdentifySummaryError: 405 // Return the IdentifySummaryError, which is exportable. 406 // Frontend presents this error specifically. 407 return res, e 408 default: 409 return res, err 410 } 411 default: 412 return res, err 413 } 414 res = keybase1.TeamAddMembersResult{NotAdded: notAdded} 415 416 // AddMembers succeeded 417 if arg.SendChatNotification { 418 go func() { 419 h.G().Log.CDebugf(ctx, "sending team welcome messages") 420 ctx := libkb.WithLogTag(context.Background(), "BG") 421 for i, res := range added { 422 h.G().Log.CDebugf(ctx, "team welcome message for i:%v assertion:%v username:%v invite:%v, role: %v", 423 i, arg.Users[i].Assertion, res.Username, res.Invite, arg.Users[i].Role) 424 if !res.Invite && !res.Username.IsNil() { 425 err := teams.SendTeamChatWelcomeMessage(ctx, h.G().ExternalG(), arg.TeamID, "", 426 res.Username.String(), chat1.ConversationMembersType_TEAM, arg.Users[i].Role) 427 if err != nil { 428 h.G().Log.CDebugf(ctx, "send team welcome message [%v] err: %v", i, err) 429 } else { 430 h.G().Log.CDebugf(ctx, "send team welcome message [%v] success", i) 431 } 432 } else { 433 h.G().Log.CDebugf(ctx, "send team welcome message [%v] skipped", i) 434 } 435 } 436 h.G().Log.CDebugf(ctx, "done sending team welcome messages") 437 }() 438 } 439 440 var usernames []string 441 for _, user := range arg.Users { 442 // the server handles bot membership, skip these users 443 if !user.Role.IsBotLike() { 444 usernames = append(usernames, user.Assertion) 445 } 446 } 447 uid := gregor1.UID(h.G().GetMyUID().ToBytes()) 448 for _, convIDStr := range arg.AddToChannels { 449 convID, err := chat1.MakeConvID(convIDStr) 450 if err != nil { 451 return res, err 452 } 453 err = h.G().ChatHelper.BulkAddToConv(ctx, uid, convID, usernames) 454 if err != nil { 455 return res, err 456 } 457 } 458 return res, nil 459 } 460 461 func (h *TeamsHandler) TeamRemoveMember(ctx context.Context, arg keybase1.TeamRemoveMemberArg) (err error) { 462 ctx = libkb.WithLogTag(ctx, "TM") 463 defer h.G().CTrace(ctx, fmt.Sprintf("TeamRemoveMember(%s, %+v)", arg.TeamID, arg), &err)() 464 465 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 466 return err 467 } 468 469 return teams.RemoveMemberSingle(ctx, h.G().ExternalG(), arg.TeamID, arg.Member) 470 } 471 472 func (h *TeamsHandler) TeamRemoveMembers(ctx context.Context, arg keybase1.TeamRemoveMembersArg) (res keybase1.TeamRemoveMembersResult, err error) { 473 ctx = libkb.WithLogTag(ctx, "TM") 474 defer h.G().CTrace(ctx, fmt.Sprintf("TeamRemoveMembers(%s, %v)", arg.TeamID, arg), &err)() 475 if len(arg.Members) == 0 { 476 return res, errors.New("no members provided to TeamRemoveMembers") 477 } 478 479 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 480 return res, err 481 } 482 483 return teams.RemoveMembers(ctx, h.G().ExternalG(), arg.TeamID, arg.Members, arg.NoErrorOnPartialFailure) 484 } 485 486 func (h *TeamsHandler) TeamEditMember(ctx context.Context, arg keybase1.TeamEditMemberArg) (err error) { 487 ctx = libkb.WithLogTag(ctx, "TM") 488 defer h.G().CTrace(ctx, fmt.Sprintf("TeamEditMember(%s,%s,%s)", arg.Name, arg.Username, arg.Role), 489 &err)() 490 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 491 return err 492 } 493 return teams.EditMember(ctx, h.G().ExternalG(), arg.Name, arg.Username, arg.Role, arg.BotSettings) 494 } 495 496 func (h *TeamsHandler) TeamEditMembers(ctx context.Context, arg keybase1.TeamEditMembersArg) (res keybase1.TeamEditMembersResult, err error) { 497 ctx = libkb.WithLogTag(ctx, "TM") 498 debugString := "0" 499 if len(arg.Users) > 0 { 500 debugString = fmt.Sprintf("'%v, %v'", arg.Users[0].Assertion, arg.Users[0].Role) 501 if len(arg.Users) > 1 { 502 debugString = fmt.Sprintf("'%v' + %v more", arg.Users[0].Assertion, len(arg.Users)-1) 503 } 504 } 505 defer h.G().CTrace(ctx, fmt.Sprintf("TeamEditMembers(%s, %s)", arg.TeamID, debugString), 506 &err)() 507 if len(arg.Users) == 0 { 508 return res, nil 509 } 510 511 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 512 return res, err 513 } 514 515 return teams.EditMembers(ctx, h.G().ExternalG(), arg.TeamID, arg.Users) 516 } 517 518 func (h *TeamsHandler) TeamSetBotSettings(ctx context.Context, arg keybase1.TeamSetBotSettingsArg) (err error) { 519 ctx = libkb.WithLogTag(ctx, "TM") 520 defer h.G().CTrace(ctx, fmt.Sprintf("TeamSetBotSettings(%s,%s,%v)", arg.Name, arg.Username, arg.BotSettings), 521 &err)() 522 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 523 return err 524 } 525 return teams.SetBotSettings(ctx, h.G().ExternalG(), arg.Name, arg.Username, arg.BotSettings) 526 } 527 528 func (h *TeamsHandler) TeamGetBotSettings(ctx context.Context, arg keybase1.TeamGetBotSettingsArg) (res keybase1.TeamBotSettings, err error) { 529 ctx = libkb.WithLogTag(ctx, "TM") 530 defer h.G().CTrace(ctx, fmt.Sprintf("TeamGetBotSettings(%s,%s)", arg.Name, arg.Username), 531 &err)() 532 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 533 return res, err 534 } 535 return teams.GetBotSettings(ctx, h.G().ExternalG(), arg.Name, arg.Username) 536 } 537 538 func (h *TeamsHandler) TeamLeave(ctx context.Context, arg keybase1.TeamLeaveArg) (err error) { 539 ctx = libkb.WithLogTag(ctx, "TM") 540 defer h.G().CTrace(ctx, fmt.Sprintf("TeamLeave(%s)", arg.Name), &err)() 541 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 542 return err 543 } 544 return teams.Leave(ctx, h.G().ExternalG(), arg.Name, arg.Permanent) 545 } 546 547 func (h *TeamsHandler) TeamRename(ctx context.Context, arg keybase1.TeamRenameArg) (err error) { 548 ctx = libkb.WithLogTag(ctx, "TM") 549 defer h.G().CTrace(ctx, fmt.Sprintf("TeamRename(%s)", arg.PrevName), &err)() 550 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 551 return err 552 } 553 return teams.RenameSubteam(ctx, h.G().ExternalG(), arg.PrevName, arg.NewName) 554 } 555 556 func (h *TeamsHandler) TeamAcceptInvite(ctx context.Context, arg keybase1.TeamAcceptInviteArg) (err error) { 557 ctx = libkb.WithLogTag(ctx, "TM") 558 defer h.G().CTrace(ctx, "TeamAcceptInvite", &err)() 559 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 560 return err 561 } 562 563 // If token looks at all like Seitan, don't pass to functions that might 564 // log or send to server. 565 parsedToken, wasSeitany := teams.ParseSeitanTokenFromPaste(arg.Token) 566 if wasSeitany { 567 mctx := h.MetaContext(ctx) 568 ui := h.getTeamsUI(arg.SessionID) 569 _, err = teams.ParseAndAcceptSeitanToken(mctx, ui, parsedToken) 570 return err 571 } 572 573 // Fallback to legacy email TOFU token 574 return teams.AcceptServerTrustInvite(ctx, h.G().ExternalG(), arg.Token) 575 } 576 577 func (h *TeamsHandler) TeamRequestAccess(ctx context.Context, arg keybase1.TeamRequestAccessArg) (res keybase1.TeamRequestAccessResult, err error) { 578 ctx = libkb.WithLogTag(ctx, "TM") 579 h.G().CTrace(ctx, "TeamRequestAccess", &err)() 580 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 581 return keybase1.TeamRequestAccessResult{}, err 582 } 583 return teams.RequestAccess(ctx, h.G().ExternalG(), arg.Name) 584 } 585 586 func (h *TeamsHandler) TeamAcceptInviteOrRequestAccess(ctx context.Context, arg keybase1.TeamAcceptInviteOrRequestAccessArg) (res keybase1.TeamAcceptOrRequestResult, err error) { 587 ctx = libkb.WithLogTag(ctx, "TM") 588 defer h.G().CTrace(ctx, "TeamAcceptInviteOrRequestAccess", &err)() 589 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 590 return res, err 591 } 592 ui := h.getTeamsUI(arg.SessionID) 593 594 // If token looks at all like Seitan, don't pass to functions that might log or send to server. 595 maybeSeitan, keepSecret := teams.ParseSeitanTokenFromPaste(arg.TokenOrName) 596 if keepSecret { 597 mctx := h.MetaContext(ctx) 598 _, err = teams.ParseAndAcceptSeitanToken(mctx, ui, maybeSeitan) 599 return keybase1.TeamAcceptOrRequestResult{WasSeitan: true, WasToken: true}, err 600 } 601 return teams.TeamAcceptInviteOrRequestAccess(ctx, h.G().ExternalG(), ui, arg.TokenOrName) 602 } 603 604 func (h *TeamsHandler) TeamListRequests(ctx context.Context, arg keybase1.TeamListRequestsArg) (res []keybase1.TeamJoinRequest, err error) { 605 ctx = libkb.WithLogTag(ctx, "TM") 606 defer h.G().CTrace(ctx, "TeamListRequests", &err)() 607 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 608 return nil, err 609 } 610 return teams.ListRequests(ctx, h.G().ExternalG(), arg.TeamName) 611 } 612 613 func (h *TeamsHandler) TeamListMyAccessRequests(ctx context.Context, arg keybase1.TeamListMyAccessRequestsArg) (res []keybase1.TeamName, err error) { 614 ctx = libkb.WithLogTag(ctx, "TM") 615 defer h.G().CTrace(ctx, "TeamListMyAccessRequests", &err)() 616 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 617 return nil, err 618 } 619 return teams.ListMyAccessRequests(ctx, h.G().ExternalG(), arg.TeamName) 620 } 621 622 func (h *TeamsHandler) TeamIgnoreRequest(ctx context.Context, arg keybase1.TeamIgnoreRequestArg) (err error) { 623 ctx = libkb.WithLogTag(ctx, "TM") 624 defer h.G().CTrace(ctx, "TeamIgnoreRequest", &err)() 625 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 626 return err 627 } 628 return teams.IgnoreRequest(ctx, h.G().ExternalG(), arg.Name, arg.Username) 629 } 630 631 func (h *TeamsHandler) TeamTreeUnverified(ctx context.Context, arg keybase1.TeamTreeUnverifiedArg) (res keybase1.TeamTreeResult, err error) { 632 ctx = libkb.WithLogTag(ctx, "TM") 633 defer h.G().CTrace(ctx, "TeamTreeUnverified", &err)() 634 return teams.TeamTreeUnverified(ctx, h.G().ExternalG(), arg) 635 } 636 637 func (h *TeamsHandler) TeamDelete(ctx context.Context, arg keybase1.TeamDeleteArg) (err error) { 638 ctx = libkb.WithLogTag(ctx, "TM") 639 defer h.G().CTrace(ctx, fmt.Sprintf("TeamDelete(%s)", arg.TeamID), &err)() 640 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 641 return err 642 } 643 ui := h.getTeamsUI(arg.SessionID) 644 return teams.Delete(ctx, h.G().ExternalG(), ui, arg.TeamID) 645 } 646 647 func (h *TeamsHandler) TeamSetSettings(ctx context.Context, arg keybase1.TeamSetSettingsArg) (err error) { 648 ctx = libkb.WithLogTag(ctx, "TM") 649 defer h.G().CTrace(ctx, fmt.Sprintf("TeamSetSettings(%s)", arg.TeamID), &err)() 650 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 651 return err 652 } 653 return teams.ChangeTeamSettingsByID(ctx, h.G().ExternalG(), arg.TeamID, arg.Settings) 654 } 655 656 func (h *TeamsHandler) LoadTeamPlusApplicationKeys(ctx context.Context, arg keybase1.LoadTeamPlusApplicationKeysArg) (res keybase1.TeamPlusApplicationKeys, err error) { 657 ctx = libkb.WithLogTag(ctx, "TM") 658 ctx = libkb.WithLogTag(ctx, "LTPAK") 659 defer h.G().CTrace(ctx, fmt.Sprintf("LoadTeamPlusApplicationKeys(%s)", arg.Id), &err)() 660 661 mctx := libkb.NewMetaContext(ctx, h.G().ExternalG()) 662 loader := func(mctx libkb.MetaContext) (interface{}, error) { 663 return teams.LoadTeamPlusApplicationKeys(ctx, h.G().ExternalG(), arg.Id, arg.Application, arg.Refreshers, 664 arg.IncludeKBFSKeys) 665 } 666 667 // argKey is a copy of arg that's going to be used for a cache key, so clear out 668 // refreshers and sessionID, since they don't affect the cache key value. 669 argKey := arg 670 argKey.Refreshers = keybase1.TeamRefreshers{} 671 argKey.SessionID = 0 672 argKey.IncludeKBFSKeys = false 673 674 servedRes, err := h.service.offlineRPCCache.Serve(mctx, arg.Oa, offline.Version(1), "teams.loadTeamPlusApplicationKeys", true, argKey, &res, loader) 675 if err != nil { 676 return keybase1.TeamPlusApplicationKeys{}, err 677 } 678 if s, ok := servedRes.(keybase1.TeamPlusApplicationKeys); ok { 679 res = s 680 } 681 return res, nil 682 } 683 684 func (h *TeamsHandler) TeamCreateSeitanToken(ctx context.Context, arg keybase1.TeamCreateSeitanTokenArg) (token keybase1.SeitanIKey, err error) { 685 ctx = libkb.WithLogTag(ctx, "TM") 686 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 687 return "", err 688 } 689 return teams.CreateSeitanToken(ctx, h.G().ExternalG(), arg.Teamname, arg.Role, arg.Label) 690 } 691 692 func (h *TeamsHandler) TeamCreateSeitanTokenV2(ctx context.Context, arg keybase1.TeamCreateSeitanTokenV2Arg) (token keybase1.SeitanIKeyV2, err error) { 693 ctx = libkb.WithLogTag(ctx, "TM") 694 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 695 return "", err 696 } 697 return teams.CreateSeitanTokenV2(ctx, h.G().ExternalG(), arg.Teamname, arg.Role, arg.Label) 698 } 699 700 func (h *TeamsHandler) TeamCreateSeitanInvitelink(ctx context.Context, 701 arg keybase1.TeamCreateSeitanInvitelinkArg) (invitelink keybase1.Invitelink, err error) { 702 ctx = libkb.WithLogTag(ctx, "TM") 703 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 704 return invitelink, err 705 } 706 mctx := libkb.NewMetaContext(ctx, h.G().ExternalG()) 707 return teams.CreateInvitelink(mctx, arg.Teamname, arg.Role, arg.MaxUses, arg.Etime) 708 } 709 710 func (h *TeamsHandler) TeamCreateSeitanInvitelinkWithDuration(ctx context.Context, 711 arg keybase1.TeamCreateSeitanInvitelinkWithDurationArg) (invitelink keybase1.Invitelink, err error) { 712 ctx = libkb.WithLogTag(ctx, "TM") 713 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 714 return invitelink, err 715 } 716 717 mctx := libkb.NewMetaContext(ctx, h.G().ExternalG()) 718 719 var etimeUnixPtr *keybase1.UnixTime 720 if arg.ExpireAfter != nil { 721 etime, err := kbtime.AddLongDuration(h.G().Clock().Now(), *arg.ExpireAfter) 722 if err != nil { 723 return invitelink, err 724 } 725 mctx.Debug("Etime from duration %q is: %s", arg.ExpireAfter, etime.String()) 726 etimeUnix := keybase1.ToUnixTime(etime) 727 etimeUnixPtr = &etimeUnix 728 } 729 730 return teams.CreateInvitelink(mctx, arg.Teamname, arg.Role, arg.MaxUses, etimeUnixPtr) 731 } 732 733 func (h *TeamsHandler) GetTeamRootID(ctx context.Context, id keybase1.TeamID) (keybase1.TeamID, error) { 734 ctx = libkb.WithLogTag(ctx, "TM") 735 return teams.GetRootID(ctx, h.G().ExternalG(), id) 736 } 737 738 func (h *TeamsHandler) LookupImplicitTeam(ctx context.Context, arg keybase1.LookupImplicitTeamArg) (res keybase1.LookupImplicitTeamRes, err error) { 739 ctx = libkb.WithLogTag(ctx, "TM") 740 defer h.G().CTrace(ctx, fmt.Sprintf("LookupImplicitTeam(%s)", arg.Name), &err)() 741 var team *teams.Team 742 team, res.Name, res.DisplayName, err = 743 teams.LookupImplicitTeam(ctx, h.G().ExternalG(), arg.Name, arg.Public, teams.ImplicitTeamOptions{}) 744 if err == nil { 745 res.TeamID = team.ID 746 res.TlfID = team.LatestKBFSTLFID() 747 } 748 return res, err 749 } 750 751 func (h *TeamsHandler) LookupOrCreateImplicitTeam(ctx context.Context, arg keybase1.LookupOrCreateImplicitTeamArg) (res keybase1.LookupImplicitTeamRes, err error) { 752 ctx = libkb.WithLogTag(ctx, "TM") 753 defer h.G().CTrace(ctx, fmt.Sprintf("LookupOrCreateImplicitTeam(%s)", arg.Name), 754 &err)() 755 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 756 return res, err 757 } 758 var team *teams.Team 759 team, res.Name, res.DisplayName, err = teams.LookupOrCreateImplicitTeam(ctx, h.G().ExternalG(), 760 arg.Name, arg.Public) 761 if err == nil { 762 res.TeamID = team.ID 763 res.TlfID = team.LatestKBFSTLFID() 764 } 765 return res, err 766 } 767 768 func (h *TeamsHandler) TeamReAddMemberAfterReset(ctx context.Context, arg keybase1.TeamReAddMemberAfterResetArg) (err error) { 769 ctx = libkb.WithLogTag(ctx, "TM") 770 defer h.G().CTrace(ctx, fmt.Sprintf("TeamReAddMemberAfterReset(%s)", arg.Id), &err)() 771 if err := assertLoggedIn(ctx, h.G().ExternalG()); err != nil { 772 return err 773 } 774 return teams.ReAddMemberAfterReset(ctx, h.G().ExternalG(), arg.Id, arg.Username) 775 } 776 777 func (h *TeamsHandler) TeamAddEmailsBulk(ctx context.Context, arg keybase1.TeamAddEmailsBulkArg) (res keybase1.BulkRes, err error) { 778 ctx = libkb.WithLogTag(ctx, "TM") 779 defer h.G().CTrace(ctx, fmt.Sprintf("TeamAddEmailsBulk(%s)", arg.Name), &err)() 780 781 return teams.AddEmailsBulk(ctx, h.G().ExternalG(), arg.Name, arg.Emails, arg.Role) 782 } 783 784 func (h *TeamsHandler) GetTeamShowcase(ctx context.Context, teamID keybase1.TeamID) (ret keybase1.TeamShowcase, err error) { 785 ctx = libkb.WithLogTag(ctx, "TM") 786 defer h.G().CTrace(ctx, fmt.Sprintf("GetTeamShowcase(%s)", teamID), &err)() 787 788 return teams.GetTeamShowcase(ctx, h.G().ExternalG(), teamID) 789 } 790 791 func (h *TeamsHandler) GetTeamAndMemberShowcase(ctx context.Context, id keybase1.TeamID) (ret keybase1.TeamAndMemberShowcase, err error) { 792 ctx = libkb.WithLogTag(ctx, "TM") 793 defer h.G().CTrace(ctx, fmt.Sprintf("GetTeamAndMemberShowcase(%s)", id), &err)() 794 795 return teams.GetTeamAndMemberShowcase(ctx, h.G().ExternalG(), id) 796 } 797 798 func (h *TeamsHandler) SetTeamShowcase(ctx context.Context, arg keybase1.SetTeamShowcaseArg) (err error) { 799 ctx = libkb.WithLogTag(ctx, "TM") 800 defer h.G().CTrace(ctx, fmt.Sprintf("SetTeamShowcase(%s)", arg.TeamID), &err)() 801 802 err = teams.SetTeamShowcase(ctx, h.G().ExternalG(), arg.TeamID, arg.IsShowcased, arg.Description, arg.AnyMemberShowcase) 803 return err 804 } 805 806 func (h *TeamsHandler) SetTeamMemberShowcase(ctx context.Context, arg keybase1.SetTeamMemberShowcaseArg) (err error) { 807 ctx = libkb.WithLogTag(ctx, "TM") 808 defer h.G().CTrace(ctx, fmt.Sprintf("SetTeamMemberShowcase(%s)", arg.TeamID), &err)() 809 810 err = teams.SetTeamMemberShowcase(ctx, h.G().ExternalG(), arg.TeamID, arg.IsShowcased) 811 return err 812 } 813 814 func (h *TeamsHandler) CanUserPerform(ctx context.Context, teamname string) (ret keybase1.TeamOperation, err error) { 815 ctx = libkb.WithLogTag(ctx, "TM") 816 defer h.G().CTrace(ctx, fmt.Sprintf("CanUserPerform(%s)", teamname), &err)() 817 // We never want to return an error from this, the frontend has no proper reaction to an error from 818 // this RPC call. We retry until we work. 819 for { 820 if ret, err = teams.CanUserPerform(ctx, h.G().ExternalG(), teamname); err == nil { 821 break 822 } 823 select { 824 case <-ctx.Done(): 825 return ret, ctx.Err() 826 default: 827 } 828 time.Sleep(5 * time.Second) 829 } 830 return ret, err 831 } 832 833 func (h *TeamsHandler) TeamRotateKey(ctx context.Context, arg keybase1.TeamRotateKeyArg) (err error) { 834 ctx = libkb.WithLogTag(ctx, "TM") 835 defer h.G().CTrace(ctx, fmt.Sprintf("TeamRotateKey(%v)", arg.TeamID), &err)() 836 return teams.RotateKey(ctx, h.G().ExternalG(), arg) 837 } 838 839 func (h *TeamsHandler) TeamDebug(ctx context.Context, teamID keybase1.TeamID) (res keybase1.TeamDebugRes, err error) { 840 ctx = libkb.WithLogTag(ctx, "TM") 841 defer h.G().CTrace(ctx, fmt.Sprintf("TeamDebug(%v)", teamID), &err)() 842 843 return teams.TeamDebug(ctx, h.G().ExternalG(), teamID) 844 } 845 846 func (h *TeamsHandler) GetTarsDisabled(ctx context.Context, teamID keybase1.TeamID) (res bool, err error) { 847 ctx = libkb.WithLogTag(ctx, "TM") 848 defer h.G().CTrace(ctx, fmt.Sprintf("GetTarsDisabled(%s)", teamID), &err)() 849 850 return teams.GetTarsDisabled(ctx, h.G().ExternalG(), teamID) 851 } 852 853 func (h *TeamsHandler) SetTarsDisabled(ctx context.Context, arg keybase1.SetTarsDisabledArg) (err error) { 854 ctx = libkb.WithLogTag(ctx, "TM") 855 defer h.G().CTrace(ctx, fmt.Sprintf("SetTarsDisabled(%s,%t)", arg.TeamID, arg.Disabled), &err)() 856 857 return teams.SetTarsDisabled(ctx, h.G().ExternalG(), arg.TeamID, arg.Disabled) 858 } 859 860 func (h *TeamsHandler) TeamProfileAddList(ctx context.Context, arg keybase1.TeamProfileAddListArg) (res []keybase1.TeamProfileAddEntry, err error) { 861 ctx = libkb.WithLogTag(ctx, "TM") 862 defer h.G().CTrace(ctx, fmt.Sprintf("TeamProfileAddList(%v)", arg.Username), &err)() 863 864 return teams.TeamProfileAddList(ctx, h.G().ExternalG(), arg.Username) 865 } 866 867 func (h *TeamsHandler) UploadTeamAvatar(ctx context.Context, arg keybase1.UploadTeamAvatarArg) (err error) { 868 ctx = libkb.WithLogTag(ctx, "TM") 869 defer h.G().CTrace(ctx, fmt.Sprintf("UploadTeamAvatar(%s,%s)", arg.Teamname, arg.Filename), &err)() 870 871 mctx := libkb.NewMetaContext(ctx, h.G().ExternalG()) 872 return teams.ChangeTeamAvatar(mctx, arg) 873 } 874 875 func (h *TeamsHandler) TryDecryptWithTeamKey(ctx context.Context, arg keybase1.TryDecryptWithTeamKeyArg) (ret []byte, err error) { 876 ctx = libkb.WithLogTag(ctx, "TM") 877 defer h.G().CTrace(ctx, fmt.Sprintf("TryDecryptWithTeamKey(teamID:%s)", arg.TeamID), &err)() 878 879 mctx := libkb.NewMetaContext(ctx, h.G().ExternalG()) 880 return teams.TryDecryptWithTeamKey(mctx, arg) 881 } 882 883 func (h *TeamsHandler) FindNextMerkleRootAfterTeamRemoval(ctx context.Context, arg keybase1.FindNextMerkleRootAfterTeamRemovalArg) (res keybase1.NextMerkleRootRes, err error) { 884 ctx = libkb.WithLogTag(ctx, "TM") 885 defer h.G().CTrace(ctx, fmt.Sprintf("FindNextMerkleRootAfterTeamRemoval(%+v)", arg), &err)() 886 mctx := libkb.NewMetaContext(ctx, h.G().ExternalG()) 887 return libkb.FindNextMerkleRootAfterTeamRemoval(mctx, arg) 888 } 889 890 func (h *TeamsHandler) FindNextMerkleRootAfterTeamRemovalBySigningKey(ctx context.Context, arg keybase1.FindNextMerkleRootAfterTeamRemovalBySigningKeyArg) (res keybase1.NextMerkleRootRes, err error) { 891 ctx = libkb.WithLogTag(ctx, "TM") 892 defer h.G().CTrace(ctx, fmt.Sprintf("FindNextMerkleRootAfterTeamRemovalBySigningKey(%+v)", arg), &err)() 893 mctx := libkb.NewMetaContext(ctx, h.G().ExternalG()) 894 return teams.FindNextMerkleRootAfterRemoval(mctx, arg) 895 } 896 897 func (h *TeamsHandler) ProfileTeamLoad(ctx context.Context, arg keybase1.LoadTeamArg) (res keybase1.ProfileTeamLoadRes, err error) { 898 ctx = libkb.WithLogTag(ctx, "TM") 899 defer h.G().CTrace(ctx, fmt.Sprintf("ProfileTeamLoad(%+v)", arg), &err)() 900 mctx := libkb.NewMetaContext(ctx, h.G().ExternalG()) 901 return teams.ProfileTeamLoad(mctx, arg) 902 } 903 904 func (h *TeamsHandler) Ftl(ctx context.Context, arg keybase1.FastTeamLoadArg) (res keybase1.FastTeamLoadRes, err error) { 905 ctx = libkb.WithLogTag(ctx, "TM") 906 defer h.G().CTrace(ctx, fmt.Sprintf("Ftl(%+v)", arg), &err)() 907 mctx := libkb.NewMetaContext(ctx, h.G().ExternalG()) 908 return teams.FTL(mctx, arg) 909 910 } 911 912 func (h *TeamsHandler) GetTeamID(ctx context.Context, teamName string) (res keybase1.TeamID, err error) { 913 ctx = libkb.WithLogTag(ctx, "TM") 914 defer h.G().CTrace(ctx, fmt.Sprintf("GetTeamIDByName(%s)", teamName), &err)() 915 mctx := libkb.NewMetaContext(ctx, h.G().ExternalG()) 916 return teams.GetTeamIDByNameRPC(mctx, teamName) 917 } 918 919 func (h *TeamsHandler) GetTeamName(ctx context.Context, teamID keybase1.TeamID) (res keybase1.TeamName, err error) { 920 ctx = libkb.WithLogTag(ctx, "TM") 921 defer h.G().CTrace(ctx, fmt.Sprintf("GetTeamNameByID(%s)", teamID), &err)() 922 mctx := libkb.NewMetaContext(ctx, h.G().ExternalG()) 923 return teams.ResolveIDToName(mctx.Ctx(), mctx.G(), teamID) 924 } 925 926 func (h *TeamsHandler) GetTeamRoleMap(ctx context.Context) (res keybase1.TeamRoleMapAndVersion, err error) { 927 mctx := libkb.NewMetaContext(ctx, h.G().ExternalG()) 928 return mctx.G().GetTeamRoleMapManager().Get(mctx, true /* retry on fail */) 929 } 930 931 func (h *TeamsHandler) GetUntrustedTeamInfo(ctx context.Context, name keybase1.TeamName) (info keybase1.UntrustedTeamInfo, err error) { 932 ctx = libkb.WithLogTag(ctx, "TM") 933 defer h.G().CTrace(ctx, fmt.Sprintf("GetUntrustedTeamInfo(%s)", name), &err)() 934 mctx := libkb.NewMetaContext(ctx, h.G().ExternalG()) 935 return teams.GetUntrustedTeamInfo(mctx, name) 936 } 937 938 func (h *TeamsHandler) LoadTeamTreeMembershipsAsync(ctx context.Context, 939 arg keybase1.LoadTeamTreeMembershipsAsyncArg) (res keybase1.TeamTreeInitial, err error) { 940 ctx = libkb.WithLogTag(ctx, "TM") 941 ctx = libkb.WithLogTag(ctx, "TMTREE") 942 defer h.G().CTrace(ctx, fmt.Sprintf("LoadTeamTreeMembershipsAsync(%s, %s, %d)", 943 arg.TeamID, arg.Username, arg.SessionID), &err)() 944 945 mctx := libkb.NewMetaContext(ctx, h.G().ExternalG()) 946 loader, err := teams.NewTreeloader(mctx, arg.Username, arg.TeamID, 947 arg.SessionID, true /* includeAncestors */) 948 if err != nil { 949 return res, err 950 } 951 err = loader.LoadAsync(mctx) 952 if err != nil { 953 return res, err 954 } 955 return keybase1.TeamTreeInitial{Guid: arg.SessionID}, nil 956 } 957 958 func (h *TeamsHandler) GetInviteLinkDetails(ctx context.Context, inviteID keybase1.TeamInviteID) (details keybase1.InviteLinkDetails, err error) { 959 ctx = libkb.WithLogTag(ctx, "TM") 960 defer h.G().CTrace(ctx, fmt.Sprintf("GetInviteLinkDetails(%s)", inviteID), &err)() 961 mctx := libkb.NewMetaContext(ctx, h.G().ExternalG()) 962 return teams.GetInviteLinkDetails(mctx, inviteID) 963 } 964 965 func (h *TeamsHandler) FindAssertionsInTeamNoResolve(ctx context.Context, arg keybase1.FindAssertionsInTeamNoResolveArg) (ret []string, err error) { 966 ctx = libkb.WithLogTag(ctx, "TM") 967 traceMsg := fmt.Sprintf("FindAssertionsInTeam(%s, %d)", arg.TeamID, len(arg.Assertions)) 968 defer h.G().CTrace(ctx, traceMsg, &err)() 969 mctx := libkb.NewMetaContext(ctx, h.G().ExternalG()) 970 return teams.FindAssertionsInTeamNoResolve(mctx, arg.TeamID, arg.Assertions) 971 }