Skip to content

Commit

Permalink
Azure AD support + defaultReadAccess option + All Pages UI work
Browse files Browse the repository at this point in the history
  • Loading branch information
NGPixel committed Apr 10, 2017
1 parent 5a010f2 commit 7c1dd8b
Show file tree
Hide file tree
Showing 17 changed files with 206 additions and 116 deletions.
4 changes: 4 additions & 0 deletions app/data.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ defaults:
lang: en
public: false
auth:
defaultReadAccess: false
local:
enabled: true
microsoft:
Expand All @@ -35,6 +36,8 @@ defaults:
enabled: false
ldap:
enabled: false
azure:
enabled: false
db: mongodb://localhost/wiki
sessionSecret: null
admin: null
Expand All @@ -55,6 +58,7 @@ defaults:
loggly: false
papertrail: false
rollbar: false
sentry: false
langs:
-
id: en
Expand Down
1 change: 1 addition & 0 deletions client/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ $(() => {
// ====================================

require('./pages/view.js')(alerts)
require('./pages/all.js')(alerts, socket)
require('./pages/create.js')(alerts, socket)
require('./pages/edit.js')(alerts, socket)
require('./pages/source.js')(alerts)
Expand Down
9 changes: 9 additions & 0 deletions client/js/pages/all.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'use strict'

import $ from 'jquery'

module.exports = (alerts, socket) => {
if ($('#page-type-all').length) {

}
}
69 changes: 29 additions & 40 deletions client/scss/components/collapsable-nav.scss
Original file line number Diff line number Diff line change
@@ -1,25 +1,52 @@
.has-collapsable-nav {
background-color: mc('blue-grey', '50');
display: flex;
justify-content: flex-start;
align-items: stretch;
}

.collapsable-nav {
width: 300px;
background-color: mc($primary, '500');
background-color: mc('blue-grey', '900');
color: #FFF;
min-height: 80vh;
transition: all .6s ease;
border-left: 1px solid darken(mc('blue-grey', '900'), 5%);

&:last-child {
border-bottom-right-radius: 5px;
}

&.has-children {
width: 50px;
background-color: mc($primary, '500');
border-left: 1px solid mc($primary, '700');

&:nth-child(2) {
border-left: 1px solid darken(mc('blue-grey', '900'), 5%);
}

li {
border-top: none;
display: none;
}

}

li {
display: flex;
border-top: 1px solid mc($primary, '700');
border-top: 1px solid darken(mc('blue-grey', '900'), 5%);

&.is-title {
background-color: mc('blue-grey', '800');
padding: 8px 15px;
color: mc('blue-grey', '300');
font-size: 13px;
letter-spacing: 1px;
text-transform: uppercase;
box-shadow: 0 0 5px rgba(0,0,0,0.3);
margin-right:1px;
}

&.is-active {
display: flex;
Expand All @@ -32,48 +59,10 @@
a {
height: 50px;
}

}

}

a {
display: flex;
height: 40px;
width: 100%;
align-items: center;
padding: 0 15px;
color: #FFF;
cursor: pointer;
transition: all .4s ease;
background-color: rgba(0,0,0,0);

i {
font-size: 14px;
margin-right: 10px;
}

&:hover {
background-color: rgba(0,0,0,.1);
text-decoration: none;
}

}

}

.collapsable-nav-sub {
width: 300px;
background-color: mc('blue-grey', '800');
border-left: 1px solid mc('blue-grey', '900');
color: #FFF;
min-height: 80vh;

li {
display: flex;
border-top: 1px solid mc('blue-grey', '900');
}

a {
display: flex;
height: 40px;
Expand Down
4 changes: 0 additions & 4 deletions client/scss/components/sidebar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,6 @@
width: 50px;

aside {
.sidebar-label {
margin-right: 1px;
}

.sidebar-menu li a {
padding: 10px 0;
justify-content: center;
Expand Down
7 changes: 7 additions & 0 deletions config.sample.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ lang: en
public: false

auth:
defaultReadAccess: false
local:
enabled: true
google:
Expand Down Expand Up @@ -85,6 +86,12 @@ auth:
searchFilter: (uid={{username}})
tlsEnabled: false
tlsCertPath: C:\example\root_ca_cert.crt
azure:
enabled: false
clientID: APP_ID
clientSecret: APP_SECRET_KEY,
resource: '00000002-0000-0000-c000-000000000000',
tenant: 'YOUR_TENANT.onmicrosoft.com'

# ---------------------------------------------------------------------
# Secret key to use when encrypting sessions
Expand Down
2 changes: 2 additions & 0 deletions controllers/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,14 @@ router.get('/login/google', passport.authenticate('google', { scope: ['profile',
router.get('/login/facebook', passport.authenticate('facebook', { scope: ['public_profile', 'email'] }))
router.get('/login/github', passport.authenticate('github', { scope: ['user:email'] }))
router.get('/login/slack', passport.authenticate('slack', { scope: ['identity.basic', 'identity.email'] }))
router.get('/login/azure', passport.authenticate('azure_ad_oauth2'))

router.get('/login/ms/callback', passport.authenticate('windowslive', { failureRedirect: '/login', successRedirect: '/' }))
router.get('/login/google/callback', passport.authenticate('google', { failureRedirect: '/login', successRedirect: '/' }))
router.get('/login/facebook/callback', passport.authenticate('facebook', { failureRedirect: '/login', successRedirect: '/' }))
router.get('/login/github/callback', passport.authenticate('github', { failureRedirect: '/login', successRedirect: '/' }))
router.get('/login/slack/callback', passport.authenticate('slack', { failureRedirect: '/login', successRedirect: '/' }))
router.get('/login/azure/callback', passport.authenticate('azure_ad_oauth2', { failureRedirect: '/login', successRedirect: '/' }))

/**
* Logout
Expand Down
40 changes: 33 additions & 7 deletions libs/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,6 @@

/* global appconfig, appdata, db, winston */

const LocalStrategy = require('passport-local').Strategy
const GoogleStrategy = require('passport-google-oauth20').Strategy
const WindowsLiveStrategy = require('passport-windowslive').Strategy
const FacebookStrategy = require('passport-facebook').Strategy
const GitHubStrategy = require('passport-github2').Strategy
const SlackStrategy = require('passport-slack').Strategy
const LdapStrategy = require('passport-ldapauth').Strategy
const fs = require('fs')

module.exports = function (passport) {
Expand All @@ -34,6 +27,7 @@ module.exports = function (passport) {
// Local Account

if (!appdata.capabilities.manyAuthProviders || (appconfig.auth.local && appconfig.auth.local.enabled)) {
const LocalStrategy = require('passport-local').Strategy
passport.use('local',
new LocalStrategy({
usernameField: 'email',
Expand All @@ -60,6 +54,7 @@ module.exports = function (passport) {
// Google ID

if (appdata.capabilities.manyAuthProviders && appconfig.auth.google && appconfig.auth.google.enabled) {
const GoogleStrategy = require('passport-google-oauth20').Strategy
passport.use('google',
new GoogleStrategy({
clientID: appconfig.auth.google.clientId,
Expand All @@ -79,6 +74,7 @@ module.exports = function (passport) {
// Microsoft Accounts

if (appdata.capabilities.manyAuthProviders && appconfig.auth.microsoft && appconfig.auth.microsoft.enabled) {
const WindowsLiveStrategy = require('passport-windowslive').Strategy
passport.use('windowslive',
new WindowsLiveStrategy({
clientID: appconfig.auth.microsoft.clientId,
Expand All @@ -98,6 +94,7 @@ module.exports = function (passport) {
// Facebook

if (appdata.capabilities.manyAuthProviders && appconfig.auth.facebook && appconfig.auth.facebook.enabled) {
const FacebookStrategy = require('passport-facebook').Strategy
passport.use('facebook',
new FacebookStrategy({
clientID: appconfig.auth.facebook.clientId,
Expand All @@ -118,6 +115,7 @@ module.exports = function (passport) {
// GitHub

if (appdata.capabilities.manyAuthProviders && appconfig.auth.github && appconfig.auth.github.enabled) {
const GitHubStrategy = require('passport-github2').Strategy
passport.use('github',
new GitHubStrategy({
clientID: appconfig.auth.github.clientId,
Expand All @@ -138,6 +136,7 @@ module.exports = function (passport) {
// Slack

if (appdata.capabilities.manyAuthProviders && appconfig.auth.slack && appconfig.auth.slack.enabled) {
const SlackStrategy = require('passport-slack').Strategy
passport.use('slack',
new SlackStrategy({
clientID: appconfig.auth.slack.clientId,
Expand All @@ -157,6 +156,7 @@ module.exports = function (passport) {
// LDAP

if (appdata.capabilities.manyAuthProviders && appconfig.auth.ldap && appconfig.auth.ldap.enabled) {
const LdapStrategy = require('passport-ldapauth').Strategy
passport.use('ldapauth',
new LdapStrategy({
server: {
Expand Down Expand Up @@ -187,6 +187,32 @@ module.exports = function (passport) {
))
}

// AZURE AD

if (appdata.capabilities.manyAuthProviders && appconfig.auth.azure && appconfig.auth.azure.enabled) {
const AzureAdOAuth2Strategy = require('passport-azure-ad-oauth2').Strategy
const jwt = require('jsonwebtoken')
passport.use('azure_ad_oauth2',
new AzureAdOAuth2Strategy({
clientID: appconfig.auth.azure.clientId,
clientSecret: appconfig.auth.azure.clientSecret,
callbackURL: appconfig.host + '/login/azure/callback',
resource: appconfig.auth.azure.resource,
tenant: appconfig.auth.azure.tenant
},
(accessToken, refreshToken, params, profile, cb) => {
let waadProfile = jwt.decode(params.id_token)
waadProfile.id = waadProfile.oid
waadProfile.provider = 'azure'
db.User.processProfile(waadProfile).then((user) => {
return cb(null, user) || true
}).catch((err) => {
return cb(err, null) || true
})
}
))
}

// Create users for first-time

db.onReady.then(() => {
Expand Down
6 changes: 2 additions & 4 deletions libs/config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
'use strict'

/* global winston */

const fs = require('fs')
const yaml = require('js-yaml')
const _ = require('lodash')
Expand All @@ -25,7 +23,7 @@ module.exports = (confPaths) => {
appconfig = yaml.safeLoad(fs.readFileSync(confPaths.config, 'utf8'))
appdata = yaml.safeLoad(fs.readFileSync(confPaths.data, 'utf8'))
} catch (ex) {
winston.error(ex)
console.error(ex)
process.exit(1)
}

Expand All @@ -41,7 +39,7 @@ module.exports = (confPaths) => {
socialEnabled: (_.chain(appconfig.auth).omit('local').reject({ enabled: false }).value().length > 0)
}
if (appconfig.authStrategies.list.length < 1) {
winston.error(new Error('You must enable at least 1 authentication strategy!'))
console.error(new Error('You must enable at least 1 authentication strategy!'))
process.exit(1)
}
} else {
Expand Down
3 changes: 2 additions & 1 deletion locales/en/auth.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
"providers": {
"local": "Local",
"windowslive": "Microsoft Account",
"azure": "Azure Active Directory",
"google": "Google ID",
"facebook": "Facebook",
"github": "GitHub",
"slack": "Slack",
"ldap": "LDAP / Active Directory"
}
}
}
5 changes: 2 additions & 3 deletions models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,8 @@ userSchema.statics.processProfile = (profile) => {
}, {
new: true
}).then((user) => {
// LDAP - Handle unregistered accounts
// Todo: Allow this behavior for any provider...
if (!user && profile.provider === 'ldap') {
// Handle unregistered accounts
if (!user && profile.provider !== 'local' && (appconfig.auth.defaultReadAccess || profile.provider === 'ldap' || profile.provider === 'azure')) {
let nUsr = {
email: primaryEmail,
provider: profile.provider,
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"image-size": "^0.5.1",
"jimp": "github:ngpixel/jimp",
"js-yaml": "^3.8.3",
"jsonwebtoken": "^7.3.0",
"klaw": "^1.3.1",
"levelup": "^1.3.5",
"lodash": "^4.17.3",
Expand All @@ -91,6 +92,7 @@
"multer": "^1.2.1",
"ora": "^1.2.0",
"passport": "^0.3.2",
"passport-azure-ad-oauth2": "0.0.4",
"passport-facebook": "^2.1.1",
"passport-github2": "^0.1.10",
"passport-google-oauth20": "^1.0.0",
Expand Down
4 changes: 4 additions & 0 deletions views/auth/login.pug
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ html(data-logic='login')
button.ms(onclick='window.location.assign("/login/ms")')
i.icon-windows2
span Microsoft Account
if appconfig.auth.azure && appconfig.auth.azure.enabled
button.ms(onclick='window.location.assign("/login/azure")')
i.icon-windows2
span Azure AD
if appconfig.auth.google && appconfig.auth.google.enabled
button.google(onclick='window.location.assign("/login/google")')
i.icon-google
Expand Down
1 change: 1 addition & 0 deletions views/pages/admin/profile.pug
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ block adminContent
case user.provider
when 'local': i.icon-server
when 'windowslive': i.icon-windows2.is-blue
when 'azure': i.icon-windows2.is-blue
when 'google': i.icon-google.is-blue
when 'facebook': i.icon-facebook.is-indigo
when 'github': i.icon-github.is-grey
Expand Down
3 changes: 3 additions & 0 deletions views/pages/admin/users-edit.pug
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ block adminContent
when 'windowslive'
i.icon-windows2.is-blue
| Microsoft Account
when 'azure'
i.icon-windows2.is-blue
| Azure Active Directory
when 'google'
i.icon-google.is-blue
| Google ID
Expand Down

0 comments on commit 7c1dd8b

Please sign in to comment.