Skip to content

Commit

Permalink
Persist user if in configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
jenow committed Feb 3, 2016
1 parent 1bd61d4 commit 687e519
Show file tree
Hide file tree
Showing 9 changed files with 221 additions and 25 deletions.
58 changes: 58 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"rules": {
"consistent-return": 2,
"curly": 2,
"dot-notation": 2,
"eqeqeq": 2,
"guard-for-in": 2,
"indent": [2, 2, {"SwitchCase": 1}],
"linebreak-style": [2, "unix"],
"new-cap": 1,
"no-caller": 2,
"no-catch-shadow": 2,
"no-else-return": 2,
"no-extend-native": 2,
"no-extra-bind": 2,
"no-eval": 2,
"no-implicit-coercion": 2,
"no-implied-eval": 2,
"no-invalid-this": 2,
"no-irregular-whitespace": 2,
"no-labels": 2,
"no-lone-blocks": 2,
"no-lonely-if": 1,
"no-loop-func": 2,
"no-multi-spaces": 1,
"no-multiple-empty-lines": 1,
"no-native-reassign": 2,
"no-nested-ternary": 2,
"no-new": 2,
"no-new-func": 2,
"no-new-require": 2,
"no-new-wrappers": 2,
"no-return-assign": 2,
"no-self-compare": 2,
"no-sequences": 2,
"no-shadow": 2,
"no-shadow-restricted-names": 2,
"no-throw-literal": 2,
"no-undef": 2,
"no-undef-init": 1,
"no-unreachable": 2,
"no-unused-expressions": 2,
"no-useless-call": 2,
"no-with": 2,
"quotes": [2, "single"],
"semi": [2, "always"],
"space-after-keywords": 2,
"space-before-blocks": 2,
"space-in-parens": [2, "never"],
"vars-on-top": 2,
"yoda": [2, "never"]
},
"env": {
"node": true,
"es6": true
},
"extends": "eslint:recommended"
}
13 changes: 13 additions & 0 deletions .jshintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"camelcase": true,
"curly": true,
"eqeqeq": true,
"esnext": true,
"freeze": true,
"indent": 2,
"newcap": true,
"quotmark": "single",
"eqnull": true,
"funcscope": true,
"node": true
}
44 changes: 43 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,52 @@ This plugin doesn't need any right.

# Configuration

You can override the configuration in your `config/customPlugins.json` file in Kuzzle:

| Name | Default value | Type | Description |
|------|---------------|-----------|-----------------------------|
| ``persist`` | ``{}`` | Object | Attributes you want to persist if the user doesn't exist |
| ``scope`` | ``[]`` | Array | List of attributes which requires rights to get |
| ``clientID`` | | String | Github clientID |
| ``clientSecret`` | | String | Github secret |
| ``callbackUrl`` | | String | Github callback url |

Here is an example of a configuration:

```json
"kuzzle-plugin-auth-github": {
"version": "1.0.0",
"activated": true,
"name": "kuzzle-plugin-auth-github",
"defaultConfig": {
"persist": {}
},
"customConfig": {
"persist": [
"login",
"avatar_url",
"name",
"email"
],
"scope": [
"user:email",
"user:avatar_url"
],
"clientID": "<your-client-id>",
"clientSecret": "<your-client-secret>",
"callbackUrl": "http://host:7511/api/1.0/_login/github"
}
}
```

# Usage

@TODO : complete doc.
Just send following data to the auth controller:

{"body":{
"strategy": "github",
"username": "<username>"
}}

See [Kuzzle API Documentation](http://kuzzleio.github.io/kuzzle-api-documentation/#auth-controller) for more details about Kuzzle authentication mechanism.

Expand Down
3 changes: 3 additions & 0 deletions lib/config/pipes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
'passport:loadScope': 'loadScope'
};
8 changes: 7 additions & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var
hooks = require('./config/hooks'),
pipes = require('./config/pipes'),
Strategy = require('./passport/strategy');

module.exports = function () {
Expand Down Expand Up @@ -40,15 +41,20 @@ module.exports = function () {
if (!config.level) {
config.level = 'error';
}

return this;
};

this.hooks = hooks;
this.pipes = pipes;

this.loadStrategy = function(passport) {
var strategy = new Strategy(this.context);
strategy.load(passport, this.config);
};

this.loadScope = function(requestObject, callback) {
requestObject.scope.github = this.config.scope;
callback(null, requestObject.scope);
};

};
47 changes: 28 additions & 19 deletions lib/passport/strategy.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,52 @@
var
q = require('q'),
GithubStrategy = require('passport-github2').Strategy;
GithubStrategy = require('passport-github').Strategy,
refresh = require('passport-oauth2-refresh');

