policy_machine 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/CONTRIBUTING.md +35 -0
  2. data/Gemfile +2 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +98 -0
  5. data/lib/generators/policy_machine/policy_machine_generator.rb +13 -0
  6. data/lib/generators/policy_machine/templates/migration.rb +40 -0
  7. data/lib/policy_machine.rb +236 -0
  8. data/lib/policy_machine/association.rb +73 -0
  9. data/lib/policy_machine/policy_element.rb +269 -0
  10. data/lib/policy_machine/version.rb +3 -0
  11. data/lib/policy_machine_storage_adapters/active_record.rb +306 -0
  12. data/lib/policy_machine_storage_adapters/in_memory.rb +266 -0
  13. data/lib/policy_machine_storage_adapters/neography.rb +236 -0
  14. data/lib/policy_machine_storage_adapters/template.rb +169 -0
  15. data/lib/tasks/policy_machine_tasks.rake +4 -0
  16. data/policy_machine.gemspec +23 -0
  17. data/spec/policy_machine/association_spec.rb +61 -0
  18. data/spec/policy_machine/policy_element_spec.rb +20 -0
  19. data/spec/policy_machine_spec.rb +7 -0
  20. data/spec/policy_machine_storage_adapters/active_record_spec.rb +54 -0
  21. data/spec/policy_machine_storage_adapters/in_memory_spec.rb +13 -0
  22. data/spec/policy_machine_storage_adapters/neography_spec.rb +42 -0
  23. data/spec/policy_machine_storage_adapters/template_spec.rb +6 -0
  24. data/spec/spec_helper.rb +24 -0
  25. data/spec/support/neography_helpers.rb +39 -0
  26. data/spec/support/policy_machine_helpers.rb +22 -0
  27. data/spec/support/shared_examples_policy_machine_spec.rb +697 -0
  28. data/spec/support/shared_examples_policy_machine_storage_adapter_spec.rb +278 -0
  29. data/spec/support/shared_examples_storage_adapter_public_methods.rb +20 -0
  30. data/spec/support/storage_adapter_helpers.rb +7 -0
  31. data/test/dummy/Rakefile +7 -0
  32. data/test/dummy/app/controllers/application_controller.rb +3 -0
  33. data/test/dummy/app/helpers/application_helper.rb +2 -0
  34. data/test/dummy/app/models/.gitkeep +0 -0
  35. data/test/dummy/config.ru +4 -0
  36. data/test/dummy/config/application.rb +65 -0
  37. data/test/dummy/config/boot.rb +10 -0
  38. data/test/dummy/config/database.yml +42 -0
  39. data/test/dummy/config/environment.rb +5 -0
  40. data/test/dummy/config/environments/development.rb +37 -0
  41. data/test/dummy/config/environments/test.rb +37 -0
  42. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  43. data/test/dummy/config/initializers/inflections.rb +15 -0
  44. data/test/dummy/config/initializers/mime_types.rb +5 -0
  45. data/test/dummy/config/initializers/secret_token.rb +7 -0
  46. data/test/dummy/config/initializers/session_store.rb +8 -0
  47. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  48. data/test/dummy/config/routes.rb +58 -0
  49. data/test/dummy/db/migrate/20131015214828_generate_policy_machine.rb +40 -0
  50. data/test/dummy/db/migrate/20131021221759_add_color_to_policy_element.rb +5 -0
  51. data/test/dummy/db/schema.rb +57 -0
  52. data/test/dummy/lib/assets/.gitkeep +0 -0
  53. data/test/dummy/script/rails +6 -0
  54. data/test/policy_machine_test.rb +7 -0
  55. data/test/test_helper.rb +15 -0
  56. metadata +270 -0
