amos 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.
- data/MIT-LICENSE +1 -1
- data/README.rdoc +21 -4
- data/Rakefile +25 -1
- data/app/controllers/amos_controller.rb +139 -0
- data/app/models/ability.rb +13 -0
- data/config/routes.rb +8 -0
- data/lib/amos/engine.rb +1 -0
- metadata +165 -7
data/MIT-LICENSE
CHANGED
data/README.rdoc
CHANGED
@@ -16,20 +16,24 @@ E.g. If the incoming request is /recipe it executes the index action which does
|
|
16
16
|
:put => "/users/1" + form data. Updates user record 1. Returns success => true / false
|
17
17
|
:post => "/users" + form data. Returns details of new record on success, or errors array on failure
|
18
18
|
|
19
|
-
*
|
19
|
+
*Amos gem is now available on rubygems.org*
|
20
20
|
|
21
21
|
Distributed under the MIT License, all rights reserved 2011 Geoff Drake
|
22
22
|
|
23
|
+
== Source
|
24
|
+
The source is available on GitHub https://github.com/geoffd123/amos
|
25
|
+
|
23
26
|
== Installation
|
24
27
|
Create a rails application as normal using:
|
25
28
|
|
26
|
-
|
29
|
+
rails create MyApp
|
27
30
|
|
28
31
|
Add the following line to your Gemfile
|
29
32
|
|
30
33
|
gem 'amos'
|
31
34
|
|
32
35
|
Run
|
36
|
+
|
33
37
|
bundle install
|
34
38
|
|
35
39
|
Amos uses cancan[https://github.com/ryanb/cancan] for its security checking so you need to add the following class in *app/models/ability.rb*
|
@@ -42,8 +46,8 @@ Amos uses cancan[https://github.com/ryanb/cancan] for its security checking so y
|
|
42
46
|
end
|
43
47
|
end
|
44
48
|
|
45
|
-
Replace the code inside the initialize with your requirements. There is a skeleton class in lib/app/models/ability.rb
|
46
|
-
if you are getting authorisation errors you have not overridden that version.
|
49
|
+
Replace the code inside the initialize with your requirements. There is a skeleton class in lib/app/models/ability.rb that
|
50
|
+
disallows any access, so if you are getting authorisation errors you have not overridden that version correctly.
|
47
51
|
|
48
52
|
Cancan also needs access to a method called current_user in the controllers. If you are using devise or similar
|
49
53
|
this should automatically be available.
|
@@ -75,3 +79,16 @@ the data and what is returned.
|
|
75
79
|
== Thing to to
|
76
80
|
* More tests against a javascriptMVC application
|
77
81
|
* Add code to support rails dynamic finders.
|
82
|
+
|
83
|
+
== Change list
|
84
|
+
=== 0.0.3
|
85
|
+
Fixed problem with incomplete file list in gemspec.
|
86
|
+
Fixed problem with cancan methods not being found when using gem in a rails app.
|
87
|
+
|
88
|
+
=== 0.0.2
|
89
|
+
Implemented fields filters, associations.
|
90
|
+
Changed js errors to return correct status codes
|
91
|
+
Implemented pluggable security using CanCan
|
92
|
+
|
93
|
+
=== 0.0.1
|
94
|
+
Basic skeleton and minimal functionality
|
data/Rakefile
CHANGED
@@ -10,8 +10,17 @@ require 'rake'
|
|
10
10
|
require 'rake/rdoctask'
|
11
11
|
|
12
12
|
require 'rake/testtask'
|
13
|
+
require 'rspec/core/rake_task'
|
14
|
+
require 'cucumber/rake/task'
|
13
15
|
|
14
|
-
|
16
|
+
|
17
|
+
desc 'Run specs and cukes'
|
18
|
+
task :test => [:spec, :cuke] do
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'Run unit tests'
|
22
|
+
|
23
|
+
Rake::TestTask.new(:unittest) do |t|
|
15
24
|
t.libs << 'lib'
|
16
25
|
t.libs << 'test'
|
17
26
|
t.pattern = 'test/**/*_test.rb'
|
@@ -27,3 +36,18 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
27
36
|
rdoc.rdoc_files.include('README.rdoc')
|
28
37
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
29
38
|
end
|
39
|
+
|
40
|
+
desc "Run specs"
|
41
|
+
RSpec::Core::RakeTask.new do |t|
|
42
|
+
t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
|
43
|
+
t.verbose = false
|
44
|
+
# Put spec opts in a file named .rspec in root
|
45
|
+
end
|
46
|
+
|
47
|
+
desc "Run cucumber features in the test/dummy directory"
|
48
|
+
task :cuke do
|
49
|
+
sh 'cd test/dummy; cucumber features'
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'cancan'
|
2
|
+
|
3
|
+
class AmosController < ApplicationController
|
4
|
+
|
5
|
+
unloadable
|
6
|
+
|
7
|
+
before_filter :set_model
|
8
|
+
before_filter :set_current_record, :only => [:show, :update, :destroy]
|
9
|
+
|
10
|
+
def index
|
11
|
+
@the_fields = process_field_names([], params[:fields])
|
12
|
+
records = self.instance_eval("#{@model}.all")
|
13
|
+
result_records = []
|
14
|
+
records.each{|rec|
|
15
|
+
if @the_fields.count == 0
|
16
|
+
result = filter_record rec
|
17
|
+
else
|
18
|
+
result = select_fields rec, @the_fields
|
19
|
+
end
|
20
|
+
result_records << result
|
21
|
+
} unless records.nil?
|
22
|
+
render :json => result_records
|
23
|
+
end
|
24
|
+
|
25
|
+
def show
|
26
|
+
@the_fields = process_field_names([], params[:fields])
|
27
|
+
if @the_fields.count == 0
|
28
|
+
result = filter_record @record
|
29
|
+
else
|
30
|
+
result = select_fields @record, @the_fields
|
31
|
+
end
|
32
|
+
|
33
|
+
@the_associations = process_association_names([], params[:association])
|
34
|
+
if @the_associations.count > 0
|
35
|
+
@the_associations.each{|name|
|
36
|
+
assoc_records = self.instance_eval("@record.#{name}")
|
37
|
+
data = []
|
38
|
+
assoc_records.each{|ar|
|
39
|
+
data << filter_record(ar, ["#{@model.downcase}_id"])
|
40
|
+
}
|
41
|
+
result[name] = data
|
42
|
+
}
|
43
|
+
end
|
44
|
+
render :json => result
|
45
|
+
end
|
46
|
+
|
47
|
+
def destroy
|
48
|
+
if can? :delete, @record
|
49
|
+
@record.destroy
|
50
|
+
render :json => {:success => "true"}
|
51
|
+
else
|
52
|
+
render_authorized
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def create
|
57
|
+
if can? :create, eval("#{@model}")
|
58
|
+
p = remove_attributes_from ['id', 'model', 'controller', 'action'], params.clone
|
59
|
+
record = self.instance_eval("#{@model}.new(p)")
|
60
|
+
|
61
|
+
if record.save
|
62
|
+
result = filter_record record
|
63
|
+
render :json => result
|
64
|
+
else
|
65
|
+
render :json => record.errors, :status => 400
|
66
|
+
end
|
67
|
+
else
|
68
|
+
render_authorized
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def update
|
73
|
+
if can? :update, eval("#{@model}")
|
74
|
+
attributes = remove_attributes_from ['id', 'model', 'controller', 'action'], params.clone
|
75
|
+
if @record.update_attributes(attributes)
|
76
|
+
render :json => attributes
|
77
|
+
else
|
78
|
+
render :json => @record.errors, :status => 400
|
79
|
+
end
|
80
|
+
else
|
81
|
+
render_authorized
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
protected
|
86
|
+
|
87
|
+
def set_model
|
88
|
+
m = params[:model]
|
89
|
+
m.chop! if m.end_with? 's'
|
90
|
+
@model = m.camelize
|
91
|
+
if cannot? :read, eval("#{@model}")
|
92
|
+
render_authorized
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def set_current_record
|
97
|
+
begin
|
98
|
+
@record = self.instance_eval("#{@model}.find(#{params[:id]})")
|
99
|
+
rescue ActiveRecord::RecordNotFound => e
|
100
|
+
render :json => {:error => "Record #{params[:id]} not found"}, :status => 400
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def filter_record record, extras = nil
|
105
|
+
data = remove_attributes_from ['created_at', 'updated_at'], record.attributes.clone
|
106
|
+
data = remove_attributes_from extras , data unless extras.nil?
|
107
|
+
data
|
108
|
+
end
|
109
|
+
|
110
|
+
def remove_attributes_from attribute_names, collection
|
111
|
+
attribute_names.each{|key| collection.delete(key)}
|
112
|
+
collection
|
113
|
+
end
|
114
|
+
|
115
|
+
def process_association_names assocs, names
|
116
|
+
return [] if names.nil?
|
117
|
+
names.split(',').each{|n| assocs << n}
|
118
|
+
end
|
119
|
+
|
120
|
+
def process_field_names fields, names
|
121
|
+
return [] if names.nil?
|
122
|
+
names.split(',').each{|n| fields << n}
|
123
|
+
end
|
124
|
+
|
125
|
+
def select_fields record, fields
|
126
|
+
selected_fields = {}
|
127
|
+
record.attributes.each_pair{|key, value|
|
128
|
+
if fields.include?(key)
|
129
|
+
selected_fields[key] = value
|
130
|
+
end
|
131
|
+
}
|
132
|
+
selected_fields
|
133
|
+
end
|
134
|
+
|
135
|
+
def render_authorized
|
136
|
+
render :json => {:error => "You are not authorized to access this data"}, :status => 401
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
data/config/routes.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
Rails.application.routes.draw do
|
2
|
+
# match 'with_id/:model/:id' => 'amos/amos#with_id'
|
3
|
+
match ":model/:id" => "amos#show", :constraints => { :model => /.*/ }, :via => :get
|
4
|
+
match ":model/:id" => "amos#destroy", :constraints => { :model => /.*/ }, :via => :delete
|
5
|
+
match ":model/:id" => "amos#update", :constraints => { :model => /.*/ }, :via => :put
|
6
|
+
match ":model" => "amos#create", :constraints => { :model => /.*/ }, :via => :post
|
7
|
+
match ":model" => "amos#index", :constraints => { :model => /.*/ }
|
8
|
+
end
|
data/lib/amos/engine.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amos
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 3
|
10
|
+
version: 0.0.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Geoff Drake
|
@@ -24,16 +24,171 @@ dependencies:
|
|
24
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
hash:
|
29
|
+
hash: 7
|
30
30
|
segments:
|
31
31
|
- 3
|
32
32
|
- 0
|
33
|
-
|
34
|
-
version: 3.0.4
|
33
|
+
version: "3.0"
|
35
34
|
type: :runtime
|
36
35
|
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: cancan
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 3
|
45
|
+
segments:
|
46
|
+
- 1
|
47
|
+
- 6
|
48
|
+
- 6
|
49
|
+
version: 1.6.6
|
50
|
+
type: :runtime
|
51
|
+
version_requirements: *id002
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
name: database_cleaner
|
54
|
+
prerelease: false
|
55
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 3
|
61
|
+
segments:
|
62
|
+
- 0
|
63
|
+
version: "0"
|
64
|
+
type: :development
|
65
|
+
version_requirements: *id003
|
66
|
+
- !ruby/object:Gem::Dependency
|
67
|
+
name: sqlite3-ruby
|
68
|
+
prerelease: false
|
69
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
hash: 3
|
75
|
+
segments:
|
76
|
+
- 0
|
77
|
+
version: "0"
|
78
|
+
type: :development
|
79
|
+
version_requirements: *id004
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: ruby-debug
|
82
|
+
prerelease: false
|
83
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
hash: 3
|
89
|
+
segments:
|
90
|
+
- 0
|
91
|
+
version: "0"
|
92
|
+
type: :development
|
93
|
+
version_requirements: *id005
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: launchy
|
96
|
+
prerelease: false
|
97
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
hash: 3
|
103
|
+
segments:
|
104
|
+
- 0
|
105
|
+
version: "0"
|
106
|
+
type: :development
|
107
|
+
version_requirements: *id006
|
108
|
+
- !ruby/object:Gem::Dependency
|
109
|
+
name: syntax
|
110
|
+
prerelease: false
|
111
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
112
|
+
none: false
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
hash: 3
|
117
|
+
segments:
|
118
|
+
- 0
|
119
|
+
version: "0"
|
120
|
+
type: :development
|
121
|
+
version_requirements: *id007
|
122
|
+
- !ruby/object:Gem::Dependency
|
123
|
+
name: rspec
|
124
|
+
prerelease: false
|
125
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
126
|
+
none: false
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
hash: 3
|
131
|
+
segments:
|
132
|
+
- 0
|
133
|
+
version: "0"
|
134
|
+
type: :development
|
135
|
+
version_requirements: *id008
|
136
|
+
- !ruby/object:Gem::Dependency
|
137
|
+
name: rspec-rails
|
138
|
+
prerelease: false
|
139
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
140
|
+
none: false
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
hash: 3
|
145
|
+
segments:
|
146
|
+
- 0
|
147
|
+
version: "0"
|
148
|
+
type: :development
|
149
|
+
version_requirements: *id009
|
150
|
+
- !ruby/object:Gem::Dependency
|
151
|
+
name: factory_girl_rails
|
152
|
+
prerelease: false
|
153
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
154
|
+
none: false
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
hash: 3
|
159
|
+
segments:
|
160
|
+
- 0
|
161
|
+
version: "0"
|
162
|
+
type: :development
|
163
|
+
version_requirements: *id010
|
164
|
+
- !ruby/object:Gem::Dependency
|
165
|
+
name: cucumber-rails
|
166
|
+
prerelease: false
|
167
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
168
|
+
none: false
|
169
|
+
requirements:
|
170
|
+
- - ">="
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
hash: 3
|
173
|
+
segments:
|
174
|
+
- 0
|
175
|
+
version: "0"
|
176
|
+
type: :development
|
177
|
+
version_requirements: *id011
|
178
|
+
- !ruby/object:Gem::Dependency
|
179
|
+
name: pickle
|
180
|
+
prerelease: false
|
181
|
+
requirement: &id012 !ruby/object:Gem::Requirement
|
182
|
+
none: false
|
183
|
+
requirements:
|
184
|
+
- - ">="
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
hash: 3
|
187
|
+
segments:
|
188
|
+
- 0
|
189
|
+
version: "0"
|
190
|
+
type: :development
|
191
|
+
version_requirements: *id012
|
37
192
|
description: A simple server that determines the model and action data based upon the incoming url.
|
38
193
|
email: drakeg@mandes.com
|
39
194
|
executables: []
|
@@ -48,6 +203,9 @@ files:
|
|
48
203
|
- MIT-LICENSE
|
49
204
|
- Rakefile
|
50
205
|
- README.rdoc
|
206
|
+
- app/controllers/amos_controller.rb
|
207
|
+
- app/models/ability.rb
|
208
|
+
- config/routes.rb
|
51
209
|
has_rdoc: true
|
52
210
|
homepage: http://rubygems.org/gems/amos
|
53
211
|
licenses: []
|