From 3561ad1fa60f54383271315d8482a4f38f22cfd8 Mon Sep 17 00:00:00 2001 From: Chris Rhodes Date: Sun, 17 Jan 2016 11:13:02 -0800 Subject: [PATCH 1/4] Add a LoginWithToken method which is a cheaper way to login. Closes #89. Eventually we should consider allowing Login/LoginWithToken to mutate s.Token, it would probably simplify the API a bit. --- restapi.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/restapi.go b/restapi.go index 3d2f6bb..cdb99d4 100644 --- a/restapi.go +++ b/restapi.go @@ -128,8 +128,8 @@ func unmarshal(data []byte, v interface{}) error { // Functions specific to Discord Sessions // ------------------------------------------------------------------------------------------------ -// Login asks the Discord server for an authentication token -func (s *Session) Login(email string, password string) (token string, err error) { +// Login asks the Discord server for an authentication token. +func (s *Session) Login(email, password string) (token string, err error) { data := struct { Email string `json:"email"` @@ -154,6 +154,18 @@ func (s *Session) Login(email string, password string) (token string, err error) return } +// LoginWithToken will verify a login token, or return a new one if it is invalid. +// This is the preferred way to login, as it uses less rate limiting quota. +func (s *Session) LoginWithToken(email, password, token string) (token string, err error) { + + old := s.Token + s.Token = token + token, err = s.Login(email, password) + s.Token = old + + return +} + // Register sends a Register request to Discord, and returns the authentication token // Note that this account is temporary and should be verified for future use. // Another option is to save the authentication token external, but this isn't recommended. From e2ab871e125c85f34cbbd1623be30ce8fc3b6596 Mon Sep 17 00:00:00 2001 From: Chris Rhodes Date: Sun, 17 Jan 2016 11:59:22 -0800 Subject: [PATCH 2/4] Fix colliding vars. --- restapi.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/restapi.go b/restapi.go index cdb99d4..5a1998c 100644 --- a/restapi.go +++ b/restapi.go @@ -156,11 +156,11 @@ func (s *Session) Login(email, password string) (token string, err error) { // LoginWithToken will verify a login token, or return a new one if it is invalid. // This is the preferred way to login, as it uses less rate limiting quota. -func (s *Session) LoginWithToken(email, password, token string) (token string, err error) { +func (s *Session) LoginWithToken(email, password, token string) (newToken string, err error) { old := s.Token s.Token = token - token, err = s.Login(email, password) + newToken, err = s.Login(email, password) s.Token = old return From 1d9f97e2832db1e8c5e8beb6d70c68d5809eb6d1 Mon Sep 17 00:00:00 2001 From: Chris Rhodes Date: Sun, 17 Jan 2016 14:17:51 -0800 Subject: [PATCH 3/4] Update New to allow an auth token to be specified. --- discord.go | 27 +++++++++++++++++++++------ restapi.go | 16 ++-------------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/discord.go b/discord.go index efd4af7..e77ec94 100644 --- a/discord.go +++ b/discord.go @@ -20,9 +20,15 @@ const VERSION = "0.10.0-alpha" // New creates a new Discord session and will automate some startup // tasks if given enough information to do so. Currently you can pass zero -// arguments and it will return an empty Discord session. If you pass a token -// or username and password (in that order), then it will attempt to login to -// Discord and open a websocket connection. +// arguments and it will return an empty Discord session. +// There are 3 ways to call New: +// With a single auth token - All requests will use the token blindly, +// no verification of the token will be done and requests may fail. +// With an email and password - Discord will sign in with the provided +// credentials. +// With an email, password and auth token - Discord will verify the auth +// token, if it is invalid it will sign in with the provided +// credentials. This is the Discord recommended way to sign in. func New(args ...interface{}) (s *Session, err error) { // Create an empty Session interface. @@ -46,7 +52,7 @@ func New(args ...interface{}) (s *Session, err error) { switch v := arg.(type) { case []string: - if len(v) > 2 { + if len(v) > 3 { err = fmt.Errorf("Too many string parameters provided.") return } @@ -61,6 +67,11 @@ func New(args ...interface{}) (s *Session, err error) { pass = v[1] } + // If third string exists, it must be an auth token. + if len(v) > 2 { + s.Token = v[2] + } + case string: // First string must be either auth token or username. // Second string must be a password. @@ -70,6 +81,8 @@ func New(args ...interface{}) (s *Session, err error) { auth = v } else if pass == "" { pass = v + } else if s.Token == "" { + s.Token = v } else { err = fmt.Errorf("Too many string parameters provided.") return @@ -85,11 +98,13 @@ func New(args ...interface{}) (s *Session, err error) { } // If only one string was provided, assume it is an auth token. - // Otherwise get auth token from Discord + // Otherwise get auth token from Discord, if a token was specified + // Discord will verify it for free, or log the user in if it is + // invalid. if pass == "" { s.Token = auth } else { - s.Token, err = s.Login(auth, pass) + err = s.Login(auth, pass) if err != nil || s.Token == "" { err = fmt.Errorf("Unable to fetch discord authentication token. %v", err) return diff --git a/restapi.go b/restapi.go index 5a1998c..e1e9d3a 100644 --- a/restapi.go +++ b/restapi.go @@ -129,7 +129,7 @@ func unmarshal(data []byte, v interface{}) error { // ------------------------------------------------------------------------------------------------ // Login asks the Discord server for an authentication token. -func (s *Session) Login(email, password string) (token string, err error) { +func (s *Session) Login(email, password string) (err error) { data := struct { Email string `json:"email"` @@ -150,19 +150,7 @@ func (s *Session) Login(email, password string) (token string, err error) { return } - token = temp.Token - return -} - -// LoginWithToken will verify a login token, or return a new one if it is invalid. -// This is the preferred way to login, as it uses less rate limiting quota. -func (s *Session) LoginWithToken(email, password, token string) (newToken string, err error) { - - old := s.Token - s.Token = token - newToken, err = s.Login(email, password) - s.Token = old - + s.Token = temp.Token return } From 3fbdb406defbb0d23facfd2bd7441ba2de8031de Mon Sep 17 00:00:00 2001 From: Chris Rhodes Date: Sun, 17 Jan 2016 14:19:46 -0800 Subject: [PATCH 4/4] Fix basic example. --- examples/api_basic/api_basic.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/api_basic/api_basic.go b/examples/api_basic/api_basic.go index d29d608..890fa9f 100644 --- a/examples/api_basic/api_basic.go +++ b/examples/api_basic/api_basic.go @@ -28,7 +28,7 @@ func main() { } // Login to the Discord server and store the authentication token - dg.Token, err = dg.Login(os.Args[1], os.Args[2]) + err = dg.Login(os.Args[1], os.Args[2]) if err != nil { fmt.Println(err) return