Browse Source

Add mattermost authentication

pull/606/head
Christoph Witzany 4 years ago
parent
commit
5cda55086a
14 changed files with 116 additions and 13 deletions
  1. +13
    -9
      README.md
  2. +12
    -0
      app.json
  3. +5
    -0
      config.json.example
  4. +5
    -0
      lib/config/default.js
  5. +4
    -0
      lib/config/dockerSecret.js
  6. +5
    -0
      lib/config/environment.js
  7. +1
    -0
      lib/config/index.js
  8. +9
    -0
      lib/models/user.js
  9. +1
    -0
      lib/response.js
  10. +1
    -0
      lib/web/auth/index.js
  11. +49
    -0
      lib/web/auth/mattermost/index.js
  12. +2
    -0
      package.json
  13. +2
    -2
      public/views/index/body.ejs
  14. +7
    -2
      public/views/shared/signin-modal.ejs

+ 13
- 9
README.md View File

@ -8,8 +8,8 @@ HackMD
[![version][github-version-badge]][github-release-page]
HackMD lets you create realtime collaborative markdown notes on all platforms.
Inspired by Hackpad, with more focus on speed and flexibility.
HackMD lets you create realtime collaborative markdown notes on all platforms.
Inspired by Hackpad, with more focus on speed and flexibility.
Still in the early stage, feel free to fork or contribute to HackMD.
Thanks for using! :smile:
@ -97,13 +97,13 @@ If you are upgrading HackMD from an older version, follow these steps:
* [migration-to-0.5.0](https://github.com/hackmdio/migration-to-0.5.0)
We don't use LZString to compress socket.io data and DB data after version 0.5.0.
We don't use LZString to compress socket.io data and DB data after version 0.5.0.
Please run the migration tool if you're upgrading from the old version.
* [migration-to-0.4.0](https://github.com/hackmdio/migration-to-0.4.0)
We've dropped MongoDB after version 0.4.0.
So here is the migration tool for you to transfer the old DB data to the new DB.
We've dropped MongoDB after version 0.4.0.
So here is the migration tool for you to transfer the old DB data to the new DB.
This tool is also used for official service.
# Configuration
@ -141,6 +141,9 @@ There are some configs you need to change in the files below
| HMD_GITLAB_BASEURL | no example | GitLab authentication endpoint, set to use other endpoint than GitLab.com (optional) |
| HMD_GITLAB_CLIENTID | no example | GitLab API client id |
| HMD_GITLAB_CLIENTSECRET | no example | GitLab API client secret |
| HMD_MATTERMOST_BASEURL | no example | Mattermost authentication endpoint |
| HMD_MATTERMOST_CLIENTID | no example | Mattermost API client id |
| HMD_MATTERMOST_CLIENTSECRET | no example | Mattermost API client secret |
| HMD_DROPBOX_CLIENTID | no example | Dropbox API client id |
| HMD_DROPBOX_CLIENTSECRET | no example | Dropbox API client secret |
| HMD_GOOGLE_CLIENTID | no example | Google API client id |
@ -216,7 +219,7 @@ There are some configs you need to change in the files below
| service | settings location | description |
| ------- | --------- | ----------- |
| facebook, twitter, github, gitlab, dropbox, google, ldap | environment variables or `config.json` | for signin |
| facebook, twitter, github, gitlab, mattermost, dropbox, google, ldap | environment variables or `config.json` | for signin |
| imgur | environment variables or `config.json` | for image upload |
| google drive(`google/apiKey`, `google/clientID`), dropbox(`dropbox/appKey`) | `config.json` | for export and import |
@ -228,6 +231,7 @@ There are some configs you need to change in the files below
| twitter | `/auth/twitter/callback` |
| github | `/auth/github/callback` |
| gitlab | `/auth/gitlab/callback` |
| mattermost | `/auth/mattermost/callback` |
| dropbox | `/auth/dropbox/callback` |
| google | `/auth/google/callback` |
@ -249,9 +253,9 @@ hackmd/
## Operational Transformation
From 0.3.2, we started supporting operational transformation.
It makes concurrent editing safe and will not break up other users' operations.
Additionally, now can show other clients' selections.
From 0.3.2, we started supporting operational transformation.
It makes concurrent editing safe and will not break up other users' operations.
Additionally, now can show other clients' selections.
See more at [http://operational-transformation.github.io/](http://operational-transformation.github.io/)


+ 12
- 0
app.json View File

@ -100,6 +100,18 @@
"description": "GitLab API client scope (optional)",
"required": false
},
"HMD_MATTERMOST_BASEURL": {
"description": "Mattermost authentication endpoint",
"required": false
},
"HMD_MATTERMOST_CLIENTID": {
"description": "Mattermost API client id",
"required": false
},
"HMD_MATTERMOST_CLIENTSECRET": {
"description": "Mattermost API client secret",
"required": false
},
"HMD_DROPBOX_CLIENTID": {
"description": "Dropbox API client id",
"required": false


+ 5
- 0
config.json.example View File

@ -48,6 +48,11 @@
"clientSecret": "change this",
"scope": "use 'read_user' scope for auth user only or remove this property if you need gitlab snippet import/export support (will result to be default scope 'api')"
},
"mattermost": {
"baseURL": "change this",
"clientID": "change this",
"clientSecret": "change this"
},
"dropbox": {
"clientID": "change this",
"clientSecret": "change this",


+ 5
- 0
lib/config/default.js View File

@ -74,6 +74,11 @@ module.exports = {
clientSecret: undefined,
scope: undefined
},
mattermost: {
baseURL: undefined,
clientID: undefined,
clientSecret: undefined
},
dropbox: {
clientID: undefined,
clientSecret: undefined


+ 4
- 0
lib/config/dockerSecret.js View File

@ -38,6 +38,10 @@ if (fs.existsSync(basePath)) {
clientID: getSecret('gitlab_clientID'),
clientSecret: getSecret('gitlab_clientSecret')
},
mattermost: {
clientID: getSecret('mattermost_clientID'),
clientSecret: getSecret('mattermost_clientSecret')
},
dropbox: {
clientID: getSecret('dropbox_clientID'),
clientSecret: getSecret('dropbox_clientSecret')


+ 5
- 0
lib/config/environment.js View File

@ -49,6 +49,11 @@ module.exports = {
clientSecret: process.env.HMD_GITLAB_CLIENTSECRET,
scope: process.env.HMD_GITLAB_SCOPE
},
mattermost: {
baseURL: process.env.HMD_MATTERMOST_BASEURL,
clientID: process.env.HMD_MATTERMOST_CLIENTID,
clientSecret: process.env.HMD_MATTERMOST_CLIENTSECRET
},
dropbox: {
clientID: process.env.HMD_DROPBOX_CLIENTID,
clientSecret: process.env.HMD_DROPBOX_CLIENTSECRET


+ 1
- 0
lib/config/index.js View File

@ -90,6 +90,7 @@ config.isTwitterEnable = config.twitter.consumerKey && config.twitter.consumerSe
config.isEmailEnable = config.email
config.isGitHubEnable = config.github.clientID && config.github.clientSecret
config.isGitLabEnable = config.gitlab.clientID && config.gitlab.clientSecret
config.isMattermostEnable = config.mattermost.clientID && config.mattermost.clientSecret
config.isLDAPEnable = config.ldap.url
config.isPDFExportEnable = config.allowpdfexport


+ 9
- 0
lib/models/user.js View File

@ -111,6 +111,15 @@ module.exports = function (sequelize, DataTypes) {
photo = letterAvatars(profile.username)
}
break
case 'mattermost':
photo = profile.avatarUrl
if (photo) {
if (bigger) photo = photo.replace(/(\?s=)\d*$/i, '$1400')
else photo = photo.replace(/(\?s=)\d*$/i, '$196')
} else {
photo = letterAvatars(profile.username)
}
break
case 'dropbox':
// no image api provided, use gravatar
photo = 'https://www.gravatar.com/avatar/' + md5(profile.emails[0].value)


+ 1
- 0
lib/response.js View File

@ -64,6 +64,7 @@ function showIndex (req, res, next) {
twitter: config.isTwitterEnable,
github: config.isGitHubEnable,
gitlab: config.isGitLabEnable,
mattermost: config.isMattermostEnable,
dropbox: config.isDropboxEnable,
google: config.isGoogleEnable,
ldap: config.isLDAPEnable,


+ 1
- 0
lib/web/auth/index.js View File

@ -33,6 +33,7 @@ if (config.isFacebookEnable) authRouter.use(require('./facebook'))
if (config.isTwitterEnable) authRouter.use(require('./twitter'))
if (config.isGitHubEnable) authRouter.use(require('./github'))
if (config.isGitLabEnable) authRouter.use(require('./gitlab'))
if (config.isMattermostEnable) authRouter.use(require('./mattermost'))
if (config.isDropboxEnable) authRouter.use(require('./dropbox'))
if (config.isGoogleEnable) authRouter.use(require('./google'))
if (config.isLDAPEnable) authRouter.use(require('./ldap'))


+ 49
- 0
lib/web/auth/mattermost/index.js View File

@ -0,0 +1,49 @@
'use strict'
const Router = require('express').Router
const passport = require('passport')
const Mattermost = require('mattermost')
const OAuthStrategy = require('passport-oauth2').Strategy
const config = require('../../../config')
const {setReturnToFromReferer, passportGeneralCallback} = require('../utils')
const mattermost = new Mattermost.Client()
let mattermostAuth = module.exports = Router()
let mattermostStrategy = new OAuthStrategy({
authorizationURL: config.mattermost.baseURL + '/oauth/authorize',
tokenURL: config.mattermost.baseURL + '/oauth/access_token',
clientID: config.mattermost.clientID,
clientSecret: config.mattermost.clientSecret,
callbackURL: config.serverurl + '/auth/mattermost/callback'
}, passportGeneralCallback)
mattermostStrategy.userProfile = (accessToken, done) => {
mattermost.setUrl(config.mattermost.baseURL)
mattermost.token = accessToken
mattermost.useHeaderToken()
mattermost.getMe(
(data) => {
done(null, data)
},
(err) => {
done(err)
}
)
}
passport.use(mattermostStrategy)
mattermostAuth.get('/auth/mattermost', function (req, res, next) {
setReturnToFromReferer(req)
passport.authenticate('oauth2')(req, res, next)
})
// mattermost auth callback
mattermostAuth.get('/auth/mattermost/callback',
passport.authenticate('oauth2', {
successReturnToOrRedirect: config.serverurl + '/',
failureRedirect: config.serverurl + '/'
})
)

+ 2
- 0
package.json View File

@ -76,6 +76,7 @@
"markdown-pdf": "^7.0.0",
"mathjax": "~2.7.0",
"mermaid": "~7.1.0",
"mattermost": "^3.4.0",
"meta-marked": "^0.4.2",
"method-override": "^2.3.7",
"moment": "^2.17.1",
@ -91,6 +92,7 @@
"passport-google-oauth20": "^1.0.0",
"passport-ldapauth": "^0.6.0",
"passport-local": "^1.0.0",
"passport-oauth2": "^1.4.0",
"passport-twitter": "^1.0.4",
"passport.socketio": "^3.7.0",
"pdfobject": "^2.0.201604172",


+ 2
- 2
public/views/index/body.ejs View File

@ -15,7 +15,7 @@
<% if(allowAnonymous) { %>
<a type="button" href="<%- url %>/new" class="btn btn-sm btn-primary"><i class="fa fa-plus"></i> <%= __('New guest note') %></a>
<% } %>
<% if(facebook || twitter || github || gitlab || dropbox || google || ldap || email) { %>
<% if(facebook || twitter || github || gitlab || mattermost || dropbox || google || ldap || email) { %>
<button class="btn btn-sm btn-success ui-signin" data-toggle="modal" data-target=".signin-modal"><%= __('Sign In') %></button>
<% } %>
</div>
@ -48,7 +48,7 @@
<% if (errorMessage && errorMessage.length > 0) { %>
<div class="alert alert-danger" style="max-width: 400px; margin: 0 auto;"><%= errorMessage %></div>
<% } %>
<% if(facebook || twitter || github || gitlab || dropbox || google || ldap || email) { %>
<% if(facebook || twitter || github || gitlab || mattermost || dropbox || google || ldap || email) { %>
<span class="ui-signin">
<br>
<a type="button" class="btn btn-lg btn-success ui-signin" data-toggle="modal" data-target=".signin-modal" style="min-width: 200px;"><%= __('Sign In') %></a>


+ 7
- 2
public/views/shared/signin-modal.ejs View File

@ -28,6 +28,11 @@
<i class="fa fa-gitlab"></i> <%= __('Sign in via %s', 'GitLab') %>
</a>
<% } %>
<% if(mattermost) { %>
<a href="<%- url %>/auth/mattermost" class="btn btn-lg btn-block btn-social btn-soundcloud">
<i class="fa fa-mattermost"></i> <%= __('Sign in via %s', 'Mattermost') %>
</a>
<% } %>
<% if(dropbox) { %>
<a href="<%- url %>/auth/dropbox" class="btn btn-lg btn-block btn-social btn-dropbox">
<i class="fa fa-dropbox"></i> <%= __('Sign in via %s', 'Dropbox') %>
@ -38,7 +43,7 @@
<i class="fa fa-google"></i> <%= __('Sign in via %s', 'Google') %>
</a>
<% } %>
<% if((facebook || twitter || github || gitlab || dropbox || google) && ldap) { %>
<% if((facebook || twitter || github || gitlab || mattermost || dropbox || google) && ldap) { %>
<hr>
<% }%>
<% if(ldap) { %>
@ -63,7 +68,7 @@
</div>
</form>
<% } %>
<% if((facebook || twitter || github || gitlab || dropbox || google || ldap) && email) { %>
<% if((facebook || twitter || github || gitlab || mattermost || dropbox || google || ldap) && email) { %>
<hr>
<% }%>
<% if(email) { %>


Loading…
Cancel
Save