1package main 2 3import ( 4 "fmt" 5 "log" 6 "strings" 7 8 "github.com/rivo/tview" 9) 10 11type authStep int 12 13const ( 14 authNoneStep authStep = iota 15 authInstanceStep 16 authCodeStep 17) 18 19func NewAuthOverlay(app *App) *AuthOverlay { 20 a := &AuthOverlay{ 21 app: app, 22 Flex: tview.NewFlex(), 23 Input: tview.NewInputField(), 24 Text: tview.NewTextView(), 25 authStep: authNoneStep, 26 } 27 28 a.Flex.SetBackgroundColor(app.Config.Style.Background) 29 a.Input.SetBackgroundColor(app.Config.Style.Background) 30 a.Input.SetFieldBackgroundColor(app.Config.Style.Background) 31 a.Input.SetFieldTextColor(app.Config.Style.Text) 32 a.Text.SetBackgroundColor(app.Config.Style.Background) 33 a.Text.SetTextColor(app.Config.Style.Text) 34 a.Flex.SetDrawFunc(app.Config.ClearContent) 35 a.Draw() 36 return a 37} 38 39type AuthOverlay struct { 40 app *App 41 Flex *tview.Flex 42 Input *tview.InputField 43 Text *tview.TextView 44 authStep authStep 45 account AccountRegister 46 redirectURL string 47} 48 49func (a *AuthOverlay) GotInput() { 50 input := strings.TrimSpace(a.Input.GetText()) 51 switch a.authStep { 52 case authInstanceStep: 53 if !(strings.HasPrefix(input, "https://") || strings.HasPrefix(input, "http://")) { 54 input = "https://" + input 55 } 56 57 _, err := TryInstance(input) 58 if err != nil { 59 a.app.UI.CmdBar.ShowError(fmt.Sprintf("Couldn't connect to instance %s\n", input)) 60 return 61 } 62 63 acc, err := Authorize(input) 64 if err != nil { 65 a.app.UI.CmdBar.ShowError(fmt.Sprintf("Couldn't authorize. Error: %v\n", err)) 66 return 67 } 68 a.account = acc 69 openURL(a.app.Config.Media, acc.AuthURI) 70 a.Input.SetText("") 71 a.authStep = authCodeStep 72 a.Draw() 73 case authCodeStep: 74 client, err := AuthorizationCode(a.account, input) 75 if err != nil { 76 a.app.UI.CmdBar.ShowError(fmt.Sprintf("Couldn't verify the code. Error: %v\n", err)) 77 a.Input.SetText("") 78 return 79 } 80 path, _, err := CheckConfig("accounts.toml") 81 if err != nil { 82 log.Fatalf("Couldn't open the account file for reading. Error: %v", err) 83 } 84 ad := AccountData{ 85 Accounts: []Account{ 86 { 87 Server: client.Config.Server, 88 ClientID: client.Config.ClientID, 89 ClientSecret: client.Config.ClientSecret, 90 AccessToken: client.Config.AccessToken, 91 }, 92 }, 93 } 94 err = ad.Save(path) 95 if err != nil { 96 log.Fatalf("Couldn't save the account file. Error: %v", err) 97 } 98 a.app.API.SetClient(client) 99 a.app.HaveAccount = true 100 a.app.UI.LoggedIn() 101 } 102} 103 104func (a *AuthOverlay) Draw() { 105 switch a.authStep { 106 case authNoneStep: 107 a.authStep = authInstanceStep 108 a.Input.SetText("") 109 a.Draw() 110 return 111 case authInstanceStep: 112 a.Input.SetLabel("Instance: ") 113 a.Text.SetText("Enter the url of your instance. Will default to https://\nPress Enter when done") 114 case authCodeStep: 115 a.Text.SetText(fmt.Sprintf("The login URL has opened in your browser. If it didn't work open this URL\n%s", a.account.AuthURI)) 116 a.Input.SetLabel("Authorization code: ") 117 } 118} 119