fine_print 1.3.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +56 -44
  3. data/app/controllers/fine_print/application_controller.rb +0 -3
  4. data/app/models/fine_print/contract.rb +9 -8
  5. data/app/models/fine_print/signature.rb +1 -1
  6. data/config/initializers/fine_print.rb +20 -16
  7. data/db/migrate/0_install_fine_print.rb +4 -3
  8. data/lib/fine_print/controller_includes.rb +114 -0
  9. data/lib/fine_print/version.rb +1 -1
  10. data/lib/fine_print.rb +20 -24
  11. data/spec/controllers/contracts_controller_spec.rb +38 -36
  12. data/spec/controllers/home_controller_spec.rb +4 -4
  13. data/spec/controllers/signatures_controller_spec.rb +8 -8
  14. data/spec/dummy/Rakefile +0 -1
  15. data/spec/dummy/app/assets/javascripts/application.js +3 -5
  16. data/spec/dummy/app/views/layouts/application.html.erb +2 -2
  17. data/spec/dummy/bin/bundle +3 -0
  18. data/spec/dummy/bin/rails +4 -0
  19. data/spec/dummy/bin/rake +4 -0
  20. data/spec/dummy/config/application.rb +3 -37
  21. data/spec/dummy/config/boot.rb +4 -9
  22. data/spec/dummy/config/environment.rb +2 -2
  23. data/spec/dummy/config/environments/development.rb +11 -19
  24. data/spec/dummy/config/environments/production.rb +40 -27
  25. data/spec/dummy/config/environments/test.rb +13 -14
  26. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  27. data/spec/dummy/config/initializers/fine_print.rb +1 -34
  28. data/spec/dummy/config/initializers/inflections.rb +6 -5
  29. data/spec/dummy/config/initializers/secret_token.rb +7 -2
  30. data/spec/dummy/config/initializers/session_store.rb +1 -6
  31. data/spec/dummy/config/initializers/wrap_parameters.rb +6 -6
  32. data/spec/dummy/config/locales/en.yml +20 -2
  33. data/spec/dummy/config/routes.rb +2 -1
  34. data/spec/dummy/config.ru +1 -1
  35. data/spec/dummy/db/development.sqlite3 +0 -0
  36. data/spec/dummy/db/schema.rb +21 -21
  37. data/spec/dummy/db/test.sqlite3 +0 -0
  38. data/spec/dummy/log/development.log +15 -1849
  39. data/spec/dummy/log/test.log +10536 -53785
  40. data/spec/dummy/public/404.html +43 -11
  41. data/spec/dummy/public/422.html +43 -11
  42. data/spec/dummy/public/500.html +43 -11
  43. data/spec/factories/contract.rb +2 -2
  44. data/spec/lib/fine_print/{controller_additions_spec.rb → controller_includes_spec.rb} +16 -6
  45. metadata +104 -166
  46. data/app/assets/javascripts/application.js~ +0 -16
  47. data/app/controllers/fine_print/application_controller.rb~ +0 -15
  48. data/app/controllers/fine_print/contracts_controller.rb~ +0 -79
  49. data/app/controllers/fine_print/home_controller.rb~ +0 -6
  50. data/app/controllers/fine_print/signatures_controller.rb~ +0 -14
  51. data/app/helpers/fine_print/application_helper.rb~ +0 -7
  52. data/app/helpers/fine_print/contracts_helper.rb~ +0 -7
  53. data/app/models/fine_print/contract.rb~ +0 -100
  54. data/app/models/fine_print/signature.rb~ +0 -25
  55. data/app/views/fine_print/contracts/_form.html.erb~ +0 -35
  56. data/app/views/fine_print/contracts/index.html.erb~ +0 -43
  57. data/app/views/fine_print/contracts/show.html.erb~ +0 -35
  58. data/app/views/fine_print/home/index.html.erb~ +0 -15
  59. data/app/views/fine_print/signatures/index.html.erb~ +0 -32
  60. data/app/views/layouts/fine_print/application.html.erb~ +0 -20
  61. data/config/initializers/fine_print.rb~ +0 -36
  62. data/config/routes.rb~ +0 -12
  63. data/db/migrate/0_install_fine_print.rb~ +0 -26
  64. data/lib/fine_print/controller_additions.rb +0 -80
  65. data/lib/fine_print/controller_additions.rb~ +0 -86
  66. data/lib/fine_print/utilities.rb~ +0 -26
  67. data/lib/fine_print/version.rb~ +0 -3
  68. data/lib/fine_print.rb~ +0 -120
  69. data/spec/controllers/contracts_controller_spec.rb~ +0 -224
  70. data/spec/controllers/home_controller_spec.rb~ +0 -25
  71. data/spec/controllers/signatures_controller_spec.rb~ +0 -46
  72. data/spec/dummy/app/controllers/dummy_models_controller.rb~ +0 -29
  73. data/spec/dummy/app/models/dummy_user.rb~ +0 -4
  74. data/spec/dummy/app/models/user.rb~ +0 -78
  75. data/spec/dummy/config/application.rb~ +0 -60
  76. data/spec/dummy/config/initializers/fine_print.rb~ +0 -36
  77. data/spec/dummy/config/initializers/session_store.rb~ +0 -8
  78. data/spec/dummy/config/initializers/wrap_parameters.rb~ +0 -14
  79. data/spec/dummy/config/routes.rb~ +0 -4
  80. data/spec/dummy/db/migrate/1_create_dummy_users.rb~ +0 -8
  81. data/spec/dummy/script/rails +0 -6
  82. data/spec/factories/contract.rb~ +0 -26
  83. data/spec/factories/dummy_user.rb~ +0 -6
  84. data/spec/factories/signature.rb~ +0 -8
  85. data/spec/factories/user.rb~ +0 -6
  86. data/spec/fine_print_spec.rb~ +0 -18
  87. data/spec/lib/fine_print/controller_additions_spec.rb~ +0 -20
  88. data/spec/lib/fine_print_spec.rb~ +0 -47
  89. data/spec/models/contract_spec.rb~ +0 -80
  90. data/spec/models/signature_spec.rb~ +0 -28
  91. data/spec/spec_helper.rb~ +0 -32
  92. data/spec/test_helper.rb~ +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1b2e32a76793d71e6cf6ac6971ba125269c52658
