the_garage 2.0.0

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.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +162 -0
  4. data/Rakefile +33 -0
  5. data/app/assets/javascripts/garage/application.js +16 -0
  6. data/app/assets/javascripts/garage/docs/console.js.coffee +90 -0
  7. data/app/assets/javascripts/garage/docs/jquery.colorbox.js +1026 -0
  8. data/app/assets/stylesheets/garage/application.css +14 -0
  9. data/app/assets/stylesheets/garage/colorbox.scss +62 -0
  10. data/app/assets/stylesheets/garage/style.scss +59 -0
  11. data/app/assets/stylesheets/vendor/bootstrap.min.css +9 -0
  12. data/app/controllers/garage/application_controller.rb +4 -0
  13. data/app/controllers/garage/docs/resources_controller.rb +103 -0
  14. data/app/controllers/garage/meta/docs_controller.rb +20 -0
  15. data/app/controllers/garage/meta/services_controller.rb +20 -0
  16. data/app/helpers/garage/application_helper.rb +4 -0
  17. data/app/helpers/garage/docs/resources_helper.rb +24 -0
  18. data/app/models/garage/hash_representer.rb +11 -0
  19. data/app/views/garage/docs/resources/_layout_navigation.html.haml +5 -0
  20. data/app/views/garage/docs/resources/_navigation.html.haml +6 -0
  21. data/app/views/garage/docs/resources/callback.html.haml +5 -0
  22. data/app/views/garage/docs/resources/console.html.haml +45 -0
  23. data/app/views/garage/docs/resources/index.html.haml +2 -0
  24. data/app/views/garage/docs/resources/show.html.haml +16 -0
  25. data/app/views/layouts/garage/application.html.haml +26 -0
  26. data/config/routes.rb +0 -0
  27. data/lib/garage/app_responder.rb +22 -0
  28. data/lib/garage/authorizable.rb +26 -0
  29. data/lib/garage/config.rb +76 -0
  30. data/lib/garage/controller_helper.rb +110 -0
  31. data/lib/garage/docs/anchor_building.rb +28 -0
  32. data/lib/garage/docs/application.rb +24 -0
  33. data/lib/garage/docs/config.rb +61 -0
  34. data/lib/garage/docs/console_link_building.rb +14 -0
  35. data/lib/garage/docs/document.rb +141 -0
  36. data/lib/garage/docs/engine.rb +35 -0
  37. data/lib/garage/docs/example.rb +26 -0
  38. data/lib/garage/docs/renderer.rb +17 -0
  39. data/lib/garage/docs/toc_renderer.rb +14 -0
  40. data/lib/garage/docs.rb +9 -0
  41. data/lib/garage/exceptions.rb +49 -0
  42. data/lib/garage/hypermedia_filter.rb +44 -0
  43. data/lib/garage/hypermedia_responder.rb +120 -0
  44. data/lib/garage/meta/engine.rb +16 -0
  45. data/lib/garage/meta/remote_service.rb +78 -0
  46. data/lib/garage/meta.rb +6 -0
  47. data/lib/garage/meta_resource.rb +17 -0
  48. data/lib/garage/nested_field_query.rb +183 -0
  49. data/lib/garage/optional_response_body_responder.rb +16 -0
  50. data/lib/garage/paginating_responder.rb +113 -0
  51. data/lib/garage/permission.rb +13 -0
  52. data/lib/garage/permissions.rb +75 -0
  53. data/lib/garage/representer.rb +214 -0
  54. data/lib/garage/resource_casting_responder.rb +13 -0
  55. data/lib/garage/restful_actions.rb +219 -0
  56. data/lib/garage/strategy/access_token.rb +57 -0
  57. data/lib/garage/strategy/auth_server.rb +200 -0
  58. data/lib/garage/strategy/no_authentication.rb +13 -0
  59. data/lib/garage/strategy/test.rb +44 -0
  60. data/lib/garage/strategy.rb +4 -0
  61. data/lib/garage/test/migrator.rb +31 -0
  62. data/lib/garage/token_scope.rb +134 -0
  63. data/lib/garage/utils.rb +28 -0
  64. data/lib/garage/version.rb +3 -0
  65. data/lib/garage.rb +23 -0
  66. metadata +275 -0
