amos 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
- Copyright 2011 YOURNAME
1
+ Copyright 2011 Geoff Drake drakeg at mandes dot com
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -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
- *Currently only available via github*. I will be releasing the amos gem once I have done some more testing
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
- rails create MyApp
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, so
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
- Rake::TestTask.new(:test) do |t|
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
+
@@ -0,0 +1,13 @@
1
+ class Ability
2
+ include CanCan::Ability
3
+
4
+ def initialize(user)
5
+ can :manage, :all
6
+ end
7
+ end
8
+
9
+ class ApplicationController < ActionController::Base
10
+ def current_user
11
+ nil
12
+ end
13
+ end
@@ -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
@@ -4,5 +4,6 @@ require "rails"
4
4
 
5
5
  module Amos
6
6
  class Engine < Rails::Engine
7
+ paths.app.controllers << "lib/controllers"
7
8
  end
8
9
  end
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: 27
4
+ hash: 25
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
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: 15
29
+ hash: 7
30
30
  segments:
31
31
  - 3
32
32
  - 0
33
- - 4
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: []