openstax_api 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/openstax/api/v1/api_controller.rb +9 -145
  3. data/app/controllers/openstax/api/v1/oauth_based_api_controller.rb +0 -2
  4. data/app/models/openstax/api/api_user.rb +5 -4
  5. data/lib/openstax/api/apipie.rb +51 -0
  6. data/lib/{openstax_api → openstax/api}/constraints.rb +0 -0
  7. data/lib/{openstax_api → openstax/api}/doorkeeper_extensions.rb +0 -0
  8. data/lib/{openstax_api → openstax/api}/engine.rb +0 -0
  9. data/lib/openstax/api/representable_schema_printer.rb +83 -0
  10. data/lib/openstax/api/roar.rb +132 -0
  11. data/lib/{openstax_api → openstax/api}/route_extensions.rb +1 -1
  12. data/lib/{openstax_api → openstax/api}/version.rb +1 -1
  13. data/lib/openstax_api.rb +20 -3
  14. data/spec/app/models/openstax/api/api_user_spec.rb +1 -1
  15. data/spec/app/representers/openstax/api/v1/representable_schema_printer_spec.rb +1 -1
  16. data/spec/dummy/app/models/dummy_user.rb +2 -0
  17. data/spec/dummy/app/representers/{user_representer.rb → dummy_user_representer.rb} +1 -1
  18. data/spec/dummy/config/initializers/openstax_api.rb +3 -0
  19. data/spec/dummy/db/development.sqlite3 +0 -0
  20. data/spec/dummy/db/migrate/{1_create_users.rb → 1_create_dummy_users.rb} +2 -2
  21. data/spec/dummy/db/schema.rb +7 -7
  22. data/spec/dummy/db/test.sqlite3 +0 -0
  23. data/spec/dummy/log/development.log +101 -597
  24. data/spec/dummy/log/test.log +62 -3216
  25. data/spec/lib/openstax/api/apipie.rb +11 -0
  26. data/spec/lib/{openstax_api → openstax/api}/constraints_spec.rb +0 -0
  27. data/spec/lib/{openstax_api → openstax/api}/doorkeeper_extensions_spec.rb +0 -0
  28. data/spec/lib/openstax/api/roar.rb +11 -0
  29. data/spec/lib/{openstax_api → openstax/api}/route_extensions_spec.rb +0 -0
  30. metadata +42 -20
  31. data/app/representers/openstax/api/v1/representable_schema_printer.rb +0 -85
  32. data/spec/dummy/app/models/user.rb +0 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cce40c843b8d217abd9a7474b34217a10f380468
4
- data.tar.gz: ae159bd0eda6a2191a5dfb3d8ac6b14f504b1df3
3
+ metadata.gz: 0182a7fe7cdaf9adbe7a8719473cd4546c2f3bcb
4
+ data.tar.gz: be4936d879e58990235b59857c65892fc1711456
5
5
  SHA512:
6
- metadata.gz: 7416764ded4187e6dde991c812339d9c370a426ef7ca928807edbb9be0d86aa591d12b01660868066527c2dfb2df84322bdb2da1acbecddc6dade5e218cf4860
7
- data.tar.gz: b714b80dbd734dd882eeb2a28442835f66372d9f5b32e920258e7291b90e536154c9e883de04b72b1a913991d6082763479e4a87dfabc3950527894e03d6b72f
6
+ metadata.gz: 2948208fe965b6e01bc5e67615b48058d52998fb40e4f2db620e4ee646f6559b19c0725439956f2107dc171b698b718b9252703a267a484ff324dcb7208949aa
7
+ data.tar.gz: 433bd360c6317cde8864ad9933877605387eaf3a8d92ee3267836abdce5e143663b2cb65acdec7f7ce735b0b4adb266ab5f97e04020c14496f9c7daaed6b9b3a
@@ -1,4 +1,7 @@
1
1
  require 'roar-rails'
2
+ require 'exception_notification'
3
+ require 'openstax/api/roar'
4
+ require 'openstax/api/apipie'
2
5
 
3
6
  module OpenStax
4
7
  module Api
@@ -6,7 +9,9 @@ module OpenStax
6
9
 
7
10
  class ApiController < ::ApplicationController
8
11
 
9
- include Roar::Rails::ControllerAdditions
12
+ include ::Roar::Rails::ControllerAdditions
13
+ include OpenStax::Api::Roar
14
+ include OpenStax::Api::Apipie
10
15
 
