fine_print 0.1.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (156) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +74 -45
  3. data/Rakefile +9 -9
  4. data/app/assets/javascripts/application.js~ +16 -0
  5. data/app/assets/javascripts/fine_print/application.js +8 -2
  6. data/app/controllers/fine_print/application_controller.rb +9 -7
  7. data/app/controllers/fine_print/application_controller.rb~ +9 -7
  8. data/app/controllers/fine_print/contracts_controller.rb +79 -0
  9. data/app/controllers/fine_print/contracts_controller.rb~ +79 -0
  10. data/app/controllers/fine_print/home_controller.rb +1 -11
  11. data/app/controllers/fine_print/home_controller.rb~ +2 -11
  12. data/app/controllers/fine_print/signatures_controller.rb +14 -0
  13. data/app/controllers/fine_print/signatures_controller.rb~ +14 -0
  14. data/app/helpers/fine_print/application_helper.rb +7 -0
  15. data/app/helpers/fine_print/application_helper.rb~ +7 -0
  16. data/app/helpers/fine_print/contracts_helper.rb~ +7 -0
  17. data/app/models/fine_print/contract.rb +96 -0
  18. data/app/models/fine_print/contract.rb~ +100 -0
  19. data/app/models/fine_print/signature.rb +25 -0
  20. data/app/models/fine_print/signature.rb~ +25 -0
  21. data/app/views/fine_print/contracts/_form.html.erb +35 -0
  22. data/app/views/fine_print/contracts/_form.html.erb~ +35 -0
  23. data/app/views/fine_print/contracts/edit.html.erb +10 -0
  24. data/app/views/fine_print/contracts/index.html.erb +43 -0
  25. data/app/views/fine_print/contracts/index.html.erb~ +43 -0
  26. data/app/views/fine_print/contracts/new.html.erb +9 -0
  27. data/app/views/fine_print/contracts/new_version.html.erb +9 -0
  28. data/app/views/fine_print/contracts/show.html.erb +33 -0
  29. data/app/views/fine_print/contracts/show.html.erb~ +35 -0
  30. data/app/views/fine_print/home/index.html.erb +15 -6
  31. data/app/views/fine_print/home/index.html.erb~ +12 -4
  32. data/app/views/fine_print/signatures/index.html.erb +36 -0
  33. data/app/views/fine_print/signatures/index.html.erb~ +32 -0
  34. data/app/views/layouts/fine_print/application.html.erb +6 -0
  35. data/app/views/layouts/fine_print/application.html.erb~ +20 -0
  36. data/config/initializers/fine_print.rb +27 -44
  37. data/config/initializers/fine_print.rb~ +23 -40
  38. data/config/routes.rb +9 -3
  39. data/config/routes.rb~ +9 -4
  40. data/db/migrate/0_install_fine_print.rb +26 -0
  41. data/db/migrate/0_install_fine_print.rb~ +26 -0
  42. data/lib/fine_print/controller_additions.rb +69 -0
  43. data/lib/fine_print/controller_additions.rb~ +69 -0
  44. data/lib/fine_print/engine.rb +8 -0
  45. data/lib/fine_print/security_transgression.rb +1 -2
  46. data/lib/fine_print/utilities.rb~ +26 -0
  47. data/lib/fine_print/version.rb +1 -1
  48. data/lib/fine_print.rb +89 -42
  49. data/lib/fine_print.rb~ +89 -41
  50. data/lib/tasks/fine_print_tasks.rake +11 -8
  51. data/spec/controllers/contracts_controller_spec.rb +222 -0
  52. data/spec/controllers/contracts_controller_spec.rb~ +224 -0
  53. data/spec/controllers/home_controller_spec.rb +25 -0
  54. data/spec/controllers/home_controller_spec.rb~ +25 -0
  55. data/spec/controllers/signatures_controller_spec.rb +46 -0
  56. data/spec/controllers/signatures_controller_spec.rb~ +46 -0
  57. data/spec/dummy/README.md +1 -1
  58. data/spec/dummy/app/controllers/dummy_models_controller.rb +2 -0
  59. data/spec/dummy/app/controllers/dummy_models_controller.rb~ +29 -0
  60. data/spec/dummy/app/helpers/application_helper.rb +13 -0
  61. data/spec/dummy/app/models/dummy_user.rb +3 -0
  62. data/spec/dummy/app/models/dummy_user.rb~ +4 -0
  63. data/spec/dummy/app/models/user.rb~ +78 -0
  64. data/spec/dummy/config/application.rb +2 -2
  65. data/spec/dummy/config/application.rb~ +60 -0
  66. data/spec/dummy/config/initializers/fine_print.rb +36 -0
  67. data/spec/dummy/config/initializers/fine_print.rb~ +36 -0
  68. data/spec/dummy/config/initializers/session_store.rb +1 -1
  69. data/spec/dummy/config/initializers/session_store.rb~ +8 -0
  70. data/spec/dummy/config/initializers/wrap_parameters.rb +1 -1
  71. data/spec/dummy/config/initializers/wrap_parameters.rb~ +14 -0
  72. data/spec/dummy/config/routes.rb +1 -2
  73. data/spec/dummy/config/routes.rb~ +4 -0
  74. data/spec/dummy/db/development.sqlite3 +0 -0
  75. data/spec/dummy/db/migrate/1_create_dummy_users.rb +9 -0
  76. data/spec/dummy/db/migrate/1_create_dummy_users.rb~ +8 -0
  77. data/spec/dummy/db/schema.rb +20 -12
  78. data/spec/dummy/db/test.sqlite3 +0 -0
  79. data/spec/dummy/log/development.log +1635 -0
  80. data/spec/dummy/log/test.log +46188 -0
  81. data/spec/factories/contract.rb +25 -0
  82. data/spec/factories/contract.rb~ +26 -0
  83. data/spec/factories/dummy_user.rb +4 -0
  84. data/spec/factories/dummy_user.rb~ +6 -0
  85. data/spec/factories/signature.rb +6 -0
  86. data/spec/factories/signature.rb~ +8 -0
  87. data/spec/factories/user.rb~ +6 -0
  88. data/spec/fine_print_spec.rb~ +15 -4
  89. data/spec/lib/fine_print/controller_additions_spec.rb +20 -0
  90. data/spec/lib/fine_print/controller_additions_spec.rb~ +20 -0
  91. data/spec/lib/fine_print_spec.rb +47 -0
  92. data/spec/lib/fine_print_spec.rb~ +47 -0
  93. data/spec/models/contract_spec.rb +79 -0
  94. data/spec/models/contract_spec.rb~ +80 -0
  95. data/spec/models/signature_spec.rb +28 -0
  96. data/spec/models/signature_spec.rb~ +28 -0
  97. data/spec/spec_helper.rb +31 -0
  98. data/spec/spec_helper.rb~ +32 -0
  99. data/spec/test_helper.rb~ +15 -0
  100. metadata +153 -91
  101. data/app/assets/javascripts/fine_print/agreements.js +0 -19
  102. data/app/assets/javascripts/fine_print/agreements.js~ +0 -19
  103. data/app/assets/javascripts/fine_print/application.js~ +0 -5
  104. data/app/assets/javascripts/fine_print/dialog.js +0 -2
  105. data/app/assets/javascripts/fine_print/dialog.js~ +0 -2
  106. data/app/assets/javascripts/fine_print/user_agreements.js +0 -20
  107. data/app/assets/javascripts/fine_print/user_agreements.js~ +0 -20
  108. data/app/assets/stylesheets/fine_print/agreements.css +0 -11
  109. data/app/assets/stylesheets/fine_print/agreements.css~ +0 -11
  110. data/app/assets/stylesheets/fine_print/application.css~ +0 -60
  111. data/app/assets/stylesheets/fine_print/user_agreements.css~ +0 -3
  112. data/app/assets/stylesheets/scaffold.css~ +0 -56
  113. data/app/controllers/fine_print/agreements_controller.rb +0 -114
  114. data/app/controllers/fine_print/agreements_controller.rb~ +0 -113
  115. data/app/controllers/fine_print/user_agreements_controller.rb +0 -63
  116. data/app/controllers/fine_print/user_agreements_controller.rb~ +0 -63
  117. data/app/models/fine_print/agreement.rb +0 -50
  118. data/app/models/fine_print/agreement.rb~ +0 -50
  119. data/app/models/fine_print/user_agreement.rb +0 -19
  120. data/app/models/fine_print/user_agreement.rb~ +0 -21
  121. data/app/views/fine_print/agreements/_agreement.html.erb +0 -77
  122. data/app/views/fine_print/agreements/_agreement.html.erb~ +0 -77
  123. data/app/views/fine_print/agreements/_dialog.html.erb +0 -27
  124. data/app/views/fine_print/agreements/_dialog.html.erb~ +0 -27
  125. data/app/views/fine_print/agreements/_form.html.erb +0 -51
  126. data/app/views/fine_print/agreements/_form.html.erb~ +0 -51
  127. data/app/views/fine_print/agreements/edit.html.erb +0 -8
  128. data/app/views/fine_print/agreements/edit.html.erb~ +0 -8
  129. data/app/views/fine_print/agreements/index.html.erb +0 -32
  130. data/app/views/fine_print/agreements/index.html.erb~ +0 -32
  131. data/app/views/fine_print/agreements/new.html.erb +0 -7
  132. data/app/views/fine_print/agreements/new.html.erb~ +0 -7
  133. data/app/views/fine_print/agreements/new_version.html.erb +0 -7
  134. data/app/views/fine_print/agreements/new_version.html.erb~ +0 -7
  135. data/app/views/fine_print/agreements/show.html.erb +0 -15
  136. data/app/views/fine_print/agreements/show.html.erb~ +0 -14
  137. data/app/views/fine_print/user_agreements/cancel.js.erb +0 -1
  138. data/app/views/fine_print/user_agreements/cancel.js.erb~ +0 -2
  139. data/app/views/fine_print/user_agreements/create.js.erb +0 -2
  140. data/app/views/fine_print/user_agreements/create.js.erb~ +0 -2
  141. data/app/views/fine_print/user_agreements/index.html.erb +0 -25
  142. data/app/views/fine_print/user_agreements/index.html.erb~ +0 -25
  143. data/db/migrate/0_create_fine_print_agreements.rb~ +0 -22
  144. data/db/migrate/0_install.rb +0 -28
  145. data/db/migrate/0_install.rb~ +0 -28
  146. data/lib/fine_print/agreements_helper.rb +0 -13
  147. data/lib/fine_print/agreements_helper.rb~ +0 -11
  148. data/lib/fine_print/fine_print_agreement.rb +0 -26
  149. data/lib/fine_print/fine_print_agreement.rb~ +0 -26
  150. data/lib/fine_print/require_agreement.rb~ +0 -22
  151. data/lib/fine_print/security_transgression.rb~ +0 -3
  152. data/lib/fine_print/version.rb~ +0 -3
  153. data/lib/tasks/fine_print_tasks.rake~ +0 -42
  154. data/spec/dummy/README.md~ +0 -3
  155. data/spec/fine_print_spec.rb +0 -7
  156. data/spec/minitest_helper.rb +0 -12
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d381ead09489e5ca6b883c0ce22c68f7c9b9a623
4
+ data.tar.gz: 05d8ababdd00605954298ffdb15c0f89dfe9268b
5
+ SHA512:
6
+ metadata.gz: 01d698b01cc332ba64c925ee1d1a1e9fd0502a398f95a9c654b5b00199e4f0e7eda1ea96623484779defda49541b341801e5d6d0c0dd9490adb0ba869b22512c
7
+ data.tar.gz: 4aeb8f6fb1b4971033c9ab4c21676d22ffdf60651a4423e63e85286bc3dc606faced415717dd6f4aa8dfe448532f2000b72a59fb09d089ffbd6da16e3b3829f3
data/README.md CHANGED
@@ -1,6 +1,12 @@
1
1
  # FinePrint
