From 803edf07c29d857ca912522ca0c9ec9c4d23b53a Mon Sep 17 00:00:00 2001 From: rob Date: Mon, 27 Jun 2022 05:19:00 -0400 Subject: [PATCH] more OAuth2 integration --- app/controllers/auth.js | 39 +++++++++++++++++++++++++++++++++------ app/services/oauth2.js | 4 ++-- app/services/user.js | 23 +++++++++++++++++++++++ lib/site-platform.js | 1 + package.json | 1 + yarn.lock | 21 +++++++++++++++++++++ 6 files changed, 81 insertions(+), 8 deletions(-) diff --git a/app/controllers/auth.js b/app/controllers/auth.js index a032ec2..9bc78f2 100644 --- a/app/controllers/auth.js +++ b/app/controllers/auth.js @@ -31,34 +31,51 @@ class AuthController extends SiteController { const authRequired = this.dtp.services.session.authCheckMiddleware({ requireLogin: true }); - router.post('/otp/enable', + router.post( + '/otp/enable', limiterService.create(limiterService.config.auth.postOtpEnable), this.postOtpEnable.bind(this), ); - router.post('/otp/auth', + router.post( + '/otp/auth', limiterService.create(limiterService.config.auth.postOtpAuthenticate), this.postOtpAuthenticate.bind(this), ); - router.post('/login', + router.post( + '/login', limiterService.create(limiterService.config.auth.postLogin), upload.none(), this.postLogin.bind(this), ); - router.get('/api-token/personal', + router.get( + '/api-token/personal', authRequired, limiterService.create(limiterService.config.auth.getPersonalApiToken), this.getPersonalApiToken.bind(this), ); - router.get('/socket-token', + router.get( + '/socket-token', authRequired, limiterService.create(limiterService.config.auth.getSocketToken), this.getSocketToken.bind(this), ); - router.get('/logout', + router.get( + '/core', + passport.authenticate('oauth2'), + ); + + router.get( + '/core/callback', + passport.authenticate('oauth2', { failureRedirect: '/' }), + this.getCoreCallback.bind(this), + ); + + router.get( + '/logout', authRequired, limiterService.create(limiterService.config.auth.getLogout), this.getLogout.bind(this), @@ -173,6 +190,16 @@ class AuthController extends SiteController { } } + async getCoreCallback (req, res) { + // req.login(user, (error) => { + // if (error) { + // return next(error); + // } + // return res.redirect('/'); + // }); + return res.redirect('/'); + } + async getLogout (req, res, next) { if (!req.user) { return next(new SiteError(403, 'You are not signed in')); diff --git a/app/services/oauth2.js b/app/services/oauth2.js index 2f56fc4..c6605b9 100644 --- a/app/services/oauth2.js +++ b/app/services/oauth2.js @@ -97,14 +97,14 @@ class OAuth2Service extends SiteService { const requireLogin = sessionService.authCheckMiddleware({ requireLogin: true }); app.get( - '/dialog/authorize', + '/oauth2/authorize', requireLogin, this.server.authorize(this.processAuthorize.bind(this)), this.renderAuthorizeDialog.bind(this), ); app.post( - '/dialog/authorize/decision', + '/oauth2/authorize/decision', requireLogin, this.server.decision(), ); diff --git a/app/services/user.js b/app/services/user.js index 202e39a..e78c7e5 100644 --- a/app/services/user.js +++ b/app/services/user.js @@ -13,6 +13,7 @@ const UserBlock = mongoose.model('UserBlock'); const passport = require('passport'); const PassportLocal = require('passport-local'); +const OAuth2Strategy = require('passport-oauth2'); const striptags = require('striptags'); const uuidv4 = require('uuid').v4; @@ -39,7 +40,10 @@ class UserService { async start ( ) { this.log.info(`starting ${module.exports.name} service`); + this.registerPassportLocal(); + this.registerPassportOAuth2(); + if (process.env.DTP_ADMIN === 'enabled') { this.registerPassportAdmin(); } @@ -327,6 +331,25 @@ class UserService { } } + registerPassportOAuth2 ( ) { + const AUTH_HOST = process.env.DTP_CORE_AUTH_HOST || 'localhost'; + const oauthOptions = { + authorizationURL: `http://${AUTH_HOST}/oauth2/authorize`, + tokenURL: `http://${AUTH_HOST}/oauth2/token`, + clientID: process.env.DTP_CORE_CLIENT_ID, + clientSecret: process.env.DTP_CORE_CLIENT_SECRET, + callbackURL: `http://${process.env.DTP_SITE_DOMAIN}/auth/example/callback`, + }; + passport.use(new OAuth2Strategy(oauthOptions, this.handleOAuth2Login.bind(this))); + } + + async handleOAuth2Login (accessToken, refreshToken, profile, cb) { + this.log.info('OAuth2 login', { accessToken, refreshToken, profile }); + User.findOrCreate({ exampleId: profile.id }, function (err, user) { + return cb(err, user); + }); + } + registerPassportAdmin ( ) { const options = { usernameField: 'username', diff --git a/lib/site-platform.js b/lib/site-platform.js index 783efdb..4e1e2c4 100644 --- a/lib/site-platform.js +++ b/lib/site-platform.js @@ -342,6 +342,7 @@ module.exports.startWebServer = async (dtp) => { * System Init */ try { + dtp.services.oauth2.attachRoutes(module.app); await module.loadControllers(dtp); } catch (error) { module.log.error('failed to initialize application controller', { error }); diff --git a/package.json b/package.json index aa19843..59c21dd 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "otplib": "^12.0.1", "passport": "^0.5.2", "passport-local": "^1.0.0", + "passport-oauth2": "^1.6.1", "pug": "^3.0.2", "qrcode": "^1.5.0", "rate-limiter-flexible": "^2.3.6", diff --git a/yarn.lock b/yarn.lock index 8a8d755..cd861f8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1773,6 +1773,11 @@ base64id@2.0.0, base64id@~2.0.0: resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== +base64url@3.x.x: + version "3.0.1" + resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d" + integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A== + base@^0.11.1: version "0.11.2" resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" @@ -6070,6 +6075,11 @@ oauth2orize@^1.11.1: uid2 "0.0.x" utils-merge "1.x.x" +oauth@0.9.x: + version "0.9.15" + resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1" + integrity sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA== + object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -6344,6 +6354,17 @@ passport-local@^1.0.0: dependencies: passport-strategy "1.x.x" +passport-oauth2@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/passport-oauth2/-/passport-oauth2-1.6.1.tgz#c5aee8f849ce8bd436c7f81d904a3cd1666f181b" + integrity sha512-ZbV43Hq9d/SBSYQ22GOiglFsjsD1YY/qdiptA+8ej+9C1dL1TVB+mBE5kDH/D4AJo50+2i8f4bx0vg4/yDDZCQ== + dependencies: + base64url "3.x.x" + oauth "0.9.x" + passport-strategy "1.x.x" + uid2 "0.0.x" + utils-merge "1.x.x" + passport-strategy@1.x.x: version "1.0.0" resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4"