11
16
  fine_print_skip_signatures(:general_terms_of_use,
12
17
  :privacy_policy) \
@@ -19,18 +24,7 @@ module OpenStax
19
24
  respond_to :json
20
25
  rescue_from Exception, :with => :rescue_from_exception
21
26
 
22
- def self.api_example(options={})
23
- return if Rails.env.test?
24
- raise IllegalArgument, "must supply a :url parameter" if !options[:url_base]
25
-
26
- url_base = options[:url_base].is_a?(Symbol) ?
27
- UrlGenerator.new.send(options[:url_base], protocol: 'https') :
28
- options[:url_base].to_s
29
-
30
- "#{url_base}/#{options[:url_end] || ''}"
31
- end
32
-
33
- # TODO doorkeeper users (or rather users who have doorkeeper
27
+ # TODO: doorkeeper users (or rather users who have doorkeeper
34
28
  # applications) need to agree to API terms of use (need to have agreed
35
29
  # to it at one time, can't require them to agree when terms change since
36
30
  # their apps are doing the talking) -- this needs more thought
@@ -39,13 +33,11 @@ module OpenStax
39
33
  @current_user ||= doorkeeper_token ?
40
34
  User.find(doorkeeper_token.resource_owner_id) :
41
35
  super
42
- # TODO maybe freak out if current user is anonymous (require we know
36
+ # TODO: maybe freak out if current user is anonymous (require we know
43
37
  # who person/app is so we can do things like throttling, API terms
44
38
  # agreement, etc)
45
39
  end
46
40
 
47
-
48
-
49
41
  protected
50
42
 
51
43
  def rescue_from_exception(exception)
@@ -66,147 +58,19 @@ module OpenStax
66
58
  end
67
59
 
68
60
  if notify
69
- # TODO: Not yet in OSU
70
- =begin
71
61
  ExceptionNotifier.notify_exception(
72
62
  exception,
73
63
  env: request.env,
74
64
  data: { message: "An exception occurred" }
75
65
  )
76
- =end
66
+
77
67
  Rails.logger.error("An exception occurred: #{exception.message}\n\n#{exception.backtrace.join("\n")}") \
78
68
  end
79
69
 
80
70
  head error
81
71
  end
82
72
 
83
- def self.json_schema(representer, options={})
84
- RepresentableSchemaPrinter.json(representer, options)
85
- end
86
-
87
- # A hack at a conversion from a Representer to a series of Apipie declarations
88
- # Can call it like any Apipie DSL method,
89
- #
90
- # example "blah"
91
- # representer Api::V1::ExerciseRepresenter
92
- # def update ...
93
- #
94
- def self.representer(representer)
95
- representer.representable_attrs.each do |attr|
96
- schema_info = attr.options[:schema_info] || {}
97
- param attr.name, (attr.options[:type] || Object), required: schema_info[:required]
98
- end
99
- end
100
73
 