4
- data.tar.gz: a95a87faf71c9aefb4bc80d7a7516dfc47c18c49
3
+ metadata.gz: 5ae19efef1a93bef86de360020973d0c72e58e74
4
+ data.tar.gz: fd9d302b91cebd30ad20e4aaac6530c0d9d29e95
5
5
  SHA512:
6
- metadata.gz: 4362c6e678e9ce7eeeebf1f5553e6267b1c7a3a6285ac4663966763a58bca44ec0652b06af57c271c4ac81f654c6fa469e15d220c5780da92f133fb8df422cbe
7
- data.tar.gz: b11890e37902d3e00c403ed3b4a6459cb76ff8827f54a99634e7086180124ab3db85d3f66176bc43f4f9f7fe96149bd8370d76f33db75955b274f2032670ea75
6
+ metadata.gz: eb8a60a9956d17a72e7b8b59725d6ca269a7103ddd1219ad9318b68662b34ec4384ee3529294aae6d1706835e4ade31e5f53a97dfe6fd30434d2bdff95ad4661
7
+ data.tar.gz: 212e0c1badbd251eba90272f370ef6e77d96755ade8e067ef3c2cd780c618f2b53b064e5ea0b354e0ceb3d0eb6666bef6bbb0557dddd1a2bbd583c56fa2977dd
data/README.md CHANGED
@@ -46,7 +46,7 @@ Also add FinePrint to your application's routes:
46
46
  mount FinePrint::Engine => "/fine_print"
47
47
  ```
48
48
 
49
- And provide a link on your site for administrators to access the FinePrint engine to manage contracts.
49
+ And provide a link on your site for administrators to access the FinePrint engine to manage your contracts.
50
50
 
51
51
  ```erb
