From bb05cf2928604ad9a7c43ab07a978d6e86479333 Mon Sep 17 00:00:00 2001 From: David Florness Date: Sat, 23 Jan 2021 18:19:50 -0500 Subject: [PATCH] Use .well-know/matrix/client to discover homeserver URL https://matrix.org/docs/spec/client_server/r0.6.1#get-well-known-matrix-client --- matrix/auth.go | 70 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/matrix/auth.go b/matrix/auth.go index 731dba8..d17fb8a 100644 --- a/matrix/auth.go +++ b/matrix/auth.go @@ -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 { -- 2.38.4