fine_print 2.3.1 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +101 -61
- data/Rakefile +2 -2
- data/app/controllers/fine_print/application_controller.rb +5 -5
- data/app/controllers/fine_print/contracts_controller.rb +15 -12
- data/app/controllers/fine_print/signatures_controller.rb +11 -8
- data/app/models/fine_print/contract.rb +10 -10
- data/app/models/fine_print/signature.rb +9 -8
- data/app/views/fine_print/contracts/_form.html.erb +8 -8
- data/app/views/fine_print/contracts/edit.html.erb +2 -2
- data/app/views/fine_print/contracts/index.html.erb +39 -16
- data/app/views/fine_print/contracts/new.html.erb +3 -1
- data/app/views/fine_print/contracts/new_version.html.erb +7 -4
- data/app/views/fine_print/contracts/show.html.erb +33 -18
- data/app/views/fine_print/signatures/_form.html.erb +7 -4
- data/app/views/fine_print/signatures/index.html.erb +17 -9
- data/app/views/fine_print/signatures/new.html.erb +6 -4
- data/config/initializers/fine_print.rb +39 -36
- data/config/routes.rb +3 -2
- data/db/migrate/0_install_fine_print.rb +8 -8
- data/lib/fine_print.rb +40 -55
- data/lib/fine_print/action_controller/base.rb +118 -0
- data/lib/fine_print/configuration.rb +24 -0
- data/lib/fine_print/engine.rb +10 -6
- data/lib/fine_print/version.rb +1 -1
- data/lib/tasks/fine_print_tasks.rake +4 -2
- data/spec/controllers/contracts_controller_spec.rb +22 -22
- data/spec/controllers/home_controller_spec.rb +1 -1
- data/spec/controllers/signatures_controller_spec.rb +11 -11
- data/spec/dummy/app/views/layouts/application.html.erb +2 -1
- data/spec/dummy/config/initializers/fine_print.rb +2 -1
- data/spec/dummy/config/routes.rb +0 -1
- data/spec/dummy/db/migrate/1_create_dummy_users.rb +1 -1
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/test.log +585 -3119
- data/spec/factories/fine_print/contract.rb +1 -1
- data/spec/factories/fine_print/signature.rb +2 -2
- data/spec/factories/user.rb +1 -1
- data/spec/lib/fine_print/action_controller/base_spec.rb +30 -0
- data/spec/lib/fine_print_spec.rb +14 -11
- data/spec/models/contract_spec.rb +2 -2
- data/spec/models/signature_spec.rb +1 -1
- metadata +6 -5
- data/lib/fine_print/controller_includes.rb +0 -93
- data/spec/lib/fine_print/controller_includes_spec.rb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f81ee20572ca69333bf085618f19c261ef9858a
|
4
|
+
data.tar.gz: 1e17485c34cce0a8881ddacab69a290a3e2cb880
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93a19883752880c9fa1fd4e57fd94b0ca37d6a4e0ba8bbd82b9178111bf59c17307c1b0d2b1b359c6133bf4dca277f753620eb63e0fbd4c5db45d8c5ff93ebdf
|
7
|
+
data.tar.gz: 2d85aae86ba3db77ff0e7072bef2147c754f6617f1bbdd3af2c610127c2a42b25f62e7dec243bb48c6bdf5d754d73f8c794ef9b90454bb5b5a35e89f25b19caa
|
data/README.md
CHANGED
@@ -4,13 +4,25 @@
|
|
4
4
|
[![Build Status](https://travis-ci.org/lml/fine_print.svg?branch=master)](https://travis-ci.org/lml/fine_print)
|
5
5
|
[![Code Climate](https://codeclimate.com/github/lml/fine_print/badges/gpa.svg)](https://codeclimate.com/github/lml/fine_print)
|
6
6
|
|
7
|
-
FinePrint is a Rails engine in gem form that makes managing web site agreements
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
7
|
+
FinePrint is a Rails engine in gem form that makes managing web site agreements
|
8
|
+
(terms of use, privacy policy, etc) simple and easy.
|
9
|
+
|
10
|
+
As the meaning of 'agreement' can be somewhat ambiguous (meaning either the
|
11
|
+
thing someone agrees to or the record of the agreement between that thing and
|
12
|
+
the user), we call a set of terms a 'contract' and a user's agreement to that
|
13
|
+
contract a 'signature'.
|
14
|
+
|
15
|
+
A version history of all contracts is maintained. Once a particular version of
|
16
|
+
a contract is published, it becomes available for users to sign. Once it has
|
17
|
+
been signed, it cannot be changed. To effect a change, a new version must be
|
18
|
+
created and published. When a new version of a contract is created and
|
19
|
+
published, users visiting pages requiring signature of that contract will be
|
20
|
+
redirected to a page where they can sign the new contract.
|
21
|
+
|
22
|
+
FinePrint provides views for admins to manage contracts and signatures and for
|
23
|
+
users to sign those contracts, although these views can be overriden by
|
24
|
+
application-specific views. FinePrint also provides convenience methods for
|
25
|
+
finding unsigned contracts and for recording when a user signs a contract.
|
14
26
|
|
15
27
|
## Installation
|
16
28
|
|
@@ -58,120 +70,145 @@ And provide a link on your site for administrators to access the FinePrint engin
|
|
58
70
|
|
59
71
|
## Configuration
|
60
72
|
|
61
|
-
After installation, the initializer for FinePrint will be located under
|
62
|
-
Make sure to configure it to suit
|
63
|
-
Pay particular attention to `
|
73
|
+
After installation, the initializer for FinePrint will be located under
|
74
|
+
`config/initializers/fine_print.rb`. Make sure to configure it to suit
|
75
|
+
your needs. Pay particular attention to `authenticate_manager_proc`,
|
76
|
+
as you will be unable to manage your contracts unless you setup
|
77
|
+
this proc to return `true` for your admins.
|
64
78
|
|
65
79
|
## Usage
|
66
80
|
|
67
|
-
You can choose to check if users signed contracts either
|
81
|
+
You can choose to check if users signed contracts either
|
82
|
+
as a before_filter or inside your controller actions.
|
68
83
|
|
69
84
|
### Option 1 - As a before_filter
|
70
85
|
|
71
|
-
If you choose to have FinePrint work like a before_filter, you can user the following
|
86
|
+
If you choose to have FinePrint work like a before_filter, you can user the following class methods, which are automatically added to your controllers:
|
72
87
|
|
73
88
|
```rb
|
74
|
-
|
75
|
-
|
76
|
-
fine_print_skip_signatures(contract_names..., options_hash)
|
89
|
+
fine_print_require(contract_names..., options_hash)
|
90
|
+
fine_print_skip(contract_names..., options_hash)
|
77
91
|
```
|
78
92
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
93
|
+
- `fine_print_require` will redirect users to a page that asks them
|
94
|
+
to sign each contract provided, in order
|
95
|
+
- `fine_print_skip` is used to skip asking the user to sign
|
96
|
+
the given contracts for certain controller actions
|
83
97
|
|
84
|
-
|
85
|
-
symbols), along with an options hash.
|
98
|
+
These methods take a list of contract names to check, along with an options hash.
|
86
99
|
|
87
|
-
The options hash can include any options you could pass to a `before_filter`,
|
100
|
+
The options hash can include any options you could pass to a `before_filter`,
|
101
|
+
e.g. `only` and `except`, plus the FinePrint-specific option
|
102
|
+
`redirect_to_contracts_proc`, which is a proc that controls
|
103
|
+
where users are redirected to in order to sign contracts.
|
88
104
|
|
89
105
|
Example:
|
90
106
|
|
91
107
|
```rb
|
92
108
|
class MyController < ApplicationController
|
93
|
-
|
94
|
-
|
109
|
+
fine_print_require :terms_of_use, :privacy_policy, except: :index
|
110
|
+
end
|
95
111
|
```
|
96
112
|
|
97
|
-
|
98
|
-
|
99
|
-
|
113
|
+
Before checking the contracts to be signed, FinePrint will check that the user
|
114
|
+
is logged in by calling the authenticate_user_proc. This method should render
|
115
|
+
or redirect the user if they are not signed in.
|
100
116
|
|
101
117
|
One way you can use these methods is to require signatures in every controller
|
102
118
|
by default, and then to skip them in certain situations, e.g.:
|
103
119
|
|
104
120
|
```rb
|
105
121
|
class ApplicationController < ActionController::Base
|
106
|
-
|
122
|
+
fine_print_require :terms_of_use
|
123
|
+
end
|
107
124
|
```
|
108
125
|
|
109
126
|
```rb
|
110
127
|
class NoSigsRequiredController < ApplicationController
|
111
|
-
|
128
|
+
fine_print_skip :terms_of_use
|
129
|
+
end
|
112
130
|
```
|
113
131
|
|
114
132
|
### Option 2 - Inside your controller actions
|
115
133
|
|
116
|
-
If instead you have to check
|
117
|
-
|
118
|
-
```rb
|
119
|
-
fine_print_get_unsigned_contract_names(contract_names)
|
120
|
-
fine_print_redirect(unsigned_contract_names)
|
121
|
-
```
|
122
|
-
|
123
|
-
This can be done in one line, like so:
|
134
|
+
If, instead, you have to check a contract signature inside a controller action,
|
135
|
+
you can use the following instance methods, also available in all controllers:
|
124
136
|
|
125
137
|
```rb
|
126
|
-
|
138
|
+
fine_print_require(contract_names..., options_hash)
|
139
|
+
fine_print_return
|
127
140
|
```
|
128
141
|
|
129
|
-
|
130
|
-
|
131
|
-
|
142
|
+
- `fine_print_require` works just like the before_filter version and will
|
143
|
+
redirect the user if they haven't signed one or more of the given contracts
|
144
|
+
- `fine_print_return` can be used to return from a redirect
|
145
|
+
made by `fine_print_require`
|
132
146
|
|
133
147
|
### Displaying and signing contracts
|
134
148
|
|
135
|
-
When a set of contracts is found by FinePrint to be required but unsigned,
|
136
|
-
|
137
|
-
|
149
|
+
When a set of contracts is found by FinePrint to be required but unsigned,
|
150
|
+
and the user is allowed to sign contracts, FinePrint will call the
|
151
|
+
redirect_to_contracts_proc, which should redirect the user to some action
|
152
|
+
that allows the user to sign said contracts, passing along the id's of the
|
153
|
+
contract objects that need to be signed. By default, it redirects to one
|
154
|
+
of FinePrint's views that presents one contract at a time to the user.
|
155
|
+
|
156
|
+
If you choose to create this view yourself, your job as the site developer is
|
157
|
+
to present the terms to the user and ask them to sign them. This normally
|
158
|
+
involves the user clicking an "I have read the above terms" checkbox which
|
159
|
+
enables an "I Agree" button. When the "Agree" button is clicked (and you should
|
160
|
+
verify that the checkbox is actually clicked in the params passed to the
|
161
|
+
server), you need to send the information off to a controller method that will
|
162
|
+
mark the contract as signed using the `FinePrint.sign_contract` method. The
|
163
|
+
following methods in the FinePrint module can be used to help you find contract
|
164
|
+
objects and mark them as signed:
|
138
165
|
|
139
166
|
```rb
|
140
167
|
FinePrint.get_contract(contract_object_or_id_or_name)
|
141
168
|
FinePrint.sign_contract(user, contract_object_or_id_or_name)
|
142
169
|
FinePrint.signed_contract?(user, contract_object_or_id_or_name)
|
143
|
-
FinePrint.
|
144
|
-
FinePrint.get_unsigned_contract_names(user, contract_names...)
|
170
|
+
FinePrint.signed_any_version_of_contract?(user, contract_object_or_id_or_name)
|
145
171
|
```
|
146
172
|
|
147
173
|
If you require more explanation about these methods and their arguments, check the `lib/fine_print.rb` file.
|
148
174
|
|
149
175
|
### Redirecting users back
|
150
176
|
|
151
|
-
Regardless if you use
|
177
|
+
Regardless if you use the class before_filter or instance methods,
|
178
|
+
after your contract is signed you can use the `fine_print_return` controller
|
179
|
+
instance method to send the user back to the place where they came from.
|
152
180
|
|
153
|
-
If there are multiple unsigned contracts, you are not required to
|
154
|
-
them all at once.
|
155
|
-
|
156
|
-
|
181
|
+
If there are multiple unsigned contracts, you are not required to ask the user
|
182
|
+
to sign them all at once. One strategy is to present only the first unsigned
|
183
|
+
contract to them. Once they sign it, they'll be redirected to where they were
|
184
|
+
trying to go and FinePrint will once again determine that they still have
|
185
|
+
remaining unsigned contracts, and redirect them back to your contract signing
|
186
|
+
path with one less contract id passed in.
|
157
187
|
|
158
188
|
## Managing Contracts
|
159
189
|
|
160
190
|
Here are some important notes about managing your contracts with FinePrint:
|
161
191
|
|
162
|
-
- Contracts have a name and a title; the former is used by your code,
|
163
|
-
is intended for display to end users and
|
164
|
-
- Creating another contract with the same name as an existing contract
|
165
|
-
|
192
|
+
- Contracts have a name and a title; the former is used by your code,
|
193
|
+
the latter is intended for display to end users and site admins.
|
194
|
+
- Creating another contract with the same name as an existing contract
|
195
|
+
will make it a new version of that existing contract.
|
196
|
+
- Contracts need to be explicitly published to be available to users to sign
|
197
|
+
(this can be done on the contracts admin page).
|
166
198
|
- The latest published version is what users will see.
|
167
|
-
- A contract cannot be modified after at least one user has signed it,
|
168
|
-
|
199
|
+
- A contract cannot be modified after at least one user has signed it,
|
200
|
+
but you can always create a new version.
|
201
|
+
- When a published contract version is available but has not been signed,
|
202
|
+
users will be asked to accept it the next time they visit a controller action
|
203
|
+
that calls either `fine_print_require` with that contract's name.
|
169
204
|
|
170
205
|
## Customization
|
171
206
|
|
172
|
-
You can customize FinePrint's stylesheets, javascripts, views
|
207
|
+
You can customize FinePrint's stylesheets, javascripts, views
|
208
|
+
and even controllers to suit your needs.
|
173
209
|
|
174
|
-
Run the following command to copy a part of FinePrint
|
210
|
+
Run the following command to copy a part of FinePrint
|
211
|
+
into your main application:
|
175
212
|
|
176
213
|
```sh
|
177
214
|
$ rake fine_print:copy:folder
|
@@ -185,7 +222,8 @@ Example:
|
|
185
222
|
$ rake fine_print:copy:views
|
186
223
|
```
|
187
224
|
|
188
|
-
Alternatively, you can run the following command
|
225
|
+
Alternatively, you can run the following command
|
226
|
+
to copy all of the above into your main application:
|
189
227
|
|
190
228
|
```sh
|
191
229
|
$ rake fine_print:copy
|
@@ -193,7 +231,9 @@ $ rake fine_print:copy
|
|
193
231
|
|
194
232
|
## Testing
|
195
233
|
|
196
|
-
From the gem's main folder, run `bundle install`,
|
234
|
+
From the gem's main folder, run `bundle install`,
|
235
|
+
`bundle exec rake db:migrate` and then
|
236
|
+
`bundle exec rake` to run all the specs.
|
197
237
|
|
198
238
|
## Contributing
|
199
239
|
|
data/Rakefile
CHANGED
@@ -17,6 +17,6 @@ require 'rspec/core'
|
|
17
17
|
require 'rspec/core/rake_task'
|
18
18
|
|
19
19
|
desc 'Run all specs in spec directory (excluding plugin specs)'
|
20
|
-
RSpec::Core::RakeTask.new(:
|
20
|
+
RSpec::Core::RakeTask.new(spec: 'app:db:test:prepare')
|
21
21
|
|
22
|
-
task :
|
22
|
+
task default: :spec
|
@@ -1,23 +1,23 @@
|
|
1
1
|
require 'responders'
|
2
2
|
|
3
3
|
module FinePrint
|
4
|
-
class ApplicationController < ActionController::Base
|
4
|
+
class ApplicationController < ::ActionController::Base
|
5
5
|
respond_to :html
|
6
6
|
|
7
7
|
before_filter :get_user, :can_manage
|
8
8
|
|
9
|
-
layout FinePrint.layout
|
9
|
+
layout FinePrint.config.layout
|
10
10
|
|
11
|
-
helper FinePrint.helpers
|
11
|
+
helper FinePrint.config.helpers
|
12
12
|
|
13
13
|
protected
|
14
14
|
|
15
15
|
def get_user
|
16
|
-
@user = instance_exec &FinePrint.current_user_proc
|
16
|
+
@user = instance_exec &FinePrint.config.current_user_proc
|
17
17
|
end
|
18
18
|
|
19
19
|
def can_manage
|
20
|
-
instance_exec @user, &FinePrint.
|
20
|
+
instance_exec @user, &FinePrint.config.authenticate_manager_proc
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -2,7 +2,7 @@ module FinePrint
|
|
2
2
|
class ContractsController < FinePrint::ApplicationController
|
3
3
|
include FinePrint::ApplicationHelper
|
4
4
|
|
5
|
-
before_filter :get_contract, :
|
5
|
+
before_filter :get_contract, except: [:index, :new, :create]
|
6
6
|
|
7
7
|
def index
|
8
8
|
@contracts = Contract.includes(:signatures).all.to_a.group_by(&:name)
|
@@ -19,9 +19,9 @@ module FinePrint
|
|
19
19
|
@contract.content = params[:contract][:content]
|
20
20
|
|
21
21
|
if @contract.save
|
22
|
-
redirect_to @contract, :
|
22
|
+
redirect_to @contract, notice: t('fine_print.contract.notices.created')
|
23
23
|
else
|
24
|
-
render :
|
24
|
+
render action: 'new', alert: merge_errors_for(@contract)
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -30,7 +30,7 @@ module FinePrint
|
|
30
30
|
|
31
31
|
def edit
|
32
32
|
@contract.no_signatures
|
33
|
-
redirect_to contracts_path, :
|
33
|
+
redirect_to contracts_path, alert: merge_errors_for(@contract) \
|
34
34
|
unless @contract.errors.empty?
|
35
35
|
end
|
36
36
|
|
@@ -40,33 +40,36 @@ module FinePrint
|
|
40
40
|
@contract.content = params[:contract][:content]
|
41
41
|
|
42
42
|
if @contract.save
|
43
|
-
redirect_to @contract, :
|
43
|
+
redirect_to @contract, notice: t('fine_print.contract.notices.updated')
|
44
44
|
else
|
45
|
-
render :
|
45
|
+
render action: 'edit', alert: merge_errors_for(@contract)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
49
|
def destroy
|
50
50
|
if @contract.destroy
|
51
|
-
redirect_to contracts_path,
|
51
|
+
redirect_to contracts_path,
|
52
|
+
notice: t('fine_print.contract.notices.deleted')
|
52
53
|
else
|
53
|
-
redirect_to contracts_path, :
|
54
|
+
redirect_to contracts_path, alert: merge_errors_for(@contract)
|
54
55
|
end
|
55
56
|
end
|
56
57
|
|
57
58
|
def publish
|
58
59
|
if @contract.publish
|
59
|
-
redirect_to contracts_path,
|
60
|
+
redirect_to contracts_path,
|
61
|
+
notice: t('fine_print.contract.notices.published')
|
60
62
|
else
|
61
|
-
redirect_to contracts_path, :
|
63
|
+
redirect_to contracts_path, alert: merge_errors_for(@contract)
|
62
64
|
end
|
63
65
|
end
|
64
66
|
|
65
67
|
def unpublish
|
66
68
|
if @contract.unpublish
|
67
|
-
redirect_to contracts_path,
|
69
|
+
redirect_to contracts_path,
|
70
|
+
notice: t('fine_print.contract.notices.unpublished')
|
68
71
|
else
|
69
|
-
redirect_to contracts_path, :
|
72
|
+
redirect_to contracts_path, alert: merge_errors_for(@contract)
|
70
73
|
end
|
71
74
|
end
|
72
75
|
|
@@ -2,9 +2,10 @@ module FinePrint
|
|
2
2
|
class SignaturesController < FinePrint::ApplicationController
|
3
3
|
include FinePrint::ApplicationHelper
|
4
4
|
|
5
|
-
skip_before_filter :can_manage, :
|
6
|
-
|
7
|
-
before_filter :
|
5
|
+
skip_before_filter :can_manage, only: [:new, :create]
|
6
|
+
fine_print_skip only: [:new, :create]
|
7
|
+
before_filter :can_sign, only: [:new, :create]
|
8
|
+
before_filter :get_contract, only: [:index, :new, :create]
|
8
9
|
|
9
10
|
def index
|
10
11
|
@signatures = @contract.signatures
|
@@ -18,8 +19,10 @@ module FinePrint
|
|
18
19
|
@signature = Signature.new
|
19
20
|
|
20
21
|
unless params[:signature_accept]
|
21
|
-
@signature.errors.add(
|
22
|
-
|
22
|
+
@signature.errors.add(
|
23
|
+
:contract, t('fine_print.signature.errors.contract.must_agree')
|
24
|
+
)
|
25
|
+
render action: 'new'
|
23
26
|
return
|
24
27
|
end
|
25
28
|
|
@@ -29,7 +32,7 @@ module FinePrint
|
|
29
32
|
if @signature.save
|
30
33
|
fine_print_return
|
31
34
|
else
|
32
|
-
render :
|
35
|
+
render action: 'new', alert: merge_errors_for(@signature)
|
33
36
|
end
|
34
37
|
end
|
35
38
|
|
@@ -38,13 +41,13 @@ module FinePrint
|
|
38
41
|
|
39
42
|
@signature.destroy
|
40
43
|
redirect_to contract_signatures_path(@signature.contract),
|
41
|
-
:
|
44
|
+
notice: t('fine_print.signature.notices.deleted')
|
42
45
|
end
|
43
46
|
|
44
47
|
protected
|
45
48
|
|
46
49
|
def can_sign
|
47
|
-
instance_exec @user, &FinePrint.
|
50
|
+
instance_exec @user, &FinePrint.config.authenticate_user_proc
|
48
51
|
end
|
49
52
|
|
50
53
|
def get_contract
|
@@ -1,20 +1,20 @@
|
|
1
1
|
module FinePrint
|
2
2
|
class Contract < ActiveRecord::Base
|
3
|
-
has_many :signatures, :
|
3
|
+
has_many :signatures, dependent: :destroy, inverse_of: :contract
|
4
4
|
|
5
|
-
has_many :same_name, :
|
6
|
-
:
|
5
|
+
has_many :same_name, class_name: 'Contract',
|
6
|
+
primary_key: :name, foreign_key: :name
|
7
7
|
|
8
8
|
before_validation :downcase_name
|
9
9
|
before_update :no_signatures
|
10
10
|
before_destroy :no_signatures
|
11
11
|
|
12
|
-
validates :name, :
|
13
|
-
validates :title, :
|
14
|
-
validates :content, :
|
15
|
-
validates :version, :
|
16
|
-
|
17
|
-
:
|
12
|
+
validates :name, presence: true, format: /\A[\w-]+\z/
|
13
|
+
validates :title, presence: true
|
14
|
+
validates :content, presence: true
|
15
|
+
validates :version, uniqueness: { scope: :name,
|
16
|
+
case_sensitive: false},
|
17
|
+
allow_nil: true
|
18
18
|
|
19
19
|
default_scope lambda { order{[name.asc, version.desc]} }
|
20
20
|
|
@@ -49,7 +49,7 @@ module FinePrint
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def new_version
|
52
|
-
Contract.where(:
|
52
|
+
Contract.where(name: name, version: nil).first || \
|
53
53
|
dup.tap{|contract| contract.version = nil}
|
54
54
|
end
|
55
55
|
|