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.
- checksums.yaml +4 -4
- data/README.md +56 -44
- data/app/controllers/fine_print/application_controller.rb +0 -3
- data/app/models/fine_print/contract.rb +9 -8
- data/app/models/fine_print/signature.rb +1 -1
- data/config/initializers/fine_print.rb +20 -16
- data/db/migrate/0_install_fine_print.rb +4 -3
- data/lib/fine_print/controller_includes.rb +114 -0
- data/lib/fine_print/version.rb +1 -1
- data/lib/fine_print.rb +20 -24
- data/spec/controllers/contracts_controller_spec.rb +38 -36
- data/spec/controllers/home_controller_spec.rb +4 -4
- data/spec/controllers/signatures_controller_spec.rb +8 -8
- data/spec/dummy/Rakefile +0 -1
- data/spec/dummy/app/assets/javascripts/application.js +3 -5
- data/spec/dummy/app/views/layouts/application.html.erb +2 -2
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config/application.rb +3 -37
- data/spec/dummy/config/boot.rb +4 -9
- data/spec/dummy/config/environment.rb +2 -2
- data/spec/dummy/config/environments/development.rb +11 -19
- data/spec/dummy/config/environments/production.rb +40 -27
- data/spec/dummy/config/environments/test.rb +13 -14
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/fine_print.rb +1 -34
- data/spec/dummy/config/initializers/inflections.rb +6 -5
- data/spec/dummy/config/initializers/secret_token.rb +7 -2
- data/spec/dummy/config/initializers/session_store.rb +1 -6
- data/spec/dummy/config/initializers/wrap_parameters.rb +6 -6
- data/spec/dummy/config/locales/en.yml +20 -2
- data/spec/dummy/config/routes.rb +2 -1
- data/spec/dummy/config.ru +1 -1
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/schema.rb +21 -21
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +15 -1849
- data/spec/dummy/log/test.log +10536 -53785
- data/spec/dummy/public/404.html +43 -11
- data/spec/dummy/public/422.html +43 -11
- data/spec/dummy/public/500.html +43 -11
- data/spec/factories/contract.rb +2 -2
- data/spec/lib/fine_print/{controller_additions_spec.rb → controller_includes_spec.rb} +16 -6
- metadata +104 -166
- data/app/assets/javascripts/application.js~ +0 -16
- data/app/controllers/fine_print/application_controller.rb~ +0 -15
- data/app/controllers/fine_print/contracts_controller.rb~ +0 -79
- data/app/controllers/fine_print/home_controller.rb~ +0 -6
- data/app/controllers/fine_print/signatures_controller.rb~ +0 -14
- data/app/helpers/fine_print/application_helper.rb~ +0 -7
- data/app/helpers/fine_print/contracts_helper.rb~ +0 -7
- data/app/models/fine_print/contract.rb~ +0 -100
- data/app/models/fine_print/signature.rb~ +0 -25
- data/app/views/fine_print/contracts/_form.html.erb~ +0 -35
- data/app/views/fine_print/contracts/index.html.erb~ +0 -43
- data/app/views/fine_print/contracts/show.html.erb~ +0 -35
- data/app/views/fine_print/home/index.html.erb~ +0 -15
- data/app/views/fine_print/signatures/index.html.erb~ +0 -32
- data/app/views/layouts/fine_print/application.html.erb~ +0 -20
- data/config/initializers/fine_print.rb~ +0 -36
- data/config/routes.rb~ +0 -12
- data/db/migrate/0_install_fine_print.rb~ +0 -26
- data/lib/fine_print/controller_additions.rb +0 -80
- data/lib/fine_print/controller_additions.rb~ +0 -86
- data/lib/fine_print/utilities.rb~ +0 -26
- data/lib/fine_print/version.rb~ +0 -3
- data/lib/fine_print.rb~ +0 -120
- data/spec/controllers/contracts_controller_spec.rb~ +0 -224
- data/spec/controllers/home_controller_spec.rb~ +0 -25
- data/spec/controllers/signatures_controller_spec.rb~ +0 -46
- data/spec/dummy/app/controllers/dummy_models_controller.rb~ +0 -29
- data/spec/dummy/app/models/dummy_user.rb~ +0 -4
- data/spec/dummy/app/models/user.rb~ +0 -78
- data/spec/dummy/config/application.rb~ +0 -60
- data/spec/dummy/config/initializers/fine_print.rb~ +0 -36
- data/spec/dummy/config/initializers/session_store.rb~ +0 -8
- data/spec/dummy/config/initializers/wrap_parameters.rb~ +0 -14
- data/spec/dummy/config/routes.rb~ +0 -4
- data/spec/dummy/db/migrate/1_create_dummy_users.rb~ +0 -8
- data/spec/dummy/script/rails +0 -6
- data/spec/factories/contract.rb~ +0 -26
- data/spec/factories/dummy_user.rb~ +0 -6
- data/spec/factories/signature.rb~ +0 -8
- data/spec/factories/user.rb~ +0 -6
- data/spec/fine_print_spec.rb~ +0 -18
- data/spec/lib/fine_print/controller_additions_spec.rb~ +0 -20
- data/spec/lib/fine_print_spec.rb~ +0 -47
- data/spec/models/contract_spec.rb~ +0 -80
- data/spec/models/signature_spec.rb~ +0 -28
- data/spec/spec_helper.rb~ +0 -32
- data/spec/test_helper.rb~ +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ae19efef1a93bef86de360020973d0c72e58e74
|
4
|
+
data.tar.gz: fd9d302b91cebd30ad20e4aaac6530c0d9d29e95
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
-
|
63
|
+
You can choose to check if users signed contracts either as a before_filter or inside your controller actions.
|
64
64
|
|
65
|
-
|
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
|
-
|
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
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
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
|
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
|
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
|
-
|
122
|
-
|
123
|
-
|
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
|
-
|
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
|
134
|
-
|
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`
|
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
|
|
@@ -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,
|
19
|
-
.joins(:same_name)
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
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
|
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
|
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
|
16
|
-
#
|
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
|
19
|
-
#
|
20
|
-
|
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
|
-
|
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
|
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.
|
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,
|
23
|
-
|
24
|
-
|
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
|
data/lib/fine_print/version.rb
CHANGED
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/
|
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
|
-
:
|
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
|
18
|
-
|
19
|
-
|
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 +
|
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
|
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
|
48
|
-
# - contract
|
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
|
63
|
-
# - contract
|
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
|
75
|
-
# - contract
|
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
|
88
|
-
# - names
|
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
|
-
|
102
|
+
user_can_sign_proc.call(user)
|
107
103
|
end
|
108
104
|
|
109
105
|
def self.is_admin?(user)
|