~edwargix/tallyard

bb05cf2928604ad9a7c43ab07a978d6e86479333 — David Florness 4 years ago ddaea91
Use .well-know/matrix/client to discover homeserver URL

https://matrix.org/docs/spec/client_server/r0.6.1#get-well-known-matrix-client
1 files changed, 46 insertions(+), 24 deletions(-)

M matrix/auth.go
M matrix/auth.go => matrix/auth.go +46 -24
@@ 6,8 6,10 @@ import (
	"fmt"
	"io/ioutil"
	"os"
	"syscall"

	"github.com/kyoh86/xdg"
	"golang.org/x/crypto/ssh/terminal"
	"maunium.net/go/mautrix"
	"maunium.net/go/mautrix/id"
)


@@ 56,48 58,68 @@ func stripNewline(s string) string {
}

func inquireForAuthInfo() (authInfo *AuthInfo, err error) {
	var (
		password string
		reader   = bufio.NewReader(os.Stdin)
	)
	reader := bufio.NewReader(os.Stdin)

	fmt.Println(`============================== DISCLAIMER ==============================
tallyard won't make any attempts to read your personal Matrix messages.
It uses a Matrix filter that restricts messages it reads to only those
with a type beginning with "xyz.tallyard.".  If you're skeptical, I
encourage you to read the source code.
========================================================================
`)

try:
	authInfo = &AuthInfo{}

	for authInfo.Homeserver == "" || authInfo.Homeserver == "\n" {
		fmt.Print("enter homeserver: ")
		authInfo.Homeserver, err = reader.ReadString('\n')
		if err != nil {
			return nil, fmt.Errorf("error reading homeserver: %s", err)
		}
	fmt.Print("Enter full Matrix username (@localpart:domain): ")
	username, err := reader.ReadString('\n')
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error reading username: %s\n", err)
		goto try
	}
	username = stripNewline(username)
	localPart, serverName, err := id.UserID(username).Parse()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error parsing username: %s\n", err)
		goto try
	}
	authInfo.Homeserver = stripNewline(authInfo.Homeserver)
	authInfo.Username = localPart

	for authInfo.Username == "" || authInfo.Username == "\n" {
		fmt.Print("enter username: ")
		authInfo.Username, err = reader.ReadString('\n')
	wellKnownResp, err := mautrix.DiscoverClientAPI(serverName)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error discovering homeserver: %s\n", err)
		goto try
	}
	if wellKnownResp == nil {
		fmt.Println("You should contact your homeserver sysadmin to setup /.well-known/matrix/client")
		fmt.Print("Enter homeserver: ")
		homeserver, err := reader.ReadString('\n')
		if err != nil {
			return nil, fmt.Errorf("error reading username: %s", err)
			fmt.Printf("Error reading homeserver: %s\n", err)
			goto try
		}
		authInfo.Homeserver = stripNewline(homeserver)
	} else {
		authInfo.Homeserver = wellKnownResp.Homeserver.BaseURL
	}
	authInfo.Username = stripNewline(authInfo.Username)

	for password == "" || password == "\n" {
		fmt.Print("enter password: ")
		password, err = reader.ReadString('\n')
		if err != nil {
			return nil, fmt.Errorf("error reading password: %s", err)
		}
	fmt.Print("Enter password: ")
	rawPassword, err := terminal.ReadPassword(syscall.Stdin)
	if err != nil {
		fmt.Printf("Error reading password: %s\n", err)
		goto try
	}
	password = stripNewline(password)

	client, err := mautrix.NewClient(authInfo.Homeserver, "", "")
	if err != nil {
		return nil, fmt.Errorf("error creating mautrix client: %s", err)
	}
	// entering a password doesn't insert a newline
	fmt.Printf("\nAttempting login...\n")
	respLogin, err := client.Login(&mautrix.ReqLogin{
		Type:             "m.login.password",
		Identifier:       mautrix.UserIdentifier{Type: mautrix.IdentifierTypeUser, User: authInfo.Username},
		Password:         password,
		Password:         string(rawPassword),
		StoreCredentials: true,
	})
	if err != nil {