2
2
 
3
- FinePrint is a Rails gem that makes managing web site agreements (terms, privacy policy, etc) simple and easy.
3
+ FinePrint is a Rails gem (engine) that makes managing web site agreements (terms, privacy policy, etc) simple and easy.
4
+
5
+ As the meaning of 'agreement' can be somewhat ambiguous (meaning either the thing someone agrees to or the record of the agreement between that thing and the user), we call a set of terms a 'contract' and a user's agreement to that contract a 'signature'.
6
+
7
+ A version history of all contracts is maintained. Once a particular version of a contract is published, it becomes available for users to sign. Once a version has been signed, it cannot be changed (to effect a change, a new version must be created and published). When a new version of a contract is created and published, users visiting pages requiring signature of that contract will be redirected to a page you specify where they can sign the new contract.
8
+
9
+ FinePrint provides views for admins to manage contracts and signatures, but does not provide views for the application to display contracts to end users, as that functionality is specific to each particular application. FinePrint does provide convenience methods for finding unsigned contracts and for recording when a user signs a contract.
4
10
 
5
11
  ## Installation
6
12
 
@@ -40,78 +46,97 @@ Also add FinePrint to your application's routes:
40
46
  mount FinePrint::Engine => "/fine_print"
41
47
  ```
42
48
 
43
- And provide a link on your site for administrators to access the fine_print engine to manage agreements.
49
+ And provide a link on your site for administrators to access the FinePrint engine to manage contracts.
44
50
 
45
51
  ```erb