@@ -0,0 +1,13 @@
1
+ module Garage
2
+ module Strategy
3
+ module NoAuthentication
4
+ def access_token
5
+ nil
6
+ end
7
+
8
+ def verify_permission?
9
+ false
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,44 @@
1
+ module Garage
2
+ module Strategy
3
+ module Test
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ before_action :verify_auth, if: -> (_) { verify_permission? }
8
+ end
9
+
10
+ def access_token
11
+ if defined? @access_token
12
+ @access_token
13
+ else
14
+ token = AccessToken.new(attributes.merge(token: requested_token, token_type: 'bearer'))
15
+ @access_token = token.token.present? && token.accessible? ? token : nil
16
+ end
17
+ end
18
+
19
+ def verify_permission?
20
+ true
21
+ end
22
+
23
+ private
24
+
25
+ def attribute_names
26
+ %i(application_id expired_at resource_owner_id scope)
27
+ end
28
+
29
+ def attributes
30
+ Hash[attribute_names.map {|name| [name, from_header(name)] }]
31
+ end
32
+
33
+ def from_header(name)
34
+ canonical = name.to_s.dasherize.split('-').map(&:capitalize).join('-')
35
+ request.headers[canonical]
36
+ end
37
+
38
+ def requested_token
39
+ value = request.authorization
40
+ value.present? ? value.gsub(/^Bearer\s(.*)/) { $1 } : nil
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,4 @@
1
+ require "garage/strategy/access_token"
2
+ require "garage/strategy/auth_server"
3
+ require "garage/strategy/no_authentication"
4
+ require "garage/strategy/test"
@@ -0,0 +1,31 @@
1
+ require "generators/doorkeeper/templates/migration"
2
+
3
+ module Garage
4
+ module Test
5
+ module Migrator
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ before(:all) do
10
+ silence_stream(STDOUT) do
11
+ begin
12
+ CreateDoorkeeperTables.migrate(:up)
13
+ rescue ActiveRecord::StatementInvalid
14
+ # Rescue exceptions if the tables are already created.
15
+ end
16
+ end
17
+ end
18
+
19
+ after(:all) do
20
+ silence_stream(STDOUT) do
21
+ begin
22
+ CreateDoorkeeperTables.migrate(:down)
23
+ rescue ActiveRecord::StatementInvalid
24
+ # Rescue exceptions if the tables are already created.
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,134 @@
1
+ module Garage
2
+ class TokenScope
3
+ def self.configure(&block)
4
+ @config = Config.new
5
+ @config.instance_eval(&block)
6
+ end
7
+
8
+ def self.configuration
9
+ @config or raise "Garage::TokenScope.configure must be called in initializer"
10
+ end
11
+
12
+ def self.all_scopes
13
+ configuration.scopes.values
14
+ end
15
+
16
+ def self.optional_scopes
17
+ configuration.scopes.values.select(&:optional?)
18
+ end
19
+
20
+ def self.revealed_scopes
21
+ configuration.scopes.values.reject(&:hidden?)
22
+ end
23
+
24
+ def self.hidden_scopes
25
+ configuration.scopes.values.select(&:hidden?)
26
+ end
27
+
28
+ def self.ability(user, scopes)
29
+ scopes = scopes.map(&:to_sym)
30
+ scopes = [:public] if scopes.empty? # backward compatiblity for scopes without any scope, assuming public
31
+ Ability.new(user, configuration.scopes.slice(*scopes).values)
32
+ end
33
+
34
+ class Ability
35
+ def initialize(user, scopes = [])
36
+ @user = user
37
+ @access = []
38
+ load_scopes(scopes)
39
+ end
40
+
41
+ def load_scopes(scopes)
42
+ scopes.each do |scope|
43
+ load_scope(scope)
44
+ end
45
+ end
46
+
47
+ def load_scope(scope)
48
+ scope = TokenScope.configuration.scopes[scope] if scope.is_a?(Symbol)
49
+ @access.concat(scope.accessible_resources)
50
+ end
51
+
52
+ def missing_scopes(klass, action)
53
+ TokenScope.configuration.required_scopes(klass, action)
54
+ end
55
+
56
+ def access!(klass, action)
57
+ allow?(klass, action) or raise MissingScopeError.new(@user, action, klass, :forbidden, missing_scopes(klass, action))
58
+ end
59
+
60
+ def allow?(klass, action)
61
+ @access.include?([klass.to_s, action])
62
+ end
63
+ end
64
+
65
+
66
+ class Config
67
+ def namespace(ns, &block)
68
+ @ns = ns
69
+ instance_eval(&block)
70
+ @ns = nil
71
+ end
72
+
73
+ def scopes
74
+ @scopes ||= {}
75
+ end
76
+
77
+ def required_scopes(klass, action)
78
+ @required_scopes ||= {}
79
+ @required_scopes[[klass.to_s, action]] ||= []
80
+ end
81
+
82
+ def register(scope_symbol, options={}, &block)
83
+ if options[:namespace] || @ns
84
+ scope_symbol = [options[:namespace] || @ns, scope_symbol].join(".").to_sym
85
+ end
86
+ scope = Scope.new(scope_symbol, options)
87
+ scope.instance_eval(&block) if block_given?
88
+ unless scope.hidden?
89
+ scope.accessible_resources.each do |klass, action|
90
+ required_scopes(klass, action) << scope.to_sym
91
+ end
92
+ end
93
+
94
+ scopes[scope_symbol] = scope
95
+ end
96
+ end
97
+
98
+ class Scope
99
+ attr_reader :description
100
+
101
+ def initialize(sym, options={})
102
+ @sym = sym
103
+ @access = []
104
+ @hidden = options[:hidden]
105
+ @description = options[:desc]
106
+ end
107
+
108
+ def name
109
+ @sym.to_s
110
+ end
111
+ alias_method :to_s, :name
112
+
113
+ def access(action, klass)
114
+ @access << [klass.to_s, action]
115
+ end
116
+
117
+ def accessible_resources
118
+ @access
119
+ end
120
+
121
+ def to_sym
122
+ @sym
123
+ end
124
+
125
+ def hidden?
126
+ !!@hidden
127
+ end
128
+
129
+ def optional?
130
+ @sym != :public && !hidden?
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,28 @@
1
+ module Garage
2
+ module Utils
3
+ private
4
+
5
+ # Private: extract date time range query from query parameters
6
+ # Treat `from` and `to` as aliases for `gte` and `lte` respectively
7
+ def extract_datetime_query(prefix)
8
+ query = {}
9
+ {:from => :gte, :to => :lte, :gt => nil, :lt => nil, :gte => nil, :lte => nil}.each do |key, as|
10
+ k = "#{prefix}.#{key}"
11
+ if params.has_key?(k)
12
+ query[as || key] = fuzzy_parse(params[k]) or raise Garage::BadRequest, "Can't parse datetime #{params[k]}"
13
+ end
14
+ end
15
+ query if query.size > 0
16
+ end
17
+
18
+ def fuzzy_parse(date)
19
+ if date.is_a?(Numeric) || /^\d+$/ === date
20
+ Time.zone.at(date.to_i)
21
+ else
22
+ Time.zone.parse(date)
23
+ end
24
+ rescue ArgumentError
25
+ nil
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ module Garage
2
+ VERSION = '2.0.0'
3
+ end
data/lib/garage.rb ADDED
@@ -0,0 +1,23 @@
1
+ require "rails"
2
+ require "rack-accept-default"
3
+ require "http_accept_language"
4
+
5
+ require "garage/version"
6
+ require "garage/strategy"
7
+ require "garage/config"
8
+ require "garage/nested_field_query"
9
+ require "garage/app_responder"
10
+ require "garage/utils"
11
+ require "garage/controller_helper"
12
+ require "garage/representer"
13
+ require "garage/restful_actions"
14
+ require "garage/hypermedia_filter"
15
+
16
+ require "garage/exceptions"
17
+ require "garage/authorizable"
18
+ require "garage/meta_resource"
19
+ require "garage/permissions"
20
+ require "garage/token_scope"
21
+
22
+ module Garage
23
+ end
metadata ADDED
@@ -0,0 +1,275 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: the_garage
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Tatsuhiko Miyagawa
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-02-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 4.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 4.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rack-accept-default
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.0.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.0.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: oj
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: responders
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: oauth2
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: redcarpet
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 3.1.1
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: 3.1.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: haml
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: hashie
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: sass-rails
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: coffee-rails
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: http_accept_language
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: 2.0.0
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: 2.0.0
167
+ - !ruby/object:Gem::Dependency
168
+ name: appraisal
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ description: Garage extends your RESTful, Hypermedia APIs as a Platform
182
+ email:
183
+ - miyagawa@bulknews.net
184
+ executables: []
185
+ extensions: []
186
+ extra_rdoc_files: []
187
+ files:
188
+ - MIT-LICENSE
189
+ - README.md
190
+ - Rakefile
191
+ - app/assets/javascripts/garage/application.js
192
+ - app/assets/javascripts/garage/docs/console.js.coffee
193
+ - app/assets/javascripts/garage/docs/jquery.colorbox.js
194
+ - app/assets/stylesheets/garage/application.css
195
+ - app/assets/stylesheets/garage/colorbox.scss
196
+ - app/assets/stylesheets/garage/style.scss
197
+ - app/assets/stylesheets/vendor/bootstrap.min.css
198
+ - app/controllers/garage/application_controller.rb
199
+ - app/controllers/garage/docs/resources_controller.rb
200
+ - app/controllers/garage/meta/docs_controller.rb
201
+ - app/controllers/garage/meta/services_controller.rb
202
+ - app/helpers/garage/application_helper.rb
203
+ - app/helpers/garage/docs/resources_helper.rb
204
+ - app/models/garage/hash_representer.rb
205
+ - app/views/garage/docs/resources/_layout_navigation.html.haml
206
+ - app/views/garage/docs/resources/_navigation.html.haml
207
+ - app/views/garage/docs/resources/callback.html.haml
208
+ - app/views/garage/docs/resources/console.html.haml
209
+ - app/views/garage/docs/resources/index.html.haml
210
+ - app/views/garage/docs/resources/show.html.haml
211
+ - app/views/layouts/garage/application.html.haml
212
+ - config/routes.rb
213
+ - lib/garage.rb
214
+ - lib/garage/app_responder.rb
215
+ - lib/garage/authorizable.rb
216
+ - lib/garage/config.rb
217
+ - lib/garage/controller_helper.rb
218
+ - lib/garage/docs.rb
219
+ - lib/garage/docs/anchor_building.rb
220
+ - lib/garage/docs/application.rb
221
+ - lib/garage/docs/config.rb
222
+ - lib/garage/docs/console_link_building.rb
223
+ - lib/garage/docs/document.rb
224
+ - lib/garage/docs/engine.rb
225
+ - lib/garage/docs/example.rb
226
+ - lib/garage/docs/renderer.rb
227
+ - lib/garage/docs/toc_renderer.rb
228
+ - lib/garage/exceptions.rb
229
+ - lib/garage/hypermedia_filter.rb
230
+ - lib/garage/hypermedia_responder.rb
231
+ - lib/garage/meta.rb
232
+ - lib/garage/meta/engine.rb
233
+ - lib/garage/meta/remote_service.rb
234
+ - lib/garage/meta_resource.rb
235
+ - lib/garage/nested_field_query.rb
236
+ - lib/garage/optional_response_body_responder.rb
237
+ - lib/garage/paginating_responder.rb
238
+ - lib/garage/permission.rb
239
+ - lib/garage/permissions.rb
240
+ - lib/garage/representer.rb
241
+ - lib/garage/resource_casting_responder.rb
242
+ - lib/garage/restful_actions.rb
243
+ - lib/garage/strategy.rb
244
+ - lib/garage/strategy/access_token.rb
245
+ - lib/garage/strategy/auth_server.rb
246
+ - lib/garage/strategy/no_authentication.rb
247
+ - lib/garage/strategy/test.rb
248
+ - lib/garage/test/migrator.rb
249
+ - lib/garage/token_scope.rb
250
+ - lib/garage/utils.rb
251
+ - lib/garage/version.rb
252
+ homepage: https://github.com/cookpad/garage
253
+ licenses: []
254
+ metadata: {}
255
+ post_install_message:
256
+ rdoc_options: []
257
+ require_paths:
258
+ - lib
259
+ required_ruby_version: !ruby/object:Gem::Requirement
260
+ requirements:
261
+ - - ">="
262
+ - !ruby/object:Gem::Version
263
+ version: '0'
264
+ required_rubygems_version: !ruby/object:Gem::Requirement
265
+ requirements:
266
+ - - ">="
267
+ - !ruby/object:Gem::Version
268
+ version: '0'
269
+ requirements: []
270
+ rubyforge_project:
271
+ rubygems_version: 2.5.1
272
+ signing_key:
273
+ specification_version: 4
274
+ summary: Garage Platform Engine
275
+ test_files: []