52
52
  <%= link_to 'FinePrint', fine_print_path %>
@@ -56,37 +56,28 @@ And provide a link on your site for administrators to access the FinePrint engin
56
56
 
57
57
  After installation, the initializer for FinePrint will be located under `config/initializers/fine_print.rb`.
58
58
  Make sure to configure it to suit your needs.
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.
59
+ Pay particular attention to `user_admin_proc`, as you will be unable to manage your contracts unless you setup this proc to return true for your admins.
60
60
 
61
61
  ## Usage
62
62
 
63
- The FinePrint module contains several methods that help you find contracts and mark them as signed:
63
+ You can choose to check if users signed contracts either as a before_filter or inside your controller actions.
64
64
 
65
- `get_contract(contract_object_or_id_or_name)`
66
- `sign_contract(user, contract_object_or_id_or_name)`
67
- `signed_contract?(user, contract_object_or_id_or_name)`
68
- `signed_any_contract_version?(user, contract_object_or_id_or_name)`
69
- `get_unsigned_contract_names(user, contract_names...)`
65
+ ### Option 1 - As a before_filter
70
66
 
71
- Additionally, FinePrint adds 2 class methods to all of your controllers:
67
+ If you choose to have FinePrint work like a before_filter, you can user the following 2 class methods, which are automatically added to all of your controllers:
72
68
 
73
- `fine_print_get_signatures(contract_names..., options_hash)`
74
- `fine_print_skip_signatures(contract_names..., options_hash)`
75
-
76
- And 1 instance method, also to all of your controllers:
77
-
78
- `fine_print_return`
69
+ ```rb
70
+ fine_print_get_signatures(contract_names..., options_hash)
71
+ fine_print_skip_signatures(contract_names..., options_hash)
72
+ ```
79
73
 
80
74
  To require that your users sign the most recent version of a contract, call
81
- `fine_print_get_signatures` in your controllers, just as you would a
82
- `before_filter` (in fact, this method works by adding a `before_filter` for you).
75
+ `fine_print_get_signatures` in your controller classes. It works just like a `before_filter` (in fact, it will add a `before_filter` for you).
83
76
 
