mirror of
https://github.com/gotify/cli.git
synced 2024-01-28 15:20:39 +03:00
252 lines
5.6 KiB
Go
252 lines
5.6 KiB
Go
package command
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"net/url"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"syscall"
|
|
|
|
apiruntime "github.com/go-openapi/runtime"
|
|
"github.com/gotify/cli/v2/config"
|
|
"github.com/gotify/cli/v2/utils"
|
|
"github.com/gotify/go-api-client/v2/auth"
|
|
api "github.com/gotify/go-api-client/v2/client"
|
|
"github.com/gotify/go-api-client/v2/client/application"
|
|
"github.com/gotify/go-api-client/v2/client/message"
|
|
"github.com/gotify/go-api-client/v2/gotify"
|
|
"github.com/gotify/go-api-client/v2/models"
|
|
"golang.org/x/crypto/ssh/terminal"
|
|
"gopkg.in/urfave/cli.v1"
|
|
)
|
|
|
|
func Init() cli.Command {
|
|
return cli.Command{
|
|
Name: "init",
|
|
Usage: "Initializes the Gotify-CLI",
|
|
Action: doInit,
|
|
}
|
|
}
|
|
|
|
func doInit(ctx *cli.Context) {
|
|
serverURL := inputServerURL()
|
|
hr()
|
|
token := inputToken(gotify.NewClient(serverURL, utils.CreateHTTPClient()))
|
|
hr()
|
|
|
|
conf := &config.Config{
|
|
URL: serverURL.String(),
|
|
Token: token,
|
|
}
|
|
|
|
pathToWrite, err := config.ExistingConfig(config.GetLocations())
|
|
|
|
var writeErr error
|
|
if err == config.ErrNoneSet {
|
|
pathToWrite = inputConfigLocation()
|
|
writeErr = config.WriteConfig(pathToWrite, conf)
|
|
} else {
|
|
writeErr = config.WriteConfig(pathToWrite, conf)
|
|
}
|
|
|
|
if writeErr == nil {
|
|
fmt.Println("Written config to:", pathToWrite)
|
|
} else {
|
|
fmt.Println("Something went wrong: ", writeErr)
|
|
}
|
|
}
|
|
|
|
func inputConfigLocation() string {
|
|
locations := config.GetLocations()
|
|
|
|
if len(locations) == 1 {
|
|
return locations[0]
|
|
}
|
|
|
|
for {
|
|
fmt.Println("Where to put the config file?")
|
|
for i, location := range locations {
|
|
fmt.Println(fmt.Sprintf("%d. %s", i+1, location))
|
|
}
|
|
value := inputString("Enter a number: ")
|
|
hr()
|
|
|
|
choice, err := strconv.Atoi(value)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
if choice > 0 && choice <= len(locations) {
|
|
indexedChoice := choice - 1
|
|
return locations[indexedChoice]
|
|
}
|
|
}
|
|
}
|
|
|
|
func inputString(text string) string {
|
|
fmt.Print(text)
|
|
reader := bufio.NewReader(os.Stdin)
|
|
readString, err := reader.ReadString('\n')
|
|
if err != nil {
|
|
utils.Exit1With(err)
|
|
}
|
|
return strings.TrimSpace(readString)
|
|
}
|
|
|
|
func inputToken(gotify *api.GotifyREST) string {
|
|
for {
|
|
fmt.Println("Configure an application token")
|
|
fmt.Println("1. Enter an application-token")
|
|
fmt.Println("2. Create an application token (with user/pass)")
|
|
value := inputString("Enter 1 or 2: ")
|
|
hr()
|
|
|
|
switch value {
|
|
case "1":
|
|
return inputRawToken(gotify)
|
|
case "2":
|
|
return inputCredentialsAndCreateToken(gotify)
|
|
}
|
|
}
|
|
}
|
|
|
|
func inputCredentialsAndCreateToken(gotify *api.GotifyREST) string {
|
|
for {
|
|
fmt.Println("Enter Credentials (only used for creating the token not saved afterwards)")
|
|
username := inputString("Username: ")
|
|
fmt.Print("Password: ")
|
|
password := readPassword()
|
|
basicAuth := auth.BasicAuth(username, password)
|
|
_, err := utils.SpinLoader("Authenticating", func(success chan interface{}, failure chan error) {
|
|
user, err := gotify.User.CurrentUser(nil, basicAuth)
|
|
if err == nil {
|
|
success <- *user.Payload
|
|
} else {
|
|
failure <- err
|
|
}
|
|
})
|
|
|
|
if err == nil {
|
|
hr()
|
|
return createToken(gotify, basicAuth)
|
|
}
|
|
}
|
|
}
|
|
|
|
func readPassword() string {
|
|
password, err := terminal.ReadPassword(int(syscall.Stdin))
|
|
if err != nil {
|
|
return inputString("")
|
|
}
|
|
fmt.Println()
|
|
return string(password)
|
|
}
|
|
|
|
func createToken(gotify *api.GotifyREST, auth apiruntime.ClientAuthInfoWriter) string {
|
|
for {
|
|
name := inputString("Application name: ")
|
|
if name == "" {
|
|
erred("Name may not be empty")
|
|
continue
|
|
}
|
|
description := inputString("Application description (can be empty): ")
|
|
|
|
resp, err := utils.SpinLoader("Creating", func(success chan interface{}, failure chan error) {
|
|
params := application.NewCreateAppParams()
|
|
params.Body = &models.Application{Name: name, Description: description}
|
|
resp, err := gotify.Application.CreateApp(params, auth)
|
|
if err == nil {
|
|
success <- *resp.Payload
|
|
} else {
|
|
failure <- err
|
|
}
|
|
})
|
|
|
|
if err == nil {
|
|
app := resp.(models.Application)
|
|
return app.Token
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func inputRawToken(gotify *api.GotifyREST) string {
|
|
for {
|
|
enteredToken := inputString("Application Token: ")
|
|
|
|
if len(enteredToken) != 15 {
|
|
fmt.Println("A application token must have a length of 15 characters")
|
|
hr()
|
|
continue
|
|
}
|
|
_, err := utils.SpinLoader("Validating", func(success chan interface{}, failure chan error) {
|
|
params := message.NewCreateMessageParams()
|
|
params.Body = &models.MessageExternal{
|
|
Title: "Test message",
|
|
Message: "Test message from Gotify CLI",
|
|
Priority: 0,
|
|
}
|
|
|
|
resp, err := gotify.Message.CreateMessage(params, auth.TokenAuth(enteredToken))
|
|
|
|
if err == nil {
|
|
success <- *resp.Payload
|
|
} else {
|
|
failure <- err
|
|
}
|
|
})
|
|
if err == nil {
|
|
return enteredToken
|
|
}
|
|
hr()
|
|
}
|
|
|
|
}
|
|
|
|
func inputServerURL() *url.URL {
|
|
for {
|
|
rawURL := inputString("Gotify URL: ")
|
|
parsedURL, err := url.Parse(rawURL)
|
|
if err != nil {
|
|
erred("Could not parse URL:", err)
|
|
continue
|
|
}
|
|
if parsedURL.Scheme == "" {
|
|
erred("Add a scheme to the url (http:// or https://)")
|
|
continue
|
|
}
|
|
|
|
if parsedURL.Host == "" {
|
|
erred("The host part of the url may not be empty")
|
|
continue
|
|
}
|
|
|
|
version, err := utils.SpinLoader("Connecting", func(success chan interface{}, failure chan error) {
|
|
client := gotify.NewClient(parsedURL, utils.CreateHTTPClient())
|
|
|
|
ver, e := client.Version.GetVersion(nil)
|
|
if e == nil {
|
|
success <- *ver.Payload
|
|
} else {
|
|
failure <- e
|
|
}
|
|
})
|
|
if err == nil {
|
|
info := version.(models.VersionInfo)
|
|
fmt.Println(fmt.Sprintf("Gotify v%s@%s", info.Version, info.BuildDate))
|
|
return parsedURL
|
|
}
|
|
hr()
|
|
}
|
|
}
|
|
|
|
func erred(data ...interface{}) {
|
|
fmt.Println(append([]interface{}{"Error"}, data...)...)
|
|
hr()
|
|
}
|
|
|
|
func hr() {
|
|
fmt.Println()
|
|
}
|