Daniel B. Chapman
Daniel B. Chapman

Reputation: 4687

Is it possible to user custom authentication in keystone.js without a keystone user model?

I have a (I hope) quick question regarding Authorization in Keystone: it seems like the "User" object is a core dependency in the framework. I'd like to side-step it completely but there doesn't seem to be a way to get the application functional without it.

I've run a basic bypass here:

keystone.init({
    //...
    'auth': (req, res, next)=>{
      if(Roles.has(Roles.Admin, Roles.Keyston)){
        next();
      } else {
        throw "403"; //Terminate
      }
    },
    'user model': 'User',
    //...
})

Which results in:

Sorry, an error occurred loading the page (500)

snip\KS2\node_modules\keystone\templates\layout\base.jade:80
> 79| a(href='/keystone/' + User.path + '/' + user.id)= User.getDocumentName(user)
80| | .
81| 
82| //- Common

item.get is not a function

As a result it expects the user object to exist on the request (even though I'm using my own authentication method). If I disable authentication completely it seems fine and I can protect the route with some middleware, but this seems like fairly buggy behavior.

Is the "User" object actually a dependency in the framework or is it basically there for convinience? Removing the model

//'user model' : 'User'

crashes Keystone

Sorry, an error occurred loading the page (500) Unknown keystone list undefined).

I'm fairly certain the former error is related to the "User Object" on the request being set to something silly and thus the Jade template blows up. Is it possible to decouple this User object from the framework? If it isn't is it possible to set this object so that I can continue using passport.js for primary authentication?

I'm particularly interested in this topic as I'd like to implement Role Based Authentication in the Keystone.js administration module and without more information on how this works/ideas for workarounds I don't have a jumping off point.

(**EDIT The error exists even with auth set to false)

Sorry, an error occurred loading the page (500)

...snip\KS2\node_modules\keystone\templates\layout\base.jade:78
76| if User && user
77| | Signed in as 
> 78| a(href='/keystone/' + User.path + '/' + user.id)= User.getDocumentName(user)
79| | .
80| 
81| //- Common

item.get is not a function

Exits even with auth: false as I have a "user" object that is turning up null and crashing the template.

EDIT #2 I've created a patch that solved the crash when user authentication is turned off, it doesn't really answer the question but it makes the application usable once again without depending on Keystone.js for authentication (which was a CRITICAL requirement for this CMS).

Upvotes: 3

Views: 1317

Answers (1)

Daniel B. Chapman
Daniel B. Chapman

Reputation: 4687

I'm still looking for help on this but here's how I bypassed it for the time being. It looks like the application is headed in a whole new direction for the administration console.

I'm issuing a pull request against that fork (which I believe is the package on npm currently).

You can view my fork here: https://github.com/danielbchapman/keystone/commit/d28dae031252fc2512598ef8496f336f27c1bbc0

//Git Patch for tag v3.22 From d28dae031252fc2512598ef8496f336f27c1bbc0 Mon Sep 17 00:00:00 2001 From: "Daniel B. Chapman" Date: Tue, 30 Aug 2016 09:25:50 -0600 Subject: [PATCH] Added a local auth variable that mirrors the keystone.get('auth') configuration setting so that applications that use a custom User object (like Passport.js) do not trigger a crash in the adiministration page due to the 'signed in as' functionality.

---
 lib/core/render.js         | 1 +
 templates/layout/base.jade | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/core/render.js b/lib/core/render.js
index 5d80453..2b03b7f 100644
--- a/lib/core/render.js
+++ b/lib/core/render.js
@@ -59,6 +59,7 @@ function render(req, res, view, ext) {
        moment: moment,
        numeral: numeral,
        env: keystone.get('env'),
+       auth: keystone.get('auth'),
        brand: keystone.get('brand'),
        appversion : keystone.get('appversion'),
        nav: keystone.nav,
diff --git a/templates/layout/base.jade b/templates/layout/base.jade
index 1caee5e..95639c6 100644
--- a/templates/layout/base.jade
+++ b/templates/layout/base.jade
@@ -73,7 +73,7 @@ html
        #footer: .container
            p   #{brand} #{appversion} 
                | Powered by <a href="http://keystonejs.com" target="_blank">KeystoneJS</a> version #{version}.
-               if User && user
+               if User && user && auth
                    |  Signed in as 
                    a(href='/keystone/' + User.path + '/' + user.id)= User.getDocumentName(user)
                    | .
-- 
1.9.5.msysgit.0

Upvotes: 4

Related Questions