101
- def get_representer(represent_with, model=nil)
102
- return nil if represent_with.nil?
103
- if represent_with.is_a? Proc
104
- represent_with.call(model)
105
- else
106
- represent_with
107
- end
108
- end
109
-
110
- def rest_get(model_klass, id, represent_with=nil)
111
- @model = model_klass.find(id)
112
- raise SecurityTransgression unless current_user.can_read?(@model)
113
- respond_with @model, represent_with: get_representer(represent_with, @model)
114
- end
115
-
116
- def rest_update(model_klass, id, represent_with=nil)
117
- @model = model_klass.find(id)
118
- raise SecurityTransgression unless current_user.can_update?(@model)
119
- consume!(@model, represent_with: get_representer(represent_with, @model))
120
-
121
- if @model.save
122
- head :no_content
123
- else
124
- render json: @model.errors, status: :unprocessable_entity
125
- end
126
- end
127
-
128
- def rest_create(model_klass)
129
- @model = model_klass.new()
130
-
131
- # Unlike the implications of the representable README, "consume!" can
132
- # actually make changes to the database. See http://goo.gl/WVLBqA.
133
- # We do want to consume before checking the permissions so we can know
134
- # what we're dealing with, but if user doesn't have permission we don't
135
- # want to have changed the DB. Wrap in a transaction to protect ourselves.
136
-
137
- model_klass.transaction do
138
- consume!(@model)
139
- raise SecurityTransgression unless current_user.can_create?(@model)
140
- end
141
-
142
- if @model.save
143
- respond_with @model
144
- else
145
- render json: @model.errors, status: :unprocessable_entity
146
- end
147
- end
148
-
149
- def rest_destroy(model_klass, id)
150
- @model = model_klass.find(id)
151
- raise SecurityTransgression unless current_user.can_destroy?(@model)
152
-
153
- if @model.destroy
154
- head :no_content
155
- else
156
- render json: @model.errors, status: :unprocessable_entity
157
- end
158
- end
159
-
160
- def standard_sort(model_klass)
161
- # take array of all IDs or hash of id => position,
162
- # regardless build up an array of all IDs in the right order and pass those to sort
163
-
164
- new_positions = params['newPositions']
165
- return head :no_content if new_positions.length == 0
166
-
167
- # Can't have duplicate positions or IDs
168
- unique_ids = new_positions.collect{|np| np['id']}.uniq
169
- unique_positions = new_positions.collect{|np| np['position']}.uniq
170
-
171
- return head :bad_request if unique_ids.length != new_positions.length
172
- return head :bad_request if unique_positions.length != new_positions.length
173
-
174
- first = model_klass.where(:id => new_positions[0]['id']).first
175
-
176
- return head :not_found if first.blank?
177
-
178
- originalOrdered = first.me_and_peers.ordered.all
179
-
180
- originalOrdered.each do |item|
181
- raise SecurityTransgression unless item.send(:container_column) == originalOrdered[0].send(:container_column) \
182
- if item.respond_to?(:container_column)
183
- raise SecurityTransgression unless current_user.can_sort?(item)
184
- end
185
-
186
- originalOrderedIds = originalOrdered.collect{|sc| sc.id}
187
-
188
- newOrderedIds = Array.new(originalOrderedIds.size)
189
-
190
- new_positions.each do |newPosition|
191
- id = newPosition['id'].to_i
192
- newOrderedIds[newPosition['position']] = id
193
- originalOrderedIds.delete(id)
194
- end
195
-
196
- ptr = 0
197
- for oldId in originalOrderedIds
198
- while !newOrderedIds[ptr].nil?; ptr += 1; end
199
- newOrderedIds[ptr] = oldId
200
- end
201
-
202
- begin
203
- model_klass.sort!(newOrderedIds)
204
- rescue Exception => e
205
- return head :internal_server_error
206
- end
207
-
208
- head :no_content
209
- end
210
74
 
211
75
  end
212
76
 
@@ -4,8 +4,6 @@ module OpenStax
4
4
 
5
5
  class OauthBasedApiController < ApiController
6
6
 
7
- respond_to :json
8
-
9
7
  def current_user
10
8
  @current_api_user ||= ApiUser.new(doorkeeper_token, lambda { super })
11
9
  end
@@ -11,6 +11,8 @@
11
11
  # This API class gives us a way to abstract out these cases and also
12
12
  # gives us accessors to get the Application and User objects, if available.
13
13
 
14
+ require 'openstax_utilities'
15
+
14
16
  module OpenStax
15
17
  module Api
16
18
  class ApiUser
@@ -25,10 +27,11 @@ module OpenStax
25
27
  # procs that can get it for us. This could save us some queries.
26
28
 
27
29
  if doorkeeper_token
30
+ user_class = OpenStax::Api.configuration.user_class_name.classify.constantize
28
31
  @application_proc = lambda { doorkeeper_token.application }
29
32
  @user_proc = lambda {
30
33
  doorkeeper_token.resource_owner_id ?
31
- User.find(doorkeeper_token.resource_owner_id) :
34
+ user_class.find(doorkeeper_token.resource_owner_id) :
32
35
  nil
33
36
  }
34
37
  else
@@ -37,9 +40,7 @@ module OpenStax
37
40
  end
38
41
  end
39
42
 
40
- # Returns a Doorkeeper::Application or nil
41
- # TODO should we have a NoApplication like NoUser (or maybe should
42
- # NoUser just be replaced with nil)
43
+ # Returns a Doorkeeper::Application or nil
43
44
  def application
44
45
  @application ||= @application_proc.call
45
46
  end