46
52
  <%= link_to 'FinePrint', fine_print_path %>
47
53
  ```
48
54
 
49
- Finally, make sure your `application.js` requires jquery and jquery_ujs (it usually does by default):
50
-
51
- ```js
52
- //= require jquery
53
- //= require jquery_ujs
54
- ```
55
-
56
- **Note:** FinePrint will **automatically** add the fine_print/dialog.js file to your asset precompilation list.
57
-
58
55
  ## Configuration
59
56
 
60
57
  After installation, the initializer for FinePrint will be located under `config/initializers/fine_print.rb`.
61
58
  Make sure to configure it to suit your needs.
62
- Pay particular attention to `user_admin_proc`, as you will be unable to manage your agreements unless you set up this proc to return true for your admins.
63
-
64
- If you want to use FinePrint's modal dialogs, then make sure `application.js` also requires jquery-ui:
65
-
66
- ```js
67
- //= require jquery-ui
68
- ```
59
+ Pay particular attention to `user_admin_proc`, as you will be unable to manage your contracts unless you set up this proc to return true for your admins.
69
60
 
70
61
  ## Usage
71
62
 
72
- FinePrint adds a new method to all controllers that behaves like a before_filter.
73
- It can be accessed by calling `fine_print_agreement` from any controller.
74
- This method takes an agreement name and an options hash.
75
- Accepted options are (see initializer for more explanation):
63
+ FinePrint adds 3 controller methods to all of your controllers:
64
+
65
+ `fine_print_get_signatures`, `fine_print_skip_signatures` and `fine_print_return`
76
66
 
77
- - `only` and `except` just like a before_filter
67
+ Additionally, the FinePrint module contains several methods that help you find contracts and mark them as signed.
78
68
 
79
- - `agreement_notice` notice to be shown to the user above the agreement
69
+ To require that your users sign the most recent version of a contract, call
70
+ `fine_print_get_signatures` in your controllers, just as you would a
71
+ `before_filter` (in fact, this method works by adding a `before_filter` for you).
80
72
 
81
- - `accept_path` path to redirect users to when an agreement is accepted and no referer information is available
82
- - `cancel_path` path to redirect users to when an agreement is not accepted and no referer information is available
83
- - `use_referers` false if you want users to always be redirected to the above paths
73
+ This method takes a list of contract names (given either as strings or as
74
+ symbols), along with an options hash.
84
75
 
85
- - `use_modal_dialogs` true if you want to use FinePrint's modal dialogs
76
+ The options hash can include any options you could pass to a `before_filter`, e.g. `only` and `except`,
77
+ plus the FinePrint-specific option `pose_contracts_path`, which can override the value specified
78
+ in the FinePrint initializer.
86
79
 
87
80
  Example:
88
81
 
89
82
  ```rb
