spree_api 1.0.7 → 1.1.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +6 -0
- data/LICENSE +19 -23
- data/README.md +22 -10
- data/Rakefile +30 -0
- data/app/controllers/spree/api/v1/base_controller.rb +71 -0
- data/app/controllers/spree/api/v1/images_controller.rb +46 -0
- data/app/controllers/spree/api/v1/line_items_controller.rb +40 -0
- data/app/controllers/spree/api/v1/orders_controller.rb +53 -0
- data/app/controllers/spree/api/v1/products_controller.rb +46 -0
- data/app/controllers/spree/api/v1/variants_controller.rb +56 -0
- data/app/helpers/spree/api/api_helpers.rb +44 -0
- data/app/models/spree/line_item_decorator.rb +3 -0
- data/app/models/spree/option_value_decorator.rb +5 -0
- data/app/models/spree/order_decorator.rb +12 -0
- data/app/models/spree/user_decorator.rb +11 -0
- data/app/views/spree/api/v1/errors/invalid_api_key.rabl +2 -0
- data/app/views/spree/api/v1/errors/invalid_resource.rabl +3 -0
- data/app/views/spree/api/v1/errors/must_specify_api_key.rabl +2 -0
- data/app/views/spree/api/v1/errors/not_found.rabl +2 -0
- data/app/views/spree/api/v1/errors/unauthorized.rabl +2 -0
- data/app/views/spree/api/v1/images/show.rabl +2 -0
- data/app/views/spree/api/v1/line_items/new.rabl +3 -0
- data/app/views/spree/api/v1/line_items/show.rabl +5 -0
- data/app/views/spree/api/v1/orders/address.rabl +0 -0
- data/app/views/spree/api/v1/orders/cart.rabl +0 -0
- data/app/views/spree/api/v1/orders/complete.rabl +0 -0
- data/app/views/spree/api/v1/orders/could_not_transition.rabl +3 -0
- data/app/views/spree/api/v1/orders/delivery.rabl +3 -0
- data/app/views/spree/api/v1/orders/index.rabl +7 -0
- data/app/views/spree/api/v1/orders/invalid_shipping_method.rabl +2 -0
- data/app/views/spree/api/v1/orders/payment.rabl +0 -0
- data/app/views/spree/api/v1/orders/show.rabl +3 -0
- data/app/views/spree/api/v1/products/index.rabl +8 -0
- data/app/views/spree/api/v1/products/new.rabl +3 -0
- data/app/views/spree/api/v1/products/product.rabl +1 -0
- data/app/views/spree/api/v1/products/show.rabl +21 -0
- data/app/views/spree/api/v1/variants/index.rabl +3 -0
- data/app/views/spree/api/v1/variants/new.rabl +2 -0
- data/app/views/spree/api/v1/variants/show.rabl +3 -0
- data/app/views/spree/api/v1/variants/variant.rabl +1 -0
- data/config/locales/en.yml +11 -15
- data/config/routes.rb +14 -28
- data/db/migrate/{20100107141738_add_api_key_to_users.rb → 20100107141738_add_api_key_to_spree_users.rb} +1 -1
- data/lib/spree/api.rb +7 -4
- data/lib/spree/api/controller_setup.rb +27 -0
- data/lib/spree/api/engine.rb +3 -13
- data/lib/spree/api/version.rb +5 -0
- data/lib/spree_api.rb +0 -2
- data/script/rails +5 -0
- data/spec/controllers/spree/api/v1/base_controller_spec.rb +29 -0
- data/spec/controllers/spree/api/v1/images_controller_spec.rb +50 -0
- data/spec/controllers/spree/api/v1/line_items_controller_spec.rb +77 -0
- data/spec/controllers/spree/api/v1/orders_controller_spec.rb +148 -0
- data/spec/controllers/spree/api/v1/products_controller_spec.rb +159 -0
- data/spec/controllers/spree/api/v1/variants_controller_spec.rb +90 -0
- data/spec/fixtures/thinking-cat.jpg +0 -0
- data/spec/models/spree/order_spec.rb +18 -0
- data/spec/models/spree/user_spec.rb +19 -0
- data/spec/spec_helper.rb +28 -0
- data/spec/support/api_helpers.rb +68 -0
- data/spec/support/controller_hacks.rb +27 -0
- data/spree_api.gemspec +24 -0
- metadata +123 -56
- data/app/assets/javascripts/admin/spree.js +0 -4
- data/app/assets/javascripts/admin/spree_api.js +0 -2
- data/app/assets/javascripts/store/spree.js +0 -4
- data/app/assets/javascripts/store/spree_api.js +0 -2
- data/app/assets/stylesheets/admin/spree.css +0 -6
- data/app/assets/stylesheets/admin/spree_api.css +0 -4
- data/app/assets/stylesheets/store/spree.css +0 -6
- data/app/assets/stylesheets/store/spree_api.css +0 -4
- data/app/controllers/spree/admin/users_controller_decorator.rb +0 -17
- data/app/controllers/spree/api/base_controller.rb +0 -172
- data/app/controllers/spree/api/countries_controller.rb +0 -3
- data/app/controllers/spree/api/inventory_units_controller.rb +0 -18
- data/app/controllers/spree/api/line_items_controller.rb +0 -20
- data/app/controllers/spree/api/orders_controller.rb +0 -19
- data/app/controllers/spree/api/products_controller.rb +0 -14
- data/app/controllers/spree/api/shipments_controller.rb +0 -35
- data/app/controllers/spree/api/states_controller.rb +0 -8
- data/app/models/line_item_decorator.rb +0 -7
- data/app/models/order_decorator.rb +0 -9
- data/app/models/shipment_decorator.rb +0 -9
- data/app/models/user_decorator.rb +0 -19
- data/app/overrides/api_admin_user_edit_form.rb +0 -6
- data/app/views/spree/admin/users/_api_fields.html.erb +0 -16
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
CHANGED
@@ -1,26 +1,22 @@
|
|
1
|
-
Copyright (c)
|
2
|
-
All rights reserved.
|
1
|
+
Copyright (c) 2012 Ryan Bigg
|
3
2
|
|
4
|
-
|
5
|
-
are permitted provided that the following conditions are met:
|
3
|
+
MIT License
|
6
4
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
prior written permission.
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
15
12
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,17 +1,29 @@
|
|
1
|
-
|
2
|
-
===
|
1
|
+
# Api
|
3
2
|
|
4
|
-
|
3
|
+
TODO: Write a gem description
|
5
4
|
|
6
|
-
|
5
|
+
## Installation
|
7
6
|
|
8
|
-
|
9
|
-
-------
|
7
|
+
Add this line to your application's Gemfile:
|
10
8
|
|
11
|
-
|
9
|
+
gem 'api'
|
12
10
|
|
13
|
-
|
11
|
+
And then execute:
|
14
12
|
|
15
|
-
|
13
|
+
$ bundle
|
16
14
|
|
17
|
-
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install api
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rake/packagetask'
|
5
|
+
require 'rubygems/package_task'
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
require 'spree/core/testing_support/common_rake'
|
8
|
+
require 'rails/all'
|
9
|
+
|
10
|
+
Bundler::GemHelper.install_tasks
|
11
|
+
RSpec::Core::RakeTask.new
|
12
|
+
|
13
|
+
spec = eval(File.read('spree_api.gemspec'))
|
14
|
+
Gem::PackageTask.new(spec) do |p|
|
15
|
+
p.gem_spec = spec
|
16
|
+
end
|
17
|
+
|
18
|
+
desc "Release to gemcutter"
|
19
|
+
task :release do
|
20
|
+
version = File.read(File.expand_path("../../SPREE_VERSION", __FILE__)).strip
|
21
|
+
cmd = "cd pkg && gem push spree_api-#{version}.gem"; puts cmd; system cmd
|
22
|
+
end
|
23
|
+
|
24
|
+
task :default => :spec
|
25
|
+
|
26
|
+
desc "Generates a dummy app for testing"
|
27
|
+
task :test_app do
|
28
|
+
ENV['LIB_NAME'] = 'spree/api'
|
29
|
+
Rake::Task['common:test_app'].invoke
|
30
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Spree
|
2
|
+
module Api
|
3
|
+
module V1
|
4
|
+
class BaseController < ActionController::Metal
|
5
|
+
include Spree::Api::ControllerSetup
|
6
|
+
|
7
|
+
attr_accessor :current_api_user
|
8
|
+
|
9
|
+
before_filter :check_for_api_key
|
10
|
+
before_filter :authenticate_user
|
11
|
+
|
12
|
+
rescue_from CanCan::AccessDenied, :with => :unauthorized
|
13
|
+
rescue_from ActiveRecord::RecordNotFound, :with => :not_found
|
14
|
+
|
15
|
+
helper Spree::Api::ApiHelpers
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def check_for_api_key
|
20
|
+
render "spree/api/v1/errors/must_specify_api_key", :status => 401 and return if api_key.blank?
|
21
|
+
end
|
22
|
+
|
23
|
+
def authenticate_user
|
24
|
+
unless @current_api_user = User.find_by_api_key(api_key)
|
25
|
+
render "spree/api/v1/errors/invalid_api_key", :status => 401 and return
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def unauthorized
|
30
|
+
render "spree/api/v1/errors/unauthorized", :status => 401 and return
|
31
|
+
end
|
32
|
+
|
33
|
+
def not_found
|
34
|
+
render "spree/api/v1/errors/not_found", :status => 404 and return
|
35
|
+
end
|
36
|
+
|
37
|
+
def current_ability
|
38
|
+
Spree::Ability.new(current_api_user)
|
39
|
+
end
|
40
|
+
|
41
|
+
def invalid_resource!(resource)
|
42
|
+
render "spree/api/v1/errors/invalid_resource", :resource => resource, :status => 422
|
43
|
+
end
|
44
|
+
|
45
|
+
def api_key
|
46
|
+
request.headers["X-Spree-Token"] || params[:token]
|
47
|
+
end
|
48
|
+
helper_method :api_key
|
49
|
+
|
50
|
+
def find_product(id)
|
51
|
+
begin
|
52
|
+
product_scope.find_by_permalink!(id)
|
53
|
+
rescue ActiveRecord::RecordNotFound
|
54
|
+
product_scope.find(id)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def product_scope
|
59
|
+
if current_api_user.has_role?("admin")
|
60
|
+
scope = Product
|
61
|
+
else
|
62
|
+
scope = Product.active
|
63
|
+
end
|
64
|
+
scope.includes(:master)
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Spree
|
2
|
+
module Api
|
3
|
+
module V1
|
4
|
+
class ImagesController < Spree::Api::V1::BaseController
|
5
|
+
def create
|
6
|
+
@image = product_or_variant.images.create!(params[:image])
|
7
|
+
render :show, :status => 201
|
8
|
+
end
|
9
|
+
|
10
|
+
def update
|
11
|
+
image.update_attributes(params[:image])
|
12
|
+
render :show, :status => 200
|
13
|
+
end
|
14
|
+
|
15
|
+
def destroy
|
16
|
+
image.destroy
|
17
|
+
render :text => nil
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def image
|
23
|
+
@image = product_or_variant.images.find(params[:id])
|
24
|
+
end
|
25
|
+
|
26
|
+
def product_or_variant
|
27
|
+
return @product_or_variant if @product_or_variant
|
28
|
+
if params[:product_id]
|
29
|
+
@product_or_variant = product
|
30
|
+
else
|
31
|
+
@product_or_variant = variant
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def variant
|
36
|
+
Variant.find(params[:variant_id])
|
37
|
+
end
|
38
|
+
|
39
|
+
def product
|
40
|
+
find_product(params[:product_id]).master
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Spree
|
2
|
+
module Api
|
3
|
+
module V1
|
4
|
+
class LineItemsController < Spree::Api::V1::BaseController
|
5
|
+
def create
|
6
|
+
authorize! :read, order
|
7
|
+
@line_item = order.line_items.build(params[:line_item], :as => :api)
|
8
|
+
if @line_item.save
|
9
|
+
render :show, :status => 201
|
10
|
+
else
|
11
|
+
invalid_resource!(@line_item)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def update
|
16
|
+
authorize! :read, order
|
17
|
+
@line_item = order.line_items.find(params[:id])
|
18
|
+
if @line_item.update_attributes(params[:line_item])
|
19
|
+
render :show
|
20
|
+
else
|
21
|
+
invalid_resource!(@line_item)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def destroy
|
26
|
+
authorize! :read, order
|
27
|
+
@line_item = order.line_items.find(params[:id])
|
28
|
+
@line_item.destroy
|
29
|
+
render :text => nil, :status => 200
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def order
|
35
|
+
@order ||= Order.find_by_number!(params[:order_id])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Spree
|
2
|
+
module Api
|
3
|
+
module V1
|
4
|
+
class OrdersController < Spree::Api::V1::BaseController
|
5
|
+
def index
|
6
|
+
# should probably look at turning this into a CanCan step
|
7
|
+
raise CanCan::AccessDenied unless current_api_user.has_role?("admin")
|
8
|
+
@orders = Order.page(params[:page])
|
9
|
+
end
|
10
|
+
|
11
|
+
def show
|
12
|
+
authorize! :read, order
|
13
|
+
end
|
14
|
+
|
15
|
+
def create
|
16
|
+
@order = Order.build_from_api(current_api_user, params[:order])
|
17
|
+
next!
|
18
|
+
end
|
19
|
+
|
20
|
+
def address
|
21
|
+
order.build_ship_address(params[:shipping_address])
|
22
|
+
order.build_bill_address(params[:billing_address])
|
23
|
+
next!
|
24
|
+
end
|
25
|
+
|
26
|
+
def delivery
|
27
|
+
begin
|
28
|
+
ShippingMethod.find(params[:shipping_method_id])
|
29
|
+
rescue ActiveRecord::RecordNotFound
|
30
|
+
render :invalid_shipping_method, :status => 422
|
31
|
+
else
|
32
|
+
order.update_attribute(:shipping_method_id, params[:shipping_method_id])
|
33
|
+
next!
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def order
|
40
|
+
@order ||= Order.find_by_number!(params[:id])
|
41
|
+
end
|
42
|
+
|
43
|
+
def next!
|
44
|
+
if @order.valid? && @order.next
|
45
|
+
render :show, :status => 200
|
46
|
+
else
|
47
|
+
render :could_not_transition, :status => 422
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Spree
|
2
|
+
module Api
|
3
|
+
module V1
|
4
|
+
class ProductsController < Spree::Api::V1::BaseController
|
5
|
+
def index
|
6
|
+
@products = product_scope.page(params[:page])
|
7
|
+
end
|
8
|
+
|
9
|
+
def show
|
10
|
+
@product = find_product(params[:id])
|
11
|
+
end
|
12
|
+
|
13
|
+
def new
|
14
|
+
end
|
15
|
+
|
16
|
+
def create
|
17
|
+
authorize! :create, Product
|
18
|
+
@product = Product.new(params[:product])
|
19
|
+
if @product.save
|
20
|
+
render :show, :status => 201
|
21
|
+
else
|
22
|
+
invalid_resource!(@product)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def update
|
27
|
+
authorize! :update, Product
|
28
|
+
@product = find_product(params[:id])
|
29
|
+
if @product.update_attributes(params[:product])
|
30
|
+
render :show, :status => 200
|
31
|
+
else
|
32
|
+
invalid_resource!(@product)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def destroy
|
37
|
+
authorize! :delete, Product
|
38
|
+
@product = find_product(params[:id])
|
39
|
+
@product.update_attribute(:deleted_at, Time.now)
|
40
|
+
@product.variants_including_master.update_all(:deleted_at => Time.now)
|
41
|
+
render :text => nil, :status => 200
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Spree
|
2
|
+
module Api
|
3
|
+
module V1
|
4
|
+
class VariantsController < Spree::Api::V1::BaseController
|
5
|
+
before_filter :product
|
6
|
+
|
7
|
+
def index
|
8
|
+
@variants = scope.includes(:option_values).scoped
|
9
|
+
end
|
10
|
+
|
11
|
+
def show
|
12
|
+
@variant = scope.includes(:option_values).find(params[:id])
|
13
|
+
end
|
14
|
+
|
15
|
+
def new
|
16
|
+
end
|
17
|
+
|
18
|
+
def create
|
19
|
+
authorize! :create, Variant
|
20
|
+
@variant = scope.new(params[:product])
|
21
|
+
if @variant.save
|
22
|
+
render :show, :status => 201
|
23
|
+
else
|
24
|
+
invalid_resource!(@variant)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def update
|
29
|
+
authorize! :update, Variant
|
30
|
+
@variant = scope.find(params[:id])
|
31
|
+
if @variant.update_attributes(params[:variant])
|
32
|
+
render :show, :status => 200
|
33
|
+
else
|
34
|
+
invalid_resource!(@product)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def destroy
|
39
|
+
authorize! :delete, Variant
|
40
|
+
@variant = scope.find(params[:id])
|
41
|
+
@variant.destroy
|
42
|
+
render :text => nil, :status => 200
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
def product
|
47
|
+
@product ||= Spree::Product.find_by_permalink(params[:product_id]) if params[:product_id]
|
48
|
+
end
|
49
|
+
|
50
|
+
def scope
|
51
|
+
@product ? @product.variants_including_master : Variant
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|