sinatra-bouncer 1.3.0 → 2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6b8592539c3824fa1985a4c02b877bd7d53e6ab2635f4227b173325f16484465
4
- data.tar.gz: 1aac0ef35f8584e83cbafd5843172798f8967ad217235f9048e476cf3cc8945f
3
+ metadata.gz: f07c9c87e55563ac21610aecc8813d32ee3322d291382bb1bd5cca0ce0d55a12
4
+ data.tar.gz: fa55400409722c0f0f4ea83c6ee552654d0d8aee128d484f3a42c2c888e9b46b
5
5
  SHA512:
6
- metadata.gz: 83ed25a0acff1d864f978dbbd3667d20f53be0bea36fa5db5abd55eeb4353cad53e29ebeb424f1c462e4a8790444f4a5850cad33c579729aab684ff4f0d482aa
7
- data.tar.gz: a3caa0c02709faa60e5512f73f2b4c4f21066f519999e014ffac2545271198d8a98a7a73d430494a185a00e0ea255170e1693274c7fb8bca51b56c6108fcd8a6
6
+ metadata.gz: 4fc6e73dcb5867a418dea6b555f74fee57f41b58d75ab76657925a71b1b2ff059295135c30646f4de83fe82a00bc816a6d668d54ecd64f035b63f27d68b80ef1
7
+ data.tar.gz: ca808e79a1f59743c17afc6e7475dd03a9a3186d8ed1ec3c6b4412ec96af2c38c0e454a0fada15c513e83c1070eb7b6f72c2a116be9e2ed7135592ce7f04ce70
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
- core/config.yml
21
- persist/database.yml
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'
@@ -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.0'
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 'capybara', '~> 3.39'
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 (2.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,268 @@
1
- #Sinatra-Bouncer
2
- Simple authorization permissions extension for [Sinatra](http://www.sinatrarb.com/). Require the gem, then declare which routes are permitted based on your own logic.
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 rules look like:
3
9
 
4
- **Gemfile**
5
10
  ```ruby
6
- gem 'sinatra-bouncer'
7
- ```
11
+ rules do
12
+ # Routes match based on one or more strings.
13
+ can get: '/',
14
+ post: %w[/user/sign-in
15
+ /user/sign-out]
16
+
17
+ # Wildcards match anything directly under that path
18
+ can get: '/lib/js/*'
19
+
20
+ # Use a conditional rule block for additional logic
21
+ can_sometimes get: '/admin/*',
22
+ post: '/admin/actions/*' do
23
+ current_user.admin?
24
+ end
25
+
26
+ # ... etc ...
27
+ end
8
28
 
9
- **Terminal**
10
- ```sh
11
- gem install sinatra-bouncer
12
29
  ```
13
30
 
14
- ##Quickstart
15
- ###Step 1: Require/Register Bouncer
31
+ ## Features
16
32
 
17
- After registration, Bouncer will reject any request that either:
18
- * has no rule associated with it, or
19
- * has no associated rule that returns `true`
33
+ Here's what this Gem provides:
34
+
35
+ * **Block-by-default**
36
+ * Any route must be explicitly allowed
37
+ * **Declarative Syntax**
38
+ * Straightforward syntax reduces complexity of layered permissions
39
+ * Keeps permissions together for clarity
40
+ * **Conditional Logic Via Blocks**
41
+ * Often additional checks must be performed to know if a route is allowed.
42
+ * **Grouping**
43
+ * Routes can be matched by wildcard
44
+ * **Forced Boolean Affirmation**
45
+ * Condition blocks must explicitly return `true`, avoiding accidental truthy values
46
+
47
+ ## Anti-Features
48
+
49
+ Bouncer intentionally does not support some concepts.
50
+
51
+ * **No User Identification** *(aka Authentication)*
52
+ * Bouncer is not a user identification gem. It assumes you already have an existing solution
53
+ like [Warden](https://github.com/wardencommunity/warden). Knowing *who* someone is is already a complex enough
54
+ problem and should be separate from what they may do.
55
+ * **No Rails Integration**
56
+ * Bouncer is not intended to work with Rails. Use one of the Rails-based permissions gems for these situations.
57
+ * **No Negation**
58
+ * There is intentionally no negation (eg. `cannot`) to preserve the default-deny frame of mind
59
+
60
+ ## Installation
61
+
62
+ Add this to your gemfile:
20
63
 
21
- **Sinatra Classic**
22
64
  ```ruby
23
- require 'sinatra'
24
- require 'sinatra/bouncer'
65
+ gem 'sinatra-bouncer'
66
+ ```
25
67
 
26
- # ... routes and other config
68
+ Then run:
69
+
70
+ ```shell
71
+ bundle install
27
72
  ```
28
73
 
29
- **Modular**
74
+ **Sinatra Modular Style**
75
+
30
76
  ```ruby
31
77
  require 'sinatra/base'
32
78
  require 'sinatra/bouncer'
33
79
 
34
80
  class MyApp < Sinatra::Base
35
- register Sinatra::Bouncer
36
-
37
- # ... routes and other config
81
+ register Sinatra::Bouncer
82
+
83
+ rules do
84
+ # ... can statements ...
85
+ end
86
+
87
+ # ... routes and other config
38
88
  end
39
89
  ```
40
90
 
41
- ###Step 2: Declare Bouncer Rules
42
- Call `rules` with a block that uses `can` and `can_sometimes` to declare which paths are legalduring this request. The rules block is run in the context of the request, which means you will have access to sinatra helpers,
43
- the `request` object, and `params`.
91
+ **Sinatra Classic Style**
44
92
 
45
93
  ```ruby
46
94
  require 'sinatra'
47
95
  require 'sinatra/bouncer'
48
96
 
49
97
  rules do
50
- # example: allow any GET request
51
- can(:get, :all)
52
-
53
- # example: logged in users can edit their account
54
- if(current_user)
55
- can(:post, '/user_edits_account')
56
- end
98
+ # ... can statements ...
57
99
  end
58
100
 
59
- # ... route declarations as normal below
101
+ # ... routes and other config
60
102
  ```
61
103
 
62
- ## API
63
- #### can
64
- Any route declared with #can will be accepted without further challenge.
104
+ ## Usage
105
+
106
+ Call `rules` with a block that uses the `#can` and `#can_sometimes` DSL methods to declare rules for paths.
107
+
108
+ The rules block is run once as part of the configuration phase but the condition blocks are evaluated in the context of
109
+ the
110
+ request, which means you will have access to Sinatra helpers,
111
+ the `request` object, and `params`.
65
112
 
66
113
  ```ruby
114
+ require 'sinatra'
115
+ require 'sinatra/bouncer'
116
+
67
117
  rules do
68
- can(:post, '/user_posts_blog')
118
+ # example: always allow GET requests to root path or /sign-in
119
+ can get: %w[/
120
+ /sign-in]
121
+
122
+ # example: logged in users can view (GET) member restricted paths and edit their account (POST)
123
+ can_sometimes get: '/members/*',
124
+ post: '/members/edit-account' do
125
+ !current_user.nil?
126
+ end
127
+
128
+ # example: check an arbitrary request header is present
129
+ can_sometimes get: '/bots/*' do
130
+ !request.get_header('X-CUSTOM_PROP').nil?
131
+ end
69
132
  end
133
+
134
+ # ... Sinatra route declarations as normal ...
70
135
  ```
71
136
 
72
- ####can_sometimes
73
- `can_sometimes` is for occasions that you to check further, but want to defer that choice until the path is actually attempted.
74
- `can_sometimes` takes a block that will be run once the path is attempted. This block **must return an explicit boolean**
75
- (ie. `true` or `false`) to avoid any accidental truthy values creating unwanted access.
137
+ ### HTTP Method and Route Matching
138
+
139
+ Both `#can` and `#can_sometimes` accept multiple
140
+ [HTTP methods](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) as symbols
141
+ and each key is paired with one or more path strings.
142
+
143
+ ```ruby
144
+ # example: single method, single route
145
+ can get: '/'
146
+
147
+ # example: multiple methods, single route each
148
+ can get: '/',
149
+ post: '/blog/action/save'
150
+
151
+ # example: multiple methods, multiple routes (using string array syntax)
152
+ can get: %w[/
153
+ /sign-in
154
+ /blog/editor],
155
+ post: %w[/blog/action/save
156
+ /blog/action/delete]
157
+ ```
158
+
159
+ > **Note** Allowing GET implies allowing HEAD, since HEAD is by spec a GET without a response body. The reverse is not
160
+ > true, however; allowing HEAD will not also allow GET.
161
+
162
+ #### Wildcards and Special Symbols
163
+
164
+ > **Warning** Always be cautious when using wildcards and special symbols to not accidentally open up pathways that
165
+ > should remain private.
166
+
167
+ Provide a wildcard `*` to match any string excluding slash. There is intentionally no syntax for matching wildcards
168
+ recursively, so nested paths will also need to be declared.
169
+
170
+ ```ruby
171
+ # example: match anything directly under the /members/ path
172
+ can get: '/members/*'
173
+ ```
174
+
175
+ There are also 2 special symbols:
176
+
177
+ 1. `:any` will match any HTTP method.
178
+ 2. `:all` will match all paths.
179
+
180
+ ```ruby
181
+ # this allows any method type on the / path
182
+ can any: '/'
183
+
184
+ # this allows GET on all paths
185
+ can get: :all
186
+ ```
187
+
188
+ ### Always Allow: `can`
189
+
190
+ Any route declared with `#can` will be accepted without further challenge.
76
191
 
77
192
  ```ruby
78
193
  rules do
79
- can_sometimes('/login') # Anyone can access this path
194
+ # Anyone can access this path over GET
195
+ can get: '/login'
80
196
  end
81
197
  ```
82
198
 
83
- #### :any and :all special parameters
84
- Passing `can` or `can_sometimes`:
85
- * `:any` to the first parameter will match any HTTP method.
86
- * `:all` to the second parameter will match any path.
199
+ ### Conditionally Allow: `can_sometimes`
200
+
201
+ `can_sometimes` is for occasions that you to check further, but want to defer that choice until the path is actually
202
+ attempted.
203
+ `can_sometimes` takes a block that will be run once the path is attempted. This block **must return an explicit boolean
204
+ **
205
+ (ie. `true` or `false`) to avoid any accidental truthy values creating unwanted access.
87
206
 
88
207
  ```ruby
89
- # this allows get on all paths
90
- can(:get, :all)
208
+ rules do
209
+ can_sometimes get: '/login' # Anyone can access this path over GET
91
210
 
92
- # this allows any method type to run on the /login path
93
- can(:any, '/login')
211
+ can_sometimes post: '/user/blog/actions/save' do
212
+ !current_user.nil?
213
+ end
214
+ end
94
215
  ```
95
216
 
96
217
  ### Custom Bounce Behaviour
97
- The default bounce action is to `halt 403`. Call `bounce_with` with a block to specify your own behaviour. The block is also run in a sinatra request context, so you can use helpers here as well.
218
+
219
+ The default bounce action is to `halt 403`. Call `bounce_with` with a block to specify your own behaviour. The block is
220
+ also run in a sinatra request context, so you can use helpers here as well.
98
221
 
99
222
  ```ruby
100
223
  require 'sinatra'
101
224
  require 'sinatra/bouncer'
102
225
 
103
- bounce_with do
104
- redirect '/login'
226
+ bounce_with do
227
+ redirect '/login'
105
228
  end
106
229
 
107
230
  # bouncer rules, routes, etc...
108
231
  ```
232
+
233
+ ## Alternatives
234
+
235
+ The syntax for Bouncer is largely influenced by the now-deprecated [CanCan](https://github.com/ryanb/cancan) gem.
236
+
237
+ ## Contributing
238
+
239
+ Bug reports and pull requests are welcome on GitHub at https://github.com/TenjinInc/Sinatra-Bouncer.
240
+
241
+ Valued topics:
242
+
243
+ * Error messages (clarity, hinting)
244
+ * Documentation
245
+ * API
246
+ * Security correctness
247
+
248
+ This project is intended to be a friendly space for collaboration, and contributors are expected to adhere to the
249
+ [Contributor Covenant](https://www.contributor-covenant.org/) code of conduct. Play nice.
250
+
251
+ ### Core Developers
252
+
253
+ After checking out the repo, run `bundle install` to install dependencies. Then, run `rake spec` to run the tests. You
254
+ can also run `bin/console` for an interactive prompt that will allow you to experiment.
255
+
256
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the
257
+ version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version,
258
+ push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
259
+
260
+ Documentation is produced by Yard. Run `bundle exec rake yard`. The goal is to have 100% documentation coverage and 100%
261
+ test coverage.
262
+
263
+ Release notes are provided in `RELEASE_NOTES.md`, and should vaguely
264
+ follow [Keep A Changelog](https://keepachangelog.com/en/1.0.0/) recommendations.
265
+
266
+ ## License
267
+
268
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/license/mit/).
data/RELEASE_NOTES.md ADDED
@@ -0,0 +1,153 @@
1
+ # Release Notes
2
+
3
+ All notable changes to this project will be documented below.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project loosely follows
6
+ [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Major Changes
11
+
12
+ * none
13
+
14
+ ### Minor Changes
15
+
16
+ * none
17
+
18
+ ### Bugfixes
19
+
20
+ * none
21
+
22
+ ## [2.0.0] - 2023-11-13
23
+
24
+ ### Major Changes
25
+
26
+ * Converted to hash syntax in `can` and `can_sometimes` statements
27
+
28
+ ### Minor Changes
29
+
30
+ * Converted Cucumber tests to Rspec integration tests for consistency
31
+ * HEAD requests are evaluated like GET requests due to semantic equivalence
32
+ * Falsey values are now acceptable rule block results
33
+
34
+ ### Bugfixes
35
+
36
+ * none
37
+
38
+ ## [1.3.0] - 2023-09-13
39
+
40
+ ### Major Changes
41
+
42
+ * none
43
+
44
+ ### Minor Changes
45
+
46
+ * Increased minimum Ruby to 3.1
47
+ * Cleaned up development dependencies
48
+ * Rubocop cleanups
49
+ * Installed Simplecov
50
+ * Created Rakefile
51
+
52
+ ### Bugfixes
53
+
54
+ * none
55
+
56
+ ## [1.2.0] - 2016-10-02
57
+
58
+ ### Major Changes
59
+
60
+ * none
61
+
62
+ ### Minor Changes
63
+
64
+ * Supports wildcard matches in route strings
65
+
66
+ ### Bugfixes
67
+
68
+ * none
69
+
70
+ ## [1.1.1] - 2015-06-02
71
+
72
+ ### Major Changes
73
+
74
+ * none
75
+
76
+ ### Minor Changes
77
+
78
+ * none
79
+
80
+ ### Bugfixes
81
+
82
+ * Runs `bounce_with` in context of web request
83
+
84
+ ## [1.1.0] - 2015-05-28
85
+
86
+ ### Major Changes
87
+
88
+ * none
89
+
90
+ ### Minor Changes
91
+
92
+ * none
93
+
94
+ ### Bugfixes
95
+
96
+ * Correctly forgets rules between routes
97
+
98
+ ## [1.0.2] - 2015-05-24
99
+
100
+ ### Major Changes
101
+
102
+ * none
103
+
104
+ ### Minor Changes
105
+
106
+ * Changed default halt to 403
107
+ * Application available in rule block
108
+
109
+ ### Bugfixes
110
+
111
+ * Fixed sinatra module registration
112
+
113
+ ## [1.0.1] - 2015-05-21
114
+
115
+ ### Major Changes
116
+
117
+ * none
118
+
119
+ ### Minor Changes
120
+
121
+ * none
122
+
123
+ ### Bugfixes
124
+
125
+ * none
126
+
127
+ ## [1.0.0] - Unreleased Prototype
128
+
129
+ ### Major Changes
130
+
131
+ * none
132
+
133
+ ### Minor Changes
134
+
135
+ * none
136
+
137
+ ### Bugfixes
138
+
139
+ * none
140
+
141
+ ## [0.1.0] - Unreleased Prototype
142
+
143
+ ### Major Changes
144
+
145
+ * Initial prototype
146
+
147
+ ### Minor Changes
148
+
149
+ * none
150
+
151
+ ### Bugfixes
152
+
153
+ * none