module.exports = function(context) {

this.verify = function (accessToken, refreshToken, profile, done) {
var deferred = q.defer(),
repositories = context.repositories();
repositories = context.repositories(),
user = new repositories.user.ObjectConstructor(),
hydratedUser = {
profile: 'admin',
_id: profile._json.login
};

repositories.user.load(profile.username)
repositories.user.load(profile._json.login)
.then(userObject => {
if (userObject !== null) {
deferred.resolve(userObject);
}
else {
if (this.persist) {
var user = repositories.user.anonymous();
Object.keys(profile).forEach(function (attr) {
user[attr] = profile[attr];
});
repositories.user.persist(user);
Object.keys(profile._json).forEach(attr => {
if (this.config.persist.indexOf(attr) > -1) {
hydratedUser[attr] = profile._json[attr];
}
});
if (this.config.persist.length !== 0) {
repositories.user.hydrate(user, hydratedUser)
.then(u => {
repositories.user.persist(u, { database: {method: 'create'} });
});
}
deferred.resolve(profile);
deferred.resolve(hydratedUser);
}
})
.catch(err => deferred.reject(err));

}).catch(err => deferred.reject(err));
deferred.promise.nodeify(done);
return deferred.promise;
};

this.load = function (passport, config) {
var
strategy = new GithubStrategy({
clientID: config.clientID,
clientSecret: config.clientSecret,
callbackURL: config.callbackUrl
}, this.verify.bind(this));
this.config = config;
var strategy = new GithubStrategy({
clientID: this.config.clientID,
clientSecret: this.config.clientSecret,
callbackURL: this.config.callbackUrl
}, this.verify.bind(this));

passport.use(strategy);
refresh.use(strategy);
};
};
11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,26 @@
},
"pluginInfo": {
"defaultConfig": {
"persist": false
"persist": {}
}
},
"license": "Apache-2.0",
"dependencies": {
"passport": "0.3.2",
"passport-github": "1.0.0",
"passport-oauth2": "1.x.x"
"passport-oauth2": "1.x.x",
"passport-oauth2-refresh": "1.0.0",
"q": "2.0.3"
},
"devDependencies": {
"eslint": "1.9.0",
"grunt": "^0.4.5",
"grunt-contrib-jshint": "^0.11.3",
"gruntify-eslint": "^1.2.0",
"mocha": "2.3.3",
"should": "7.1.1",
"rewire": "2.4.0"
"proxyquire": "^1.7.3",
"rewire": "2.4.0",
"should": "8.1.1"
},
"gitHead": "06f51a7b72065f5961f135b75d7a937b2937b83d",
"homepage": "https://github.com/kuzzleio/kuzzle-plugin-auth-github#readme",
Expand Down
26 changes: 26 additions & 0 deletions test/pipes.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
var
should = require('should'),
pipes = require('../lib/config/pipes'),
rewire = require('rewire'),
PluginGithub = rewire('../lib');

describe('pipes definition', function() {
var pluginGithub;

before(function () {
pluginGithub = new PluginGithub();
pluginGithub.init({persist: true, clientID: 'id', clientSecret: 'secret', callbackUrl: 'http://callback.url', scope: ['test']});
});

it('should link kuzzle pipe correctly', function() {
should(pipes).be.an.Object();
should(pipes["passport:loadScope"]).be.a.String().and.be.eql('loadScope');
});

it('should trigger loadScope pipe', function(done) {
pluginGithub.loadScope({scope: {}}, function(err, object) {
should(object.github[0]).equal('test');
done();
});
});
});
36 changes: 36 additions & 0 deletions test/verify.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
var
should = require('should'),
pipes = require('../lib/config/pipes'),
rewire = require('rewire'),
PluginGithub = rewire('../lib'),
strategy = require('../lib/passport/strategy'),
proxyquire = require('proxyquire');


describe('passport verify', function() {
var
pluginGithub,
Passport;

before(function () {
pluginGithub = new PluginGithub();
pluginGithub.init({persist: true, clientID: 'id', clientSecret: 'secret', callbackUrl: 'http://callback.url', scope: ['test']});
});

it('should link kuzzle pipe correctly', function() {
should(pipes).be.an.Object();
should(pipes["passport:loadScope"]).be.a.String().and.be.eql('loadScope');
});

it('should trigger loadScope pipe', function(done) {
pluginGithub.loadScope({scope: {}}, function(err, object) {
should(object.github[0]).equal('test');
done();
});
});

it('should load a new user', function() {
Passport = proxyquire('passport', {});
strategy.verify();
});
});

0 comments on commit 687e519

Please sign in to comment.