Permalink
Browse files

Merge pull request #128 from mattolson/customer-login

Add support for customer login
  • Loading branch information...
2 parents 62a84f5 + 9b01ea7 commit 9844fa69700ead77a20dded0cc060ec13df6e16e @pedelman pedelman committed on GitHub Jul 8, 2016
View
1 .gitignore
@@ -15,3 +15,4 @@ pkg/*
tmp/*
.env
.env-*
+vendor/bundle
View
1 CHANGELOG.md
@@ -2,6 +2,7 @@
Your contribution here.
* [#000](https://github.com/bigcommerce/bigcommerce-api-ruby/pull/000): Brief description here. - [@username](https://github.com/username).
+* [#128](https://github.com/bigcommerce/bigcommerce-api-ruby/pull/128): Added support for token generation for storefront login. - [@mattolson](https://github.com/mattolson).
## 1.0.0
Please note that this is the start of a new major release which breaks all backward compatibility.
View
3 CONTRIBUTING.md
@@ -1,7 +1,6 @@
# Contributing to Bigcommerce
-
-We would love to see contributors! You're encouraged to submit [pull requests](https://github.com/bigcommerce/bigcommerce-api-ruby/pulls), [propose features, and discuss issues](https://github.com/bigcommerce/bigcommerce-api-ruby/issues).
+We welcome your contribution! You're encouraged to submit [pull requests](https://github.com/bigcommerce/bigcommerce-api-ruby/pulls), [propose features, and discuss issues](https://github.com/bigcommerce/bigcommerce-api-ruby/issues).
#### Fork the Project
View
1 DEPENDENCIES.md
@@ -5,3 +5,4 @@ Many thanks to the contributors and authors of the following libraries!
- [Faraday](https://github.com/lostisland/faraday) Simple, but flexible HTTP client library, with support for multiple backends. - [MIT](https://github.com/lostisland/faraday/blob/master/LICENSE.md)
- [Faraday Middleware](https://github.com/lostisland/faraday_middleware) Various Faraday middlewares for Faraday-based API wrappers. - [MIT](https://github.com/lostisland/faraday_middleware/blob/master/LICENSE.md)
- [Hashie](https://github.com/intridea/hashie) Hashie is a collection of classes and mixins that make hashes more powerful. - [MIT](https://github.com/intridea/hashie/blob/master/LICENSE)
+- [JWT](https://github.com/jwt/ruby-jwt) Used to encode and sign JWT tokens for the Customer Login API. - [MIT](https://github.com/jwt/ruby-jwt/blob/master/LICENSE)
View
22 README.md
@@ -92,6 +92,20 @@ For more information about configuring SSL with Faraday, please see the followin
- [Faraday SSL example](https://gist.github.com/mislav/938183)
- [Faraday: Setting up SSL certificates](https://github.com/lostisland/faraday/wiki/Setting-up-SSL-certificates)
+### Customer Login API
+If you want to generate tokens for storefront login using the Customer Login API, you need to configure your app's client secret.
+
+- ```store_hash```: The store hash of the store you are operating against.
+- ```client_id```: Obtained from the on the BigCommerce [Developer Portal's](http://developer.bigcommerce.com) "My Apps" section.
+- ```client_secret```: Obtained from the on the BigCommerce [Developer Portal's](http://developer.bigcommerce.com) "My Apps" section.
+
+```rb
+Bigcommerce.configure do |config|
+ config.store_hash = ENV['BC_STORE_HASH']
+ config.client_id = ENV['BC_CLIENT_ID']
+ config.client_secret = ENV['BC_CLIENT_SECRET']
+end
+```
## Usage
For full examples of using the API client, please see the [examples folder](examples) and refer to BigCommerce's [developer documentation](https://developer.bigcommerce.com/api).
@@ -124,8 +138,8 @@ This connection is nothing more than a `Faraday::Connection` – so if you want
```rb
connection = Bigcommerce::Connection.build(
Bigcommerce::Config.new(
- store_hash: ENV['BC_STORE_HASH'],
- client_id: ENV['BC_CLIENT_ID'],
+ store_hash: ENV['BC_STORE_HASH'],
+ client_id: ENV['BC_CLIENT_ID'],
access_token: ENV['BC_ACCESS_TOKEN']
)
)
@@ -143,7 +157,7 @@ Bigcommerce::System.raw_request(:get, 'time', connection: connection)
```rb
connection_legacy = Bigcommerce::Connection.build(
Bigcommerce::Config.new(
- auth: 'legacy',
+ auth: 'legacy',
url: ENV['BC_API_ENDPOINT_LEGACY'],
username: ENV['BC_USERNAME'],
api_key: ENV['BC_API_KEY']
@@ -159,4 +173,4 @@ Bigcommerce::System.raw_request(:get, 'time', connection: connection_legacy)
```
## Contributing
-See [CONTRIBUTING.md](CONTRIBUTING.md)
+See [CONTRIBUTING.md](CONTRIBUTING.md)
View
1 bigcommerce.gemspec
@@ -23,4 +23,5 @@ Gem::Specification.new do |s|
s.add_dependency 'faraday', '~> 0.9'
s.add_dependency 'faraday_middleware', '~> 0.10.0'
s.add_dependency 'hashie', '~> 3.4'
+ s.add_dependency 'jwt', '~> 1.5.4'
end
View
14 examples/customers/customer_login.rb
@@ -0,0 +1,14 @@
+require 'bigcommerce'
+
+Bigcommerce.configure do |config|
+ config.store_hash = ENV['BC_STORE_HASH']
+ config.client_id = ENV['BC_CLIENT_ID']
+ config.client_secret = ENV['BC_CLIENT_SECRET']
+ config.access_token = ENV['BC_ACCESS_TOKEN']
+end
+
+# Get a customer
+customer = Bigcommerce::Customer.all(page: 1).first
+
+# Generate token login url
+puts customer.login_token
View
2 lib/bigcommerce.rb
@@ -12,7 +12,7 @@ module Bigcommerce
Dir.glob(resources, &method(:require))
class << self
- attr_reader :api
+ attr_reader :api, :config
def configure
@config = Bigcommerce::Config.new.tap { |h| yield(h) }
View
19 lib/bigcommerce/resources/customers/customer.rb
@@ -1,3 +1,6 @@
+require 'jwt'
+require 'securerandom'
+
# Customer
# Identity and account details for customers shopping at a Bigcommerce store.
# https://developer.bigcommerce.com/api/stores/v2/customers
@@ -26,5 +29,21 @@ class Customer < Resource
def self.count(params = {})
get 'customers/count', params
end
+
+ # Generate a token that can be used to log the customer into the storefront.
+ # This requires your app to have the store_v2_customers_login scope and to
+ # be installed in the store.
+ def login_token(config: Bigcommerce.config)
+ payload = {
+ 'iss' => config.client_id,
+ 'iat' => Time.now.to_i,
+ 'jti' => SecureRandom.uuid,
+ 'operation' => 'customer_login',
+ 'store_hash' => config.store_hash,
+ 'customer_id' => id
+ }
+
+ JWT.encode(payload, config.client_secret, 'HS256')
+ end
end
end
View
33 spec/bigcommerce/unit/resources/customers/customer_spec.rb
@@ -1,10 +1,35 @@
RSpec.describe Bigcommerce::Customer do
- before(:each) { @customer = Bigcommerce::Customer }
-
describe '.count' do
it 'should hit the correct path' do
- expect(@customer).to receive(:get).with('customers/count', {})
- @customer.count
+ expect(described_class).to receive(:get).with('customers/count', {})
+ described_class.count
+ end
+ end
+
+ describe '.login_token' do
+ let(:client_id) { SecureRandom.hex(6) }
+ let(:client_secret) { SecureRandom.hex(6) }
+ let(:store_hash) { SecureRandom.hex(4) }
+ let(:customer_id) { Random.rand(1000) }
+ let(:customer) { described_class.new(id: customer_id) }
+ subject { customer.login_token }
+
+ before do
+ Bigcommerce.configure do |config|
+ config.store_hash = store_hash
+ config.client_id = client_id
+ config.client_secret = client_secret
+ end
+ end
+
+ it 'should generate a signed token with the right payload' do
+ payload = JWT.decode(subject, client_secret, true, { :algorithm => 'HS256' })[0]
+ expect(payload['iss']).to eq(client_id)
+ expect(payload['store_hash']).to eq(store_hash)
+ expect(payload['operation']).to eq('customer_login')
+ expect(payload['customer_id']).to eq(customer_id)
+ expect(payload['iat']).to be <= Time.now.to_i
+ expect(payload['jti']).to_not be_empty
end
end
end

0 comments on commit 9844fa6

Please sign in to comment.