@@ -0,0 +1,51 @@
1
+ # Copyright 2011-2014 Rice University. Licensed under the Affero General Public
2
+ # License version 3 or later. See the COPYRIGHT file for details.
3
+
4
+ require 'openstax/api/representable_schema_printer'
5
+
6
+ module OpenStax
7
+ module Api
8
+
9
+ module Apipie
10
+
11
+ def self.included(base)
12
+ base.send :extend, ClassMethods
13
+ end
14
+
15
+ module ClassMethods
16
+
17
+ def api_example(options={})
18
+ return if Rails.env.test?
19
+ raise IllegalArgument, "must supply a :url parameter" if !options[:url_base]
20
+
21
+ url_base = options[:url_base].is_a?(Symbol) ?
22
+ UrlGenerator.new.send(options[:url_base], protocol: 'https') :
23
+ options[:url_base].to_s
24
+
25
+ "#{url_base}/#{options[:url_end] || ''}"
26
+ end
27
+
28
+ def json_schema(representer, options={})
29
+ RepresentableSchemaPrinter.json(representer, options)
30
+ end
31
+
32
+ # A hack at a conversion from a Representer to a series of Apipie declarations
33
+ # Can call it like any Apipie DSL method,
34
+ #
35
+ # example "blah"
36
+ # representer Api::V1::ExerciseRepresenter
37
+ # def update ...
38
+ #
39
+ def representer(representer)
40
+ representer.representable_attrs.each do |attr|
41
+ schema_info = attr.options[:schema_info] || {}
42
+ param attr.name, (attr.options[:type] || Object), required: schema_info[:required]
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ end
49
+
50
+ end
51
+ end
File without changes
File without changes
@@ -0,0 +1,83 @@
1
+ module OpenStax
2
+ module Api
3
+ class RepresentableSchemaPrinter
4
+
5
+ def self.json(representer, options={})
6
+ options[:include] ||= [:readable, :writeable]
7
+ options[:indent] ||= ' '
8
+
9
+ definitions = {}
10
+
11
+ schema = json_schema(representer, definitions, options)
12
+ schema[:definitions] = definitions
13
+
14
+ json_string = JSON.pretty_generate(schema, {indent: options[:indent]})
15
+
16
+ "\nSchema {##{SecureRandom.hex(4)} .schema}\n------\n" +
17
+ "<pre class='code'>\n#{json_string}\n</pre>\n"
18
+ end
19
+
20
+ protected
21
+
22
+ def self.json_schema(representer, definitions, options={})
23
+ schema = {
24
+ # id: schema_id(representer),
25
+ # title: schema_title(representer),
26
+ type: "object",
27
+ properties: {},
28
+ required: []
29
+ # :$schema => "http://json-schema.org/draft-04/schema#"
30
+ }
31
+
32
+ representer.representable_attrs.each do |attr|
33
+ schema_info = attr.options[:schema_info] || {}
34
+
35
+ schema[:required].push(attr.name) if schema_info[:required]
36
+
37
+ next unless [options[:include]].flatten.any?{|inc| attr.send(inc.to_s+"?") || schema_info[:required]}
38
+
39
+ attr_info = {}
40
+
41
+ if attr.options[:collection]
42
+ attr_info[:type] = "array"
43
+ else
44
+ attr_info[:type] = attr.options[:type].to_s.downcase if attr.options[:type]
45
+ end
46
+
47
+ schema_info.each do |key, value|
48
+ next if [:required].include?(key)
49
+ value = value.to_s.downcase if key == :type
50
+ attr_info[key] = value
51
+ end
52
+
53
+ decorator = attr.options[:decorator].try(:is_a?, Proc) ? nil : attr.options[:decorator]
54
+
55
+ if decorator
56
+ relative_schema_id(decorator).tap do |id|
57
+ attr_info[:$ref] = "#/definitions/#{id}"
58
+ definitions[id] ||= json_schema(decorator, definitions, options)
59
+ end
60
+ end
61
+
62
+ schema[:properties][attr.name.to_sym] = attr_info
63
+ end
64
+
65
+ schema
66
+ end
67
+
68
+ def self.schema_title(representer)
69
+ representer.name.gsub(/Representer/,'')
70
+ end
71
+
72
+ def self.schema_id(representer)
73
+ "http://#{OpenStax::Api::Engine::MAIN_APP_NAME.to_s}.openstax.org/" +
74
+ "#{schema_title(representer).downcase.gsub(/::/,'/')}"
75
+ end
76
+
77
+ def self.relative_schema_id(representer)
78
+ representer.name.gsub(/Representer/,'').downcase.gsub(/::/,'/')
79
+ end
80
+
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,132 @@
1
+ # Copyright 2011-2014 Rice University. Licensed under the Affero General Public
2
+ # License version 3 or later. See the COPYRIGHT file for details.
3
+
4
+ module OpenStax
5
+ module Api
6
+
7
+ module Roar
8
+
9
+ def get_representer(represent_with, model=nil)
10
+ return nil if represent_with.nil?
11
+ if represent_with.is_a? Proc
12
+ represent_with.call(model)
13
+ else
14
+ represent_with
15
+ end
16
+ end
17
+
18
+ def standard_read(model_klass, id, represent_with=nil)
19
+ @model = model_klass.find(id)
20
+ raise SecurityTransgression unless current_user.can_read?(@model)
21
+ respond_with @model, represent_with: get_representer(represent_with, @model)
22
+ end
23
+
24
+ def standard_update(model_klass, id, represent_with=nil)
25
+ @model = model_klass.find(id)
26
+ raise SecurityTransgression unless current_user.can_update?(@model)
27
+ consume!(@model, represent_with: get_representer(represent_with, @model))
28
+
29
+ if @model.save
30
+ head :no_content
31
+ else
32
+ render json: @model.errors, status: :unprocessable_entity
33
+ end
34
+ end
35
+
36
+ def standard_create(model_klass, represent_with=nil)
37
+ standard_nested_create(model_klass, nil, nil, represent_with)
38
+ end
39
+
40
+ def standard_nested_create(model_klass, container_association=nil, container_id=nil, represent_with=nil)
41
+ @model = model_klass.new()
42
+
43
+ if container_association && container_id
44
+ foreign_key = model_klass.reflect_on_association(container_association).association_foreign_key
45
+ @model.send(foreign_key + '=', container_id)
46
+ end
47
+
48
+ # Unlike the implications of the representable README, "consume!" can
49
+ # actually make changes to the database. See http://goo.gl/WVLBqA.
50
+ # We do want to consume before checking the permissions so we can know
51
+ # what we're dealing with, but if user doesn't have permission we don't
52
+ # want to have changed the DB. Wrap in a transaction to protect ourselves.
53
+
54
+ model_klass.transaction do
55
+ consume!(@model, represent_with: get_representer(represent_with, @model))
56
+ yield @model if block_given?
57
+ raise SecurityTransgression unless current_user.can_create?(@model)
58
+ end
59
+
60
+ if @model.save
61
+ respond_with @model, represent_with: get_representer(represent_with, @model), status: :created
62
+ else
63
+ render json: @model.errors, status: :unprocessable_entity
64
+ end
65
+ end
66
+
67
+ def standard_destroy(model_klass, id)
68
+ @model = model_klass.find(id)
69
+ raise SecurityTransgression unless current_user.can_destroy?(@model)
70
+
71
+ if @model.destroy
72
+ head :no_content
73
+ else
74
+ render json: @model.errors, status: :unprocessable_entity
75
+ end
76
+ end
77
+
78
+ def standard_sort(model_klass)
79
+ # Take array of all IDs or hash of id => position,
80
+ # Regardless, build up an array of all IDs in the right order and pass those to sort
81
+
82
+ new_positions = params['newPositions']
83
+ return head :no_content if new_positions.length == 0
84
+
85
+ # Can't have duplicate positions or IDs
86
+ unique_ids = new_positions.collect{|np| np['id']}.uniq
87
+ unique_positions = new_positions.collect{|np| np['position']}.uniq
88
+
89
+ return head :bad_request if unique_ids.length != new_positions.length
90
+ return head :bad_request if unique_positions.length != new_positions.length
91
+
92
+ first = model_klass.where(:id => new_positions[0]['id']).first
93
+
94
+ return head :not_found if first.blank?
95
+
96
+ originalOrdered = first.me_and_peers.ordered.all
97
+
98
+ originalOrdered.each do |item|
99
+ raise SecurityTransgression unless item.send(:container_column) == originalOrdered[0].send(:container_column) \
100
+ if item.respond_to?(:container_column)
101
+ raise SecurityTransgression unless current_user.can_sort?(item)
102
+ end
103
+
104
+ originalOrderedIds = originalOrdered.collect{|sc| sc.id}
105
+
106
+ newOrderedIds = Array.new(originalOrderedIds.size)
107
+
108
+ new_positions.each do |newPosition|
109
+ id = newPosition['id'].to_i
110
+ newOrderedIds[newPosition['position']] = id
111
+ originalOrderedIds.delete(id)
112
+ end
113
+
114
+ ptr = 0
115
+ for oldId in originalOrderedIds
116
+ while !newOrderedIds[ptr].nil?; ptr += 1; end
117
+ newOrderedIds[ptr] = oldId
118
+ end
119
+
120
+ begin
121
+ model_klass.sort!(newOrderedIds)
122
+ rescue Exception => e
123
+ return head :internal_server_error
124
+ end
125
+
126
+ head :no_content
127
+ end
128
+
129
+ end
130
+
131
+ end
132
+ end
@@ -1,4 +1,4 @@
1
- require 'openstax_api/constraints'
1
+ require 'openstax/api/constraints'
2
2
 