90
- fine_print_agreement 'terms of use', :except => :index, :use_modal_dialogs => true
83
+ class MyController < ApplicationController
84
+ fine_print_get_signatures :terms_of_use, :privacy_policy,
85
+ :except => :index
91
86
  ```
92
87
 
93
- This gem also adds the `fine_print_dialog` helper method, which needs to be called (usually from your layout) if you want to use FinePrint's modal dialogs.
94
- This method only takes an options hash. Accepted options are:
88
+ You should only try to get signatures when you have a user who is logged in
89
+ (FinePrint will raise an exception if you try to get a non-logged in user to sign
90
+ an agreement, as that does not make any sense). This normally means that before
91
+ the call to `fine_print_get_signatures` you should call whatever `before_filter`
92
+ gets a user to login.
95
93
 
96
- - `width`
97
- - `height`
94
+ Just like how rails provides a `skip_before_filter` method to offset `before_filter` calls,
95
+ FinePrint provides a `fine_print_skip_signatures` method. This method takes the same
96
+ arguments as before_filter, and can be called either before or after `fine_print_get_signatures`.
98
97
 
99
- Example:
98
+ One way you may want to use these methods is to require signatures in every controller
99
+ by default, and then to skip them in certain situations, e.g.:
100
100
 
101
- ```erb
102
- <%= fine_print_dialog, :width => 800, :height => 600 %>
101
+ ```rb
102
+ class ApplicationController < ActionController::Base
103
+ fine_print_get_signatures :terms_of_use
104
+ ```
105
+
106
+ ```rb
107
+ class NoSigsRequiredController < ApplicationController
108
+ fine_print_skip_signatures :terms_of_use
103
109
  ```
