diff --git a/cmd/cli/app/project/role/role_grant_list.go b/cmd/cli/app/project/role/role_grant_list.go index 46e18a4ac9..666764515a 100644 --- a/cmd/cli/app/project/role/role_grant_list.go +++ b/cmd/cli/app/project/role/role_grant_list.go @@ -18,7 +18,6 @@ package role import ( "context" "fmt" - "strconv" "strings" "time" @@ -88,7 +87,7 @@ func GrantListCommand(ctx context.Context, cmd *cobra.Command, _ []string, conn if len(resp.Invitations) > 0 { t := initializeTableForGrantListInvitations() for _, r := range resp.Invitations { - t.AddRow(r.Email, r.Role, r.SponsorDisplay, r.ExpiresAt.AsTime().Format(time.RFC3339), strconv.FormatBool(r.Expired), r.Code) + t.AddRow(r.Email, r.Role, r.SponsorDisplay, r.ExpiresAt.AsTime().Format(time.RFC3339)) } t.Render() } else { @@ -103,7 +102,7 @@ func initializeTableForGrantListRoleAssignments() table.Table { } func initializeTableForGrantListInvitations() table.Table { - return table.New(table.Simple, layouts.Default, []string{"Invitee", "Role", "Sponsor", "Expires At", "Expired", "Code"}) + return table.New(table.Simple, layouts.Default, []string{"Invitee", "Role", "Sponsor", "Expires At"}) } func init() { diff --git a/cmd/cli/app/project/role/role_update.go b/cmd/cli/app/project/role/role_update.go index aa6362e9c9..982f297702 100644 --- a/cmd/cli/app/project/role/role_update.go +++ b/cmd/cli/app/project/role/role_update.go @@ -17,7 +17,6 @@ package role import ( "context" - "time" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -70,16 +69,13 @@ func UpdateCommand(ctx context.Context, cmd *cobra.Command, _ []string, conn *gr cmd.Println(successMsg) - if email != "" { - t := initializeTableForGrantListInvitations() + // If it was an invitation, print the invite details + if len(ret.Invitations) != 0 { for _, r := range ret.Invitations { - expired := "No" - if r.Expired { - expired = "Yes" - } - t.AddRow(r.Email, r.Role, r.Sponsor, r.ExpiresAt.AsTime().Format(time.RFC3339), expired, r.Code) + // TODO: Add a url to the invite + cmd.Printf("Updated an invite for %s to %s on %s\n\nThe invitee can accept it by running: \n\nminder auth invite accept %s\n", + r.Email, r.Role, r.Project, r.Code) } - t.Render() return nil } // Otherwise, print the role assignments if it was about updating a role diff --git a/database/query/invitations.sql b/database/query/invitations.sql index d959ced88f..0cf9fe376f 100644 --- a/database/query/invitations.sql +++ b/database/query/invitations.sql @@ -4,7 +4,7 @@ -- the invitee. -- name: ListInvitationsForProject :many -SELECT user_invites.email, role, users.identity_subject, user_invites.created_at, user_invites.updated_at, user_invites.code +SELECT user_invites.email, role, users.identity_subject, user_invites.created_at, user_invites.updated_at FROM user_invites JOIN users ON user_invites.sponsor = users.id WHERE project = $1; diff --git a/internal/controlplane/handlers_authz.go b/internal/controlplane/handlers_authz.go index f12b832bdf..ed410d93d3 100644 --- a/internal/controlplane/handlers_authz.go +++ b/internal/controlplane/handlers_authz.go @@ -244,7 +244,11 @@ func (s *Server) ListRoleAssignments( for i := range as { identity, err := s.idClient.Resolve(ctx, as[i].Subject) if err != nil { - // if we can't resolve the subject, report the raw ID value + // If we can't resolve the subject, report the raw ID value + as[i].DisplayName = as[i].Subject + if mapIdToDisplay[as[i].Subject] == "" { + mapIdToDisplay[as[i].Subject] = as[i].Subject + } zerolog.Ctx(ctx).Error().Err(err).Msg("error resolving identity") continue } @@ -271,7 +275,7 @@ func (s *Server) ListRoleAssignments( Expired: invite.IsExpired(i.UpdatedAt), Sponsor: i.IdentitySubject, SponsorDisplay: mapIdToDisplay[i.IdentitySubject], - Code: i.Code, + // Code is explicitly not returned here }) } } @@ -359,11 +363,13 @@ func (s *Server) inviteUser( // If there are no invitations for this email, great, we should create one + sponsorDisplay := currentUser.IdentitySubject // Resolve the sponsor's identity and display name identity, err := s.idClient.Resolve(ctx, currentUser.IdentitySubject) if err != nil { zerolog.Ctx(ctx).Error().Err(err).Msg("error resolving identity") - return nil, util.UserVisibleError(codes.NotFound, "could not find identity %q", currentUser.IdentitySubject) + } else { + sponsorDisplay = identity.Human() } // Resolve the target project's display name @@ -395,8 +401,8 @@ func (s *Server) inviteUser( Project: userInvite.Project.String(), ProjectDisplay: prj.Name, Code: userInvite.Code, - Sponsor: identity.UserID, - SponsorDisplay: identity.Human(), + Sponsor: currentUser.IdentitySubject, + SponsorDisplay: sponsorDisplay, CreatedAt: timestamppb.New(userInvite.CreatedAt), ExpiresAt: invite.GetExpireIn7Days(userInvite.UpdatedAt), Expired: invite.IsExpired(userInvite.UpdatedAt), @@ -542,10 +548,12 @@ func (s *Server) removeInvite( } // Resolve the sponsor's identity and display name + sponsorDisplay := sponsorUser.IdentitySubject identity, err := s.idClient.Resolve(ctx, sponsorUser.IdentitySubject) if err != nil { zerolog.Ctx(ctx).Error().Err(err).Msg("error resolving identity") - return nil, util.UserVisibleError(codes.NotFound, "could not find identity %q", sponsorUser.IdentitySubject) + } else { + sponsorDisplay = identity.Human() } // Return the response @@ -559,7 +567,7 @@ func (s *Server) removeInvite( ExpiresAt: invite.GetExpireIn7Days(ret.UpdatedAt), Expired: invite.IsExpired(ret.UpdatedAt), Sponsor: sponsorUser.IdentitySubject, - SponsorDisplay: identity.Human(), + SponsorDisplay: sponsorDisplay, ProjectDisplay: prj.Name, }, }, nil @@ -722,7 +730,6 @@ func (s *Server) updateInvite( } return &minder.UpdateRoleResponse{ - // Leaving the role assignment empty as it's an invitation Invitations: []*minder.Invitation{ { Role: userInvite.Role, diff --git a/internal/db/invitations.sql.go b/internal/db/invitations.sql.go index b478679636..9ef2c9f865 100644 --- a/internal/db/invitations.sql.go +++ b/internal/db/invitations.sql.go @@ -230,7 +230,7 @@ func (q *Queries) GetInvitationsByEmailAndProject(ctx context.Context, arg GetIn const listInvitationsForProject = `-- name: ListInvitationsForProject :many -SELECT user_invites.email, role, users.identity_subject, user_invites.created_at, user_invites.updated_at, user_invites.code +SELECT user_invites.email, role, users.identity_subject, user_invites.created_at, user_invites.updated_at FROM user_invites JOIN users ON user_invites.sponsor = users.id WHERE project = $1 @@ -242,7 +242,6 @@ type ListInvitationsForProjectRow struct { IdentitySubject string `json:"identity_subject"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` - Code string `json:"code"` } // ListInvitationsForProject collects the information visible to project @@ -264,7 +263,6 @@ func (q *Queries) ListInvitationsForProject(ctx context.Context, project uuid.UU &i.IdentitySubject, &i.CreatedAt, &i.UpdatedAt, - &i.Code, ); err != nil { return nil, err }