Permalink
Browse files

Added oauth2 support without persitent_token too

FIXME: semantics aren't that great
  • Loading branch information...
1 parent 6471324 commit 654d85107a29d81f0bac8411c01bacda8b3adc7c @temsa temsa committed Nov 18, 2012
Showing with 151 additions and 41 deletions.
  1. +8 −0 config.js
  2. +2 −2 lib/main.js
  3. +57 −5 lib/session-oauth.js
  4. +2 −8 lib/session.js
  5. +2 −2 src/main.coffee
  6. +1 −0 src/resource.coffee
  7. +38 −5 src/session-oauth.coffee
  8. +3 −6 src/session.coffee
  9. +1 −1 test/products_test.js
  10. +37 −12 test/session_oauth_test.js
View
@@ -0,0 +1,8 @@
+module.exports = {
+ shop:"test",
+ client_id: '147852',
+ secret:"741852",
+ persistent_token:"bec575b100cf20dad723bb6edb33e153",
+ code:"123456ab",
+ test_shop:"https://test.myshopify.com"
+};
View
@@ -3,8 +3,8 @@
Session = require('./session-oauth');
- exports.createSession = function(url, token, apiKey, secret, params) {
- return new Session(url, token, apiKey, secret, params);
+ exports.createSession = function(storename, apiKey, secret, params) {
+ return new Session(storename, apiKey, secret, params);
};
}).call(this);
View

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
View
@@ -40,14 +40,12 @@
Session.prototype.protocol = "https";
- function Session(url, token, apiKey, secret, params) {
+ function Session(url, apiKey, secret, params) {
var expireTime, timestamp;
this.url = url;
- this.token = token != null ? token : '';
this.apiKey = apiKey;
this.secret = secret;
this.params = params != null ? params : {};
- if (empty(this.token)) this.token = this.url;
if (this.params['signature'] != null) {
timestamp = (new Date(this.params['timestamp'])).getTime();
expireTime = (new Date).getTime() - (24 * 84600);
@@ -74,11 +72,7 @@
};
Session.prototype.valid = function() {
- return !empty(this.url) && !empty(this.token);
- };
-
- Session.prototype.computedPassword = function() {
- return crypto.createHash('md5').update("" + this.secret + this.token).digest("hex");
+ return !empty(this.url);
};
Session.prototype.prepareUrl = function(url) {
View
@@ -1,5 +1,5 @@
Session = require './session-oauth'
-exports.createSession = (url, token, apiKey, secret, params) ->
- new Session(url, token, apiKey, secret, params)
+exports.createSession = (storename, apiKey, secret, params) ->
+ new Session(storename, apiKey, secret, params)
View
@@ -62,6 +62,7 @@ class Resource extends singleton
setOAuthToken:(@oauth_token)->
@oauth = @oauth_token?
+
module.exports = Resource.get()
View
@@ -6,17 +6,24 @@ Session = require './session'
class SessionOAuth extends Session
- constructor:(@store_name, @api_key, @secret, @persistent_token = null)->
+ constructor:(@store_name, @api_key, @secret, params = {})->
super @store_name, @api_key, @secret
- @registerOAuthToken()
+ if typeof params == 'string'
+ @persistent_token = params
+ params = {persistent_token: @persistent_token}
+ else
+ params = params || {}
+ @persistent_token = params.persistent_token || null
+ @params = params
+ @registerOAuthToken params
onRedirectUrl:(url, cb)->
url.replace /\?code=[\w\d]+/, (code)=>
temp_token = code.split('=')[1]
@requestPermanentAccessToken temp_token, (@persistent_token)=>
@registerOAuthToken()
- process.nextTick ->
- do cb
+ process.nextTick =>
+ cb(@store_name, @persistent_token)
requestPermanentAccessToken:(temp_token, cb)->
params = "client_id=#{@api_key}&client_secret=#{@secret}&code=#{temp_token}"
@@ -28,12 +35,38 @@ class SessionOAuth extends Session
process.nextTick ->
cb response.access_token
+ requestTemporaryAccessToken:()=>
+ scope = @getScope()
+ if(!scope.length)
+ @params.onAskToken(Error("No Shopify scope defined, cannot ask for no right"))
+ uri_base = "#{@site()}/oauth/authorize?client_id=#{@api_key}&scope=#{scope}"
+ if(@params.uriForTemporaryToken)
+ @params.onAskToken.call this, null, "#{uri_base}&redirect_uri=#{@params.uriForTemporaryToken}"
+ else
+ @params.onAskToken.call this, null, uri_base
site:()->
"#{@protocol}://#{@store_name}.myshopify.com/admin"
- registerOAuthToken:()->
+ registerOAuthToken:(params)->
if @persistent_token isnt null
Resource.setOAuthToken @persistent_token
+ else if typeof @params.onAskToken == 'function'
+ @requestTemporaryAccessToken()
+ else
+ throw Error("No onAskToken callback defined for getting temporary oauth2 token from Shopify, and no persistent token defined either in session")
+
+ getScope:(@scope)->
+ types = ['content', 'themes', 'products', 'customers', 'orders', 'script_tags', 'shipping'];
+ scope = [];
+ @scope = @scope || @params.scope || {};
+ for type in types
+ continue if !@scope[type]
+ @scope[type] = @scope[type].split /[\/,]/ if typeof @scope[type] == 'string'
+ if Array.isArray(@scope[type])
+ rights = @scope[type].map (right)-> "#{right}_#{type}"
+ scope.push rights.join(',')
+ return scope.join ','
+
module.exports = SessionOAuth
View
@@ -33,8 +33,8 @@ class Session
protocol: "https"
- constructor: (@url, @token = '', @apiKey, @secret, @params = {}) ->
- @token = @url if empty(@token)
+ constructor: (@url, @apiKey, @secret, @params = {}) ->
+
if @params['signature']?
timestamp = (new Date(@params['timestamp'])).getTime()
expireTime = (new Date).getTime() - (24 * 84600)
@@ -55,10 +55,7 @@ class Session
"#{@protocol}://#{@apiKey}:#{@computedPassword()}@#{@url}/admin"
valid: ->
- not empty(@url) and not empty(@token)
-
- computedPassword: ->
- crypto.createHash('md5').update("#{@secret}#{@token}").digest("hex")
+ not empty(@url)
prepareUrl: (url) ->
return '' if empty(url)
View
@@ -1,5 +1,5 @@
var assert = require('assert')
- , should = require('should')
+ , should = require('chai').should()
, nock = require('nock')
, Product = require('../lib/resources/product.js')
, helper = require('./common');
View
@@ -1,21 +1,46 @@
var assert = require('assert')
, should = require('should')
- , Session = require('../lib/session-oauth.js');
+ , nock = require('nock')
+ , config = require('../config.js')
+ , Session = require('../lib/session-oauth.js')
+ ;
+
-var config = require('../config.js');
describe('SessionOAuth', function() {
-/*
- it('should exchange the temporary token for a permanent access token on redirectURL', function(done) {
- var session = new Session(config.shop, config.client_id, config.secret);
- session.onRedirectUrl("/myredirect?code=" + config.code + "&store=test_store", function(token){
- assert(session.persistent_token != null, true);
- done();
+ it('should ask shopify for a temporary token ', function(done) {
+ var temporaryTokenToPermanentReq = nock(config.test_shop)
+ //.log(console.log)
+ .post('/admin/oauth/access_token', 'client_id='+config.client_id+'&client_secret='+config.secret+'&code='+config.code)
+ .reply(200, {access_token: config.persistent_token})
+
+ var session = new Session(config.shop, config.client_id, config.secret, {
+ scope: {orders: "read"},
+ uriForTemporaryToken: config.test_shop+"/login/finalize/token",
+ onAskToken: onToken
});
+
+ function onToken (err, url) {
+ should.not.exist(err);
+ url.should.be.a.string('scope=read_orders');
+
+ this.onRedirectUrl("/myredirect?code=" + config.code + "&store="+config.shop, function(store, token){
+
+ temporaryTokenToPermanentReq.done();
+ should.exist(store);
+ should.exist(token);
+ should.exist(session.persistent_token);
+ session.persistent_token.should.equal(token);
+
+ done();
+
+ });
+ }
});
-*/
- it('should use the pesistent_token on creation if applicable', function(done){
- var session = new Session(config.shop, '','', config.persistent_token);
- assert(session.persistent_token != null, true);
+
+ it('should use the persistent_token on creation if applicable', function(done){
+ var session = new Session(config.shop, config.client_id, config.secret, config.persistent_token);
+ should.exist(session.persistent_token);
+ session.persistent_token.should.equal(config.persistent_token);
done();
});

0 comments on commit 654d851

Please sign in to comment.