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