3
3
  module OpenStax
4
4
  module Api
@@ -1,5 +1,5 @@
1
1
  module OpenStax
2
2
  module Api
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
data/lib/openstax_api.rb CHANGED
@@ -1,8 +1,25 @@
1
- require 'openstax_api/engine'
2
- require 'openstax_api/doorkeeper_extensions'
3
- require 'openstax_api/route_extensions'
1
+ require 'openstax/api/engine'
2
+ require 'openstax/api/doorkeeper_extensions'
3
+ require 'openstax/api/route_extensions'
4
4
 
5
5
  module OpenStax
6
6
  module Api
7
+
8
+ def self.configure
9
+ yield configuration
10
+ end
11
+
12
+ def self.configuration
13
+ @configuration ||= Configuration.new
14
+ end
15
+
16
+ class Configuration
17
+ attr_accessor :user_class_name
18
+
19
+ def initialize
20
+ @user_class_name = 'User'
21
+ end
22
+ end
23
+
7
24
  end
8
25
  end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  module OpenStax
4
4
  module Api
5
5
  describe ApiUser do
6
- let(:user) { User.create }
6
+ let(:user) { DummyUser.create }
7
7
  let(:application) { double('Doorkeeper::Application') }
8
8
  let(:doorkeeper_token) { double('Doorkeeper::AccessToken') }
