Skip to content

Commit

Permalink
Merge pull request #192 from vaelen/master
Browse files Browse the repository at this point in the history
Add a way to set the username and password via callback.
  • Loading branch information
alsm authored Mar 15, 2018
2 parents b01d90b + b3742dc commit 36d01c2
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 4 deletions.
14 changes: 10 additions & 4 deletions message.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,19 @@ func newConnectMsgFromOptions(options *ClientOptions) *packets.ConnectPacket {
m.WillMessage = options.WillPayload
}

if options.Username != "" {
username := options.Username
password := options.Password
if options.CredentialsProvider != nil {
username, password = options.CredentialsProvider()
}

if username != "" {
m.UsernameFlag = true
m.Username = options.Username
m.Username = username
//mustn't have password without user as well
if options.Password != "" {
if password != "" {
m.PasswordFlag = true
m.Password = []byte(options.Password)
m.Password = []byte(password)
}
}

Expand Down
14 changes: 14 additions & 0 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import (
"time"
)

// CredentialsProvider allows the username and password to be updated
// before reconnecting. It should return the current username and password.
type CredentialsProvider func() (username string, password string)

// MessageHandler is a callback type which can be set to be
// executed upon the arrival of messages published to topics
// to which the client is subscribed.
Expand All @@ -42,6 +46,7 @@ type ClientOptions struct {
ClientID string
Username string
Password string
CredentialsProvider CredentialsProvider
CleanSession bool
Order bool
WillEnabled bool
Expand Down Expand Up @@ -142,6 +147,15 @@ func (o *ClientOptions) SetPassword(p string) *ClientOptions {
return o
}

// SetCredentialsProvider will set a method to be called by this client when
// connecting to the MQTT broker that provide the current username and password.
// Note: without the use of SSL/TLS, this information will be sent
// in plaintext accross the wire.
func (o *ClientOptions) SetCredentialsProvider(p CredentialsProvider) *ClientOptions {
o.CredentialsProvider = p
return o
}

// SetCleanSession will set the "clean session" flag in the connect message
// when this client connects to an MQTT broker. By setting this flag, you are
// indicating that no messages saved by the broker for this client should be
Expand Down
52 changes: 52 additions & 0 deletions unit_message_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2013 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andrew Young
*/

package mqtt

import (
"testing"
)

func Test_UsernamePassword(t *testing.T) {
options := NewClientOptions()
options.Username = "username"
options.Password = "password"

m := newConnectMsgFromOptions(options)

if m.Username != "username" {
t.Fatalf("Username not set correctly")
}

if string(m.Password) != "password" {
t.Fatalf("Password not set correctly")
}
}

func Test_CredentialsProvider(t *testing.T) {
options := NewClientOptions()
options.Username = "incorrect"
options.Password = "incorrect"
options.SetCredentialsProvider(func() (username string, password string) {
return "username", "password"
})

m := newConnectMsgFromOptions(options)

if m.Username != "username" {
t.Fatalf("Username not set correctly")
}

if string(m.Password) != "password" {
t.Fatalf("Password not set correctly")
}
}

0 comments on commit 36d01c2

Please sign in to comment.