zuora_connectD 1.7.09

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +38 -0
  4. data/app/assets/javascripts/zuora_connect/api/v1/app_instance.js +2 -0
  5. data/app/assets/javascripts/zuora_connect/application.js +13 -0
  6. data/app/assets/stylesheets/zuora_connect/api/v1/app_instance.css +4 -0
  7. data/app/assets/stylesheets/zuora_connect/application.css +15 -0
  8. data/app/controllers/zuora_connect/admin/tenant_controller.rb +11 -0
  9. data/app/controllers/zuora_connect/api/v1/app_instance_controller.rb +45 -0
  10. data/app/controllers/zuora_connect/application_controller.rb +8 -0
  11. data/app/controllers/zuora_connect/static_controller.rb +32 -0
  12. data/app/helpers/zuora_connect/api/v1/app_instance_helper.rb +4 -0
  13. data/app/helpers/zuora_connect/application_helper.rb +5 -0
  14. data/app/models/zuora_connect/app_instance.rb +5 -0
  15. data/app/models/zuora_connect/app_instance_base.rb +811 -0
  16. data/app/models/zuora_connect/login.rb +36 -0
  17. data/app/models/zuora_connect/telegraf.rb +88 -0
  18. data/app/views/layouts/zuora_connect/application.html.erb +14 -0
  19. data/app/views/sql/refresh_aggregate_table.txt +84 -0
  20. data/app/views/zuora_connect/static/invalid_app_instance_error.html.erb +65 -0
  21. data/app/views/zuora_connect/static/session_error.html.erb +63 -0
  22. data/config/initializers/apartment.rb +95 -0
  23. data/config/initializers/object_method_hooks.rb +27 -0
  24. data/config/initializers/postgresql_adapter.rb +32 -0
  25. data/config/initializers/prometheus.rb +41 -0
  26. data/config/initializers/redis.rb +10 -0
  27. data/config/initializers/resque.rb +6 -0
  28. data/config/initializers/to_bool.rb +24 -0
  29. data/config/initializers/unicorn.rb +9 -0
  30. data/config/routes.rb +13 -0
  31. data/db/migrate/20100718151733_create_connect_app_instances.rb +9 -0
  32. data/db/migrate/20101024162319_add_tokens_to_app_instance.rb +6 -0
  33. data/db/migrate/20101024220705_add_token_to_app_instance.rb +5 -0
  34. data/db/migrate/20110131211919_add_sessions_table.rb +13 -0
  35. data/db/migrate/20110411200303_add_expiration_to_app_instance.rb +5 -0
  36. data/db/migrate/20110413191512_add_new_api_token.rb +5 -0
  37. data/db/migrate/20110503003602_add_catalog_data_to_app_instance.rb +6 -0
  38. data/db/migrate/20110503003603_add_catalog_mappings_to_app_instance.rb +5 -0
  39. data/db/migrate/20110503003604_catalog_default.rb +5 -0
  40. data/db/migrate/20180301052853_add_catalog_attempted_at.rb +5 -0
  41. data/lib/metrics/influx/point_value.rb +79 -0
  42. data/lib/metrics/net.rb +218 -0
  43. data/lib/middleware/metrics_middleware.rb +110 -0
  44. data/lib/resque/additions.rb +53 -0
  45. data/lib/resque/dynamic_queues.rb +142 -0
  46. data/lib/resque/self_lookup.rb +19 -0
  47. data/lib/resque/silence_done.rb +71 -0
  48. data/lib/tasks/zuora_connect_tasks.rake +24 -0
  49. data/lib/zuora_connectD.rb +41 -0
  50. data/lib/zuora_connectD/configuration.rb +52 -0
  51. data/lib/zuora_connectD/controllers/helpers.rb +165 -0
  52. data/lib/zuora_connectD/engine.rb +30 -0
  53. data/lib/zuora_connectD/exceptions.rb +67 -0
  54. data/lib/zuora_connectD/railtie.rb +59 -0
  55. data/lib/zuora_connectD/version.rb +3 -0
  56. data/lib/zuora_connectD/views/helpers.rb +9 -0
  57. data/test/controllers/zuora_connect/api/v1/app_instance_controller_test.rb +13 -0
  58. data/test/dummy/README.rdoc +28 -0
  59. data/test/dummy/Rakefile +6 -0
  60. data/test/dummy/app/assets/javascripts/application.js +13 -0
  61. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  62. data/test/dummy/app/controllers/application_controller.rb +5 -0
  63. data/test/dummy/app/helpers/application_helper.rb +2 -0
  64. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  65. data/test/dummy/bin/bundle +3 -0
  66. data/test/dummy/bin/rails +4 -0
  67. data/test/dummy/bin/rake +4 -0
  68. data/test/dummy/bin/setup +29 -0
  69. data/test/dummy/config.ru +4 -0
  70. data/test/dummy/config/application.rb +26 -0
  71. data/test/dummy/config/boot.rb +5 -0
  72. data/test/dummy/config/database.yml +25 -0
  73. data/test/dummy/config/environment.rb +5 -0
  74. data/test/dummy/config/environments/development.rb +41 -0
  75. data/test/dummy/config/environments/production.rb +79 -0
  76. data/test/dummy/config/environments/test.rb +42 -0
  77. data/test/dummy/config/initializers/assets.rb +11 -0
  78. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  79. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  80. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  81. data/test/dummy/config/initializers/inflections.rb +16 -0
  82. data/test/dummy/config/initializers/mime_types.rb +4 -0
  83. data/test/dummy/config/initializers/session_store.rb +3 -0
  84. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  85. data/test/dummy/config/locales/en.yml +23 -0
  86. data/test/dummy/config/routes.rb +4 -0
  87. data/test/dummy/config/secrets.yml +22 -0
  88. data/test/dummy/db/development.sqlite3 +0 -0
  89. data/test/dummy/db/test.sqlite3 +0 -0
  90. data/test/dummy/log/development.log +2 -0
  91. data/test/dummy/log/test.log +0 -0
  92. data/test/dummy/public/404.html +67 -0
  93. data/test/dummy/public/422.html +67 -0
  94. data/test/dummy/public/500.html +66 -0
  95. data/test/dummy/public/favicon.ico +0 -0
  96. data/test/fixtures/zuora_connect/app_instances.yml +11 -0
  97. data/test/integration/navigation_test.rb +8 -0
  98. data/test/lib/generators/zuora_connect/datatable_generator_test.rb +16 -0
  99. data/test/models/zuora_connect/app_instance_test.rb +9 -0
  100. data/test/test_helper.rb +21 -0
  101. data/test/zuora_connect_test.rb +7 -0
  102. metadata +416 -0
