| 58 | } |
| 59 | |
| 60 | func (e authEntry) String(cs *iostreams.ColorScheme) string { |
| 61 | var sb strings.Builder |
| 62 | |
| 63 | switch e.State { |
| 64 | case authEntryStateSuccess: |
| 65 | sb.WriteString( |
| 66 | fmt.Sprintf(" %s Logged in to %s account %s (%s)\n", cs.SuccessIcon(), e.Host, cs.Bold(e.Login), e.TokenSource), |
| 67 | ) |
| 68 | activeStr := fmt.Sprintf("%v", e.Active) |
| 69 | sb.WriteString(fmt.Sprintf(" - Active account: %s\n", cs.Bold(activeStr))) |
| 70 | sb.WriteString(fmt.Sprintf(" - Git operations protocol: %s\n", cs.Bold(e.GitProtocol))) |
| 71 | sb.WriteString(fmt.Sprintf(" - Token: %s\n", cs.Bold(e.Token))) |
| 72 | |
| 73 | if expectScopes(e.Token) { |
| 74 | sb.WriteString(fmt.Sprintf(" - Token scopes: %s\n", cs.Bold(displayScopes(e.Scopes)))) |
| 75 | if err := shared.HeaderHasMinimumScopes(e.Scopes); err != nil { |
| 76 | var missingScopesError *shared.MissingScopesError |
| 77 | if errors.As(err, &missingScopesError) { |
| 78 | missingScopes := strings.Join(missingScopesError.MissingScopes, ",") |
| 79 | sb.WriteString(fmt.Sprintf(" %s Missing required token scopes: %s\n", |
| 80 | cs.WarningIcon(), |
| 81 | cs.Bold(displayScopes(missingScopes)))) |
| 82 | refreshInstructions := fmt.Sprintf("gh auth refresh -h %s", e.Host) |
| 83 | sb.WriteString(fmt.Sprintf(" - To request missing scopes, run: %s\n", cs.Bold(refreshInstructions))) |
| 84 | } |
| 85 | } |
| 86 | } |
| 87 | |
| 88 | case authEntryStateError: |
| 89 | if e.Login != "" { |
| 90 | sb.WriteString(fmt.Sprintf(" %s Failed to log in to %s account %s (%s)\n", cs.Red("X"), e.Host, cs.Bold(e.Login), e.TokenSource)) |
| 91 | } else { |
| 92 | sb.WriteString(fmt.Sprintf(" %s Failed to log in to %s using token (%s)\n", cs.Red("X"), e.Host, e.TokenSource)) |
| 93 | } |
| 94 | activeStr := fmt.Sprintf("%v", e.Active) |
| 95 | sb.WriteString(fmt.Sprintf(" - Active account: %s\n", cs.Bold(activeStr))) |
| 96 | sb.WriteString(fmt.Sprintf(" - The token in %s is invalid.\n", e.TokenSource)) |
| 97 | if authTokenWriteable(e.TokenSource) { |
| 98 | loginInstructions := fmt.Sprintf("gh auth login -h %s", e.Host) |
| 99 | if shared.AuthTokenRefreshable(e.Token, e.TokenSource) { |
| 100 | loginInstructions = fmt.Sprintf("gh auth refresh -h %s", e.Host) |
| 101 | } |
| 102 | logoutInstructions := fmt.Sprintf("gh auth logout -h %s -u %s", e.Host, e.Login) |
| 103 | sb.WriteString(fmt.Sprintf(" - To re-authenticate, run: %s\n", cs.Bold(loginInstructions))) |
| 104 | sb.WriteString(fmt.Sprintf(" - To forget about this account, run: %s\n", cs.Bold(logoutInstructions))) |
| 105 | } |
| 106 | |
| 107 | case authEntryStateTimeout: |
| 108 | if e.Login != "" { |
| 109 | sb.WriteString(fmt.Sprintf(" %s Timeout trying to log in to %s account %s (%s)\n", cs.Red("X"), e.Host, cs.Bold(e.Login), e.TokenSource)) |
| 110 | } else { |
| 111 | sb.WriteString(fmt.Sprintf(" %s Timeout trying to log in to %s using token (%s)\n", cs.Red("X"), e.Host, e.TokenSource)) |
| 112 | } |
| 113 | activeStr := fmt.Sprintf("%v", e.Active) |
| 114 | sb.WriteString(fmt.Sprintf(" - Active account: %s\n", cs.Bold(activeStr))) |
| 115 | } |
| 116 | |
| 117 | return sb.String() |