84
- This method takes a list of contract names (given either as strings or as
77
+ This method takes a list of contract names to check (given either as strings or as
85
78
  symbols), along with an options hash.
86
79
 
87
- The options hash can include any options you could pass to a `before_filter`, e.g. `only` and `except`,
88
- plus the FinePrint-specific option `pose_contracts_path`, which can override the value specified
89
- in the FinePrint initializer.
80
+ The options hash can include any options you could pass to a `before_filter`, e.g. `only` and `except`, plus the FinePrint-specific options `contracts_path`, which can override the value specified in the FinePrint initializer.
90
81
 
91
82
  Example:
92
83
 
@@ -96,16 +87,11 @@ class MyController < ApplicationController
96
87
  :except => :index
97
88
  ```
98
89
 
99
- You should only try to get signatures when you have a user who is logged in
100
- (FinePrint will allow non-logged in users to pass right through without signing
101
- anything). This normally means that before the call to `fine_print_get_signatures`
102
- you should call whatever `before_filter` gets a user to login.
90
+ You should only try to get signatures when you have a user who is logged in (by default FinePrint will allow non-logged in users to pass right through without signing anything). This normally means that before the call to `fine_print_get_signatures` you should call whatever `before_filter` gets a user to login.
103
91
 
104
- Just like how rails provides a `skip_before_filter` method to offset `before_filter` calls,
105
- FinePrint provides a `fine_print_skip_signatures` method. This method takes the same
106
- arguments as before_filter, and can be called either before or after `fine_print_get_signatures`.
92
+ Just like how rails provides a `skip_before_filter` method to offset `before_filter` calls, FinePrint provides a `fine_print_skip_signatures` method. This method takes the same arguments as before_filter, and can be called either before or after `fine_print_get_signatures`.
107
93
 
108
- One way you may want to use these methods is to require signatures in every controller
94
+ One way you can use these methods is to require signatures in every controller
109
95
  by default, and then to skip them in certain situations, e.g.:
110
96
 
111
97
  ```rb
@@ -118,22 +104,48 @@ class NoSigsRequiredController < ApplicationController
118
104
  fine_print_skip_signatures :terms_of_use
119
105
  ```
120
106
 
121
- When a set of contracts is found by FinePrint to be required but unsigned, FinePrint redirects
122
- the user to the path specified by the `pose_contracts_path` configuration variable, with
123
- the names of the unsigned contracts passed along in a `terms` array in the URL parameters.
107
+ ### Option 2 - Inside your controller actions
108
+
109
+ If instead you have to check for contracts inside controller action methods, you can use the following 2 instance methods, also automatically added to all of your controllers:
110
+
111
+ ```rb
112
+ fine_print_get_unsigned_contract_names(contract_names)
113
+ fine_print_redirect(unsigned_contract_names)
114
+ ```
115
+
116
+ This can be done in one line, like so:
117
+
118
+ ```rb
119
+ fine_print_redirect(fine_print_get_unsigned_contract_names(contract_names))
120
+ ```
121
+
122
+ The `fine_print_get_unsigned_contract_names` method can return nil if no contracts are provided or if the user cannot sign contracts; otherwise, it returns an array of the contract names the user has not yet signed.
123
+
124
+ Keep in mind that `fine_print_redirect` might cause a redirect, so if your controller action also needs to redirect, you should check the output of `fine_print_get_unsigned_contract_names`. This method will not redirect the user if either the array of contract names to sign is blank or if the user_can_sign_proc returns false when called with the user as an argument.
125
+
126
+ ### Displaying and signing contracts
127
+
128
+ When a set of contracts is found by FinePrint to be required but unsigned, and the user is allowed to sign contracts, FinePrint redirects the user to the path specified by the `contract_redirect_path` configuration variable, with the names of the unsigned contracts passed along in the params hash. The param key for the unsigned contract names array is determined by the `contract_param_name` configuration variable (default is :contracts).
129
+
130
+ Your job as the site developer is to present the terms to the user and ask them to sign them. This normally involves the user clicking an "I have read the above terms" checkbox which enables an "I Agree" button. 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 method that will mark the contract as signed using the `FinePrint.sign_contract` method. The following methods in the FinePrint module can be used to help you find contract objects and mark them as signed:
131
+
132
+ ```rb
133
+ FinePrint.get_contract(contract_object_or_id_or_name)
134
+ FinePrint.sign_contract(user, contract_object_or_id_or_name)
135
+ FinePrint.signed_contract?(user, contract_object_or_id_or_name)
136
+ FinePrint.signed_any_contract_version?(user, contract_object_or_id_or_name)
137
+ FinePrint.get_unsigned_contract_names(user, contract_names...)
138
+ ```
139
+
140
+ If you require more explanation about these methods and their arguments, check the `lib/fine_print.rb` file.
141
+
142
+ ### Redirecting users back
124
143
 
125
- Your job as the site developer is to present the terms to the user and ask them to sign them.
126
- This normally involves the user clicking an "I have read the above terms" checkbox which enables an "I Agree" button.
127
- When the "Agree" button is clicked (and you should verify that the checkbox is actually clicked in the params passed to the server),
128
- you need to send the information off to a controller method that can call `FinePrint.sign_contract` which takes
129
- a user and a contract name, ID, or object. On success, this controller method can send the user back to where
130
- they were trying to go by calling the `fine_print_return` controller method (only works for GET requests).
144
+ Regardless if you use `fine_print_get_signatures` or `fine_print_redirect`, after your contract is signed you can use the `fine_print_return` controller instance method to send the user back to the place where they came from.
131
145
 
132
146
  If there are multiple unsigned contracts, you are not required to get the user to sign
133
- them all in one page. One strategy is to present only the first unsigned contract to them
134
- for signature. Once they sign it, they'll be redirected to where they were trying to
135
- go and FinePrint will see again that they still have remaining unsigned contracts, and
136
- FinePrint will direct them back to your `pose_contracts_path` with one fewer contract
147
+ them all at once. One strategy is to present only the first unsigned contract to them. Once they sign it, they'll be redirected to where they were trying to
148
+ go and FinePrint will once again determine that they still have remaining unsigned contracts, and redirect them back to your `contract_redirect_path` with one less contract
137
149
  name passed in.
138
150
 
139
151
  ## Managing Contracts
@@ -141,12 +153,12 @@ name passed in.
141
153
  Here are some important notes about managing your contracts with FinePrint:
142
154
 
143
155
  - Contracts have a name and a title; the former is used by your code, the latter
144
- is intended for display to end users.
156
+ is intended for display to end users and even site admins.
145
157
  - Creating another contract with the same name as an existing contract will make it a new version of that existing contract.
146
158
  - Contracts need to be explicitly published to be available to users to sign (this can be done on the contracts admin page).
147
159
  - The latest published version is what users will see.
148
160
  - A contract cannot be modified after at least one user has signed it, but you can always create a new version.
149
- - 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.
161
+ - 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 either `fine_print_get_signatures` or the controller fine_print instance methods with that contract's name.
150
162
 
151
163
  ## Customization
152
164
 
@@ -2,9 +2,6 @@ module FinePrint
2
2
  class ApplicationController < ActionController::Base
3
3
  before_filter :verify_admin
4
4
 
5
- rescue_from FinePrint::SecurityTransgression,
6
- :with => lambda { redirect_to FinePrint.redirect_path }
7
-
8
5
  protected
9
6
 
10
7
  def verify_admin
@@ -12,14 +12,15 @@ module FinePrint
12
12
  validates_format_of :name, :with => /\A\w+\z/
13
13
  validates_uniqueness_of :version, :scope => :name, :case_sensitive => false
14
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})
15
+ default_scope { order(:name, 'version DESC') }
16
+
17
+ scope :published, lambda { where(arel_table[:version].not_eq(nil)) }
18
+ scope :latest, lambda {
19
+ published.joins(:same_name)
20
+ .group('fine_print_contracts.id')
21
+ .having(:version =>
22
+ arel_table.alias(:same_names_fine_print_contracts)[:version].maximum.tap{|mvq| mvq.alias = nil})
23
+ }
23
24
 
24
25
  def is_published?
25
26
  !version.nil?
@@ -8,7 +8,7 @@ module FinePrint
8
8
  validates_presence_of :contract, :user_type, :user_id
9
9
  validates_uniqueness_of :contract_id, :scope => [:user_type, :user_id]
10
10
 
11
- default_scope order(:contract_id, :user_type, :user_id)
11
+ default_scope { order(:contract_id, :user_type, :user_id) }
12
12
 
13
13
  protected
14
14
 
@@ -1,37 +1,41 @@
1
1
  # Change the settings below to suit your needs
2
- # All settings are initially set to their default values
2
+ # All options are initially set to their default values
3
3
  FinePrint.configure do |config|
4
4
  # Engine Configuration
5
5
 
6
- # Proc called with controller as argument that returns the current user.
6
+ # Proc called with a controller as argument.
7
+ # Returns the current user.
7
8
  # Default: lambda { |controller| controller.current_user }
8
9
  config.current_user_proc = lambda { |controller| controller.current_user }
9
10
 
10
- # Proc called with user as argument that returns true iif the user is an admin.
11
+ # Proc called with a user as argument.
12
+ # Returns true iif the user is an admin.
11
13
  # Admins can create and edit agreements and terminate accepted agreements.
12
14
  # Default: lambda { |user| false } (no admins)
13
15
  config.user_admin_proc = lambda { |user| false }
14
16
 
15
- # Proc called with user as argument that returns true iif the argument is a user
16
- # who can sign a contract. In many systems, a non-logged-in user is represented by nil.
17
+ # Proc called with a user as argument
18
+ # Returns true iif the argument the user is allowed to sign a contract.
19
+ # In many systems, a non-logged-in user is represented by nil.
17
20
  # However, some systems use something like an AnonymousUser class to represent this state.
18
- # If this proc returns false, FinePrint will not ask for signatures and will allow access
19
- # to any page, so it's up to the developer to make sure that unsigned users can't access
20
- # pages that require a contract signature to use.
21
- # Default: lambda { |user| user }
22
- config.can_sign_contracts_proc = lambda { |user| user }
21
+ # If this proc returns false, FinePrint will not ask for signatures and will not redirect the user, so it's up to the developer to make sure that unsigned users can't access pages that should require a signed contract to use.
22
+ # Default: lambda { |user| !!user }
23
+ config.user_can_sign_proc = lambda { |user| !!user }
23
24
 
24
- # Path to redirect users to when an error occurs (e.g. permission denied on admin pages).
25
- # Default: '/'
26
- config.redirect_path = '/'
27
25
 
28
- # Signature (fine_print_get_signatures) Configuration
26
+
27
+ # Contract Configuration
28
+
29
+ # What to call the contract names param, passed when the user is redirected
30
+ # This is visible to the user in the Url
31
+ # Default: 'contracts'
32
+ config.contract_param_name = 'contracts'
29
33
 
30
34
  # Path to redirect users to when they need to agree to contract(s).
31
- # A list of contract names that must be agreed to will be available in the 'contracts' parameter.
35
+ # A list of contract names that must be agreed to will be available in the `contract_param_name` parameter.
32
36
  # Your code doesn't have to deal with all of them at once, e.g. you can get
33
37
  # the user to agree to the first one and then they'll just eventually be
34
38
  # redirected back to this page with the remaining contract names.
35
39
  # Default: '/'
36
- config.pose_contracts_path = '/'
40
+ config.contract_redirect_path = '/'
37
41
  end
@@ -19,8 +19,9 @@ class InstallFinePrint < ActiveRecord::Migration
19
19
  end
20
20
 
21
21
  add_index :fine_print_signatures, :contract_id
22
- add_index :fine_print_signatures, [:user_id, :user_type, :contract_id],
23
- :name => 'index_fine_print_s_on_u_id_and_u_type_and_c_id',
24
- :unique => true
22
+ add_index :fine_print_signatures,
23
+ [:user_id, :user_type, :contract_id],
24
+ :name => 'index_fine_print_s_on_u_id_and_u_type_and_c_id',
25
+ :unique => true
25
26
  end
26
27
  end
@@ -0,0 +1,114 @@
1
+ module FinePrint
2
+ module ControllerIncludes
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ end
6
+
7
+ # For the following methods, names passed as Symbols are converted to Strings.
8
+
9
+ # Accepts an array of contract names
10
+ # Returns nil if the array is blank or the current user cannot sign contracts
11
+ # Otherwise, returns the contract names that the user hasn't signed yet
12
+ def fine_print_get_unsigned_contract_names(*contract_names)
13
+ # Convert names to an array of Strings
14
+ names = contract_names.flatten.collect{|n| n.to_s}
15
+
16
+ user = FinePrint.current_user_proc.call(self)
17
+
18
+ # If the user isn't signed in, they can't sign a contract
19
+ # Since there may be some pages that both logged in and non-logged in users
20
+ # can visit, we just return quietly instead of raising an exception
21
+ return nil if names.blank? || !FinePrint.can_sign?(user)
22
+
23
+ # Ignore contracts that don't yet exist or aren't yet published (happens
24
+ # when adding code that requires a new contract but before that contract
25
+ # has been added and published)
26
+ FinePrint.get_unsigned_contract_names(user, names)
27
+ .reject{|name| FinePrint.get_contract(name).blank?}
28
+ end
29
+
30
+ # Accepts an array of unsigned contract names and an options hash
31
+ # Unless the array of unsigned contract names is blank or the request url is
32
+ # already the contract_redirect_path, it saves the current request path and
33
+ # redirects the user to the `contract_redirect_path`, with
34
+ # `contract_param_name` containing the unsigned contract names
35
+ def fine_print_redirect(*args)
36
+ options = args.last.is_a?(Hash) ? args.pop : {}
37
+ unsigned_contract_names = args.flatten
38
+ return if unsigned_contract_names.nil? ||\
39
+ unsigned_contract_names.all? { |n| n.blank? }
40
+
41
+ path = options[:contract_redirect_path] || FinePrint.contract_redirect_path
42
+ param_name = options[:contract_param_name] || FinePrint.contract_param_name
43
+
44
+ # http://stackoverflow.com/a/6561953
45
+ redirect_path = path + (path.include?('?') ? '&' : '?') +\
46
+ {param_name.to_sym => unsigned_contract_names}.to_query
47
+
48
+ # Prevent redirect loop
49
+ return if view_context.current_page?(redirect_path)
50
+
51
+ # http://stackoverflow.com/a/2165727/1664216
52
+ session[:fine_print_return_to] = "#{request.protocol}#{request.host_with_port}#{request.fullpath}"
53
+ redirect_to redirect_path
54
+ end
55
+
56
+ # Accepts no arguments
57
+ # Redirects the user to the path saved by either
58
+ # `fine_print_get_signatures` or `fine_print_redirect`
59
+ def fine_print_return
60
+ redirect_to session.delete(:fine_print_return_to) || root_path
61
+ end
62
+
63
+ protected
64
+
65
+ def fine_print_skipped_contract_names
66
+ @fine_print_skipped_contract_names ||= []
67
+ end
68
+
69
+ module ClassMethods
70
+ # Accepts an array of contract names and an options hash
71
+ # Adds a before_filter to the current controller that will check if the
72
+ # current user has signed the given contracts and redirect them to
73
+ # `contract_redirect_path` if appropriate
74
+ # Options relevant to FinePrint are passed to fine_print_redirect, while
75
+ # other options are passed to the before_filter
76
+ def fine_print_get_signatures(*args)
77
+ options = args.last.is_a?(Hash) ? args.pop : {}
78
+
79
+ filter_options = options.except(*FinePrint::CONTRACT_OPTIONS)
80
+ fine_print_options = options.slice(*FinePrint::CONTRACT_OPTIONS)
81
+
82
+ # Convert names to an array of Strings
83
+ contract_names = args.flatten.collect{|n| n.to_s}
84
+
85
+ class_eval do
86
+ before_filter(filter_options) do |controller|
87
+ controller.fine_print_redirect(
88
+ controller.fine_print_get_unsigned_contract_names(contract_names - controller.fine_print_skipped_contract_names),
89
+ fine_print_options)
90
+ end
91
+ end
92
+ end
93
+
94
+ # Accepts an array of contract names and an options hash
95
+ # Excludes the given contracts from the `fine_print_get_signatures` check for
96
+ # this controller and subclasses
97
+ # Options are passed to prepend_before_filter
98
+ def fine_print_skip_signatures(*args)
99
+ options = args.last.is_a?(Hash) ? args.pop : {}
100
+
101
+ # Convert all names to string
102
+ names = args.flatten.collect{|n| n.to_s}
103
+
104
+ class_eval do
105
+ prepend_before_filter(options) do |controller|
106
+ controller.fine_print_skipped_contract_names.push(*names)
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+
114
+ ActionController::Base.send :include, FinePrint::ControllerIncludes
@@ -1,3 +1,3 @@
1
1
  module FinePrint
2
- VERSION = '1.3.0'
2
+ VERSION = '1.4.1'
3
3
  end
data/lib/fine_print.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'fine_print/engine'
2
2
  require 'fine_print/security_transgression'
3
- require 'fine_print/controller_additions'
3
+ require 'fine_print/controller_includes'
4
4
 
5
5
  module FinePrint
6
6
  # Attributes
@@ -9,17 +9,17 @@ module FinePrint
9
9
  ENGINE_OPTIONS = [
10
10
  :current_user_proc,
11
11
  :user_admin_proc,
12
- :can_sign_contracts_proc,
13
- :pose_contracts_path,
14
- :redirect_path
12
+ :user_can_sign_proc
15
13
  ]
16
14
 
17
- # Can be set in initializer or passed as an option to fine_print_get_signatures
18
- SIGNATURE_OPTIONS = [
19
- :pose_contracts_path
15
+ # Can be set in initializer or passed as an argument to either
16
+ # `fine_print_get_signatures` or `fine_print_redirect`
17
+ CONTRACT_OPTIONS = [
18
+ :contract_param_name,
19
+ :contract_redirect_path
20
20
  ]
21
21
 
22
- (ENGINE_OPTIONS + SIGNATURE_OPTIONS).each do |option|
22
+ (ENGINE_OPTIONS + CONTRACT_OPTIONS).each do |option|
23
23
  mattr_accessor option
24
24
  end
25
25
 
@@ -27,10 +27,9 @@ module FinePrint
27
27
  yield self
28
28
  end
29
29
 
30
- # Gets a contract given either the contract's object, ID or name
30
+ # Gets a contract, given either the contract's object, ID or name
31
31
  # If given a name, it returns the latest published version of that contract
32
- # - contract -- can be a Contract object, its ID, or its name as a String or Symbol
33
- #
32
+ # - contract - can be a Contract object, its ID, or its name (String/Symbol)
34
33
  def self.get_contract(reference)
35
34
  ref = Integer(reference) rescue reference
36
35
  case ref
@@ -44,9 +43,8 @@ module FinePrint
44
43
  end
45
44
 
46
45
  # Records that the given user has signed the given contract
47
- # - user -- the user in question
48
- # - contract -- can be a Contract object, its ID, or its name as a String or Symbol
49
- #
46
+ # - user - the user in question
47
+ # - contract - can be a Contract object, its ID, or its name (String/Symbol)
50
48
  def self.sign_contract(user, contract)
51
49
  raise_unless_can_sign(user)
52
50
  contract = get_contract(contract)
@@ -59,9 +57,8 @@ module FinePrint
59
57
  end
60
58
 
61
59
  # Returns true iff the given user has signed the given contract
62
- # - user -- the user in question
63
- # - contract -- can be a Contract object, its ID, or its name as a String or Symbol
64
- #
60
+ # - user - the user in question
61
+ # - contract - can be a Contract object, its ID, or its name (String/Symbol)
65
62
  def self.signed_contract?(user, contract)
66
63
  raise_unless_can_sign(user)
67
64
  contract = get_contract(contract)
@@ -71,8 +68,8 @@ module FinePrint
71
68
  end
72
69
 
73
70
  # Returns true iff the given user has signed any version of the given contract
74
- # - user -- the user in question
75
- # - contract -- can be a Contract object, its ID, or its name as a String or Symbol
71
+ # - user - the user in question
72
+ # - contract - can be a Contract object, its ID, or its name (String/Symbol)
76
73
  def self.signed_any_contract_version?(user, contract)
77
74
  raise_unless_can_sign(user)
78
75
  contract = get_contract(contract)
@@ -84,9 +81,8 @@ module FinePrint
84
81
 
85
82
  # Returns an array of names for the contracts whose latest published
86
83
  # version the given user has not signed.
87
- # - user -- the user in question
88
- # - names -- contract names to check
89
- #
84
+ # - user - the user in question
85
+ # - names - contract names to check
90
86
  def self.get_unsigned_contract_names(user, *names)
91
87
  raise_unless_can_sign(user)
92
88
  names = names.flatten.collect{|name| name.to_s}
@@ -97,13 +93,13 @@ module FinePrint
97
93
  .where({:name => names,
98
94
  :fine_print_signatures => {:user_id => user.id,
99
95
  :user_type => user.class.name}}).latest
100
- signed_contract_names = signed_contracts.collect{|c| c.name}
96
+ signed_contract_names = signed_contracts.to_a.collect{|c| c.name}
101
97
 
102
98
  return names - signed_contract_names
103
99
  end
104
100
 
105
101
  def self.can_sign?(user)
106
- can_sign_contracts_proc.call(user)
102
+ user_can_sign_proc.call(user)
107
103
  end
108
104
 
109
105
  def self.is_admin?(user)