sinatra-bouncer 1.3.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -7
- data/.rubocop.yml +1 -9
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +4 -3
- data/Gemfile.lock +92 -0
- data/README.md +231 -54
- data/RELEASE_NOTES.md +170 -0
- data/lib/sinatra/bouncer/basic_bouncer.rb +34 -37
- data/lib/sinatra/bouncer/rule.rb +114 -22
- data/lib/sinatra/bouncer/version.rb +1 -1
- data/lib/sinatra/bouncer.rb +6 -37
- data/sinatra_bouncer.gemspec +4 -1
- metadata +5 -14
- data/tests/integrations/dev_defines_legal_routes.feature +0 -57
- data/tests/integrations/dev_installs_bouncer.feature +0 -12
- data/tests/integrations/step_definitions/given.rb +0 -36
- data/tests/integrations/step_definitions/then.rb +0 -9
- data/tests/integrations/step_definitions/when.rb +0 -11
- data/tests/integrations/support/env.rb +0 -30
- data/tests/integrations/support/helpers.rb +0 -55
- data/tests/integrations/support/types.rb +0 -21
- data/tests/spec/basic_bouncer_spec.rb +0 -148
- data/tests/spec/rule_spec.rb +0 -67
- data/tests/spec/spec_helper.rb +0 -11
- data/tests/test_app.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 849fed52904df15b1cc036685383f197e47aae52bef8283a81decc281fc95660
|
4
|
+
data.tar.gz: 3a3ba41d0d3c2ad70b1c4e48b81558213111d86a750717e2b8f44dea9072ca1f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d63e6a5437ef4d71e7183dce458241a8efaebace1c6f95e77766412f2faf2d5d490107a4e925588509dfb8e73b0c2e3a21064e73aae4cb3f98ae0c8465f19dd5
|
7
|
+
data.tar.gz: ca6d627ae51d9ecf6c88ffa21621117adb3af2eee6c83d14846f8ac7a5aa314f9ce4d2d10c30baf192e4a7c435f750bfb5b9bc3c37ed308ee4a5255a8df0eacf
|
data/.gitignore
CHANGED
@@ -4,9 +4,6 @@
|
|
4
4
|
# or operating system, you probably want to add a global ignore instead:
|
5
5
|
# git config --global core.excludesfile ~/.gitignore_global
|
6
6
|
|
7
|
-
# Ignore bundler config
|
8
|
-
/.bundle
|
9
|
-
|
10
7
|
# Ignore all logfiles and tempfiles.
|
11
8
|
*.log
|
12
9
|
tmp/*
|
@@ -17,7 +14,5 @@ tmp/*
|
|
17
14
|
# Ignore all gem files.
|
18
15
|
*.gem
|
19
16
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
Gemfile.lock
|
17
|
+
# Ignore simplecov results
|
18
|
+
.coverage/
|
data/.rubocop.yml
CHANGED
@@ -3,6 +3,7 @@ inherit_from: ~/.config/rubocop/config.yml
|
|
3
3
|
AllCops:
|
4
4
|
Exclude:
|
5
5
|
- 'bin/*'
|
6
|
+
- 'benchmarks/*'
|
6
7
|
|
7
8
|
Layout/LineLength:
|
8
9
|
Exclude:
|
@@ -11,12 +12,3 @@ Layout/LineLength:
|
|
11
12
|
# setting to 6 to match RubyMine autoformat
|
12
13
|
Layout/FirstArrayElementIndentation:
|
13
14
|
IndentationWidth: 6
|
14
|
-
|
15
|
-
# rspec blocks are huge by design
|
16
|
-
Metrics/BlockLength:
|
17
|
-
Exclude:
|
18
|
-
- 'tests/spec/**/*.rb'
|
19
|
-
|
20
|
-
Metrics/ModuleLength:
|
21
|
-
Exclude:
|
22
|
-
- 'tests/spec/**/*.rb'
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, and in the interest of
|
4
|
+
fostering an open and welcoming community, we pledge to respect all people who
|
5
|
+
contribute through reporting issues, posting feature requests, updating
|
6
|
+
documentation, submitting pull requests or patches, and other activities.
|
7
|
+
|
8
|
+
We are committed to making participation in this project a harassment-free
|
9
|
+
experience for everyone, regardless of level of experience, gender, gender
|
10
|
+
identity and expression, sexual orientation, disability, personal appearance,
|
11
|
+
body size, race, ethnicity, age, religion, or nationality.
|
12
|
+
|
13
|
+
Examples of unacceptable behavior by participants include:
|
14
|
+
|
15
|
+
* The use of sexualized language or imagery
|
16
|
+
* Personal attacks
|
17
|
+
* Trolling or insulting/derogatory comments
|
18
|
+
* Public or private harassment
|
19
|
+
* Publishing other's private information, such as physical or electronic
|
20
|
+
addresses, without explicit permission
|
21
|
+
* Other unethical or unprofessional conduct
|
22
|
+
|
23
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
24
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
25
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
26
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
27
|
+
threatening, offensive, or harmful.
|
28
|
+
|
29
|
+
By adopting this Code of Conduct, project maintainers commit themselves to
|
30
|
+
fairly and consistently applying these principles to every aspect of managing
|
31
|
+
this project. Project maintainers who do not follow or enforce the Code of
|
32
|
+
Conduct may be permanently removed from the project team.
|
33
|
+
|
34
|
+
This code of conduct applies both within project spaces and in public spaces
|
35
|
+
when an individual is representing the project or its community.
|
36
|
+
|
37
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
38
|
+
reported by contacting a project maintainer at robin@tenjin.ca. All
|
39
|
+
complaints will be reviewed and investigated and will result in a response that
|
40
|
+
is deemed necessary and appropriate to the circumstances. Maintainers are
|
41
|
+
obligated to maintain confidentiality with regard to the reporter of an
|
42
|
+
incident.
|
43
|
+
|
44
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
45
|
+
version 1.3.0, available at
|
46
|
+
[http://contributor-covenant.org/version/1/3/0/][version]
|
47
|
+
|
48
|
+
[homepage]: http://contributor-covenant.org
|
49
|
+
[version]: http://contributor-covenant.org/version/1/3/0/
|
data/Gemfile
CHANGED
@@ -7,13 +7,14 @@ gemspec
|
|
7
7
|
|
8
8
|
group :development do
|
9
9
|
gem 'bundler', '~> 2.4'
|
10
|
-
gem 'rake', '~> 13.
|
10
|
+
gem 'rake', '~> 13.1'
|
11
|
+
gem 'rubocop', '~> 1.57'
|
12
|
+
gem 'rubocop-performance', '~> 1.19'
|
11
13
|
gem 'yard', '~> 0.9'
|
12
14
|
end
|
13
15
|
|
14
16
|
group :test do
|
15
|
-
gem '
|
16
|
-
gem 'cucumber', '~> 8.0'
|
17
|
+
gem 'rack-test', '~> 2.1'
|
17
18
|
gem 'rspec', '~> 3.12'
|
18
19
|
gem 'simplecov', '~> 0.22'
|
19
20
|
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
sinatra-bouncer (3.0.0)
|
5
|
+
sinatra (>= 2.2)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
ast (2.4.2)
|
11
|
+
diff-lcs (1.5.0)
|
12
|
+
docile (1.4.0)
|
13
|
+
json (2.6.3)
|
14
|
+
language_server-protocol (3.17.0.3)
|
15
|
+
mustermann (3.0.0)
|
16
|
+
ruby2_keywords (~> 0.0.1)
|
17
|
+
parallel (1.23.0)
|
18
|
+
parser (3.2.2.4)
|
19
|
+
ast (~> 2.4.1)
|
20
|
+
racc
|
21
|
+
racc (1.7.3)
|
22
|
+
rack (2.2.8)
|
23
|
+
rack-protection (3.1.0)
|
24
|
+
rack (~> 2.2, >= 2.2.4)
|
25
|
+
rack-test (2.1.0)
|
26
|
+
rack (>= 1.3)
|
27
|
+
rainbow (3.1.1)
|
28
|
+
rake (13.1.0)
|
29
|
+
regexp_parser (2.8.2)
|
30
|
+
rexml (3.2.6)
|
31
|
+
rspec (3.12.0)
|
32
|
+
rspec-core (~> 3.12.0)
|
33
|
+
rspec-expectations (~> 3.12.0)
|
34
|
+
rspec-mocks (~> 3.12.0)
|
35
|
+
rspec-core (3.12.2)
|
36
|
+
rspec-support (~> 3.12.0)
|
37
|
+
rspec-expectations (3.12.3)
|
38
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
39
|
+
rspec-support (~> 3.12.0)
|
40
|
+
rspec-mocks (3.12.6)
|
41
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
42
|
+
rspec-support (~> 3.12.0)
|
43
|
+
rspec-support (3.12.1)
|
44
|
+
rubocop (1.57.2)
|
45
|
+
json (~> 2.3)
|
46
|
+
language_server-protocol (>= 3.17.0)
|
47
|
+
parallel (~> 1.10)
|
48
|
+
parser (>= 3.2.2.4)
|
49
|
+
rainbow (>= 2.2.2, < 4.0)
|
50
|
+
regexp_parser (>= 1.8, < 3.0)
|
51
|
+
rexml (>= 3.2.5, < 4.0)
|
52
|
+
rubocop-ast (>= 1.28.1, < 2.0)
|
53
|
+
ruby-progressbar (~> 1.7)
|
54
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
55
|
+
rubocop-ast (1.30.0)
|
56
|
+
parser (>= 3.2.1.0)
|
57
|
+
rubocop-performance (1.19.1)
|
58
|
+
rubocop (>= 1.7.0, < 2.0)
|
59
|
+
rubocop-ast (>= 0.4.0)
|
60
|
+
ruby-progressbar (1.13.0)
|
61
|
+
ruby2_keywords (0.0.5)
|
62
|
+
simplecov (0.22.0)
|
63
|
+
docile (~> 1.1)
|
64
|
+
simplecov-html (~> 0.11)
|
65
|
+
simplecov_json_formatter (~> 0.1)
|
66
|
+
simplecov-html (0.12.3)
|
67
|
+
simplecov_json_formatter (0.1.4)
|
68
|
+
sinatra (3.1.0)
|
69
|
+
mustermann (~> 3.0)
|
70
|
+
rack (~> 2.2, >= 2.2.4)
|
71
|
+
rack-protection (= 3.1.0)
|
72
|
+
tilt (~> 2.0)
|
73
|
+
tilt (2.2.0)
|
74
|
+
unicode-display_width (2.5.0)
|
75
|
+
yard (0.9.34)
|
76
|
+
|
77
|
+
PLATFORMS
|
78
|
+
x86_64-linux
|
79
|
+
|
80
|
+
DEPENDENCIES
|
81
|
+
bundler (~> 2.4)
|
82
|
+
rack-test (~> 2.1)
|
83
|
+
rake (~> 13.1)
|
84
|
+
rspec (~> 3.12)
|
85
|
+
rubocop (~> 1.57)
|
86
|
+
rubocop-performance (~> 1.19)
|
87
|
+
simplecov (~> 0.22)
|
88
|
+
sinatra-bouncer!
|
89
|
+
yard (~> 0.9)
|
90
|
+
|
91
|
+
BUNDLED WITH
|
92
|
+
2.4.19
|
data/README.md
CHANGED
@@ -1,108 +1,285 @@
|
|
1
|
-
#Sinatra-Bouncer
|
2
|
-
|
1
|
+
# Sinatra-Bouncer
|
2
|
+
|
3
|
+
Simple permissions extension for [Sinatra](http://www.sinatrarb.com/). Require the gem, then declare which
|
4
|
+
routes are permitted based on your own logic.
|
5
|
+
|
6
|
+
## Big Picture
|
7
|
+
|
8
|
+
Bouncer's syntax looks like:
|
3
9
|
|
4
|
-
**Gemfile**
|
5
10
|
```ruby
|
6
|
-
|
11
|
+
# You can define roles to collect permissions together
|
12
|
+
bouncer.role :admins do
|
13
|
+
current_user&.admin?
|
14
|
+
end
|
15
|
+
|
16
|
+
bouncer.rules do
|
17
|
+
# Routes match based on one or more strings.
|
18
|
+
anyone.can get: '/',
|
19
|
+
post: ['/user/sign-in',
|
20
|
+
'/user/sign-out']
|
21
|
+
|
22
|
+
# Wildcards match anything directly under that path
|
23
|
+
anyone.can get: '/lib/js/*'
|
24
|
+
|
25
|
+
admins.can get: '/admin/*',
|
26
|
+
post: '/admin/actions/*'
|
27
|
+
|
28
|
+
# ... etc ...
|
29
|
+
end
|
7
30
|
```
|
8
31
|
|
9
|
-
|
10
|
-
|
11
|
-
|
32
|
+
### Features
|
33
|
+
|
34
|
+
Here's what this Gem provides:
|
35
|
+
|
36
|
+
* **Block-by-default**
|
37
|
+
* Any route must be explicitly allowed
|
38
|
+
* **Role-Oriented**
|
39
|
+
* The [DSL](https://en.wikipedia.org/wiki/Domain-specific_language) is constructed to be easily readable
|
40
|
+
* **Declarative Syntax**
|
41
|
+
* Straightforward syntax reduces complexity of layered permissions
|
42
|
+
* Keeps permissions together for clarity
|
43
|
+
* **Conditional Logic Via Blocks**
|
44
|
+
* Often additional checks must be performed to know if a route is allowed.
|
45
|
+
* **Grouping**
|
46
|
+
* Routes can be matched by wildcard
|
47
|
+
* **Forced Boolean Affirmation**
|
48
|
+
* Condition blocks must explicitly return `true`, avoiding accidental truthy values
|
49
|
+
|
50
|
+
### Anti-Features
|
51
|
+
|
52
|
+
Bouncer intentionally does not support some concepts.
|
53
|
+
|
54
|
+
* **No User Identification** *(aka Authentication)*
|
55
|
+
* Bouncer is not a user identification gem. It assumes you already have an existing solution
|
56
|
+
like [Warden](https://github.com/wardencommunity/warden). Knowing *who* someone is is already a complex enough
|
57
|
+
problem and should be separate from what they may do.
|
58
|
+
* **No Rails Integration**
|
59
|
+
* Bouncer is not intended to work with Rails. Use one of the Rails-based permissions gems for these situations.
|
60
|
+
* **No Negation**
|
61
|
+
* There is intentionally no negation (eg. `cannot`) to preserve the default-deny frame of mind
|
62
|
+
|
63
|
+
## Installation
|
64
|
+
|
65
|
+
Add this to your gemfile:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
gem 'sinatra-bouncer'
|
12
69
|
```
|
13
70
|
|
14
|
-
|
15
|
-
###Step 1: Require/Register Bouncer
|
71
|
+
Then run:
|
16
72
|
|
17
|
-
|
18
|
-
|
19
|
-
|
73
|
+
```shell
|
74
|
+
bundle install
|
75
|
+
```
|
76
|
+
|
77
|
+
**Sinatra Modular Style**
|
20
78
|
|
21
|
-
**Sinatra Classic**
|
22
79
|
```ruby
|
23
|
-
require 'sinatra'
|
80
|
+
require 'sinatra/base'
|
24
81
|
require 'sinatra/bouncer'
|
25
82
|
|
83
|
+
class MyApp < Sinatra::Base
|
84
|
+
register Sinatra::Bouncer
|
85
|
+
|
86
|
+
bouncer.rules do
|
87
|
+
# ... can statements ...
|
88
|
+
end
|
89
|
+
|
26
90
|
# ... routes and other config
|
91
|
+
end
|
27
92
|
```
|
28
93
|
|
29
|
-
**
|
94
|
+
**Sinatra Classic Style**
|
95
|
+
|
30
96
|
```ruby
|
31
|
-
require 'sinatra
|
97
|
+
require 'sinatra'
|
32
98
|
require 'sinatra/bouncer'
|
33
99
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
# ... routes and other config
|
100
|
+
bouncer.rules do
|
101
|
+
# ... can statements ...
|
38
102
|
end
|
103
|
+
|
104
|
+
# ... routes and other config
|
39
105
|
```
|
40
106
|
|
41
|
-
|
42
|
-
|
43
|
-
the `
|
107
|
+
## Usage
|
108
|
+
|
109
|
+
Define roles using the `role` method and provide each one with a condition block. Then call `rules` with a block that
|
110
|
+
uses your defined roles with the `#can` or `#can_sometimes` DSL methods to declare which
|
111
|
+
paths are allowed.
|
112
|
+
|
113
|
+
The rules block is run once as part of the configuration phase but the condition blocks are evaluated in the context of
|
114
|
+
the request handler. This means they have access to Sinatra helpers, the `request` object, and `params`.
|
44
115
|
|
45
116
|
```ruby
|
46
117
|
require 'sinatra'
|
47
118
|
require 'sinatra/bouncer'
|
48
119
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
120
|
+
bouncer.role :members do
|
121
|
+
!current_user.nil?
|
122
|
+
end
|
123
|
+
|
124
|
+
bouncer.role :bots do
|
125
|
+
!request.get_header('X-CUSTOM-BOT').nil?
|
126
|
+
end
|
127
|
+
|
128
|
+
bouncer.rules do
|
129
|
+
# example: always allow GET requests to '/' and '/about'; and POST requests to '/sign-in'
|
130
|
+
anyone.can get: ['/', '/about'],
|
131
|
+
post: '/sign-in'
|
132
|
+
|
133
|
+
# example: logged in users can view (GET) member restricted paths and edit their account (POST)
|
134
|
+
members.can get: '/members/*'
|
135
|
+
members.can_sometimes post: '/members/edit-account' do
|
136
|
+
current_user && current_user.id == params[:id]
|
137
|
+
end
|
138
|
+
|
139
|
+
# example: require presence of arbitrary request header in the role condition
|
140
|
+
bots.can get: '/bots/*'
|
57
141
|
end
|
58
142
|
|
59
|
-
# ... route declarations as normal
|
143
|
+
# ... Sinatra route declarations as normal ...
|
60
144
|
```
|
61
145
|
|
62
|
-
|
63
|
-
|
64
|
-
|
146
|
+
### Role Declarations
|
147
|
+
|
148
|
+
Roles are declared using the `#role` method in your Sinatra config. Each one must be provided a condition block that
|
149
|
+
must return exactly `true` when the role applies.
|
65
150
|
|
66
151
|
```ruby
|
67
|
-
|
68
|
-
|
152
|
+
# let's pretend that current_user is a helper that returns the user from Warden
|
153
|
+
bouncer.role :admins do
|
154
|
+
current_user&.admin?
|
69
155
|
end
|
70
156
|
```
|
71
157
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
158
|
+
> **Note:** There is a default role called `anyone` that is always declared for you.
|
159
|
+
|
160
|
+
### HTTP Method and Route Matching
|
161
|
+
|
162
|
+
Both `#can` and `#can_sometimes` accept symbol
|
163
|
+
[HTTP methods](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) as keys
|
164
|
+
and each key is paired with one or more path strings.
|
165
|
+
|
166
|
+
```ruby
|
167
|
+
# example: single method, single route
|
168
|
+
anyone.can get: '/'
|
169
|
+
|
170
|
+
# example: multiple methods, single route each
|
171
|
+
anyone.can get: '/',
|
172
|
+
post: '/blog/action/save'
|
173
|
+
|
174
|
+
# example: multiple methods, multiple routes (using string array syntax)
|
175
|
+
anyone.can get: %w[/
|
176
|
+
/sign-in
|
177
|
+
/blog/editor],
|
178
|
+
post: %w[/blog/action/save
|
179
|
+
/blog/action/delete]
|
180
|
+
```
|
181
|
+
|
182
|
+
> **Note** Allowing GET implies allowing HEAD, since HEAD is by spec a GET without a response body. The reverse is not
|
183
|
+
> true, however; allowing HEAD will not also allow GET.
|
184
|
+
|
185
|
+
#### Wildcards and Special Symbols
|
186
|
+
|
187
|
+
Provide a wildcard `*` to match any string excluding slash. There is intentionally no syntax for matching wildcards
|
188
|
+
recursively, so nested paths will also need to be declared.
|
189
|
+
|
190
|
+
```ruby
|
191
|
+
# example: match anything directly under the /members/ path
|
192
|
+
members.can get: '/members/*'
|
193
|
+
```
|
194
|
+
|
195
|
+
There is also a special symbol, `:all` that matches all paths. It is intended for rare use
|
196
|
+
with superadmin-type accounts.
|
197
|
+
|
198
|
+
```ruby
|
199
|
+
# this allows GET on all paths to those in the admin group
|
200
|
+
admins.can get: :all
|
201
|
+
```
|
202
|
+
|
203
|
+
> **Warning** Always be cautious when using wildcards and special symbols to avoid accidentally opening up pathways that
|
204
|
+
> should remain private.
|
205
|
+
|
206
|
+
### Always Allow: `can`
|
207
|
+
|
208
|
+
Any route declared with `#can` will be accepted without further challenge.
|
76
209
|
|
77
210
|
```ruby
|
78
|
-
rules do
|
79
|
-
|
211
|
+
bouncer.rules do
|
212
|
+
# Anyone can access this path over GET
|
213
|
+
anyone.can get: '/login'
|
80
214
|
end
|
81
215
|
```
|
82
216
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
217
|
+
### Conditionally Allow: `can_sometimes`
|
218
|
+
|
219
|
+
`can_sometimes` takes a condition block that will be run once the path is attempted. This block **must return an
|
220
|
+
explicit boolean** (ie. `true` or `false`) to avoid any accidental truthy values creating unwanted access.
|
87
221
|
|
88
222
|
```ruby
|
89
|
-
|
90
|
-
|
223
|
+
bouncer.role :users do
|
224
|
+
!current_user.nil?
|
225
|
+
end
|
91
226
|
|
92
|
-
|
93
|
-
|
227
|
+
bouncer.rules do
|
228
|
+
users.can_sometimes post: '/user/save' do
|
229
|
+
current_user.id == params[:id]
|
230
|
+
end
|
231
|
+
end
|
94
232
|
```
|
95
233
|
|
96
234
|
### Custom Bounce Behaviour
|
97
|
-
|
235
|
+
|
236
|
+
The default bounce action is to `halt 403`. Call `bounce_with` with a block to specify your own behaviour. The block is
|
237
|
+
also run in a Sinatra request handler context, so you can use helpers here as well.
|
98
238
|
|
99
239
|
```ruby
|
100
240
|
require 'sinatra'
|
101
241
|
require 'sinatra/bouncer'
|
102
242
|
|
103
|
-
bounce_with do
|
104
|
-
|
243
|
+
bounce_with do
|
244
|
+
redirect '/login'
|
105
245
|
end
|
106
246
|
|
107
247
|
# bouncer rules, routes, etc...
|
108
248
|
```
|
249
|
+
|
250
|
+
## Alternatives
|
251
|
+
|
252
|
+
The syntax for Bouncer is largely influenced by the now-deprecated [CanCan](https://github.com/ryanb/cancan) gem.
|
253
|
+
|
254
|
+
## Contributing
|
255
|
+
|
256
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/TenjinInc/Sinatra-Bouncer.
|
257
|
+
|
258
|
+
Valued topics:
|
259
|
+
|
260
|
+
* Error messages (clarity, hinting)
|
261
|
+
* Documentation
|
262
|
+
* API
|
263
|
+
* Security correctness
|
264
|
+
|
265
|
+
This project is intended to be a friendly space for collaboration, and contributors are expected to adhere to the
|
266
|
+
[Contributor Covenant](https://www.contributor-covenant.org/) code of conduct. Play nice.
|
267
|
+
|
268
|
+
### Core Developers
|
269
|
+
|
270
|
+
After checking out the repo, run `bundle install` to install dependencies. Then, run `rake spec` to run the tests. You
|
271
|
+
can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
272
|
+
|
273
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the
|
274
|
+
version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version,
|
275
|
+
push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
276
|
+
|
277
|
+
Documentation is produced by Yard. Run `bundle exec rake yard`. The goal is to have 100% documentation coverage and 100%
|
278
|
+
test coverage.
|
279
|
+
|
280
|
+
Release notes are provided in `RELEASE_NOTES.md`, and should vaguely
|
281
|
+
follow [Keep A Changelog](https://keepachangelog.com/en/1.0.0/) recommendations.
|
282
|
+
|
283
|
+
## License
|
284
|
+
|
285
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/license/mit/).
|