9
9
  let(:non_doorkeeper_user_proc) { lambda { user } }
@@ -5,7 +5,7 @@ module OpenStax
5
5
  module V1
6
6
  describe RepresentableSchemaPrinter do
7
7
  it 'must print model schemas' do
8
- schema = RepresentableSchemaPrinter.json(UserRepresenter)
8
+ schema = RepresentableSchemaPrinter.json(DummyUserRepresenter)
9
9
  expect(schema).to include('Schema')
10
10
  expect(schema).to include('.schema')
11
11
  expect(schema).to include('------')
@@ -0,0 +1,2 @@
1
+ class DummyUser < ActiveRecord::Base
2
+ end
@@ -1,6 +1,6 @@
1
1
  require 'representable/json'
2
2
 
3
- module UserRepresenter
3
+ module DummyUserRepresenter
4
4
  include Roar::Representer::JSON
5
5
 
6
6
  property :username
@@ -0,0 +1,3 @@
1
+ OpenStax::Api.configure do |config|
2
+ config.user_class_name = 'DummyUser'
3
+ end
Binary file
@@ -1,6 +1,6 @@
1
- class CreateUsers < ActiveRecord::Migration
1
+ class CreateDummyUsers < ActiveRecord::Migration
2
2
  def change
3
- create_table :users do |t|
3
+ create_table :dummy_users do |t|
4
4
  t.string :username
5
5
  t.string :password_hash
6
6
 
@@ -13,6 +13,13 @@
13
13
 
14
14
  ActiveRecord::Schema.define(:version => 1) do
15
15
 
16
+ create_table "dummy_users", :force => true do |t|
17
+ t.string "username"
18
+ t.string "password_hash"
19
+ t.datetime "created_at", :null => false
20
+ t.datetime "updated_at", :null => false
21
+ end
22
+
16
23
  create_table "oauth_access_grants", :force => true do |t|
17
24
  t.integer "resource_owner_id", :null => false
18
25
  t.integer "application_id", :null => false
@@ -52,11 +59,4 @@ ActiveRecord::Schema.define(:version => 1) do
52
59
 
53
60
  add_index "oauth_applications", ["uid"], :name => "index_oauth_applications_on_uid", :unique => true
54
61
 
55
- create_table "users", :force => true do |t|
56
- t.string "username"
57
- t.string "password_hash"
58
- t.datetime "created_at", :null => false
59
- t.datetime "updated_at", :null => false
60
- end
61
-
62
62
  end
Binary file