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.
@@ -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: []