title: ACL - Implement acl together with passport
body: <p>I am trying out <a href="https://github.com/OptimalBits/node_acl" rel="noreferrer">node_acl</a> with <a href="https://github.com/jaredhanson/passport-local" rel="noreferrer">passport-local</a>. When I run my code I cannot secure the route for the <code>admin-user</code> <code>'/admin'</code> and I am redirected to the <code>/login</code> page.</p>
  
  <p>Find below my minimum runnable example:</p>
  
  <pre><code>require('dotenv').config()
  const express = require('express')
  // const fs = require('fs')
  const path = require('path')
  const logger = require('morgan')
  const bodyParser = require('body-parser')
  const cookieParser = require('cookie-parser')
  const session = require('express-session')
  const passport = require('passport')
  const LocalStrategy = require('passport-local').Strategy
  const ACL = require('acl')
  
  // load user.json file
  // const d = fs.readFileSync(path.join(__dirname, '/../data/user.json'))
  // const userObj = JSON.parse(d)
  const userObj = [{
    id: 1,
    username: 'admin',
    password: 'admin',
    email: 'admin@admin.com',
    role: 'admin',
  },
  {
    id: 2,
    username: 'user',
    password: 'user',
    email: 'user@user.com',
    role: 'user',
  },
  ]
  
  const app = express()
  
  // view engine setup
  app.set('views', path.join(__dirname, 'views'))
  app.set('view engine', 'pug')
  app.use(logger(process.env.LOG_ENV))
  app.use(bodyParser.json())
  app.use(bodyParser.urlencoded({
    extended: false,
  }))
  app.use(express.static(path.join(__dirname, '/../public')))
  app.use(cookieParser())
  
  app.use(session({
    secret: 'super-mega-hyper-secret',
    resave: false,
    saveUninitialized: false,
  }))
  
  /**
   * Passport Local
   */
  app.use(passport.initialize())
  app.use(passport.session())
  
  function authenticate() {
    passport.serializeUser((user, done) =&gt; {
      done(null, user.id)
    })
  
    passport.deserializeUser(async(id, done) =&gt; {
      //        const user = await serviceAuth.findById(id)
      const user = userObj.find(item =&gt; item.id === id)
      done(null, user)
    })
  
    // Sign in with username and Password
    passport.use('local', new LocalStrategy({
      usernameField: 'username',
    }, async(username, password, done) =&gt; {
      const user = userObj.find(item =&gt; item.username === username)
      done(null, user)
    }))
  }
  
  const isAuthenticated = (req, res, next) =&gt; {
    if (req.isAuthenticated()) {
      res.locals.user = req.session.user
      return next()
    }
    res.redirect('login')
  }
  authenticate()
  
  /**
   * Node ACL
   */
  
  function accessControl() {
    const nodeAcl = new ACL(new ACL.memoryBackend())
  
    nodeAcl.allow([{
      roles: 'admin',
      allows: [{
        resources: '/admin',
        permissions: '*',
      }],
    }, {
      roles: 'user',
      allows: [{
        resources: '/dashboard',
        permissions: 'get',
      }],
    }, {
      roles: 'guest',
      allows: [],
    }])
  
    // Inherit roles
    //  Every user is allowed to do what guests do
    //  Every admin is allowed to do what users do
    nodeAcl.addRoleParents('user', 'guest')
    nodeAcl.addRoleParents('admin', 'user')
  
    nodeAcl.addUserRoles(1, 'admin')
    nodeAcl.addUserRoles(2, 'user')
    nodeAcl.addUserRoles(0, 'guest')
  
    return nodeAcl
  }
  
  /*
  function checkPermission(resource, action) {
    const access = accessControl()
  
    return (req, res, next) =&gt; {
      const uid = req.session.user.id
      access.isAllowed(uid, resource, action, (err, result) =&gt; {
        if (result) {
          next()
        } else {
          const checkError = new Error('User does not have permission to perform this action on this resource')
          next(checkError)
        }
      })
    }
  } */
  
  const getCurrentUserId = (req) =&gt; {
    console.log(req)
    req.user &amp;&amp; req.user.id.toString() || false
  }
  
  const access = accessControl()
  
  // Routes
  app.get('/login', (req, res) =&gt; {
    res.render('login')
  })
  
  app.post('/login', (req, res, next) =&gt; {
    passport.authenticate('local', (err, user) =&gt; {
      if (err) return next(err)
      if (!user) {
        return res.status(401).json({
          error: 'Email or password is incorrect.',
        })
      }
  
      return res.render('dashboard')
    })(req, res, next)
  })
  
  app.get('/dashboard', [isAuthenticated, access.middleware()], (req, res) =&gt; {
    res.render('dashboard')
  })
  
  app.get('/admin', [isAuthenticated, access.middleware()], (req, res) =&gt; {
    res.render('admin')
  })
  
  app.get('/status', (request, response) =&gt; {
    access.userRoles(getCurrentUserId(request), (error, roles) =&gt; {
      response.send(`User: ${JSON.stringify(request.user)} Roles: ${JSON.stringify(roles)}`)
    })
  })
  
  // Start Server
  const port = process.env.APP_PORT || 8080
  const host = process.env.APP_URL || 'localhost'
  
  app.listen(port, host, () =&gt; {
    console.log(`Listening on ${host}:${port}`)
  })
  
  module.exports = app
  </code></pre>
  
  <p>Any suggestions why the route, <code>/admin</code> cannot be called only be the <code>admin user</code>?</p>
  
  <p>Thank you in advance for your replies!</p>