104
110
 
105
- ## Managing Agreements
111
+ When a set of contracts is found by FinePrint to be required but unsigned, FinePrint redirects
112
+ the user to the path specified by the `pose_contracts_path` configuration variable, with
113
+ the names of the unsigned contracts passed along in a `terms` array in the URL parameters.
106
114
 
107
- Here are some important notes about managing your agreements with FinePrint:
115
+ Your job as the site developer is to present the terms to the user and ask them to sign them.
116
+ This normally involves the user clicking an "I have read the above terms" checkbox which enables an "I Agree" button.
117
+ When the "Agree" button is clicked (and you should verify that the checkbox is actually clicked in the params passed to the server), you need to send the information off to a controller
118
+ method that can call `FinePrint.sign_contract` which takes a user and a contract name, ID, or
119
+ object. On success, this controller method can send the user back to where they were trying to
120
+ go by calling the `fine_print_return` controller method (only works for GET requests).
108
121
 
109
- - Agreements are referred to on your controller by the name you specified
110
- - Creating another agreement with the same name will make it a new version of a previous agreement
111
- - Agreements need to be marked as `ready` to be able to be accepted by users
112
- - The latest version of each agreement that is marked as `ready` will always be used
113
- - Agreements cannot be modified after at least one user has accepted them, but you can always create new versions
114
- - When a new version is present, users will be asked to accept it the next time they visit a controller action that calls `fine_print_agreement`
122
+ If there are multiple unsigned contracts, you are not required to get the user to sign
123
+ them all in one page. One strategy is to present only the first unsigned contract to them
124
+ for signature. Once they sign it, they'll be redirected to where they were trying to
125
+ go and FinePrint will see again that they still have remaining unsigned contracts, and
126
+ FinePrint will direct them back to your `pose_contracts_path` with one fewer contract
127
+ name passed in.
128
+
129
+ ## Managing Contracts
130
+
131
+ Here are some important notes about managing your contracts with FinePrint:
132
+
133
+ - Contracts have a name and a title; the former is used by your code, the latter
134
+ is intended for display to end users.
135
+ - Creating another contract with the same name as an existing contract will make it a new version of that existing contract.
136
+ - Contracts need to be explicitly published to be available to users to sign (this can be done on the contracts admin page).
137
+ - The latest published version is what users will see.
138
+ - A contract cannot be modified after at least one user has signed it, but you can always create a new version.
139
+ - When a published contract version is available but has not been signed, users will be asked to accept it the next time they visit a controller action that calls `fine_print_get_signatures` for that contract's name.
115
140
 
116
141
  ## Customization
117
142
 
@@ -123,7 +148,7 @@ Run the following command to copy a part of FinePrint into your main application
123
148
  $ rake fine_print:copy:folder
124
149
  ```
125
150
 
126
- Where folder is one of `stylesheets`, `javascripts`, `layouts`, `views` or `controllers`.
151
+ Where folder is one of `stylesheets`, `layouts`, `views` or `controllers`.
127
152
 
128
153
  Example:
129
154
 
@@ -137,6 +162,10 @@ Alternatively, you can run the following command to copy all of the above into y
137
162
  $ rake fine_print:copy
138
163
  ```
139
164
 
165
+ ## Testing
166
+
167
+ From the gem's main folder, run `bundle install`, `bundle exec rake db:migrate` and then `bundle exec rake` to run all the specs.
168
+
140
169
  ## Contributing
141
170
 
142
171
  1. Fork it
data/Rakefile CHANGED
@@ -1,23 +1,23 @@
1
1
  #!/usr/bin/env rake
2
+ # http://viget.com/extend/rails-engine-testing-with-rspec-capybara-and-factorygirl
2
3
  begin
3
4
  require 'bundler/setup'
4
5
  rescue LoadError
5
6
  puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
7
  end
7
8
 
8
- APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
9
+ APP_RAKEFILE = File.expand_path('../spec/dummy/Rakefile', __FILE__)
9
10
  load 'rails/tasks/engine.rake'
10
11
 
11
12
  Bundler::GemHelper.install_tasks