@@ -0,0 +1,278 @@
1
+ # Policy Machines are directed acyclic graphs (DAG). These shared examples describe the
2
+ # API for these DAGs, which could be persisted in memory, in a graph database, etc.
3
+
4
+ require_relative 'storage_adapter_helpers.rb'
5
+
6
+ shared_examples "a policy machine storage adapter" do
7
+ let(:policy_machine_storage_adapter) { described_class.new }
8
+
9
+ PolicyMachine::POLICY_ELEMENT_TYPES.each do |pe_type|
10
+ describe "#add_#{pe_type}" do
11
+ it 'stores the policy element' do
12
+ src = policy_machine_storage_adapter.send("add_#{pe_type}", 'some_uuid', 'some_policy_machine_uuid')
13
+ policy_machine_storage_adapter.element_in_machine?(src).should be_true
14
+ end
15
+
16
+ it 'returns the instantiated policy element with persisted attribute set to true' do
17
+ node = policy_machine_storage_adapter.send("add_#{pe_type}", 'some_uuid', 'some_policy_machine_uuid')
18
+ node.persisted.should be_true
19
+ end
20
+ end
21
+
22
+ describe "find_all_of_type_#{pe_type}" do
23
+ it 'returns empty array if nothing found' do
24
+ policy_machine_storage_adapter.send("find_all_of_type_#{pe_type}").should == []
25
+ end
26
+
27
+ it 'returns array of found policy elements of given type if one is found' do
28
+ node = policy_machine_storage_adapter.send("add_#{pe_type}", 'some_uuid', 'some_policy_machine_uuid')
29
+ policy_machine_storage_adapter.send("find_all_of_type_#{pe_type}").should == [node]
30
+ end
31
+
32
+ it 'returns array of found policy elements of given type if more than one is found' do
33
+ node1 = policy_machine_storage_adapter.send("add_#{pe_type}", 'some_uuid1', 'some_policy_machine_uuid')
34
+ node2 = policy_machine_storage_adapter.send("add_#{pe_type}", 'some_uuid2', 'some_policy_machine_uuid')
35
+ policy_machine_storage_adapter.send("find_all_of_type_#{pe_type}").should == [node1, node2]
36
+ end
37
+ end
38
+ end
39
+
40
+ describe '#assign' do
41
+ before do
42
+ @src = policy_machine_storage_adapter.add_user('some_uuid1', 'some_policy_machine_uuid1')
43
+ @dst = policy_machine_storage_adapter.add_user_attribute('some_uuid2', 'some_policy_machine_uuid1')
44
+ end
45
+
46
+ context 'source or destination node is of the Node type return by add_' do
47
+ it 'assigns the nodes in one direction (from source to destination)' do
48
+ policy_machine_storage_adapter.assign(@src, @dst)
49
+ policy_machine_storage_adapter.connected?(@src, @dst).should be_true
50
+ end
51
+
52
+ it 'does not connect the nodes from destination to source' do
53
+ policy_machine_storage_adapter.assign(@src, @dst)
54
+ policy_machine_storage_adapter.connected?(@dst, @src).should be_false
55
+ end
56
+
57
+ it 'returns true' do
58
+ policy_machine_storage_adapter.assign(@src, @dst).should be_true
59
+ end
60
+ end
61
+
62
+ context 'source or destination node is not of the Node type return by add_' do
63
+ it 'raises for source' do
64
+ expect{ policy_machine_storage_adapter.assign(2, @dst) }.to raise_error(ArgumentError)
65
+ end
66
+
67
+ it 'raises for destination' do
68
+ expect{ policy_machine_storage_adapter.assign(@src, "") }.to raise_error(ArgumentError)
69
+ end
70
+ end
71
+ end
72
+
73
+ describe '#connected?' do
74
+ before do
75
+ @src = policy_machine_storage_adapter.add_user('some_uuid1', 'some_policy_machine_uuid1')
76
+ @dst = policy_machine_storage_adapter.add_user_attribute('some_uuid2', 'some_policy_machine_uuid1')
77
+
78
+ @internal1 = policy_machine_storage_adapter.add_user_attribute('some_uuid2a', 'some_policy_machine_uuid1')
79
+ @internal2 = policy_machine_storage_adapter.add_user_attribute('some_uuid2b', 'some_policy_machine_uuid1')
80
+ @internal3 = policy_machine_storage_adapter.add_user_attribute('some_uuid2c', 'some_policy_machine_uuid1')
81
+
82
+ policy_machine_storage_adapter.assign(@src, @internal1)
83
+ policy_machine_storage_adapter.assign(@internal1, @internal3)
84
+ policy_machine_storage_adapter.assign(@internal2, @internal1)
85
+ policy_machine_storage_adapter.assign(@internal3, @dst)
86
+ end
87
+
88
+ context 'source or destination node is of the Node type return by add_node' do
89
+ it 'returns true if source and destination nodes are connected' do
90
+ policy_machine_storage_adapter.connected?(@src, @dst).should be_true
91
+ end
92
+
93
+ it 'returns false if source and destination nodes are not connected' do
94
+ policy_machine_storage_adapter.connected?(@src, @internal2).should be_false
95
+ end
96
+ end
97
+
98
+ context 'source or destination node is not of the Node type return by add_node' do
99
+ it 'raises for source' do
100
+ expect{ policy_machine_storage_adapter.connected?("", @dst) }.to raise_error(ArgumentError)
101
+ end
102
+
103
+ it 'raises for destination' do
104
+ expect{ policy_machine_storage_adapter.connected?(@src, 6) }.to raise_error(ArgumentError)
105
+ end
106
+ end
107
+ end
108
+
109
+ describe '#unassign' do
110
+ before do
111
+ @src = policy_machine_storage_adapter.add_user('some_uuid1', 'some_policy_machine_uuid1')
112
+ @dst = policy_machine_storage_adapter.add_user_attribute('some_uuid2', 'some_policy_machine_uuid1')
113
+ policy_machine_storage_adapter.assign(@src, @dst)
114
+ end
115
+
116
+ context 'source or destination node is of the Node type return by add_' do
117
+ it 'disconnects source node from destination node' do
118
+ policy_machine_storage_adapter.unassign(@src, @dst)
119
+ policy_machine_storage_adapter.connected?(@src, @dst).should be_false
120
+ end
121
+
122
+ it 'does not disconnect destination from source node if there is an assignment in that direction' do
123
+ policy_machine_storage_adapter.assign(@dst, @src)
124
+ policy_machine_storage_adapter.unassign(@src, @dst)
125
+ policy_machine_storage_adapter.connected?(@dst, @src).should be_true
126
+ end
127
+
128
+ it 'returns true on successful disconnection' do
129
+ policy_machine_storage_adapter.unassign(@src, @dst).should be_true
130
+ end
131
+
132
+ it "returns false on unsuccessful disconnection (if the nodes weren't connected in the first place')" do
133
+ policy_machine_storage_adapter.unassign(@src, @dst)
134
+ policy_machine_storage_adapter.unassign(@src, @dst).should be_false
135
+ end
136
+ end
137
+
138
+ context 'source or destination node is not of the Node type return by add_node' do
139
+ it 'raises for source' do
140
+ expect{ policy_machine_storage_adapter.unassign(6, @dst) }.to raise_error(ArgumentError)
141
+ end
142
+
143
+ it 'raises for destination' do
144
+ expect{ policy_machine_storage_adapter.unassign(false, @dst) }.to raise_error(ArgumentError)
145
+ end
146
+ end
147
+ end
148
+
149
+ describe '#element_in_machine?' do
150
+ before do
151
+ @pe = policy_machine_storage_adapter.add_user('some_uuid1', 'some_policy_machine_uuid1')
152
+ end
153
+
154
+ it 'returns true when element is in machine' do
155
+ policy_machine_storage_adapter.element_in_machine?(@pe).should be_true
156
+ end
157
+ end
158
+
159
+ describe '#add_association' do
160
+ before do
161
+ @ua = policy_machine_storage_adapter.add_user_attribute('some_ua', 'some_policy_machine_uuid1')
162
+ @r = policy_machine_storage_adapter.add_operation('read', 'some_policy_machine_uuid1')
163
+ @w = policy_machine_storage_adapter.add_operation('write', 'some_policy_machine_uuid1')
164
+ @oa = policy_machine_storage_adapter.add_object_attribute('some_oa', 'some_policy_machine_uuid1')
165
+ end
166
+
167
+ it 'returns true' do
168
+ policy_machine_storage_adapter.add_association(@ua, Set.new([@r, @w]), @oa, 'some_policy_machine_uuid1').should be_true
169
+ end
170
+
171
+ it 'stores the association' do
172
+ policy_machine_storage_adapter.add_association(@ua, Set.new([@r, @w]), @oa, 'some_policy_machine_uuid1')
173
+ assocs_with_r = policy_machine_storage_adapter.associations_with(@r)
174
+ assocs_with_r.size == 1
175
+ assocs_with_r[0][0].should == @ua
176
+ assocs_with_r[0][1].to_a.should == [@r, @w]
177
+ assocs_with_r[0][2].should == @oa
178
+
179
+ assocs_with_w = policy_machine_storage_adapter.associations_with(@w)
180
+ assocs_with_w.size == 1
181
+ assocs_with_w[0][0].should == @ua
182
+ assocs_with_w[0][1].to_a.should == [@r, @w]
183
+ assocs_with_w[0][2].should == @oa
184
+ end
185
+
186
+ it 'overwrites a previously stored association' do
187
+ policy_machine_storage_adapter.add_association(@ua, Set.new([@r, @w]), @oa, 'some_policy_machine_uuid1')
188
+ policy_machine_storage_adapter.add_association(@ua, Set.new([@r]), @oa, 'some_policy_machine_uuid1')
189
+ assocs_with_r = policy_machine_storage_adapter.associations_with(@r)
190
+ assocs_with_r.size == 1
191
+ assocs_with_r[0][0].should == @ua
192
+ assocs_with_r[0][1].to_a.should == [@r]
193
+ assocs_with_r[0][2].should == @oa
194
+
195
+ policy_machine_storage_adapter.associations_with(@w).should == []
196
+ end
197
+ end
198
+
199
+ describe '#associations_with' do
200
+ before do
201
+ @ua = policy_machine_storage_adapter.add_user_attribute('some_ua', 'some_policy_machine_uuid1')
202
+ @ua2 = policy_machine_storage_adapter.add_user_attribute('some_other_ua', 'some_policy_machine_uuid1')
203
+ @r = policy_machine_storage_adapter.add_operation('read', 'some_policy_machine_uuid1')
204
+ @w = policy_machine_storage_adapter.add_operation('write', 'some_policy_machine_uuid1')
205
+ @e = policy_machine_storage_adapter.add_operation('execute', 'some_policy_machine_uuid1')
206
+ @oa = policy_machine_storage_adapter.add_object_attribute('some_oa', 'some_policy_machine_uuid1')
207
+ end
208
+
209
+ it 'returns empty array when given operation has no associated associations' do
210
+ policy_machine_storage_adapter.associations_with(@r).should == []
211
+ end
212
+
213
+ it 'returns structured array when given operation has associated associations' do
214
+ policy_machine_storage_adapter.add_association(@ua, Set.new([@w]), @oa, 'some_policy_machine_uuid1')
215
+ policy_machine_storage_adapter.add_association(@ua2, Set.new([@w, @e]), @oa, 'some_policy_machine_uuid1')
216
+ assocs_with_w = policy_machine_storage_adapter.associations_with(@w)
217
+
218
+ assocs_with_w.size == 2
219
+ assocs_with_w[0][0].should == @ua
220
+ assocs_with_w[0][1].to_a.should == [@w]
221
+ assocs_with_w[0][2].should == @oa
222
+ assocs_with_w[1][0].should == @ua2
223
+ assocs_with_w[1][1].to_a.should == [@w, @e]
224
+ assocs_with_w[1][2].should == @oa
225
+
226
+ end
227
+
228
+ end
229
+
230
+ describe '#policy_classes_for_object_attribute' do
231
+ before do
232
+ @oa = policy_machine_storage_adapter.add_object_attribute('some_oa', 'some_policy_machine_uuid1')
233
+ @pc1 = policy_machine_storage_adapter.add_policy_class('some_pc1', 'some_policy_machine_uuid1')
234
+ @pc2 = policy_machine_storage_adapter.add_policy_class('some_pc2', 'some_policy_machine_uuid1')
235
+ @pc3 = policy_machine_storage_adapter.add_policy_class('some_pc3', 'some_policy_machine_uuid1')
236
+ end
237
+
238
+ it 'returns empty array if object is in no policy classes' do
239
+ policy_machine_storage_adapter.policy_classes_for_object_attribute(@oa).should == []
240
+ end
241
+
242
+ it 'returns array of policy class(es) if object is in policy class(es)' do
243
+ policy_machine_storage_adapter.assign(@oa, @pc1)
244
+ policy_machine_storage_adapter.assign(@oa, @pc3)
245
+ policy_machine_storage_adapter.policy_classes_for_object_attribute(@oa).should == [@pc1, @pc3]
246
+ end
247
+
248
+ end
249
+
250
+ describe '#transaction' do
251
+ it 'executes the block' do
252
+ if_implements(policy_machine_storage_adapter, :transaction){}
253
+ policy_machine_storage_adapter.transaction do
254
+ @oa = policy_machine_storage_adapter.add_object_attribute('some_oa', 'some_policy_machine_uuid1')
255
+ @pc1 = policy_machine_storage_adapter.add_policy_class('some_pc1', 'some_policy_machine_uuid1')
256
+ policy_machine_storage_adapter.assign(@oa, @pc1)
257
+ end
258
+ policy_machine_storage_adapter.policy_classes_for_object_attribute(@oa).should == [@pc1]
259
+ end
260
+
261
+ it 'rolls back the block on error' do
262
+ if_implements(policy_machine_storage_adapter, :transaction){}
263
+ @oa = policy_machine_storage_adapter.add_object_attribute('some_oa', 'some_policy_machine_uuid1')
264
+ @pc1 = policy_machine_storage_adapter.add_policy_class('some_pc1', 'some_policy_machine_uuid1')
265
+ policy_machine_storage_adapter.assign(@oa, @pc1)
266
+ expect do
267
+ policy_machine_storage_adapter.transaction do
268
+ @pc2 = policy_machine_storage_adapter.add_policy_class('some_pc2', 'some_policy_machine_uuid1')
269
+ policy_machine_storage_adapter.assign(@oa, @pc2)
270
+ policy_machine_storage_adapter.assign(@oa, :invalid_policy_class)
271
+ end
272
+ end.to raise_error(ArgumentError)
273
+ policy_machine_storage_adapter.find_all_of_type_policy_class.should == [@pc1]
274
+ policy_machine_storage_adapter.policy_classes_for_object_attribute(@oa).should == [@pc1]
275
+ end
276
+ end
277
+
278
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples "a policy machine storage adapter with required public methods" do
4
+ let(:policy_machine_storage_adapter) { described_class.new }
5
+
6
+ policy_element_types = ::PolicyMachine::POLICY_ELEMENT_TYPES
7
+ required_public_methods = []
8
+ policy_element_types.each do |pe_type|
9
+ required_public_methods << "add_#{pe_type}"
10
+ required_public_methods << "find_all_of_type_#{pe_type}"
11
+ end
12
+ required_public_methods += %w(assign connected? unassign delete update element_in_machine? add_association associations_with policy_classes_for_object_attribute transaction)
13
+
14
+ required_public_methods.each do |req_public_method|
15
+ it "responds to #{req_public_method}" do
16
+ policy_machine_storage_adapter.should respond_to(req_public_method)
17
+ end
18
+ end
19
+
20
+ end
@@ -0,0 +1,7 @@
1
+ # This file contains helper methods to test policy machine integration with storage adapters.
2
+
3
+ def if_implements(storage_adapter, meth, *args,&block)
4
+ storage_adapter.send(meth,*args,&block)
5
+ rescue NotImplementedError => e
6
+ pending(e.message)
7
+ end
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env rake
2
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
3
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
4
+
5
+ require File.expand_path('../config/application', __FILE__)
6
+
7
+ Dummy::Application.load_tasks
@@ -0,0 +1,3 @@
1
+ class ApplicationController < ActionController::Base
2
+ protect_from_forgery
3
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
File without changes
@@ -0,0 +1,4 @@
1
+ # This file is used by Rack-based servers to start the application.
2
+
3
+ require ::File.expand_path('../config/environment', __FILE__)
4
+ run Dummy::Application
@@ -0,0 +1,65 @@
1
+ require File.expand_path('../boot', __FILE__)
2
+
3
+ # Pick the frameworks you want:
4
+ require "active_record/railtie"
5
+ require "action_controller/railtie"
6
+ require "action_mailer/railtie"
7
+ require "active_resource/railtie"
8
+ # require "sprockets/railtie"
9
+ require "rails/test_unit/railtie"
10
+
11
+ Bundler.require(*Rails.groups)
12
+ require "policy_machine"
13
+
14
+ module Dummy
15
+ class Application < Rails::Application
16
+ # Settings in config/environments/* take precedence over those specified here.
17
+ # Application configuration should go into files in config/initializers
18
+ # -- all .rb files in that directory are automatically loaded.
19
+
20
+ # Custom directories with classes and modules you want to be autoloadable.
21
+ # config.autoload_paths += %W(#{config.root}/extras)
22
+
23
+ # Only load the plugins named here, in the order given (default is alphabetical).
24
+ # :all can be used as a placeholder for all plugins not explicitly named.
25
+ # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
26
+
27
+ # Activate observers that should always be running.
28
+ # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
29
+
30
+ # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
31
+ # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
32
+ # config.time_zone = 'Central Time (US & Canada)'
33
+
34
+ # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
35
+ # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
36
+ # config.i18n.default_locale = :de
37
+
38
+ # Configure the default encoding used in templates for Ruby 1.9.
39
+ config.encoding = "utf-8"
40
+
41
+ # Configure sensitive parameters which will be filtered from the log file.
42
+ config.filter_parameters += [:password]
43
+
44
+ # Enable escaping HTML in JSON.
45
+ config.active_support.escape_html_entities_in_json = true
46
+
47
+ # Use SQL instead of Active Record's schema dumper when creating the database.
48
+ # This is necessary if your schema can't be completely dumped by the schema dumper,
49
+ # like if you have constraints or database-specific column types
50
+ # config.active_record.schema_format = :sql
51
+
52
+ # Enforce whitelist mode for mass assignment.
53
+ # This will create an empty whitelist of attributes available for mass-assignment for all models
54
+ # in your app. As such, your models will need to explicitly whitelist or blacklist accessible
55
+ # parameters by using an attr_accessible or attr_protected declaration.
56
+ config.active_record.whitelist_attributes = true
57
+
58
+ # Enable the asset pipeline
59
+ config.assets.enabled = true
60
+
61
+ # Version of your assets, change this if you want to expire all your assets
62
+ config.assets.version = '1.0'
63
+ end
64
+ end
65
+
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ gemfile = File.expand_path('../../../../Gemfile', __FILE__)
3
+
4
+ if File.exist?(gemfile)
5
+ ENV['BUNDLE_GEMFILE'] = gemfile
6
+ require 'bundler'
7
+ Bundler.setup
8
+ end
9
+
10
+ $:.unshift File.expand_path('../../../../lib', __FILE__)
@@ -0,0 +1,42 @@
1
+ # MySQL. Versions 4.1 and 5.0 are recommended.
2
+ #
3
+ # Install the MYSQL driver
4
+ # gem install mysql2
5
+ #
6
+ # Ensure the MySQL gem is defined in your Gemfile
7
+ # gem 'mysql2'
8
+ #
9
+ # And be sure to use new-style password hashing:
10
+ # http://dev.mysql.com/doc/refman/5.0/en/old-client.html
11
+ development:
12
+ adapter: mysql2
13
+ encoding: utf8
14
+ reconnect: false
15
+ database: dummy_development
16
+ pool: 5
17
+ username: root
18
+ password:
19
+ socket: /tmp/mysql.sock
20
+
21
+ # Warning: The database defined as "test" will be erased and
22
+ # re-generated from your development database when you run "rake".
23
+ # Do not set this db to the same as development or production.
24
+ test:
25
+ adapter: mysql2
26
+ encoding: utf8
27
+ reconnect: false
28
+ database: dummy_test
29
+ pool: 5
30
+ username: root
31
+ password:
32
+ socket: /tmp/mysql.sock
33
+
34
+ production:
35
+ adapter: mysql2
36
+ encoding: utf8
37
+ reconnect: false
38
+ database: dummy_production
39
+ pool: 5
40
+ username: root
41
+ password:
42
+ socket: /tmp/mysql.sock