restaurant 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +66 -60
- data/lib/restaurant.rb +1 -1
- data/lib/restaurant/authorization.rb +1 -73
- data/lib/restaurant/controller_helper.rb +1 -1
- data/lib/restaurant/restful_actions.rb +27 -7
- data/lib/restaurant/role_provider.rb +91 -0
- data/lib/restaurant/version.rb +1 -1
- metadata +6 -5
- data/lib/restaurant/model_class_finder.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d5122a098f9caa7cc338db255ba09004f7ccf66
|
4
|
+
data.tar.gz: c3d345db89308e5c3290712e9107a0ce5e72fd4c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: faeea0c7030f4a52afde512659ed888b5535ed1abe9ca06c913b8b643ffe39074cb857ec0035e9bf9f8b77e0d94c2d5d5c45da7ae01ed9304c6a0f03b217a95a
|
7
|
+
data.tar.gz: 7b66d037c43da749f4829d55a80ef64282544580fe07902b9ee4cbbe99d7fca79d144632055453dceae2b26f5376a7e242f00ac940cc7708875e8d4cf9154ae1
|
data/README.md
CHANGED
@@ -1,72 +1,52 @@
|
|
1
1
|
# Restaurant
|
2
|
-
Restaurant serves RESTful API on
|
2
|
+
Restaurant serves your data via auto-defined RESTful API on your rails application.
|
3
3
|
|
4
4
|
## Features
|
5
|
+
* Auto-defined controllers
|
6
|
+
* Auto-defined routes
|
7
|
+
* SQL-like URI query
|
8
|
+
* OAuth authentication
|
9
|
+
* Scope based authorization
|
10
|
+
* restrict actions
|
11
|
+
* restrict attributes
|
12
|
+
* restrict filtering
|
13
|
+
* restrict sorting
|
14
|
+
* RESTful APIs
|
15
|
+
* GET /:resources
|
16
|
+
* GET /:resources/:id
|
17
|
+
* POST /:resources
|
18
|
+
* PUT /:resources/:id
|
19
|
+
* DELETE /:resources/:id
|
5
20
|
|
6
|
-
|
7
|
-
|
8
|
-
All controllers and routings will be auto-defined based on your config/restaurant.yml definition.
|
9
|
-
No need to write any more app/controllers and config/routes.rb.
|
10
|
-
All you have to do is write your models and authorization yaml file.
|
11
|
-
|
12
|
-
```ruby
|
13
|
-
# app/controllers/application_controller.rb
|
14
|
-
class ApplicationController < ActionController::Base
|
15
|
-
include Restaurant::ControllerHelper
|
16
|
-
end
|
17
|
-
```
|
18
|
-
|
19
|
-
```ruby
|
20
|
-
# config/routes.rb
|
21
|
-
Rails.application.routes.draw do
|
22
|
-
Restaurant::Router.route(self)
|
23
|
-
end
|
24
|
-
```
|
21
|
+
## Auto-defined controllers and routes
|
22
|
+
Controllers and routes are auto-defined from your config/restaurant.yml.
|
25
23
|
|
26
24
|
```yaml
|
27
25
|
# config/restaurant.yml
|
28
|
-
public:
|
29
|
-
recipes:
|
30
|
-
actions:
|
31
|
-
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
26
|
+
public: # User with "public" scope token
|
27
|
+
recipes: #
|
28
|
+
actions: #
|
29
|
+
- show # can access to /recipes/:id
|
30
|
+
attributes: #
|
31
|
+
- title # can read recipe.title
|
32
|
+
admin: # User with "admin" scope token
|
33
|
+
recipes: #
|
34
|
+
actions: #
|
35
|
+
- index # can access to /recipes
|
36
|
+
- show # can access to /recipes/:id
|
37
|
+
where: #
|
38
|
+
- id # can filter recipes by id
|
39
|
+
- title # can filter recipes by title
|
40
|
+
order: #
|
41
|
+
- id # can sort recipes by id
|
42
|
+
- title # can sort recipes by title
|
43
|
+
attributes: #
|
44
|
+
- id # can read recipe.id
|
45
|
+
- title # can read recipe.title
|
36
46
|
```
|
37
47
|
|
38
|
-
|
39
|
-
You can
|
40
|
-
|
41
|
-
* User with "public" scope token
|
42
|
-
* can access /recipes/:id
|
43
|
-
* User with "admin" scope token
|
44
|
-
* can access /recipes/:id
|
45
|
-
* can access /recipes
|
46
|
-
* can filter recipes by id and title
|
47
|
-
* can sort recipes by id and title
|
48
|
-
|
49
|
-
```yaml
|
50
|
-
# config/restaurant.yml
|
51
|
-
public:
|
52
|
-
recipes:
|
53
|
-
actions:
|
54
|
-
- show
|
55
|
-
admin:
|
56
|
-
recipes:
|
57
|
-
actions:
|
58
|
-
- index
|
59
|
-
- show
|
60
|
-
where:
|
61
|
-
- id
|
62
|
-
- title
|
63
|
-
order:
|
64
|
-
- id
|
65
|
-
- title
|
66
|
-
```
|
67
|
-
|
68
|
-
### SQL-like URI query
|
69
|
-
Our restraunt serves SQL-like URI query system.
|
48
|
+
## SQL-like URI query
|
49
|
+
You can filter and sort resources by SQL-like URI query.
|
70
50
|
|
71
51
|
```ruby
|
72
52
|
context "with where params" do
|
@@ -84,3 +64,29 @@ context "with where params" do
|
|
84
64
|
end
|
85
65
|
end
|
86
66
|
```
|
67
|
+
|
68
|
+
## Install
|
69
|
+
```ruby
|
70
|
+
# Gemfile
|
71
|
+
gem "restaurant"
|
72
|
+
|
73
|
+
# app/controllers/application_controller.rb
|
74
|
+
class ApplicationController < ActionController::Base
|
75
|
+
include Restaurant::ControllerHelper
|
76
|
+
end
|
77
|
+
|
78
|
+
# config/routes.rb
|
79
|
+
Rails.application.routes.draw do
|
80
|
+
Restaurant::Router.route(self)
|
81
|
+
end
|
82
|
+
```
|
83
|
+
|
84
|
+
```
|
85
|
+
$ bundle install
|
86
|
+
$ bundle exec rails g doorkeeper:install
|
87
|
+
$ bundle exec rails g doorkeeper:migration
|
88
|
+
$ bundle exec rake db:migrate
|
89
|
+
```
|
90
|
+
|
91
|
+
## More
|
92
|
+
See [the example application](https://github.com/r7kamura/restaurant/tree/master/spec/dummy).
|
data/lib/restaurant.rb
CHANGED
@@ -3,10 +3,10 @@ require "restaurant/authorization"
|
|
3
3
|
require "restaurant/config"
|
4
4
|
require "restaurant/controller_helper"
|
5
5
|
require "restaurant/controller_provider"
|
6
|
-
require "restaurant/model_class_finder"
|
7
6
|
require "restaurant/params_query_responder"
|
8
7
|
require "restaurant/params_query_translator"
|
9
8
|
require "restaurant/restful_actions"
|
9
|
+
require "restaurant/role_provider"
|
10
10
|
require "restaurant/router"
|
11
11
|
require "restaurant/railtie"
|
12
12
|
|
@@ -8,78 +8,6 @@ module Restaurant::Authorization
|
|
8
8
|
private
|
9
9
|
|
10
10
|
def require_authorization
|
11
|
-
head 403 unless has_authorization?
|
12
|
-
end
|
13
|
-
|
14
|
-
def has_authorization?
|
15
|
-
has_action_authorization? && has_query_authorization?
|
16
|
-
end
|
17
|
-
|
18
|
-
def has_action_authorization?
|
19
|
-
controllers_set.any? do |controllers|
|
20
|
-
if controller = controllers[controller_name]
|
21
|
-
controller["actions"].include?(action_name)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def has_query_authorization?
|
27
|
-
if has_not_allowed_where? || has_not_allowed_order?
|
28
|
-
false
|
29
|
-
else
|
30
|
-
true
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def controllers_set
|
35
|
-
@controllers_set ||= Restaurant::Config.roles.inject([]) do |result, (role, controllers)|
|
36
|
-
result << controllers if doorkeeper_token.scopes.include?(role.to_sym)
|
37
|
-
result
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def has_where_query?
|
42
|
-
params[:where]
|
43
|
-
end
|
44
|
-
|
45
|
-
def has_order_query?
|
46
|
-
params[:order]
|
47
|
-
end
|
48
|
-
|
49
|
-
def current_abilities
|
50
|
-
@current_abilities ||= controllers_set.inject([]) do |abilities, controllers|
|
51
|
-
abilities << controllers[controller_name] if controllers[controller_name]
|
52
|
-
abilities
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def current_order_abilities
|
57
|
-
current_abilities.inject([]) do |columns, ability|
|
58
|
-
columns + (ability["order"] || [])
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def current_where_abilities
|
63
|
-
current_abilities.inject([]) do |columns, ability|
|
64
|
-
columns + (ability["where"] || [])
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def has_not_allowed_where?
|
69
|
-
has_where_query? && (where_queries - current_where_abilities).any?
|
70
|
-
end
|
71
|
-
|
72
|
-
def has_not_allowed_order?
|
73
|
-
has_order_query? && (order_queries - current_order_abilities).any?
|
74
|
-
end
|
75
|
-
|
76
|
-
def where_queries
|
77
|
-
params[:where].keys
|
78
|
-
end
|
79
|
-
|
80
|
-
def order_queries
|
81
|
-
Array.wrap(params[:order]).map do |column|
|
82
|
-
column.sub(/^-/, "")
|
83
|
-
end
|
11
|
+
head 403 unless current_role.has_authorization?
|
84
12
|
end
|
85
13
|
end
|
@@ -4,10 +4,10 @@ module Restaurant::ControllerHelper
|
|
4
4
|
included do
|
5
5
|
use Rack::AcceptDefault
|
6
6
|
include Restaurant::ControllerProvider
|
7
|
-
include Restaurant::ModelClassFinder
|
8
7
|
include Restaurant::RestfulActions
|
9
8
|
include Restaurant::Authentication
|
10
9
|
include Restaurant::Authorization
|
10
|
+
include Restaurant::RoleProvider
|
11
11
|
self.responder = Restaurant::ParamsQueryResponder
|
12
12
|
end
|
13
13
|
end
|
@@ -1,15 +1,35 @@
|
|
1
1
|
module Restaurant::RestfulActions
|
2
|
-
|
2
|
+
def index
|
3
|
+
respond_with model.scoped, :only => current_role.allowed_attributes
|
4
|
+
end
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
+
def show
|
7
|
+
respond_with resource, :only => current_role.allowed_attributes
|
6
8
|
end
|
7
9
|
|
8
|
-
def
|
9
|
-
respond_with
|
10
|
+
def create
|
11
|
+
respond_with model.create(model_param), :only => current_role.allowed_attributes
|
10
12
|
end
|
11
13
|
|
12
|
-
def
|
13
|
-
respond_with
|
14
|
+
def update
|
15
|
+
respond_with resource.update_attributes(model_param)
|
16
|
+
end
|
17
|
+
|
18
|
+
def destroy
|
19
|
+
respond_with resource.delete
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def model
|
25
|
+
self.class.name.sub(/Controller$/, "").singularize.constantize
|
26
|
+
end
|
27
|
+
|
28
|
+
def model_param
|
29
|
+
params[model.name.underscore]
|
30
|
+
end
|
31
|
+
|
32
|
+
def resource
|
33
|
+
model.find(params[:id])
|
14
34
|
end
|
15
35
|
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Restaurant::RoleProvider
|
2
|
+
def current_role
|
3
|
+
@current_role ||= Role.new(self)
|
4
|
+
end
|
5
|
+
|
6
|
+
class Role
|
7
|
+
delegate(
|
8
|
+
:action_name,
|
9
|
+
:controller_name,
|
10
|
+
:doorkeeper_token,
|
11
|
+
:params,
|
12
|
+
:to => :controller
|
13
|
+
)
|
14
|
+
|
15
|
+
attr_reader :controller
|
16
|
+
|
17
|
+
def initialize(controller)
|
18
|
+
@controller = controller
|
19
|
+
end
|
20
|
+
|
21
|
+
def has_authorization?
|
22
|
+
has_action_authorization? && has_query_authorization?
|
23
|
+
end
|
24
|
+
|
25
|
+
def abilities
|
26
|
+
@abilities ||= Restaurant::Config.roles.map do |role, controllers|
|
27
|
+
if doorkeeper_token.scopes.include?(role.to_sym)
|
28
|
+
controllers[controller_name]
|
29
|
+
end
|
30
|
+
end.compact
|
31
|
+
end
|
32
|
+
|
33
|
+
def allowed_attributes
|
34
|
+
abilities.map {|ability| ability["attributes"] }.compact.inject(:|)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def has_action_authorization?
|
40
|
+
abilities.any? do |ability|
|
41
|
+
ability["actions"].include?(action_name)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def has_query_authorization?
|
46
|
+
if has_not_allowed_where? || has_not_allowed_order?
|
47
|
+
false
|
48
|
+
else
|
49
|
+
true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def has_where_query?
|
54
|
+
params[:where]
|
55
|
+
end
|
56
|
+
|
57
|
+
def has_order_query?
|
58
|
+
params[:order]
|
59
|
+
end
|
60
|
+
|
61
|
+
def order_abilities
|
62
|
+
abilities.inject([]) do |columns, ability|
|
63
|
+
columns + (ability["order"] || [])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def where_abilities
|
68
|
+
abilities.inject([]) do |columns, ability|
|
69
|
+
columns + (ability["where"] || [])
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def has_not_allowed_where?
|
74
|
+
has_where_query? && (where_queries - where_abilities).any?
|
75
|
+
end
|
76
|
+
|
77
|
+
def has_not_allowed_order?
|
78
|
+
has_order_query? && (order_queries - order_abilities).any?
|
79
|
+
end
|
80
|
+
|
81
|
+
def where_queries
|
82
|
+
params[:where].keys
|
83
|
+
end
|
84
|
+
|
85
|
+
def order_queries
|
86
|
+
Array.wrap(params[:order]).map do |column|
|
87
|
+
column.sub(/^-/, "")
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/lib/restaurant/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: restaurant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryo Nakamura
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-05-
|
11
|
+
date: 2013-05-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -164,7 +164,8 @@ dependencies:
|
|
164
164
|
- - '>='
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0'
|
167
|
-
description:
|
167
|
+
description: Restraunt serves your data via auto-defined RESTful API on your rails
|
168
|
+
application.
|
168
169
|
email:
|
169
170
|
- r7kamura@gmail.com
|
170
171
|
executables: []
|
@@ -176,11 +177,11 @@ files:
|
|
176
177
|
- lib/restaurant/config.rb
|
177
178
|
- lib/restaurant/controller_helper.rb
|
178
179
|
- lib/restaurant/controller_provider.rb
|
179
|
-
- lib/restaurant/model_class_finder.rb
|
180
180
|
- lib/restaurant/params_query_responder.rb
|
181
181
|
- lib/restaurant/params_query_translator.rb
|
182
182
|
- lib/restaurant/railtie.rb
|
183
183
|
- lib/restaurant/restful_actions.rb
|
184
|
+
- lib/restaurant/role_provider.rb
|
184
185
|
- lib/restaurant/router.rb
|
185
186
|
- lib/restaurant/version.rb
|
186
187
|
- lib/restaurant.rb
|
@@ -210,6 +211,6 @@ rubyforge_project:
|
|
210
211
|
rubygems_version: 2.0.0
|
211
212
|
signing_key:
|
212
213
|
specification_version: 4
|
213
|
-
summary:
|
214
|
+
summary: A rails plugin to auto-define RESTful API
|
214
215
|
test_files: []
|
215
216
|
has_rdoc:
|