12
13
 
13
- require 'rake/testtask'
14
+ Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
14
15
 
15
- Rake::TestTask.new(:test => 'app:db:test:prepare') do |t|
16
- t.libs << 'lib'
17
- t.libs << 'spec'
18
- t.pattern = 'spec/**/*_spec.rb'
19
- t.verbose = false
20
- end
16
+ require 'rspec/core'
17
+ require 'rspec/core/rake_task'
18
+
19
+ desc 'Run all specs in spec directory (excluding plugin specs)'
20
+ RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
21
21
 
22
- task :default => :test
22
+ task :default => :spec
23
23
 
@@ -0,0 +1,16 @@
1
+ // This is a manifest file that'll be compiled into including all the files listed below.
2
+ // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
3
+ // be included in the compiled file accessible from http://example.com/assets/application.js
4
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
5
+ // the compiled file.
6
+ //
7
+ //= require jquery
8
+ //= require jquery_ujs
9
+ //= require jquery-ui
10
+ //= require columnizer
11
+ //= require jaccordion
12
+ //= require autocomplete-rails
13
+ //= require jcrop
14
+ //= require colorbox
15
+ //= require_tree .
16
+
@@ -1,4 +1,10 @@
1
+ // This is a manifest file that'll be compiled into including all the files listed below.
2
+ // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
3
+ // be included in the compiled file accessible from http://example.com/assets/application.js
4
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
5
+ // the compiled file.
6
+ //
1
7
  //= require jquery
2
8
  //= require jquery_ujs
3
- //= require fine_print/agreements
4
- //= require fine_print/user_agreements
9
+ //= require_tree .
10
+
@@ -1,13 +1,15 @@
1
1
  module FinePrint
2
2
  class ApplicationController < ActionController::Base
3
- before_filter :get_user
4
-
5
- rescue_from SecurityTransgression, :with => lambda { redirect_to FinePrint.redirect_path }
6
-
3
+ before_filter :verify_admin
4
+
5
+ rescue_from FinePrint::SecurityTransgression,
6
+ :with => lambda { redirect_to FinePrint.redirect_path }
7
+
7
8
  protected
8
-
9
- def get_user
10
- @user = self.send FinePrint.current_user_method
9
+
10
+ def verify_admin
11
+ user = send FinePrint.current_user_method
12
+ FinePrint.raise_unless_admin(user)
11
13
  end
12
14
  end
13
15
  end
@@ -1,13 +1,15 @@
1
1
  module FinePrint
2
2
  class ApplicationController < ActionController::Base
3
- before_filter :get_user
4
- helper MyEngine::Engine.helpers
5
- rescue_from SecurityTransgression, :with => lambda { redirect_to FinePrint.redirect_path }
6
-
3
+ before_filter :verify_admin!
4
+
5
+ rescue_from FinePrint::SecurityTransgression,
6
+ :with => lambda { redirect_to FinePrint.redirect_path }
7
+
7
8
  protected
8
-
9
- def get_user
10
- @user = self.send FinePrint.current_user_method
9
+
10
+ def verify_admin!
11
+ user = send FinePrint.current_user_method
12
+ FinePrint.raise_unless_admin!(user)
11
13
  end
12
14
  end
13
15
  end