@@ -0,0 +1,52 @@
1
+ module ZuoraConnect
2
+ class Configuration
3
+
4
+ attr_accessor :default_locale, :default_time_zone, :url, :mode, :delayed_job,:private_key, :additional_apartment_models
5
+
6
+ attr_accessor :enable_metrics, :telegraf_endpoint, :telegraf_debug, :custom_prometheus_update_block, :silencer_resque_finish
7
+
8
+ attr_accessor :oauth_client_id, :oauth_client_secret, :oauth_client_redirect_uri
9
+
10
+ attr_accessor :dev_mode_logins, :dev_mode_options, :dev_mode_mode, :dev_mode_appinstance, :dev_mode_user, :dev_mode_pass, :dev_mode_admin, :dev_mode_secret_access_key,:dev_mode_access_key_id,:aws_region, :s3_bucket_name, :s3_folder_name
11
+
12
+ def initialize
13
+ @default_locale = :en
14
+ @default_time_zone = Time.zone
15
+ @url = "https://connect.zuora.com"
16
+ @mode = "Production"
17
+ @delayed_job = false
18
+ @private_key = ENV["CONNECT_KEY"]
19
+ @additional_apartment_models = []
20
+ @silencer_resque_finish = true
21
+
22
+ # Setting the app name for telegraf write
23
+ @enable_metrics = false
24
+ @telegraf_endpoint = 'udp://telegraf-app-metrics.monitoring.svc.cluster.local:8094'
25
+ @telegraf_debug = false
26
+
27
+ # OAuth Settings
28
+ @oauth_client_id = ""
29
+ @oauth_client_secret = ""
30
+ @oauth_client_redirect_uri = "https://connect.zuora.com/"
31
+
32
+ # DEV MODE OPTIONS
33
+ @dev_mode_logins = { "target_login" => {"tenant_type" => "Zuora", "username" => "user", "password" => "pass", "url" => "url"} }
34
+ @dev_mode_options = {"name" => {"config_name" => "name", "datatype" => "type", "value" => "value"}}
35
+ @dev_mode_mode = "Universal"
36
+ @dev_mode_appinstance = "1"
37
+ @dev_mode_user = "test"
38
+ @dev_mode_pass = "test"
39
+ @dev_mode_admin = false
40
+ @dev_mode_secret_access_key = nil
41
+ @dev_mode_access_key_id = nil
42
+ @aws_region = "us-west-2"
43
+ @s3_bucket_name = "rbm-apps"
44
+ @s3_folder_name = Rails.application.class.parent_name
45
+ end
46
+
47
+ def private_key
48
+ raise "Private Key Not Set" if @private_key.blank?
49
+ @private_key.include?("BEGIN") ? @private_key : Base64.urlsafe_decode64(@private_key)
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,165 @@
1
+ require 'apartment/migrator'
2
+ module ZuoraConnect
3
+ module Controllers
4
+ module Helpers
5
+ extend ActiveSupport::Concern
6
+
7
+ def authenticate_app_api_request
8
+ #Skip session for api requests
9
+ Thread.current[:appinstance] = nil
10
+ request.session_options[:skip] = true
11
+ start_time = Time.now
12
+ if request.headers["API-Token"].present?
13
+ @appinstance = ZuoraConnect::AppInstance.where(:api_token => request.headers["API-Token"]).first
14
+ Rails.logger.debug("[#{@appinstance.id}] API REQUEST - API token") if @appinstance.present?
15
+ check_instance
16
+ else
17
+ authenticate_or_request_with_http_basic do |username, password|
18
+ @appinstance = ZuoraConnect::AppInstance.where(:token => password).first
19
+ @appinstance ||= ZuoraConnect::AppInstance.where(:api_token => password).first
20
+ Rails.logger.debug("[#{@appinstance.id}] API REQUEST - Basic Auth") if @appinstance.present?
21
+ check_instance
22
+ end
23
+ end
24
+ Rails.logger.debug("[#{@appinstance.blank? ? "N/A" : @appinstance.id}] Authenticate App API Request Completed In - #{(Time.now - start_time).round(2)}s")
25
+ end
26
+
27
+ def authenticate_connect_app_request
28
+ Thread.current[:appinstance] = nil
29
+ start_time = Time.now
30
+ if ZuoraConnect.configuration.mode == "Production"
31
+ if request["data"]
32
+ setup_instance_via_data
33
+ else
34
+ setup_instance_via_session
35
+ end
36
+ else
37
+ setup_instance_via_dev_mode
38
+ end
39
+ #Call .data_lookup with the current session to retrieve session. In some cases session may be stored/cache in redis
40
+ #so data lookup provides a model method that can be overriden per app.
41
+ if params[:controller] != 'zuora_connect/api/v1/app_instance' && params[:action] != 'drop'
42
+ if @appinstance.new_session_for_ui_requests(:params => params)
43
+ @appinstance.new_session(:session => @appinstance.data_lookup(:session => session))
44
+ end
45
+ end
46
+ PaperTrail.whodunnit = session["#{@appinstance.id}::user::email"] if defined?(PaperTrail) && session["#{@appinstance.id}::user::email"].present?
47
+ begin
48
+ I18n.locale = session["#{@appinstance.id}::user::locale"] ? session["#{@appinstance.id}::user::locale"] : @appinstance.locale
49
+ rescue I18n::InvalidLocale => ex
50
+ Rails.logger.error("Invalid Locale: #{ex.message}")
51
+ end
52
+ Time.zone = session["#{@appinstance.id}::user::timezone"] ? session["#{@appinstance.id}::user::timezone"] : @appinstance.timezone
53
+ Rails.logger.debug("[#{@appinstance.blank? ? "N/A" : @appinstance.id}] Authenticate App Request Completed In - #{(Time.now - start_time).round(2)}s")
54
+ end
55
+
56
+ def persist_connect_app_session
57
+ if @appinstance.present?
58
+ if defined?(Redis.current)
59
+ @appinstance.cache_app_instance
60
+ else
61
+ session.merge!(@appinstance.save_data)
62
+ end
63
+ end
64
+ end
65
+
66
+ def check_connect_admin!
67
+ raise ZuoraConnect::Exceptions::AccessDenied.new("User is not an authorized admin for this application") if !session["#{@appinstance.id}::admin"]
68
+ end
69
+
70
+ def check_connect_admin
71
+ return session["#{@appinstance.id}::admin"]
72
+ end
73
+
74
+ private
75
+ def setup_instance_via_data
76
+ session.clear
77
+ values = JSON.parse(ZuoraConnect::AppInstance.decrypt_response(Base64.urlsafe_decode64(request["data"])))
78
+ Rails.logger.debug("Data: #{values.to_json}")
79
+ if values["param_data"]
80
+ values["param_data"].each do |k ,v|
81
+ params[k] = v
82
+ end
83
+ end
84
+ session["#{values["appInstance"]}::destroy"] = values["destroy"]
85
+ session["appInstance"] = values["appInstance"]
86
+ if values["current_user"]
87
+ session["#{values["appInstance"]}::admin"] = values["current_user"]["admin"] ? values["current_user"]["admin"] : false
88
+ session["#{values["appInstance"]}::user::timezone"] = values["current_user"]["timezone"]
89
+ session["#{values["appInstance"]}::user::locale"] = values["current_user"]["locale"]
90
+ session["#{values["appInstance"]}::user::email"] = values["current_user"]["email"]
91
+ end
92
+
93
+ Rails.logger.debug("App Params: #{values.to_json}}") if Rails.env != "production"
94
+
95
+ @appinstance = ZuoraConnect::AppInstance.where(:id => values["appInstance"].to_i).first
96
+ if @appinstance.blank?
97
+ Apartment::Tenant.switch!("public")
98
+ begin
99
+ Apartment::Tenant.create(values["appInstance"].to_s)
100
+ rescue Apartment::TenantExists => ex
101
+ Rails.logger.debug("Tenant Already Exists")
102
+ end
103
+ @appinstance = ZuoraConnect::AppInstance.new(:api_token => values[:api_token],:id => values["appInstance"].to_i, :access_token => values["access_token"].blank? ? values["user"] : values["access_token"], :token => values["refresh_token"] , :refresh_token => values["refresh_token"].blank? ? values["key"] : values["refresh_token"], :oauth_expires_at => values["expires"])
104
+ @appinstance.save(:validate => false)
105
+ else
106
+ @appinstance.access_token = values["access_token"] if !values["access_token"].blank? && @appinstance.access_token != values["access_token"]
107
+ @appinstance.refresh_token = values["refresh_token"] if !values["refresh_token"].blank? && @appinstance.refresh_token != values["refresh_token"]
108
+ @appinstance.oauth_expires_at = values["expires"] if !values["expires"].blank?
109
+ @appinstance.api_token = values["api_token"] if !values["api_token"].blank? && @appinstance.api_token != values["api_token"]
110
+ if @appinstance.access_token_changed? && @appinstance.refresh_token_changed?
111
+ @appinstance.save(:validate => false)
112
+ else
113
+ raise ZuoraConnect::Exceptions::AccessDenied.new("Authorization mistmatch. Possible tampering")
114
+ end
115
+ end
116
+ end
117
+
118
+ def setup_instance_via_session
119
+ if session["appInstance"].present?
120
+ @appinstance = ZuoraConnect::AppInstance.where(:id => session["appInstance"]).first
121
+ else
122
+ raise ZuoraConnect::Exceptions::SessionInvalid.new("Session Blank -- Relaunch Application")
123
+ end
124
+ end
125
+
126
+ def setup_instance_via_dev_mode
127
+ session["appInstance"] = ZuoraConnect.configuration.dev_mode_appinstance
128
+ user = ZuoraConnect.configuration.dev_mode_user
129
+ key = ZuoraConnect.configuration.dev_mode_pass
130
+ values = {:user => user , :key => key, :appinstance => session["appInstance"]}
131
+ @appinstance = ZuoraConnect::AppInstance.where(:id => values[:appinstance].to_i).first
132
+ if @appinstance.blank?
133
+ Apartment::Tenant.switch!("public")
134
+ begin
135
+ Apartment::Tenant.create(values[:appinstance].to_s)
136
+ rescue Apartment::TenantExists => ex
137
+ Apartment::Tenant.drop(values[:appinstance].to_s)
138
+ retry
139
+ end
140
+
141
+ @appinstance = ZuoraConnect::AppInstance.new(:id => values[:appinstance].to_i, :access_token => values[:user], :refresh_token => values[:key], :token => "#{values[:key]}#{values[:key]}", :api_token => "#{values[:key]}#{values[:key]}")
142
+ @appinstance.save(:validate => false)
143
+ end
144
+ if @appinstance.access_token.blank? || @appinstance.refresh_token.blank? || @appinstance.token.blank? || @appinstance.api_token.blank?
145
+ @appinstance.update_attributes!(:access_token => values["user"], :refresh_token => values["key"], :token => "#{values[:key]}#{values[:key]}", :api_token => "#{values[:key]}#{values[:key]}")
146
+ end
147
+ session["#{@appinstance.id}::admin"] = ZuoraConnect.configuration.dev_mode_admin
148
+ end
149
+
150
+ #API ONLY
151
+ def check_instance
152
+ if @appinstance.present?
153
+ if @appinstance.new_session_for_api_requests(:params => params)
154
+ @appinstance.new_session(:session => @appinstance.data_lookup(:session => session))
155
+ end
156
+ Thread.current[:appinstance] = @appinstance
157
+ PaperTrail.whodunnit = "API User" if defined?(PaperTrail)
158
+ return true
159
+ else
160
+ render text: "Access Denied", status: :unauthorized
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,30 @@
1
+ require 'rails/all'
2
+ require 'zuora_connectD'
3
+ require 'apartment'
4
+ require 'httparty'
5
+ require 'zuora_apiD'
6
+ module ZuoraConnect
7
+ class Engine < ::Rails::Engine
8
+ isolate_namespace ZuoraConnect
9
+
10
+ initializer "connect", before: :load_config_initializers do |app|
11
+ Rails.application.routes.prepend do
12
+ mount ZuoraConnect::Engine, at: "/connect"
13
+ end
14
+ end
15
+
16
+ initializer :append_migrations do |app|
17
+ unless app.root.to_s.match root.to_s
18
+ config.paths["db/migrate"].expanded.each do |expanded_path|
19
+ app.config.paths["db/migrate"] << expanded_path
20
+ end
21
+ end
22
+ end
23
+
24
+ initializer "connect.helpers" do
25
+ ActiveSupport.on_load(:action_controller) do
26
+ include ZuoraConnect::Controllers::Helpers
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,67 @@
1
+ module ZuoraConnect
2
+ module Exceptions
3
+
4
+ class HoldingPattern < StandardError; end
5
+ class Error < StandardError; end
6
+ class AuthorizationNotPerformed < Error; end
7
+
8
+ class SessionInvalid < Error
9
+ attr_writer :default_message
10
+
11
+ def initialize(message = nil)
12
+ @message = message
13
+ @default_message = "Session data invalid."
14
+ end
15
+
16
+ def to_s
17
+ @message || @default_message
18
+ end
19
+ end
20
+
21
+ class ConnectCommunicationError < Error
22
+ attr_reader :code, :response
23
+ attr_writer :default_message
24
+
25
+ def initialize(message = nil,response=nil, code =nil)
26
+ @code = code
27
+ @message = message
28
+ @response = response
29
+ @default_message = "Error communication with Connect."
30
+ end
31
+
32
+ def to_s
33
+ @message || @default_message
34
+ end
35
+ end
36
+
37
+ class APIError < Error
38
+ attr_reader :code, :response
39
+ attr_writer :default_message
40
+
41
+ def initialize(message: nil,response: nil, code: nil)
42
+ @code = code
43
+ @message = message
44
+ @response = response
45
+ @default_message = "Connect update error."
46
+ end
47
+
48
+ def to_s
49
+ @message || @default_message
50
+ end
51
+
52
+ end
53
+
54
+ class AccessDenied < Error
55
+ attr_writer :default_message
56
+
57
+ def initialize(message = nil)
58
+ @message = message
59
+ @default_message = "You are not authorized to access this page."
60
+ end
61
+
62
+ def to_s
63
+ @message || @default_message
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,59 @@
1
+ require 'middleware/metrics_middleware'
2
+
3
+ module ZuoraConnect
4
+ class Railtie < Rails::Railtie
5
+
6
+
7
+ config.before_initialize do
8
+ version = Rails.version
9
+ if version >= "5.0.0"
10
+ ::Rails.configuration.public_file_server.enabled = true
11
+ elsif version >= "4.2.0"
12
+ ::Rails.configuration.serve_static_files = true
13
+ else
14
+ ::Rails.configuration.serve_static_assets = true
15
+ end
16
+ ::Rails.configuration.action_dispatch.x_sendfile_header = nil
17
+ end
18
+
19
+ if defined? Prometheus
20
+ initializer "prometheus.configure_rails_initialization" do |app|
21
+ app.middleware.use Prometheus::Middleware::Exporter,(options ={:path => '/connect/internal/metrics'})
22
+ end
23
+ end
24
+ initializer "zuora_connect.configure_rails_initialization" do |app|
25
+ app.middleware.insert_after Rack::Sendfile, Middleware::MetricsMiddleware
26
+ end
27
+
28
+ # hook to process_action
29
+ ActiveSupport::Notifications.subscribe('process_action.action_controller', Middleware::PageRequest.new)
30
+
31
+ initializer(:rails_stdout_logging, before: :initialize_logger) do
32
+ if Rails.env != 'development' && !ENV['DEIS_APP'].blank?
33
+ require 'lograge'
34
+ logger = ActiveSupport::Logger.new(STDOUT)
35
+ logger.formatter = ::Logger::Formatter.new
36
+ # logger.formatter = proc do |severity, datetime, progname, msg|
37
+ # {severity: severity, time: datetime.strftime('%FT%T.%6N'), process_id: Process.pid, message: msg }.to_json
38
+ # end
39
+ Rails.configuration.logger = ActiveSupport::TaggedLogging.new(logger)
40
+ Rails.configuration.log_tags = [:uuid]
41
+ Rails.configuration.lograge.enabled = true
42
+ Rails.configuration.lograge.formatter = Lograge::Formatters::Json.new
43
+ Rails.configuration.lograge.custom_options = lambda do |event|
44
+ exceptions = %w(controller action format id)
45
+ items = {
46
+ #time: event.time.strftime('%FT%T.%6N'),
47
+ params: event.payload[:params].except(*exceptions),
48
+ exception: event.payload[:exception],
49
+ exception_object: event.payload[:exception_object],
50
+ process_id: Process.pid
51
+ }
52
+ if Thread.current[:appinstance].present?
53
+ items.merge({appinstance_id: Thread.current[:appinstance].id, connect_user: Thread.current[:appinstance].connect_user, new_session: Thread.current[:appinstance].new_session_message})
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,3 @@
1
+ module ZuoraConnect
2
+ VERSION = "1.7.09"
3
+ end
@@ -0,0 +1,9 @@
1
+ module ZuoraConnect
2
+ module Views
3
+ module Helpers
4
+ def is_app_admin?
5
+ return @appinstance.blank? ? false : session["#{@appinstance.id}::admin"]
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ require 'test_helper'
2
+
3
+ module ZuoraConnect
4
+ class Api::V1::AppInstanceControllerTest < ActionController::TestCase
5
+ setup do
6
+ @routes = Engine.routes
7
+ end
8
+
9
+ # test "the truth" do
10
+ # assert true
11
+ # end
12
+ end
13
+ end
@@ -0,0 +1,28 @@
1
+ == README
2
+
3
+ This README would normally document whatever steps are necessary to get the
4
+ application up and running.
5
+
6
+ Things you may want to cover:
7
+
8
+ * Ruby version
9
+
10
+ * System dependencies
11
+
12
+ * Configuration
13
+
14
+ * Database creation
15
+
16
+ * Database initialization
17
+
18
+ * How to run the test suite
19
+
20
+ * Services (job queues, cache servers, search engines, etc.)
21
+
22
+ * Deployment instructions
23
+
24
+ * ...
25
+
26
+
27
+ Please feel free to use a different markup language if you do not plan to run
28
+ <tt>rake doc:app</tt>.
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Rails.application.load_tasks