fix auth/oauth

This commit is contained in:
les 2020-01-30 23:43:58 +01:00
parent c6e4569009
commit 465f2f3210
9 changed files with 55 additions and 36 deletions

View file

@ -5,7 +5,7 @@ div
el-collapse-item el-collapse-item
template(slot='title') template(slot='title')
el-button(type='text' mini size='mini') <v-icon name='plus'/> {{$t('common.new_user')}} el-button(type='text' mini size='mini') <v-icon name='plus'/> {{$t('common.new_user')}}
el-form(inline) el-form(inline @submit.native.prevent='create_user')
el-form-item(:label="$t('common.email')") el-form-item(:label="$t('common.email')")
el-input(v-model='new_user.email') el-input(v-model='new_user.email')
el-form-item(:label="$t('common.admin')") el-form-item(:label="$t('common.admin')")

View file

@ -1,39 +1,48 @@
const debug = require('debug')('auth') const debug = require('debug')('auth')
const oauth = require('./oauth') const oauth = require('./oauth')
const get = require('lodash/get')
const Auth = { const Auth = {
/** isAuth middleware
* req.user is filled in server/helper.js#initMiddleware
*/
isAuth (req, res, next) {
return oauth.oauthServer.authenticate()(req, res, next)
},
fillUser (req, res, next) { fillUser (req, res, next) {
const token = get(req.cookies, 'auth._token.local', null)
const authorization = get(req.headers, 'authorization', null)
if (!authorization && token) {
req.headers.authorization = token
}
if (!authorization && !token) {
return next()
}
oauth.oauthServer.authenticate()(req, res, () => { oauth.oauthServer.authenticate()(req, res, () => {
req.user = res.locals.oauth.token.user req.user = get(res, 'locals.oauth.token.user', null)
next() next()
}) })
}, },
/** isAdmin middleware */ isAuth (req, res, next) {
isAdmin (req, res, next) { if (req.user) {
oauth.oauthServer.authenticate()(req, res, () => { next()
req.user = res.locals.oauth.token.user } else {
if (req.user.is_admin) { res.status(404)
next() }
} else {
res.status(404)
}
})
}, },
isAdmin (req, res, next) {
if (req.user.is_admin) {
next()
} else {
res.status(404)
}
},
// TODO
hasPerm (scope) { hasPerm (scope) {
return (req, res, next) => { return (req, res, next) => {
debug(scope, req.path) debug(scope, req.path)
oauth.oauthServer.authenticate({ scope })(req, res, () => { oauth.oauthServer.authenticate({ scope })(req, res, () => {
req.user = res.locals.oauth.token.user debug('has perm')
next() next()
}) })
} }

View file

@ -6,6 +6,7 @@ const {
oauth_code: OAuthCode, user: User oauth_code: OAuthCode, user: User
} = require('../models') } = require('../models')
const debug = require('debug')('oauth') const debug = require('debug')('oauth')
const moment = require('moment')
async function randomString (len = 16) { async function randomString (len = 16) {
const bytes = await randomBytes(len * 8) const bytes = await randomBytes(len * 8)
@ -19,7 +20,6 @@ const oauthController = {
// create client => http:///gancio.org/oauth#create-client // create client => http:///gancio.org/oauth#create-client
async createClient (req, res) { async createClient (req, res) {
debug('Create client ', req.body.client_name)
// only write scope is supported // only write scope is supported
if (req.body.scopes && req.body.scopes !== 'event:write') { if (req.body.scopes && req.body.scopes !== 'event:write') {
return res.status(422).json({ error: 'Invalid scopes' }) return res.status(422).json({ error: 'Invalid scopes' })
@ -101,13 +101,13 @@ const oauthController = {
async getAuthorizationCode (code) { async getAuthorizationCode (code) {
const oauth_code = await OAuthCode.findByPk(code, const oauth_code = await OAuthCode.findByPk(code,
{ include: [User, { type: OAuthClient, as: 'client' }], nest: true, raw: true }) { include: [User, { model: OAuthClient, as: 'client' }] })
return oauth_code return oauth_code
}, },
async saveToken (token, client, user) { async saveToken (token, client, user) {
token.userId = user.id token.userId = user.id
token.oauthClientId = client.id token.clientId = client.id
const oauth_token = await OAuthToken.create(token) const oauth_token = await OAuthToken.create(token)
oauth_token.client = client oauth_token.client = client
oauth_token.user = user oauth_token.user = user
@ -115,7 +115,7 @@ const oauthController = {
}, },
async revokeAuthorizationCode (code) { async revokeAuthorizationCode (code) {
const oauth_code = await OAuthCode.findByPk(code) const oauth_code = await OAuthCode.findByPk(code.authorizationCode)
return oauth_code.destroy() return oauth_code.destroy()
}, },
@ -133,17 +133,19 @@ const oauthController = {
async saveAuthorizationCode (code, client, user) { async saveAuthorizationCode (code, client, user) {
code.userId = user.id code.userId = user.id
code.oauthClientId = client.id code.clientId = client.id
code.expiresAt = moment(code.expiresAt).toDate()
const ret = await OAuthCode.create(code) const ret = await OAuthCode.create(code)
return ret return ret
}, },
// TODO
verifyScope (token, scope) { verifyScope (token, scope) {
debug(token.user.is_admin) debug('VERIFY SCOPE ', scope)
if (token.user.is_admin) { if (token.user.is_admin) {
return true return true
} else { } else {
return false return true
} }
} }

View file

@ -107,7 +107,7 @@ const userController = {
} }
} catch (e) { } catch (e) {
res.sendStatus(400) res.sendStatus(400)
debug(e.toString()) debug(e)
} }
}, },

View file

@ -2,7 +2,7 @@ const express = require('express')
const multer = require('multer') const multer = require('multer')
const cors = require('cors')() const cors = require('cors')()
const { isAuth, isAdmin, hasPerm, fillUser } = require('./auth') const { isAuth, isAdmin, hasPerm } = require('./auth')
const eventController = require('./controller/event') const eventController = require('./controller/event')
const exportController = require('./controller/export') const exportController = require('./controller/export')
const userController = require('./controller/user') const userController = require('./controller/user')
@ -46,7 +46,7 @@ api.get('/users', isAdmin, userController.getAll)
api.put('/place', isAdmin, eventController.updatePlace) api.put('/place', isAdmin, eventController.updatePlace)
// add event // add event
api.post('/user/event', fillUser, upload.single('image'), userController.addEvent) api.post('/user/event', upload.single('image'), userController.addEvent)
// update event // update event
api.put('/user/event', hasPerm('event:write'), upload.single('image'), userController.updateEvent) api.put('/user/event', hasPerm('event:write'), upload.single('image'), userController.updateEvent)
@ -98,7 +98,7 @@ api.use((req, res) => res.sendStatus(404))
// Handle 500 // Handle 500
api.use((error, req, res, next) => { api.use((error, req, res, next) => {
debug(error.toString()) debug(error)
res.status(500).send('500: Internal Server Error') res.status(500).send('500: Internal Server Error')
}) })

View file

@ -9,6 +9,10 @@ module.exports = (sequelize, DataTypes) => {
email: { email: {
type: DataTypes.STRING, type: DataTypes.STRING,
unique: { msg: 'error.email_taken' }, unique: { msg: 'error.email_taken' },
validate: {
isEmail: true,
notEmpty: true
},
index: true, index: true,
allowNull: false allowNull: false
}, },

View file

@ -34,7 +34,7 @@ oauth.use((req, res) => res.sendStatus(404))
oauth.use((err, req, res, next) => { oauth.use((err, req, res, next) => {
const error_msg = err.toString() const error_msg = err.toString()
debug(err) debug(error_msg)
res.status(500).send(error_msg) res.status(500).send(error_msg)
}) })

View file

@ -4,6 +4,7 @@ const express = require('express')
const cors = require('cors') const cors = require('cors')
const api = require('./api') const api = require('./api')
const oauth = require('./api/oauth') const oauth = require('./api/oauth')
const auth = require('./api/auth')
const cookieParser = require('cookie-parser') const cookieParser = require('cookie-parser')
const federation = require('./federation') const federation = require('./federation')
const webfinger = require('./federation/webfinger') const webfinger = require('./federation/webfinger')
@ -44,6 +45,9 @@ app.use('/federation', federation)
// api! // api!
app.use(cookieParser()) app.use(cookieParser())
// fill req.user if request is authenticated
app.use(auth.fillUser)
app.use('/api', api) app.use('/api', api)
app.use('/oauth', oauth) app.use('/oauth', oauth)

View file

@ -13,7 +13,8 @@ class Task {
} }
process () { process () {
--this.processInNTick debug('PROCESS ', this.name)
this.processInNTick--
if (this.processInNTick > 0) { if (this.processInNTick > 0) {
return return
} }
@ -41,11 +42,11 @@ class Task {
class TaskManager { class TaskManager {
constructor () { constructor () {
this.interval = 60 * 1000 this.interval = 60 * 100
this.tasks = [] this.tasks = []
} }
start (interval = 60 * 1000) { start (interval = 60 * 100) {
this.interval = interval this.interval = interval
this.timeout = setTimeout(this.tick.bind(this), interval) this.timeout = setTimeout(this.tick.bind(this), interval)
} }
@ -74,7 +75,6 @@ class TaskManager {
} }
async tick () { async tick () {
debug('TICK')
await this.process() await this.process()
this.timeout = setTimeout(this.tick.bind(this), this.interval) this.timeout = setTimeout(this.tick.bind(this), this.interval)
} }