@@ -0,0 +1,79 @@
1
+ module FinePrint
2
+ class ContractsController < FinePrint::ApplicationController
3
+ include FinePrint::ApplicationHelper
4
+ before_filter :get_contract, :except => [:index, :new, :create]
5
+
6
+ def index
7
+ @contracts = Contract.all
8
+ end
9
+
10
+ def show
11
+ end
12
+
13
+ def new
14
+ @contract = Contract.new
15
+ end
16
+
17
+ def edit
18
+ end
19
+
20
+ def create
21
+ @contract = Contract.new
22
+ @contract.name = params[:contract][:name]
23
+ @contract.title = params[:contract][:title]
24
+ @contract.content = params[:contract][:content]
25
+
26
+ if @contract.save
27
+ redirect_to @contract, :notice => 'Contract was successfully created.'
28
+ else
29
+ render :action => 'new'
30
+ end
31
+ end
32
+
33
+ def update
34
+ @contract.name = params[:contract][:name]
35
+ @contract.title = params[:contract][:title]
36
+ @contract.content = params[:contract][:content]
37
+
38
+ if @contract.save
39
+ redirect_to @contract, :notice => 'Contract was successfully updated.'
40
+ else
41
+ render :action => 'edit'
42
+ end
43
+ end
44
+
45
+ def destroy
46
+ if @contract.destroy
47
+ redirect_to contracts_path, :notice => 'Contract was successfully deleted.'
48
+ else
49
+ redirect_to contracts_path, :alert => merge_errors_for(@contract)
50
+ end
51
+ end
52
+
53
+ def publish
54
+ if @contract.publish
55
+ redirect_to contracts_path, :notice => 'Contract was successfully published.'
56
+ else
57
+ redirect_to contracts_path, :alert => merge_errors_for(@contract)
58
+ end
59
+ end
60
+
61
+ def unpublish
62
+ if @contract.unpublish
63
+ redirect_to contracts_path, :notice => 'Contract was successfully unpublished.'
64
+ else
65
+ redirect_to contracts_path, :alert => merge_errors_for(@contract)
66
+ end
67
+ end
68
+
69
+ def new_version
70
+ @contract = @contract.draft_copy
71
+ end
72
+
73
+ protected
74
+
75
+ def get_contract
76
+ @contract = Contract.find(params[:id])
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,79 @@
1
+ module FinePrint
2
+ class ContractsController < FinePrint::ApplicationController
3
+ include FinePrint::ApplicationHelper
4
+ before_filter :get_contract, :except => [:index, :new, :create]
5
+
6
+ def index
7
+ @contracts = Contract.all
8
+ end
9
+
10
+ def show
11
+ end
12
+
13
+ def new
14
+ @contract = Contract.new
15
+ end
16
+
17
+ def edit
18
+ end
19
+
20
+ def create
21
+ @contract = Contract.new
22
+ @contract.name = params[:contract][:name]
23
+ @contract.title = params[:contract][:title]
24
+ @contract.content = params[:contract][:content]
25
+
26
+ if @contract.save
27
+ redirect_to @contract, :notice => 'Contract was successfully created.'
28
+ else
29
+ render :action => 'new'
30
+ end
31
+ end
32
+
33
+ def update
34
+ @contract.name = params[:contract][:name]
35
+ @contract.title = params[:contract][:title]
36
+ @contract.content = params[:contract][:content]
37
+
38
+ if @contract.save
39
+ redirect_to @contract, :notice => 'Contract was successfully updated.'
40
+ else
41
+ render :action => 'edit'
42
+ end
43
+ end
44
+
45
+ def destroy
46
+ if @contract.destroy
47
+ redirect_to contracts_path, :notice => 'Contract was successfully deleted.'
48
+ else
49
+ redirect_to contracts_path, :alert => merge_errors_for(@contract)
50
+ end
51
+ end
52
+
53
+ def publish
54
+ if @contract.publish
55
+ redirect_to contracts_path, :notice => 'Contract was successfully published.'
56
+ else
57
+ redirect_to contracts_path, :alert => merge_errors_for(@contract)
58
+ end
59
+ end
60
+
61
+ def unpublish
62
+ if @contract.unpublish
63
+ redirect_to contracts_path, :notice => 'Contract was successfully unpublished.'
64
+ else
65
+ redirect_to contracts_path, :alert => merge_errors_for(@contract)
66
+ end
67
+ end
68
+
69
+ def new_version
70
+ @contract = @contract.draft_copy
71
+ end
72
+
73
+ protected
74
+
75
+ def get_contract
76
+ @contract = Contract.find(params[:id])
77
+ end
78
+ end
79
+ end
@@ -1,14 +1,4 @@
1
- require_dependency "fine_print/application_controller"
2
-
3
1
  module FinePrint
4
- class HomeController < ApplicationController
5
- # GET /fine_print
6
- def index
7
- raise SecurityTransgression unless Agreement.can_be_listed_by?(@user) && UserAgreement.can_be_listed_by?(@user)
8
-
9
- respond_to do |format|
10
- format.html # index.html.erb
11
- end
12
- end
2
+ class HomeController < FinePrint::ApplicationController
13
3
  end
14
4
  end
@@ -1,15 +1,6 @@
1
- require_dependency "fine_print/application_controller"
1
+ require_dependency 'fine_print/application_controller'
2
2
 
3
3
  module FinePrint
4
- class HomeController < ApplicationController
5
- # GET /fine_print
6
- def index
7
- raise SecurityTransgression unless Agreement.can_be_listed_by?(@user) && UserAgreement.can_be_listed_by?(@user)
8
-
9
- respond_to do |format|
10
- format.html # index.html.erb
11
- format.json { render json: @agreements }
12
- end
13
- end
4
+ class HomeController < FinePrint::ApplicationController
14
5
  end
