From 53f42fabefe7fe901828ea9eb548048ddb2646a0 Mon Sep 17 00:00:00 2001 From: caizx Date: Sat, 11 Nov 2017 14:11:58 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E5=A2=9E=E5=87=8Fcas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/cfg.js | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ lib/config.js | 4 ++++ routes/auth.js | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 lib/cfg.js diff --git a/lib/cfg.js b/lib/cfg.js new file mode 100644 index 00000000..45ddbd29 --- /dev/null +++ b/lib/cfg.js @@ -0,0 +1,49 @@ +var ServiceCloudConfig = require('service-cloud-config2'); + +var loaded = false; +var env = process.env.NODE_ENV || 'development'; + +var config = new ServiceCloudConfig({ + service: 'config/' + env + '/saas-plat-wiki', + adapter: { + name: 'consul', + connection: { + host: 'cfg.saas-plat.com', + port: 4720 + } + }, + mergeWithConfigEnv: true, + envServiceName: 'config/' + env + '/environment' +}); + + +exports.getData = function(callback) { + if (loaded) { + return; + } + config.start(function(err, data) { + if (err) { + console.error(err); + callback(err); + return; + } + config.getData(function(err, data) { + if (err) { + console.error(err); + callback(err); + return; + } + console.info('配置已经加载', env); + loaded = true; + callback(null, data); + }); + }); +}; + +exports.get = function(key) { + return config.get(key); +}; + +exports.getConfig = function() { + return config.getConfig(); +}; diff --git a/lib/config.js b/lib/config.js index 23a97061..67b993fb 100644 --- a/lib/config.js +++ b/lib/config.js @@ -92,6 +92,9 @@ module.exports = (function () { passwordHash: '', email: '' }, + cas: { + enabled: false + }, local: { enabled: false, accounts: [{ @@ -167,6 +170,7 @@ module.exports = (function () { !config.authentication.github.enabled && !config.authentication.ldap.enabled && !config.authentication.alone.enabled && + !config.authentication.cas.enabled && !config.authentication.local.enabled ) { error = 'No authentication method provided.' diff --git a/routes/auth.js b/routes/auth.js index 4182d68f..592db523 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -111,6 +111,45 @@ if (auth.ldap.enabled) { )) } +if (auth.cas.enabled){ + router.get('/cas_login', function(req, res, next) { + passport.authenticate('cas', function (err, user, info) { + if (err) { + return next(err); + } + if (!user) { + return res.redirect(proxyPath + '/'); + } + req.logIn(user, function (err) { + if (err) { + return next(err); + } + req.session.messages = ''; + return res.redirect(proxyPath + '/'); + }); + })(req, res, next); + }); + + var cfg = require('../lib/cfg'); + cfg.getData(function(){ + passport.use(new(require('passport-cas').Strategy)({ + version: 'CAS3.0', + serviceURL: '/cas_login', + ssoBaseURL: cfg.get('usr.host') + cfg.get('usr.cas'), + serverBaseURL: cfg.get('wiki.host'), + validateURL: '/serviceValidate' // for CAS 2.0 + }, function(profile, done) { + console.log('cas验证完成', profile.user); + usedAuthentication('cas'); + return done(null, { + displayName: profile.attributes && (profile.attributes.displayName || profile.user), + email: profile.attributes && (profile.attributes.email || profile.user+'@saas-plat.com') + }); + }) + ); + }); +} + if (auth.alone.enabled) { passport.use(new passportLocal.Strategy( From 9dcd0322ef4ea9e722dd87c0d477b0e5f25755c0 Mon Sep 17 00:00:00 2001 From: caizx Date: Sat, 11 Nov 2017 15:14:16 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E5=8E=BB=E6=8E=89consul=EF=BC=8C=E8=BF=99?= =?UTF-8?q?=E4=B8=AAwiki=E4=B8=8D=E6=94=AF=E6=8C=81=E5=A4=9A=E5=AE=9E?= =?UTF-8?q?=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/cfg.js | 49 ------------------------------------------------- lib/config.js | 4 +++- routes/auth.js | 24 +++++++++++++----------- 3 files changed, 16 insertions(+), 61 deletions(-) delete mode 100644 lib/cfg.js diff --git a/lib/cfg.js b/lib/cfg.js deleted file mode 100644 index 45ddbd29..00000000 --- a/lib/cfg.js +++ /dev/null @@ -1,49 +0,0 @@ -var ServiceCloudConfig = require('service-cloud-config2'); - -var loaded = false; -var env = process.env.NODE_ENV || 'development'; - -var config = new ServiceCloudConfig({ - service: 'config/' + env + '/saas-plat-wiki', - adapter: { - name: 'consul', - connection: { - host: 'cfg.saas-plat.com', - port: 4720 - } - }, - mergeWithConfigEnv: true, - envServiceName: 'config/' + env + '/environment' -}); - - -exports.getData = function(callback) { - if (loaded) { - return; - } - config.start(function(err, data) { - if (err) { - console.error(err); - callback(err); - return; - } - config.getData(function(err, data) { - if (err) { - console.error(err); - callback(err); - return; - } - console.info('配置已经加载', env); - loaded = true; - callback(null, data); - }); - }); -}; - -exports.get = function(key) { - return config.get(key); -}; - -exports.getConfig = function() { - return config.getConfig(); -}; diff --git a/lib/config.js b/lib/config.js index 67b993fb..d38840d6 100644 --- a/lib/config.js +++ b/lib/config.js @@ -93,7 +93,9 @@ module.exports = (function () { email: '' }, cas: { - enabled: false + enabled: false, + ssoBaseURL: '', + serverBaseURL: '' }, local: { enabled: false, diff --git a/routes/auth.js b/routes/auth.js index 592db523..d58a2eed 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -124,30 +124,28 @@ if (auth.cas.enabled){ if (err) { return next(err); } - req.session.messages = ''; - return res.redirect(proxyPath + '/'); + var dst = req.session.destination || proxyPath + '/' + return res.redirect(dst); }); })(req, res, next); }); - var cfg = require('../lib/cfg'); - cfg.getData(function(){ - passport.use(new(require('passport-cas').Strategy)({ + passport.use(new(require('passport-cas').Strategy)({ version: 'CAS3.0', serviceURL: '/cas_login', - ssoBaseURL: cfg.get('usr.host') + cfg.get('usr.cas'), - serverBaseURL: cfg.get('wiki.host'), + ssoBaseURL: auth.cas.ssoBaseURL, + serverBaseURL: auth.cas.serverBaseURL, validateURL: '/serviceValidate' // for CAS 2.0 }, function(profile, done) { - console.log('cas验证完成', profile.user); + console.log('cas login', profile.user); usedAuthentication('cas'); return done(null, { displayName: profile.attributes && (profile.attributes.displayName || profile.user), - email: profile.attributes && (profile.attributes.email || profile.user+'@saas-plat.com') + email: profile.attributes && (profile.attributes.email || profile.user) }); }) - ); - }); + ); + } if (auth.alone.enabled) { @@ -273,6 +271,10 @@ function _getLogin (req, res) { res.locals.errors = req.flash() + if (auth.cas.enabled){ + return res.redirect('cas_login'); + } + res.render('login', { title: app.locals.config.get('application').title, auth: auth From abed2b3b99ea54f33866fa76248bd43f37a1e288 Mon Sep 17 00:00:00 2001 From: caizx Date: Mon, 13 Nov 2017 08:43:41 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E5=8E=9F=E6=9C=89=E7=9A=84authdone?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- routes/auth.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/routes/auth.js b/routes/auth.js index d58a2eed..f2cea31f 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -118,17 +118,16 @@ if (auth.cas.enabled){ return next(err); } if (!user) { - return res.redirect(proxyPath + '/'); + return next(err); } req.logIn(user, function (err) { if (err) { return next(err); } - var dst = req.session.destination || proxyPath + '/' - return res.redirect(dst); + return next(null); }); })(req, res, next); - }); + }, _getAuthDone); passport.use(new(require('passport-cas').Strategy)({ version: 'CAS3.0', From cc3909d9b372ca11f80a4e536ab5ef04390ab5c6 Mon Sep 17 00:00:00 2001 From: caizx Date: Mon, 13 Nov 2017 09:17:27 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BC=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 69004509..f8fac489 100644 --- a/package.json +++ b/package.json @@ -55,13 +55,14 @@ "morgan": "^1.5.0", "node-syntaxhighlighter": "*", "passport": "^0.2.0", + "passport-cas": "^0.1.1", "passport-github": "^0.1.5", "passport-google-oauth": "^0.1.5", "passport-local": "^1.0.0", + "pug": "^2.0.0-beta11", "semver": "^5.3.0", "serve-favicon": "^2.1.7", - "transliteration": "^0.2.1", - "pug": "^2.0.0-beta11" + "transliteration": "^0.2.1" }, "devDependencies": { "chai": "*", From ddc77a9351fbebc2829b51daae10e1c3050daffe Mon Sep 17 00:00:00 2001 From: caizx Date: Mon, 13 Nov 2017 11:25:50 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E4=BF=AE=E6=94=B9ssl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + routes/auth.js | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index f8fac489..007a5099 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "pug": "^2.0.0-beta11", "semver": "^5.3.0", "serve-favicon": "^2.1.7", + "ssl-certs": "^1.0.0", "transliteration": "^0.2.1" }, "devDependencies": { diff --git a/routes/auth.js b/routes/auth.js index f2cea31f..78e10928 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -112,22 +112,24 @@ if (auth.ldap.enabled) { } if (auth.cas.enabled){ + require('ssl-certs'); router.get('/cas_login', function(req, res, next) { passport.authenticate('cas', function (err, user, info) { if (err) { + console.error(err); return next(err); } if (!user) { - return next(err); + return next(new Error('cas login failed')); } req.logIn(user, function (err) { if (err) { return next(err); } - return next(null); + return res.redirect(proxyPath + '/auth/done'); }); })(req, res, next); - }, _getAuthDone); + }); passport.use(new(require('passport-cas').Strategy)({ version: 'CAS3.0', @@ -140,7 +142,7 @@ if (auth.cas.enabled){ usedAuthentication('cas'); return done(null, { displayName: profile.attributes && (profile.attributes.displayName || profile.user), - email: profile.attributes && (profile.attributes.email || profile.user) + email: profile.attributes && (profile.attributes.email || profile.user+'@saas-plat.com') }); }) ); From 0e0cf5010a24d671f54f7a30547afbda2950e88b Mon Sep 17 00:00:00 2001 From: caizx Date: Mon, 13 Nov 2017 16:17:06 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=EF=BC=8C=E6=9F=A5=E8=AF=A2=E6=A1=86=E4=BC=98=E5=8C=96=E5=93=8D?= =?UTF-8?q?=E5=BA=94=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/app.js | 6 +++++ public/css/style.css | 31 ++++++++++++++-------- views/layout.pug | 61 ++++++++++++++++++++++++++++++-------------- views/search.pug | 2 +- 4 files changed, 69 insertions(+), 31 deletions(-) diff --git a/lib/app.js b/lib/app.js index f60304b0..aaf32f55 100644 --- a/lib/app.js +++ b/lib/app.js @@ -84,6 +84,12 @@ module.exports.initialize = function (config) { } return config.get('application').favicon.trim() }, + get topMenus () { + return [] + }, + get accountMenus () { + return [] + }, isAnonymous: function () { return !req.user diff --git a/public/css/style.css b/public/css/style.css index 6cb64bc6..85df369a 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -27,6 +27,16 @@ a.logout i { padding-right: 0; } +.navbar a[href^="https://"], +.navbar a[href^="http://"] { + background: none; + padding-right: 0; +} + +.navbar li{ + margin-bottom: 0; +} + p.user { color: white; padding: 8px 0 0; @@ -247,9 +257,6 @@ hr { /* Overrides Bootstrap */ -.navbar-right { - float: right; -} .navbar-form { padding: 0; @@ -258,16 +265,10 @@ hr { .navbar-form.search { display: none; + margin-left: 15px; + margin-right: 15px; } -.navbar-header { - width: 100%; -} - -.navbar-brand { - overflow: hidden; - max-width: 60%; -} .navbar-inverse { background-color: rgba(0,0,0); @@ -539,6 +540,10 @@ input#pageTitle { margin-bottom: 20px; } +.search-xs input{ + border: 0; +} + .with-sidebar { background-color: rgba(255,255,255,0.5); padding: 10px; @@ -567,6 +572,10 @@ li { margin-bottom: 5px; } +.navbar-header li { + margin-bottom: 0px; +} + .jumbotron p.discrete { color: gray; font-size: 90% diff --git a/views/layout.pug b/views/layout.pug index 5b11e651..152dc64b 100644 --- a/views/layout.pug +++ b/views/layout.pug @@ -22,32 +22,55 @@ include mixins/links body -var term_ph = (typeof term == "undefined" ? "" : term) .navbar.navbar-inverse.navbar-fixed-top - .container-fluid + .container-fluid .navbar-header +anchor("/", appBrand).navbar-brand - if canSearch() - form(action=`${proxyPath}/search`).navbar-form.search.navbar-left - .input-group.input-group-sm.search - input.form-control(type="text", value=term_ph, data-i-search-input="true",name="term",placeholder="Search the wiki") - span.input-group-btn - button.btn.btn-primary(type="submit") Search - .navbar-right - if isAnonymous() - p.user You're not  - +anchor('/login?destination', 'logged in')#login(title='Access login page') - else - p.user - if hasGravatar() - img(src=gravatar().url(user.email, {s:24})) - b  #{user.displayName}  - +anchor('/logout')(title='Become anonymous') - i.icon.ion-power + button(type="button",data-toggle="collapse" data-target="#navbar-collapse-1" aria-expanded="false").navbar-toggle.collapsed + span.sr-only Toggle navigation + span.icon-bar + span.icon-bar + span.icon-bar + .collapse.navbar-collapse(id="navbar-collapse-1") + if topMenus.length>0 + ul.nav.navbar-nav + each m in topMenus + li + +anchor(m.url, m.text) + if canSearch() + form(action=`${proxyPath}/search`).navbar-form.search.navbar-left + .input-group.input-group-sm.search + input.form-control(type="text", value=term_ph, data-i-search-input="true",name="term",placeholder="Search the wiki") + span.input-group-btn + button.btn.btn-primary(type="submit") Search + ul.nav.navbar-nav.navbar-right + li.dropdown + if isAnonymous() + +anchor('/login?destination', 'logged in')#login(title='Access login page') + else + a(href="#",class="dropdown-toggle user",data-toggle="dropdown",role="button",aria-haspopup="true",aria-expanded="false") + if hasGravatar() + img(src=gravatar().url(user.email, {s:24})) + span #{user.displayName} + span.caret + ul.dropdown-menu + each am in accountMenus + li + +anchor(am.url, am.text) + li + a(href="/logout",title='Become anonymous') + i.icon.ion-power + span Logout + .tools block tools - .container + if canSearch() + form(action=`${proxyPath}/search`).visible-xs-block.search-xs + input.form-control(type="text", value=term_ph, data-i-search-input="true",name="term",placeholder="Search the wiki") + .container + .row if hasSidebar() .col-md-2.with-sidebar diff --git a/views/search.pug b/views/search.pug index bcdf9b93..5b16aeca 100644 --- a/views/search.pug +++ b/views/search.pug @@ -11,7 +11,7 @@ block content +warning() if canSearch() - form(action=`${proxyPath}/search`).search-form + form(action=`${proxyPath}/search`).search-form.hidden-xs .input-group.input-group-sm input.form-control(type="text", value=term_ph, data-i-search-input="true", name="term", placeholder="Search the wiki") span.input-group-btn From 3dbb4e2011177601621890a990d831a5dfaa6ec5 Mon Sep 17 00:00:00 2001 From: caizx Date: Mon, 13 Nov 2017 16:23:55 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=E6=9A=82=E6=97=B6=E9=9A=90=E8=97=8Fnavbar-?= =?UTF-8?q?brand?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/css/style.css | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/public/css/style.css b/public/css/style.css index 85df369a..0bcb99e7 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -257,6 +257,9 @@ hr { /* Overrides Bootstrap */ +.navbar-brand{ + display: none; +} .navbar-form { padding: 0; @@ -271,7 +274,12 @@ hr { .navbar-inverse { - background-color: rgba(0,0,0); + background-color: #24292e; +} + +.navbar-inverse .navbar-nav>li>a{ + color: rgba(255, 255, 255, 0.75); + font-weight: bold; } .alert { From f8645e1c0c0425fcc5aefa326f7165331299e254 Mon Sep 17 00:00:00 2001 From: caizx Date: Mon, 13 Nov 2017 16:49:59 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- views/layout.pug | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/views/layout.pug b/views/layout.pug index 152dc64b..f45c31e7 100644 --- a/views/layout.pug +++ b/views/layout.pug @@ -72,19 +72,19 @@ include mixins/links .container .row + #main.hide-tools.col-md-9 + block content + if hasSidebar() - .col-md-2.with-sidebar + .col-md-3.with-sidebar .content !{_sidebar} else - .col-md-2 - - #main.hide-tools.col-md-8 - block content + .col-md-3 if hasFooter() .row - .col-md-2 - .col-md-8.with-footer + .col-md-3 + .col-md-9.with-footer .content !{_footer} script(src=proxyPath + "/vendor/jquery.min.js")