|
@ -57,6 +57,7 @@ class OAuth2Service extends SiteService { |
|
|
registerPassport ( ) { |
|
|
registerPassport ( ) { |
|
|
const verifyClient = this.verifyClient.bind(this); |
|
|
const verifyClient = this.verifyClient.bind(this); |
|
|
const verifyHttpBearer = this.verifyHttpBearer.bind(this); |
|
|
const verifyHttpBearer = this.verifyHttpBearer.bind(this); |
|
|
|
|
|
const verifyKaleidoscopeBearer = this.verifyKaleidoscopeBearer.bind(this); |
|
|
|
|
|
|
|
|
const basicStrategy = new BasicStrategy(verifyClient); |
|
|
const basicStrategy = new BasicStrategy(verifyClient); |
|
|
this.log.info('registering Basic strategy', { name: basicStrategy.name }); |
|
|
this.log.info('registering Basic strategy', { name: basicStrategy.name }); |
|
@ -69,6 +70,10 @@ class OAuth2Service extends SiteService { |
|
|
const httpBearerStrategy = new BearerStrategy(verifyHttpBearer); |
|
|
const httpBearerStrategy = new BearerStrategy(verifyHttpBearer); |
|
|
this.log.info('registering Bearer strategy', { name: httpBearerStrategy.name }); |
|
|
this.log.info('registering Bearer strategy', { name: httpBearerStrategy.name }); |
|
|
passport.use(httpBearerStrategy); |
|
|
passport.use(httpBearerStrategy); |
|
|
|
|
|
|
|
|
|
|
|
const kaleidoscopeBearerStrategy = new BearerStrategy(verifyKaleidoscopeBearer); |
|
|
|
|
|
this.log.info('registering Kaleidoscope Bearer strategy'); |
|
|
|
|
|
passport.use(kaleidoscopeBearerStrategy); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
async serializeClient (client, done) { |
|
|
async serializeClient (client, done) { |
|
@ -392,6 +397,7 @@ class OAuth2Service extends SiteService { |
|
|
async verifyHttpBearer (accessToken, done) { |
|
|
async verifyHttpBearer (accessToken, done) { |
|
|
const token = await this.getAccessToken(accessToken); |
|
|
const token = await this.getAccessToken(accessToken); |
|
|
if (!token) { |
|
|
if (!token) { |
|
|
|
|
|
this.log.error('no bearer token for client', { accessToken }); |
|
|
return done(null, false); |
|
|
return done(null, false); |
|
|
} |
|
|
} |
|
|
return done(null, token.user, { scope: token.scope }); |
|
|
return done(null, token.user, { scope: token.scope }); |
|
@ -411,6 +417,45 @@ class OAuth2Service extends SiteService { |
|
|
.lean(); |
|
|
.lean(); |
|
|
return tokens; |
|
|
return tokens; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
async getKaleidoscopeClient (accessToken) { |
|
|
|
|
|
const client = await OAuth2Client |
|
|
|
|
|
.findOne({ 'kaleidoscope.token': accessToken }) |
|
|
|
|
|
.select('-secret -kaleidoscope -admin') // don't fetch them
|
|
|
|
|
|
.lean(); |
|
|
|
|
|
if (!client) { |
|
|
|
|
|
return; // we don't have one, be undefined
|
|
|
|
|
|
} |
|
|
|
|
|
/* |
|
|
|
|
|
* extreme paranoia also serializes the object to absolutely prevent leaking |
|
|
|
|
|
* a secret even if the underlying Mongoose library has a bug today. |
|
|
|
|
|
*/ |
|
|
|
|
|
return { |
|
|
|
|
|
_id: client._id, |
|
|
|
|
|
created: client.created, |
|
|
|
|
|
updated: client.updated, |
|
|
|
|
|
site: client.site, |
|
|
|
|
|
scopes: client.scopes, |
|
|
|
|
|
flags: client.flags, |
|
|
|
|
|
}; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
async verifyKaleidoscopeBearer (accessToken, done) { |
|
|
|
|
|
const client = await this.getKaleidoscopeClient(accessToken); |
|
|
|
|
|
if (!client) { |
|
|
|
|
|
this.log.error('no Kaleidoscope token for client', { accessToken }); |
|
|
|
|
|
return done(null, false); |
|
|
|
|
|
} |
|
|
|
|
|
/* |
|
|
|
|
|
* Minor hack here. You don't get a User or CoreUser for use with |
|
|
|
|
|
* Kaleidoscope. This is machine-to-machine, there simply is no "user" in |
|
|
|
|
|
* this transaction. Instead, you get a Client - the machine. |
|
|
|
|
|
* |
|
|
|
|
|
* So, up in controller space, req.user isn't a User or CoreUser for |
|
|
|
|
|
* Kaleidoscope APIs. It is the OAuth2 Client or Service Node. |
|
|
|
|
|
*/ |
|
|
|
|
|
return done(null, client); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
module.exports = { |
|
|
module.exports = { |
|
|