abilities 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +109 -0
- data/lib/abilities/action_controller/base.rb +8 -0
- data/lib/abilities/version.rb +1 -1
- data/test/changes_test.rb +1 -1
- data/test/checking_test.rb +8 -8
- data/test/controller_test.rb +3 -3
- data/test/dummy/config/environments/production.rb +5 -1
- data/test/dummy/config/environments/test.rb +9 -1
- data/test/dummy/log/test.log +90 -0
- data/test/generator_test.rb +1 -1
- data/test/view_test.rb +2 -2
- metadata +8 -8
- data/README.rdoc +0 -91
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c4eb5080e3c04dbef1447c67bdc08837aa9f378
|
4
|
+
data.tar.gz: 082e45aec19fbee6bae90078bf74a3713b86d68e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c2f1c2a5d46bbfabf1112982c9c15679c087d1bf09fb008248a8b0b4b7b9f85c2fe2dffda59d53842bd4c33d95c1bfc89a68dc7165a1634159c3df7dc28bfb24
|
7
|
+
data.tar.gz: e88f78ba38a3e2c8e7f6682f8ea7d9f79768450149677b1744ddb7976d0f98e549933edc4d4ce41a31c8676dd8476929a50c7eabb89f21609a35da8d99be7a29
|
data/MIT-LICENSE
CHANGED
data/README.md
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/abilities.svg)](http://badge.fury.io/rb/abilities) [![Code Climate](https://codeclimate.com/github/museways/abilities/badges/gpa.svg)](https://codeclimate.com/github/museways/abilities) [![Build Status](https://travis-ci.org/museways/abilities.svg?branch=master)](https://travis-ci.org/museways/abilities) [![Dependency Status](https://gemnasium.com/museways/abilities.svg)](https://gemnasium.com/museways/abilities)
|
2
|
+
|
3
|
+
# Abilities
|
4
|
+
|
5
|
+
Minimalistic authorization inspired in cancan for rails.
|
6
|
+
|
7
|
+
## Install
|
8
|
+
|
9
|
+
Put this line in your Gemfile:
|
10
|
+
```ruby
|
11
|
+
gem 'abilities'
|
12
|
+
```
|
13
|
+
|
14
|
+
Then bundle:
|
15
|
+
```
|
16
|
+
$ bundle
|
17
|
+
```
|
18
|
+
|
19
|
+
## Configuration
|
20
|
+
|
21
|
+
Generate the abilities initializer:
|
22
|
+
```
|
23
|
+
bundle exec rails g abilities:install
|
24
|
+
```
|
25
|
+
|
26
|
+
Ensure there is a current_user helper available in your controllers and views:
|
27
|
+
```ruby
|
28
|
+
class ApplicationController < ActionController::Base
|
29
|
+
helper :current_user
|
30
|
+
def current_user
|
31
|
+
@current_user ||= User.find_by(id: session[:user_id])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
```
|
35
|
+
|
36
|
+
NOTE: The gem will look for a User model and include Abilities::Concern into it.
|
37
|
+
|
38
|
+
## Usage
|
39
|
+
|
40
|
+
### Defining
|
41
|
+
|
42
|
+
All the abilities are defined in config/initializers/abilities.rb by can and cannot methods:
|
43
|
+
```ruby
|
44
|
+
Abilities.define do
|
45
|
+
can :create, Post
|
46
|
+
cannot :destroy, User unless admin?
|
47
|
+
can :edit, Post do |post|
|
48
|
+
post.user == self
|
49
|
+
end
|
50
|
+
can :manage, User
|
51
|
+
can :touch, :all
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
If you want to load the abilities from the database you may do something like this:
|
56
|
+
```ruby
|
57
|
+
Abilities.define do
|
58
|
+
permissions.each do |permission|
|
59
|
+
can premissions.action, permissions.subject
|
60
|
+
end
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
64
|
+
NOTE: Any method besides can and cannot references the current_user.
|
65
|
+
|
66
|
+
### Checking
|
67
|
+
|
68
|
+
#### Controllers
|
69
|
+
|
70
|
+
With the authorize! method Abilities::AccessDenied is raised if authorization fails:
|
71
|
+
```ruby
|
72
|
+
class PostsController < ApplicationController
|
73
|
+
def edit
|
74
|
+
@post = Post.find(params[:id])
|
75
|
+
authorize! :edit, @post
|
76
|
+
end
|
77
|
+
end
|
78
|
+
```
|
79
|
+
|
80
|
+
If you don't want an exception to be raised use can? and cannot? helpers:
|
81
|
+
```ruby
|
82
|
+
class UsersController < ApplicationController
|
83
|
+
def edit
|
84
|
+
@post = Post.find(params[:id])
|
85
|
+
if can? :edit, @post
|
86
|
+
@post.update post_params
|
87
|
+
else
|
88
|
+
# handle access denied
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
```
|
93
|
+
|
94
|
+
#### Views
|
95
|
+
|
96
|
+
The helpers can? and cannot? are available here too:
|
97
|
+
```erb
|
98
|
+
<% if can? :create, Post %>
|
99
|
+
<%= link_to new_post_path %>
|
100
|
+
<% end %>
|
101
|
+
```
|
102
|
+
|
103
|
+
## Credits
|
104
|
+
|
105
|
+
This gem is maintained and funded by [museways](http://museways.com).
|
106
|
+
|
107
|
+
## License
|
108
|
+
|
109
|
+
It is free software, and may be redistributed under the terms specified in the MIT-LICENSE file.
|
data/lib/abilities/version.rb
CHANGED
data/test/changes_test.rb
CHANGED
data/test/checking_test.rb
CHANGED
@@ -2,43 +2,43 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
class CheckingTest < ActiveSupport::TestCase
|
4
4
|
|
5
|
-
test
|
5
|
+
test 'can definition with model' do
|
6
6
|
assert user.can?(:create, Post)
|
7
7
|
assert !user.cannot?(:create, Post)
|
8
8
|
end
|
9
9
|
|
10
|
-
test
|
10
|
+
test 'can definition with instance' do
|
11
11
|
assert user.can?(:create, post)
|
12
12
|
assert !user.cannot?(:create, post)
|
13
13
|
end
|
14
14
|
|
15
|
-
test
|
15
|
+
test 'cannot definition' do
|
16
16
|
assert user.cannot?('read', post)
|
17
17
|
assert !user.can?('read', post)
|
18
18
|
end
|
19
19
|
|
20
|
-
test
|
20
|
+
test 'ability conditions' do
|
21
21
|
assert admin_user.can?(:destroy, post)
|
22
22
|
assert user.cannot?(:destroy, post)
|
23
23
|
end
|
24
24
|
|
25
|
-
test
|
25
|
+
test 'ability block' do
|
26
26
|
assert user.can?(:edit, post_with_user)
|
27
27
|
end
|
28
28
|
|
29
|
-
test
|
29
|
+
test 'manage action' do
|
30
30
|
assert user.can?(:create, User)
|
31
31
|
assert user.can?(:read, user)
|
32
32
|
assert user.can?(:edit, user)
|
33
33
|
assert user.can?(:destroy, user)
|
34
34
|
end
|
35
35
|
|
36
|
-
test
|
36
|
+
test 'all subject' do
|
37
37
|
assert user.can?(:touch, post)
|
38
38
|
assert user.can?(:touch, user)
|
39
39
|
end
|
40
40
|
|
41
|
-
test
|
41
|
+
test 'undefined definition' do
|
42
42
|
assert user.cannot?(:other, post)
|
43
43
|
assert user.cannot?(:other, post)
|
44
44
|
end
|
data/test/controller_test.rb
CHANGED
@@ -2,15 +2,15 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
class ControllerTest < ActiveSupport::TestCase
|
4
4
|
|
5
|
-
test
|
5
|
+
test 'can helper' do
|
6
6
|
assert controller.send(:can?, :create, post)
|
7
7
|
end
|
8
8
|
|
9
|
-
test
|
9
|
+
test 'cannot helper' do
|
10
10
|
assert controller.send(:cannot?, :read, post)
|
11
11
|
end
|
12
12
|
|
13
|
-
test
|
13
|
+
test 'authorize helper' do
|
14
14
|
assert_nothing_raised do
|
15
15
|
controller.send :authorize!, :create, post
|
16
16
|
end
|
@@ -20,7 +20,11 @@ Dummy::Application.configure do
|
|
20
20
|
# config.action_dispatch.rack_cache = true
|
21
21
|
|
22
22
|
# Disable Rails's static asset server (Apache or nginx will already do this).
|
23
|
-
|
23
|
+
if Rails::VERSION::MAJOR == 4 && Rails::VERSION::MINOR >= 2
|
24
|
+
config.serve_static_files = false
|
25
|
+
else
|
26
|
+
config.serve_static_assets = false
|
27
|
+
end
|
24
28
|
|
25
29
|
# Compress JavaScripts and CSS.
|
26
30
|
config.assets.js_compressor = :uglifier
|
@@ -13,7 +13,11 @@ Dummy::Application.configure do
|
|
13
13
|
config.eager_load = false
|
14
14
|
|
15
15
|
# Configure static asset server for tests with Cache-Control for performance.
|
16
|
-
|
16
|
+
if Rails::VERSION::MAJOR == 4 && Rails::VERSION::MINOR >= 2
|
17
|
+
config.serve_static_files = false
|
18
|
+
else
|
19
|
+
config.serve_static_assets = false
|
20
|
+
end
|
17
21
|
config.static_cache_control = 'public, max-age=3600'
|
18
22
|
|
19
23
|
# Show full error reports and disable caching.
|
@@ -36,4 +40,8 @@ Dummy::Application.configure do
|
|
36
40
|
|
37
41
|
# Raises error for missing translations
|
38
42
|
# config.action_view.raise_on_missing_translations = true
|
43
|
+
|
44
|
+
if Rails::VERSION::MAJOR == 4 && Rails::VERSION::MINOR >= 2
|
45
|
+
config.active_support.test_order = :random
|
46
|
+
end
|
39
47
|
end
|
data/test/dummy/log/test.log
CHANGED
@@ -5320,3 +5320,93 @@ CheckingTest: test_undefined_definition
|
|
5320
5320
|
GeneratorsTest: test_generate_initializer
|
5321
5321
|
-----------------------------------------
|
5322
5322
|
[1m[36m (0.1ms)[0m [1mrollback transaction[0m
|
5323
|
+
[1m[36m (0.3ms)[0m [1mCREATE TABLE "posts" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "content" text, "user_id" integer, "created_at" datetime, "updated_at" datetime) [0m
|
5324
|
+
[1m[35m (0.1ms)[0m CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "email" varchar, "admin" boolean, "created_at" datetime, "updated_at" datetime)
|
5325
|
+
[1m[36m (0.1ms)[0m [1mCREATE TABLE "schema_migrations" ("version" varchar NOT NULL) [0m
|
5326
|
+
[1m[35m (0.1ms)[0m select sqlite_version(*)
|
5327
|
+
[1m[36m (0.1ms)[0m [1mCREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version")[0m
|
5328
|
+
[1m[35m (0.1ms)[0m SELECT version FROM "schema_migrations"
|
5329
|
+
[1m[36m (0.1ms)[0m [1mINSERT INTO "schema_migrations" (version) VALUES ('20140629203412')[0m
|
5330
|
+
[1m[35m (0.1ms)[0m INSERT INTO "schema_migrations" (version) VALUES ('20140629203344')
|
5331
|
+
[1m[36m (0.4ms)[0m [1mCREATE TABLE "posts" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "content" text, "user_id" integer, "created_at" datetime, "updated_at" datetime) [0m
|
5332
|
+
[1m[35m (0.1ms)[0m CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "email" varchar, "admin" boolean, "created_at" datetime, "updated_at" datetime)
|
5333
|
+
[1m[36m (0.1ms)[0m [1mCREATE TABLE "schema_migrations" ("version" varchar NOT NULL) [0m
|
5334
|
+
[1m[35m (0.1ms)[0m select sqlite_version(*)
|
5335
|
+
[1m[36m (0.1ms)[0m [1mCREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version")[0m
|
5336
|
+
[1m[35m (0.1ms)[0m SELECT version FROM "schema_migrations"
|
5337
|
+
[1m[36m (0.1ms)[0m [1mINSERT INTO "schema_migrations" (version) VALUES ('20140629203412')[0m
|
5338
|
+
[1m[35m (0.1ms)[0m begin transaction
|
5339
|
+
-------------------------------------
|
5340
|
+
ControllerTest: test_authorize_helper
|
5341
|
+
-------------------------------------
|
5342
|
+
[1m[36m (0.1ms)[0m [1mrollback transaction[0m
|
5343
|
+
[1m[35m (0.1ms)[0m begin transaction
|
5344
|
+
----------------------------------
|
5345
|
+
ControllerTest: test_cannot_helper
|
5346
|
+
----------------------------------
|
5347
|
+
[1m[36m (0.0ms)[0m [1mrollback transaction[0m
|
5348
|
+
[1m[35m (0.1ms)[0m begin transaction
|
5349
|
+
-------------------------------
|
5350
|
+
ControllerTest: test_can_helper
|
5351
|
+
-------------------------------
|
5352
|
+
[1m[36m (0.0ms)[0m [1mrollback transaction[0m
|
5353
|
+
[1m[35m (0.1ms)[0m begin transaction
|
5354
|
+
--------------------------------
|
5355
|
+
ChangesTest: test_record_changes
|
5356
|
+
--------------------------------
|
5357
|
+
[1m[36m (0.0ms)[0m [1mrollback transaction[0m
|
5358
|
+
[1m[35m (0.1ms)[0m begin transaction
|
5359
|
+
-------------------------
|
5360
|
+
ViewTest: test_can_helper
|
5361
|
+
-------------------------
|
5362
|
+
[1m[36m (0.1ms)[0m [1mrollback transaction[0m
|
5363
|
+
[1m[35m (0.0ms)[0m begin transaction
|
5364
|
+
----------------------------
|
5365
|
+
ViewTest: test_cannot_helper
|
5366
|
+
----------------------------
|
5367
|
+
[1m[36m (0.0ms)[0m [1mrollback transaction[0m
|
5368
|
+
[1m[35m (0.1ms)[0m begin transaction
|
5369
|
+
--------------------------------------------
|
5370
|
+
CheckingTest: test_can_definition_with_model
|
5371
|
+
--------------------------------------------
|
5372
|
+
[1m[36m (0.1ms)[0m [1mrollback transaction[0m
|
5373
|
+
[1m[35m (0.1ms)[0m begin transaction
|
5374
|
+
------------------------------------
|
5375
|
+
CheckingTest: test_cannot_definition
|
5376
|
+
------------------------------------
|
5377
|
+
[1m[36m (0.1ms)[0m [1mrollback transaction[0m
|
5378
|
+
[1m[35m (0.1ms)[0m begin transaction
|
5379
|
+
--------------------------------
|
5380
|
+
CheckingTest: test_manage_action
|
5381
|
+
--------------------------------
|
5382
|
+
[1m[36m (0.1ms)[0m [1mrollback transaction[0m
|
5383
|
+
[1m[35m (0.1ms)[0m begin transaction
|
5384
|
+
-----------------------------------------------
|
5385
|
+
CheckingTest: test_can_definition_with_instance
|
5386
|
+
-----------------------------------------------
|
5387
|
+
[1m[36m (0.0ms)[0m [1mrollback transaction[0m
|
5388
|
+
[1m[35m (0.0ms)[0m begin transaction
|
5389
|
+
------------------------------
|
5390
|
+
CheckingTest: test_all_subject
|
5391
|
+
------------------------------
|
5392
|
+
[1m[36m (0.1ms)[0m [1mrollback transaction[0m
|
5393
|
+
[1m[35m (0.0ms)[0m begin transaction
|
5394
|
+
---------------------------------------
|
5395
|
+
CheckingTest: test_undefined_definition
|
5396
|
+
---------------------------------------
|
5397
|
+
[1m[36m (0.1ms)[0m [1mrollback transaction[0m
|
5398
|
+
[1m[35m (0.1ms)[0m begin transaction
|
5399
|
+
-------------------------------------
|
5400
|
+
CheckingTest: test_ability_conditions
|
5401
|
+
-------------------------------------
|
5402
|
+
[1m[36m (0.1ms)[0m [1mrollback transaction[0m
|
5403
|
+
[1m[35m (0.1ms)[0m begin transaction
|
5404
|
+
--------------------------------
|
5405
|
+
CheckingTest: test_ability_block
|
5406
|
+
--------------------------------
|
5407
|
+
[1m[36m (0.1ms)[0m [1mrollback transaction[0m
|
5408
|
+
[1m[35m (0.1ms)[0m begin transaction
|
5409
|
+
------------------------------------------
|
5410
|
+
GeneratorsTest: test_initializer_generator
|
5411
|
+
------------------------------------------
|
5412
|
+
[1m[36m (0.1ms)[0m [1mrollback transaction[0m
|
data/test/generator_test.rb
CHANGED
data/test/view_test.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: abilities
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Museways
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-02-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -16,8 +16,8 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
20
|
-
- - "
|
19
|
+
version: 4.0.0
|
20
|
+
- - "<="
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: 4.2.0
|
23
23
|
type: :runtime
|
@@ -26,8 +26,8 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
30
|
-
- - "
|
29
|
+
version: 4.0.0
|
30
|
+
- - "<="
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 4.2.0
|
33
33
|
- !ruby/object:Gem::Dependency
|
@@ -52,7 +52,7 @@ extensions: []
|
|
52
52
|
extra_rdoc_files: []
|
53
53
|
files:
|
54
54
|
- MIT-LICENSE
|
55
|
-
- README.
|
55
|
+
- README.md
|
56
56
|
- Rakefile
|
57
57
|
- lib/abilities.rb
|
58
58
|
- lib/abilities/action_controller/base.rb
|
@@ -132,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
132
132
|
version: '0'
|
133
133
|
requirements: []
|
134
134
|
rubyforge_project:
|
135
|
-
rubygems_version: 2.
|
135
|
+
rubygems_version: 2.4.5
|
136
136
|
signing_key:
|
137
137
|
specification_version: 4
|
138
138
|
summary: Abilities for rails.
|
data/README.rdoc
DELETED
@@ -1,91 +0,0 @@
|
|
1
|
-
{<img src="https://badge.fury.io/rb/abilities.png" alt="Gem Version" />}[http://badge.fury.io/rb/abilities] {<img src="https://codeclimate.com/github/museways/abilities.png" />}[https://codeclimate.com/github/museways/abilities] {<img src="https://travis-ci.org/museways/abilities.png?branch=master" alt="Build Status" />}[https://travis-ci.org/museways/abilities]
|
2
|
-
|
3
|
-
= Abilities
|
4
|
-
|
5
|
-
Minimalistic authorization inspired in cancan for rails.
|
6
|
-
|
7
|
-
= Install
|
8
|
-
|
9
|
-
Put this line in your Gemfile:
|
10
|
-
gem 'abilities'
|
11
|
-
|
12
|
-
Then bundle:
|
13
|
-
$ bundle
|
14
|
-
|
15
|
-
= Configuration
|
16
|
-
|
17
|
-
Generate the abilities initializer:
|
18
|
-
bundle exec rails g abilities:install
|
19
|
-
|
20
|
-
Ensure there is a current_user helper available in your controllers and views:
|
21
|
-
class ApplicationController < ActionController::Base
|
22
|
-
helper :current_user
|
23
|
-
def current_user
|
24
|
-
@current_user ||= User.find_by(id: session[:user_id])
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
NOTE: The gem will look for a User model and include Abilities::Concern into it.
|
29
|
-
|
30
|
-
= Usage
|
31
|
-
|
32
|
-
== Defining
|
33
|
-
|
34
|
-
All the abilities are defined in config/initializers/abilities.rb by can and cannot methods:
|
35
|
-
Abilities.define do
|
36
|
-
can :create, Post
|
37
|
-
cannot :destroy, User unless admin?
|
38
|
-
can :edit, Post do |post|
|
39
|
-
post.user == self
|
40
|
-
end
|
41
|
-
can :manage, :user
|
42
|
-
can :touch, :all
|
43
|
-
end
|
44
|
-
|
45
|
-
If you want to load the abilities from the database you may do something like this:
|
46
|
-
Abilities.define do
|
47
|
-
permissions.each do |permission|
|
48
|
-
can premissions.action, permissions.subject
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
NOTE: Any method besides can and cannot references the current_user.
|
53
|
-
|
54
|
-
== Checking
|
55
|
-
|
56
|
-
=== Controllers
|
57
|
-
|
58
|
-
With the authorize! method Abilities::AccessDenied is raised if authorization fails:
|
59
|
-
class PostsController < ApplicationController
|
60
|
-
def edit
|
61
|
-
@post = Post.find(params[:id])
|
62
|
-
authorize! :edit, @post
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
If you don't want an exception to be raised use can? and cannot? helpers:
|
67
|
-
class UsersController < ApplicationController
|
68
|
-
def edit
|
69
|
-
@post = Post.find(params[:id])
|
70
|
-
if can? :edit, @post
|
71
|
-
@post.update post_params
|
72
|
-
else
|
73
|
-
# handle access denied
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
=== Views
|
79
|
-
|
80
|
-
The helpers can? and cannot? are available here too:
|
81
|
-
<% if can? :create, Post %>
|
82
|
-
<%= link_to new_post_path %>
|
83
|
-
<% end %>
|
84
|
-
|
85
|
-
= Credits
|
86
|
-
|
87
|
-
This gem is maintained and funded by museways[http://museways.com].
|
88
|
-
|
89
|
-
= License
|
90
|
-
|
91
|
-
It is free software, and may be redistributed under the terms specified in the MIT-LICENSE file.
|