15
6
  end
@@ -0,0 +1,14 @@
1
+ module FinePrint
2
+ class SignaturesController < FinePrint::ApplicationController
3
+ def index
4
+ @signatures = Signature.all
5
+ end
6
+
7
+ def destroy
8
+ @signature = Signature.find(params[:id])
9
+
10
+ @signature.destroy
11
+ redirect_to signatures_path
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module FinePrint
2
+ class SignaturesController < FinePrint::ApplicationController
3
+ def index
4
+ @signatures = Signature.all
5
+ end
6
+
7
+ def destroy
8
+ @signature = Signature.find(params[:id])
9
+
10
+ @signature.destroy
11
+ redirect_to signatures_url
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,7 @@
1
+ module FinePrint
2
+ module ApplicationHelper
3
+ def merge_errors_for(obj)
4
+ "#{obj.errors.collect{|f,e| "#{e}"}.join('. ')}."
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module FinePrint
2
+ module ApplicationHelper
3
+ def merge_errors_for(contract)
4
+ contract.errors.collect{|f,e| "#{contract.name} #{e}"}.join(', ')
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module FinePrint
2
+ module ContractsHelper
3
+ def merge_errors_for(obj)
4
+ "#{obj.errors.collect{|f,e| "#{e}"}.join('. ')}."
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,96 @@
1
+ module FinePrint
2
+ class Contract < ActiveRecord::Base
3
+ has_many :signatures, :inverse_of => :contract
4
+
5
+ has_many :same_name, :class_name => 'Contract', :primary_key => :name, :foreign_key => :name
6
+
7
+ before_validation :downcase_name
8
+ before_update :no_signatures
9
+ before_destroy :no_signatures
10
+
11
+ validates_presence_of :name, :title, :content
12
+ validates_format_of :name, :with => /\A\w+\z/
13
+ validates_uniqueness_of :version, :scope => :name, :case_sensitive => false
14
+
15
+ default_scope order(:name, 'version DESC')
16
+
17
+ scope :published, where(arel_table[:version].not_eq(nil))
18
+ scope :latest, published
19
+ .joins(:same_name)
20
+ .group(:id)
21
+ .having(:version => arel_table.alias(:same_names_fine_print_contracts)[:version]
22
+ .maximum.tap{|mvq| mvq.alias = nil})
23
+
24
+ def is_published?
25
+ !version.nil?
26
+ end
27
+
28
+ def is_latest?
29
+ is_published? && version == same_name.maximum(:version)
30
+ end
31
+
32
+ def sign(user)
33
+ FinePrint.sign_contract(self, user)
34
+ end
35
+
36
+ def signed_by?(user)
37
+ FinePrint.signed_contract?(self, user)
38
+ end
39
+
40
+ def publish
41
+ no_signatures
42
+ errors.add(:base, 'Contract is already published') if is_published?
43
+ return false unless errors.empty?
44
+
45
+ self.version = (same_name.published.first.try(:version) || 0) + 1
46
+ save
47
+ end
48
+
49
+ def unpublish
50
+ no_signatures
51
+ errors.add(:base, 'Contract is not the latest published version') unless is_latest?
52
+ return false unless errors.empty?
53
+
54
+ self.version = nil
55
+ save
56
+ end
57
+
58
+ def draft_copy
59
+ Contract.where(:name => name, :version => nil).first || dup.tap{|contract| contract.version = nil}
60
+ end
61
+
62
+ ##################
63
+ # Access Control #
64
+ ##################
65
+
66
+ def can_be_updated?
67
+ signatures.empty?
68
+ end
69
+
70
+ def can_be_published?
71
+ signatures.empty? && !is_published?
72
+ end
73
+
74
+ def can_be_unpublished?
75
+ signatures.empty? && is_latest?
76
+ end
77
+
78
+ alias_method :can_be_destroyed?, :can_be_updated?
79
+
80
+ ##############
81
+ # Validation #
82
+ ##############
83
+
84
+ def no_signatures
85
+ return if signatures.empty?
86
+ errors.add(:base, 'Contract cannot be modified because users have signed it')
87
+ false
88
+ end
89
+
90
+ protected
91
+
92
+ def downcase_name
93
+ self.name = name.downcase
94
+ end
95
+ end
96
+ end