Added ad-hoc authentication to UsergridClient, fixed some false-positive shared instance-based tests
- UsergridAuth now supports token-based init via new UsergridAuth(token)
- Added UsergridClient.usingAuth(auth) method and .tempAuth for ad-hoc
authentication
- Fixed several methods that inadvertently defaulted to using the
Usergrid shared instance. Further testing required.
diff --git a/helpers/build.js b/helpers/build.js
index 8d46952..b83fc86 100644
--- a/helpers/build.js
+++ b/helpers/build.js
@@ -21,24 +21,25 @@
_.isString(options.uuidOrName) ? options.uuidOrName : ""
)
},
- headers: function(client, auth) {
+ headers: function(client) {
var headers = {
'User-Agent': util.format("usergrid-nodejs/v%s", version)
}
- if (ok(auth).getIfExists('isValid')) {
- // checks if an auth param was passed to the request and uses the token if applicable
- _.assign(headers, {
- authorization: util.format("Bearer %s", auth.token)
- })
+ var token
+ if (ok(client).getIfExists('tempAuth.isValid')) {
+ // if ad-hoc authentication was set in the client, get the token and destroy the auth
+ token = client.tempAuth.token
+ client.tempAuth.destroy()
} else if (ok(client).getIfExists('authFallback') === UsergridAuth.AuthFallback.APP && ok(client).getIfExists('appAuth.isValid')) {
// if auth-fallback is set to APP, this request will make a call using the application token
- _.assign(headers, {
- authorization: util.format("Bearer %s", client.appAuth.token)
- })
+ token = client.appAuth.token
} else if (ok(client).getIfExists('currentUser.auth.isValid')) {
// defaults to using the current user's token
+ token = client.currentUser.auth.token
+ }
+ if (token) {
_.assign(headers, {
- authorization: util.format("Bearer %s", client.currentUser.auth.token)
+ authorization: util.format("Bearer %s", token)
})
}
return headers
diff --git a/helpers/client.js b/helpers/client.js
index 94da11e..f278178 100644
--- a/helpers/client.js
+++ b/helpers/client.js
@@ -6,9 +6,10 @@
module.exports = {
validate: function(args) {
var client
- if (args[0] instanceof UsergridClient) {
+ if (args instanceof UsergridClient) {
+ client = args
+ } else if (args[0] instanceof UsergridClient) {
client = args[0]
- args.shift()
} else if (Usergrid.isInitialized) {
client = Usergrid
} else {
diff --git a/lib/auth.js b/lib/auth.js
index 7d8eefa..672637b 100644
--- a/lib/auth.js
+++ b/lib/auth.js
@@ -3,21 +3,21 @@
var UsergridAuth = function(token, expiry) {
var self = this
- self.token = token || undefined
+ self.token = token
self.expiry = expiry || 0
var usingToken = (token) ? true : false
Object.defineProperty(self, "hasToken", {
get: function() {
- return (typeof self.token === 'string' && self.token.length > 0)
+ return (self.token) ? true : false
},
configurable: true
})
Object.defineProperty(self, "isExpired", {
get: function() {
- return usingToken || (Date.now() >= self.expiry)
+ return (usingToken) ? false : (Date.now() >= self.expiry)
},
configurable: true
})
@@ -30,7 +30,8 @@
})
Object.defineProperty(self, 'tokenTtl', {
- configurable: true
+ configurable: true,
+ writable: true
})
return self
diff --git a/lib/client.js b/lib/client.js
index 898478c..a6fb920 100644
--- a/lib/client.js
+++ b/lib/client.js
@@ -9,7 +9,6 @@
UsergridUserAuth = require('./userAuth'),
_ = require('lodash')
-console.log(UsergridAuth.AuthFallback)
var defaultOptions = {
baseUrl: 'https://api.usergrid.com',
authFallback: UsergridAuth.AuthFallback.NONE
@@ -19,6 +18,8 @@
var self = this
var __appAuth
+ self.tempAuth = undefined
+ self.isSharedInstance = false
if (arguments.length === 2) {
self.orgId = arguments[0]
@@ -74,7 +75,7 @@
return new UsergridRequest(helpers.build.getConnections(this, helpers.args(arguments)))
},
setAppAuth: function(options) {
- this.appAuth = (typeof options === 'string') ? helpers.args(arguments) : options
+ this.appAuth = (_.isString(options)) ? helpers.args(arguments) : options
},
authenticateApp: function(options) {
var self = this
@@ -87,14 +88,12 @@
throw new Error('authenticateApp() failed because clientId or clientSecret are missing')
}
- var options = {
+ return new UsergridRequest({
client: self,
path: 'token',
method: 'POST',
body: helpers.build.appLoginBody(auth)
- }
-
- return new UsergridRequest(options, function(error, usergridResponse, body) {
+ }, function(error, usergridResponse, body) {
if (usergridResponse.ok) {
if (!self.appAuth) {
self.appAuth = auth
@@ -118,6 +117,12 @@
}
callback(error, usergridResponse, token)
})
+ },
+ usingAuth: function(auth) {
+ if (auth instanceof UsergridAuth) {
+ this.tempAuth = auth
+ }
+ return this
}
}
diff --git a/lib/entity.js b/lib/entity.js
index 3983f84..97dd01c 100644
--- a/lib/entity.js
+++ b/lib/entity.js
@@ -88,7 +88,7 @@
helpers.setWritable(this, ['uuid', 'name', 'type', 'created'])
_.assign(this, usergridResponse.entity)
helpers.setReadOnly(this, ['uuid', 'name', 'type', 'created'])
- callback(err || usergridResponse.error, usergridResponse, this)
+ callback(usergridResponse.error, usergridResponse, this)
}.bind(this))
},
save: function() {
@@ -99,7 +99,7 @@
helpers.setWritable(this, ['uuid', 'name', 'type', 'created'])
_.assign(this, usergridResponse.entity)
helpers.setReadOnly(this, ['uuid', 'name', 'type', 'created'])
- callback(err || usergridResponse.error, usergridResponse, this)
+ callback(usergridResponse.error, usergridResponse, this)
}.bind(this))
},
remove: function() {
@@ -107,7 +107,7 @@
var client = helpers.client.validate(args)
var callback = helpers.cb(args)
client.DELETE(this, function(err, usergridResponse) {
- callback(err || usergridResponse.error, usergridResponse, this)
+ callback(usergridResponse.error, usergridResponse, this)
}.bind(this))
},
attachAsset: function() {},
diff --git a/lib/request.js b/lib/request.js
index a387a5c..641f7ad 100644
--- a/lib/request.js
+++ b/lib/request.js
@@ -9,7 +9,6 @@
_ = require('lodash')
var UsergridRequest = function(options) {
-
var client = helpers.client.validate(options.client)
var callback = helpers.cb(helpers.args(arguments))
diff --git a/lib/user.js b/lib/user.js
index 81bcb6e..dd106af 100644
--- a/lib/user.js
+++ b/lib/user.js
@@ -63,10 +63,9 @@
login: function() {
var self = this
var args = helpers.args(arguments)
- var client = helpers.client.validate(args)
var callback = helpers.cb(args)
return new UsergridRequest({
- client: self,
+ client: helpers.client.validate(args),
path: 'token',
method: 'POST',
body: helpers.build.userLoginBody(self)
@@ -92,11 +91,10 @@
})
}
- var client = helpers.client.validate(args)
var revokeAll = _.first(args.filter(_.isBoolean)) || false
return new UsergridRequest({
- client: self,
+ client: helpers.client.validate(args),
path: util.format("users/%s/revoketoken%s", helpers.user.uniqueId(self), (revokeAll) ? "s" : ""),
method: 'PUT',
qs: (!revokeAll) ? {
@@ -116,7 +114,6 @@
var self = this
var args = helpers.args(arguments)
var callback = helpers.cb(args)
- var client = helpers.client.validate(args)
var body = {
oldpassword: _.isPlainObject(args[0]) ? args[0].oldPassword : _.isString(args[0]) ? args[0] : undefined,
newpassword: _.isPlainObject(args[0]) ? args[0].newPassword : _.isString(args[1]) ? args[1] : undefined
@@ -125,7 +122,7 @@
throw new Error('"oldPassword" and "newPassword" properties are required when resetting a user password')
}
return new UsergridRequest({
- client: self,
+ client: helpers.client.validate(args),
path: util.format('users/%s/password', helpers.user.uniqueId(self)),
method: 'PUT',
body: body
diff --git a/tests/lib/client.auth.test.js b/tests/lib/client.auth.test.js
index a247948..7797323 100644
--- a/tests/lib/client.auth.test.js
+++ b/tests/lib/client.auth.test.js
@@ -11,6 +11,7 @@
UsergridAuth = require('../../lib/auth'),
UsergridAppAuth = require('../../lib/appAuth'),
UsergridUserAuth = require('../../lib/userAuth'),
+ UsergridUser = require('../../lib/user'),
_ = require('lodash')
var _uuid,
@@ -132,7 +133,8 @@
this.slow(_slow)
this.timeout(_timeout)
- var response, token, email = util.format("%s@%s.com", chance.word(), chance.word()), client = new UsergridClient()
+ var response, token, email = util.format("%s@%s.com", chance.word(), chance.word()),
+ client = new UsergridClient()
before(function(done) {
client.authenticateUser({
username: config.test.username,
@@ -185,7 +187,7 @@
it('should support passing a UsergridUserAuth instance with a custom ttl', function(done) {
var newClient = new UsergridClient()
- var ttlInMilliseconds = 500000
+ var ttlInMilliseconds = 500000
var userAuth = new UsergridUserAuth(config.test.username, config.test.password, ttlInMilliseconds)
client.authenticateUser(userAuth, function(err, response, token) {
response.ok.should.be.true()
@@ -230,4 +232,36 @@
client.appAuth = new UsergridAppAuth(config.clientId, config.clientSecret, config.tokenTtl)
client.appAuth.should.be.instanceof(UsergridAppAuth)
})
+})
+
+describe('usingAuth()', function() {
+
+ this.slow(_slow + 500)
+ this.timeout(_timeout)
+
+ var client = new UsergridClient()
+
+ it('should authenticate using an ad-hoc token', function(done) {
+
+ client.authenticateUser({
+ username: config.test.username,
+ password: config.test.password
+ }, function(err, response, token) {
+ var authFromToken = new UsergridAuth(token)
+ authFromToken.isValid.should.be.true()
+ authFromToken.should.have.property('token')
+ client.usingAuth(authFromToken).GET({
+ path: '/users/me'
+ }, function(error, usergridResponse) {
+ usergridResponse.ok.should.be.true()
+ usergridResponse.should.have.property('user').which.is.an.instanceof(UsergridUser)
+ usergridResponse.user.should.have.property('uuid').which.is.a.uuid()
+ done()
+ })
+ })
+ })
+
+ it('client.tempAuth should be invalid after making a request ad-hoc authentication', function() {
+ client.tempAuth.isValid.should.be.false()
+ })
})
\ No newline at end of file
diff --git a/tests/lib/user.test.js b/tests/lib/user.test.js
index 8a59787..42e2b35 100644
--- a/tests/lib/user.test.js
+++ b/tests/lib/user.test.js
@@ -65,7 +65,7 @@
err.should.containDeep({
name: 'duplicate_unique_property_exists'
})
- usergridResponse.statusCode.should.be.greaterThanOrEqual(400)
+ usergridResponse.ok.should.be.false()
done()
})
})
@@ -172,7 +172,7 @@
oldPassword: 'BADOLDPASSWORD',
newPassword: config.test.password
}, function(err, response, success) {
- response.statusCode.should.be.greaterThanOrEqual(400)
+ response.ok.should.be.false()
err.name.should.equal('auth_invalid_username_or_password')
_user1.remove(function(err, response) {
done()
diff --git a/tests/lib/usergrid.singleton.test.js b/tests/lib/usergrid.singleton.test.js
index f2d0360..aa74e72 100644
--- a/tests/lib/usergrid.singleton.test.js
+++ b/tests/lib/usergrid.singleton.test.js
@@ -5,4 +5,5 @@
it('should be initialized when defined in another module', function() {
Usergrid.isInitialized.should.be.true()
+ Usergrid.isSharedInstance.should.be.true()
})
\ No newline at end of file
diff --git a/tests/main.test.js b/tests/main.test.js
index 8cd06c0..f4bc035 100644
--- a/tests/main.test.js
+++ b/tests/main.test.js
@@ -14,6 +14,8 @@
})
// end module config
+/* skip the following test using describe() in order to validate that
+ new tests added pass when the shared instance is not initialized */
describe('Usergrid', function() {
return require('./lib/usergrid.test')
})
diff --git a/usergrid.js b/usergrid.js
index 2698c3a..eb5eb5f 100644
--- a/usergrid.js
+++ b/usergrid.js
@@ -11,6 +11,7 @@
Object.setPrototypeOf(Usergrid, new UsergridClient(options))
UsergridClient.call(self)
self.isInitialized = true
+ self.isSharedInstance = true
}
}