oo 0.9.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +0 -1
- data/README.md +145 -15
- data/lib/generators/oo/install_generator.rb +2 -2
- data/lib/generators/oo/templates/initializer.rb +7 -7
- data/lib/oo.rb +10 -10
- data/lib/oo/check_license.rb +19 -0
- data/lib/oo/configuration.rb +26 -26
- data/lib/oo/errors/default_license_keys_invalid.rb +9 -0
- data/lib/oo/errors/license_checkers_default_key_invalid.rb +9 -0
- data/lib/oo/errors/license_checkers_default_user_invalid.rb +9 -0
- data/lib/oo/errors/{licence_max_depth_invalid.rb → license_max_depth_invalid.rb} +2 -2
- data/lib/oo/errors/{licence_missing.rb → license_missing.rb} +4 -4
- data/lib/oo/errors/license_missing_reaction_invalid.rb +9 -0
- data/lib/oo/{licence.rb → license.rb} +2 -2
- data/lib/oo/license_checkers.rb +34 -0
- data/lib/oo/{licence_user.rb → license_user.rb} +4 -4
- data/lib/oo/version.rb +1 -1
- data/spec/factories/licences.rb +2 -2
- data/spec/oo/check_licence_spec.rb +26 -26
- data/spec/oo/configuration_spec.rb +48 -48
- data/spec/oo/licence_spec.rb +46 -46
- data/spec/oo_spec.rb +2 -2
- metadata +12 -12
- data/lib/oo/check_licence.rb +0 -19
- data/lib/oo/errors/default_licence_keys_invalid.rb +0 -9
- data/lib/oo/errors/licence_checkers_default_key_invalid.rb +0 -9
- data/lib/oo/errors/licence_checkers_default_user_invalid.rb +0 -9
- data/lib/oo/errors/licence_missing_reaction_invalid.rb +0 -9
- data/lib/oo/licence_checkers.rb +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2378fbd29161d5abb1d0a5915f9b364d8e38d8e2
|
4
|
+
data.tar.gz: 7a6f4c6d27bf5c82494bdf7e0991870d98249de4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f890c497ef66f8618238591e2c686f5d32a03d093674b227eb6617838f488ae004814441b6e45d3ca350e7093091511fdbf46c84f1c3952833c324c50c9f93a
|
7
|
+
data.tar.gz: fd692c1c7373d8057f9c60e3ab8452dc7b2c6c9dcf4f6183baea89ded6fcb62fb9faa18ff16d94ca1edcd4eddc3e7a40fd9fff94f9a58f41ea9efd06e91cc203
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,40 +1,170 @@
|
|
1
1
|
# OO
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
3
|
+
Simple Activity Based Authorization provider for Rails projects using `mongoid`.
|
6
4
|
|
7
5
|
## Installation
|
8
6
|
|
9
|
-
Add
|
10
|
-
|
7
|
+
1. Add to your Gemfile
|
11
8
|
```ruby
|
12
9
|
gem 'oo'
|
13
10
|
```
|
14
11
|
|
15
|
-
|
12
|
+
2. Execute
|
13
|
+
```
|
14
|
+
$ bundle
|
15
|
+
```
|
16
|
+
|
17
|
+
3. Run
|
18
|
+
```
|
19
|
+
$ rails g oo:install
|
20
|
+
```
|
21
|
+
|
22
|
+
## Concept
|
23
|
+
|
24
|
+
The gem is based on following concept:
|
25
|
+
- licenses are permissions for activities,
|
26
|
+
- license key is n-deep, separated with dot, e.g. `admins.edit.iban`,
|
27
|
+
- license key allows using `*` for "all permissions in this scope", e.g:
|
28
|
+
- `admins.*` means that user can perform every activity that needs
|
29
|
+
permission `admins.[something]`, so having such a permission user can
|
30
|
+
perform `admins.edit`, can perform `admins.delete` but cannot
|
31
|
+
`admins.edit.iban`,
|
32
|
+
- `admins.*.*` means that user can perform every activity that needs
|
33
|
+
permission `admins.[something].[something_else]`, so having such a permission
|
34
|
+
user can `admins.edit`, can `admins.delete`, can `admins.edit.iban`
|
35
|
+
but cannot e.g. `admins.edit.iban.set_nil`
|
36
|
+
- etc.
|
37
|
+
- license keys without `*` shall be understood literally: `admins` does not
|
38
|
+
give access to `admins.edit` even though it's parent
|
39
|
+
|
40
|
+
## Configuration and Usage
|
41
|
+
|
42
|
+
### LicenseUser Module
|
43
|
+
|
44
|
+
Add `OO::LicenseUser` to your user model.
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
class User
|
48
|
+
include OO::LicenseUser
|
49
|
+
|
50
|
+
# ...
|
51
|
+
end
|
52
|
+
```
|
53
|
+
Ready?
|
54
|
+
|
55
|
+
If so, user class has been just extended with:
|
56
|
+
- field `license_keys` (of type array),
|
57
|
+
- method `licensed?`.
|
58
|
+
|
59
|
+
You can now assign permissions for user and use `licensed?` method to check them, like in the example below.
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
user = User.first
|
63
|
+
user.licensed?(to: 'admins_users.edit')
|
64
|
+
|
65
|
+
# true if user has permission 'admins_users.edit'
|
66
|
+
# or any wider permission:
|
67
|
+
# - `admins_users.*.*.*`, `admins_users.*.*`, `admins_users.*`
|
68
|
+
# - `*.*.*.*`, `*.*.*`, `*.*`
|
69
|
+
# otherwise: false
|
70
|
+
```
|
71
|
+
### LicenseCheckers Module
|
72
|
+
|
73
|
+
Add `OO::LicenseCheckers` to your controller.
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
class ApplicationController < ActionController::Base
|
77
|
+
include OO::LicenseCheckers
|
78
|
+
|
79
|
+
# ...
|
80
|
+
end
|
81
|
+
```
|
82
|
+
|
83
|
+
Done?
|
16
84
|
|
17
|
-
|
85
|
+
Therefore, your controller can be sent:
|
86
|
+
- method `licensed?`,
|
87
|
+
- method `check_license!`.
|
18
88
|
|
19
|
-
|
89
|
+
Please find attached examples.
|
20
90
|
|
21
|
-
|
91
|
+
```ruby
|
92
|
+
module Admins
|
93
|
+
class UsersController < ApplicationController
|
94
|
+
include OO::LicenseCheckers
|
22
95
|
|
23
|
-
## Usage
|
24
96
|
|
25
|
-
|
97
|
+
def edit
|
98
|
+
check_license!(user: current_user, to: 'admins_users.edit')
|
99
|
+
# this will check whether user can perform 'admins_users.edit' or not
|
100
|
+
# if he can't then license_missing_reaction will be raised
|
101
|
+
# license_missing_reaction can be customized in initializer
|
26
102
|
|
27
|
-
|
103
|
+
# ...
|
104
|
+
end
|
28
105
|
|
29
|
-
|
106
|
+
# ...
|
107
|
+
end
|
108
|
+
end
|
109
|
+
```
|
30
110
|
|
31
|
-
|
111
|
+
Too verbose?
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
module Admins
|
115
|
+
class UsersController < ApplicationController
|
116
|
+
include OO::LicenseCheckers
|
117
|
+
|
118
|
+
def edit
|
119
|
+
check_license!
|
120
|
+
# this is equal to previous for by default:
|
121
|
+
# - current_user method is used to inject user
|
122
|
+
# - '[parameterized controller path].[action name]' is used to inject key
|
123
|
+
# this call requires your controller to respond to #current_user
|
124
|
+
# both defaults :user and :to can be customized in initializer
|
125
|
+
|
126
|
+
# ...
|
127
|
+
end
|
128
|
+
|
129
|
+
# ...
|
130
|
+
end
|
131
|
+
end
|
132
|
+
```
|
133
|
+
|
134
|
+
### Configuration
|
135
|
+
|
136
|
+
Default configuration was set up in initializer. Please find its description.
|
137
|
+
|
138
|
+
```ruby
|
139
|
+
OO.configure do |c|
|
140
|
+
# this is about how many nodes (dot-splitted) can have a license key
|
141
|
+
c.license_max_depth = 4
|
142
|
+
|
143
|
+
# here you can change method for default user injected to license checkers
|
144
|
+
c.license_checkers_default_user = ->(base) { base.current_user }
|
145
|
+
|
146
|
+
# here you can change default permission (:to) injected to license checkers
|
147
|
+
c.license_checkers_default_key = lambda do |base|
|
148
|
+
base.controller_path.gsub('/', '_') +
|
149
|
+
OO::License.separator +
|
150
|
+
base.action_name
|
151
|
+
end
|
152
|
+
|
153
|
+
# here you can change default error raised when #check_license! fails
|
154
|
+
c.license_missing_reaction = lambda do |license_key, user|
|
155
|
+
raise OO::Errors::LicenseMissing, license_key: license_key,
|
156
|
+
user_data: user.id
|
157
|
+
end
|
158
|
+
|
159
|
+
# here you can set default license keys that user will be initialized with
|
160
|
+
c.default_license_keys = []
|
161
|
+
end
|
162
|
+
```
|
32
163
|
|
33
164
|
## Contributing
|
34
165
|
|
35
166
|
Bug reports and pull requests are welcome.
|
36
167
|
|
37
|
-
|
38
168
|
## License
|
39
169
|
|
40
170
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
@@ -4,10 +4,10 @@ module OO
|
|
4
4
|
class InstallGenerator < ::Rails::Generators::Base
|
5
5
|
namespace 'oo:install'
|
6
6
|
source_root File.expand_path('../templates', __FILE__)
|
7
|
-
desc 'Generates OO (
|
7
|
+
desc 'Generates OO (license) gem initializer.'
|
8
8
|
|
9
9
|
def install
|
10
|
-
template 'initializer.rb', 'config/initializers/
|
10
|
+
template 'initializer.rb', 'config/initializers/oo_license.rb'
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
@@ -1,17 +1,17 @@
|
|
1
1
|
OO.configure do |c|
|
2
|
-
c.
|
2
|
+
c.license_max_depth = 4
|
3
3
|
|
4
|
-
c.
|
5
|
-
c.
|
4
|
+
c.license_checkers_default_user = ->(base) { base.current_user }
|
5
|
+
c.license_checkers_default_key = lambda do |base|
|
6
6
|
base.controller_path.gsub('/', '_') +
|
7
|
-
OO::
|
7
|
+
OO::License.separator +
|
8
8
|
base.action_name
|
9
9
|
end
|
10
10
|
|
11
|
-
c.
|
12
|
-
raise OO::Errors::
|
11
|
+
c.license_missing_reaction = lambda do |license_key, user|
|
12
|
+
raise OO::Errors::LicenseMissing, license_key: license_key,
|
13
13
|
user_data: user.id
|
14
14
|
end
|
15
15
|
|
16
|
-
c.
|
16
|
+
c.default_license_keys = []
|
17
17
|
end
|
data/lib/oo.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
require 'oo/version'
|
2
2
|
require 'oo/configuration'
|
3
|
-
require 'oo/errors/
|
4
|
-
require 'oo/errors/
|
5
|
-
require 'oo/errors/
|
6
|
-
require 'oo/errors/
|
7
|
-
require 'oo/errors/
|
8
|
-
require 'oo/errors/
|
9
|
-
require 'oo/
|
10
|
-
require 'oo/
|
11
|
-
require 'oo/
|
12
|
-
require 'oo/
|
3
|
+
require 'oo/errors/license_missing'
|
4
|
+
require 'oo/errors/license_max_depth_invalid'
|
5
|
+
require 'oo/errors/license_missing_reaction_invalid'
|
6
|
+
require 'oo/errors/license_checkers_default_user_invalid'
|
7
|
+
require 'oo/errors/license_checkers_default_key_invalid'
|
8
|
+
require 'oo/errors/default_license_keys_invalid'
|
9
|
+
require 'oo/license'
|
10
|
+
require 'oo/check_license'
|
11
|
+
require 'oo/license_user'
|
12
|
+
require 'oo/license_checkers'
|
13
13
|
|
14
14
|
module OO
|
15
15
|
class << self
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module OO
|
2
|
+
class CheckLicense
|
3
|
+
attr_reader :license_key, :license_keys, :license
|
4
|
+
|
5
|
+
def self.call(attrs = {})
|
6
|
+
new(attrs).call
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(attrs = {})
|
10
|
+
@license_key = attrs.fetch(:key)
|
11
|
+
@license_keys = attrs.fetch(:in)
|
12
|
+
@license = License.new(key: license_key)
|
13
|
+
end
|
14
|
+
|
15
|
+
def call
|
16
|
+
license.masks & license_keys
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/oo/configuration.rb
CHANGED
@@ -1,46 +1,46 @@
|
|
1
1
|
module OO
|
2
2
|
class Configuration
|
3
|
-
attr_reader :
|
4
|
-
:
|
5
|
-
:
|
3
|
+
attr_reader :license_max_depth, :default_license_keys,
|
4
|
+
:license_missing_reaction, :license_checkers_default_user,
|
5
|
+
:license_checkers_default_key
|
6
6
|
|
7
7
|
def initialize
|
8
|
-
@
|
9
|
-
@
|
10
|
-
@
|
11
|
-
-> { :
|
8
|
+
@license_max_depth = 4
|
9
|
+
@default_license_keys = []
|
10
|
+
@license_missing_reaction =
|
11
|
+
-> { :license_missing_reaction_not_configured }
|
12
12
|
|
13
|
-
@
|
14
|
-
-> { :
|
13
|
+
@license_checkers_default_user =
|
14
|
+
-> { :license_checkers_default_user_not_configured }
|
15
15
|
|
16
|
-
@
|
17
|
-
-> { :
|
16
|
+
@license_checkers_default_key =
|
17
|
+
-> { :license_checkers_default_key_not_configured }
|
18
18
|
end
|
19
19
|
|
20
|
-
def
|
21
|
-
raise Errors::
|
20
|
+
def license_max_depth=(depth)
|
21
|
+
raise Errors::LicenseMaxDepthInvalid unless depth.is_a?(Fixnum) &&
|
22
22
|
depth > 0
|
23
|
-
@
|
23
|
+
@license_max_depth = depth
|
24
24
|
end
|
25
25
|
|
26
|
-
def
|
27
|
-
raise Errors::
|
28
|
-
@
|
26
|
+
def default_license_keys=(license_keys)
|
27
|
+
raise Errors::DefaultLicenseKeysInvalid unless license_keys.is_a?(Array)
|
28
|
+
@default_license_keys = license_keys
|
29
29
|
end
|
30
30
|
|
31
|
-
def
|
32
|
-
raise Errors::
|
33
|
-
@
|
31
|
+
def license_missing_reaction=(action)
|
32
|
+
raise Errors::LicenseMissingReactionInvalid unless action.is_a?(Proc)
|
33
|
+
@license_missing_reaction = action
|
34
34
|
end
|
35
35
|
|
36
|
-
def
|
37
|
-
raise Errors::
|
38
|
-
@
|
36
|
+
def license_checkers_default_user=(action)
|
37
|
+
raise Errors::LicenseCheckersDefaultUserInvalid unless action.is_a?(Proc)
|
38
|
+
@license_checkers_default_user = action
|
39
39
|
end
|
40
40
|
|
41
|
-
def
|
42
|
-
raise Errors::
|
43
|
-
@
|
41
|
+
def license_checkers_default_key=(action)
|
42
|
+
raise Errors::LicenseCheckersDefaultKeyInvalid unless action.is_a?(Proc)
|
43
|
+
@license_checkers_default_key = action
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module OO
|
2
2
|
module Errors
|
3
|
-
class
|
3
|
+
class LicenseMaxDepthInvalid < StandardError
|
4
4
|
def initialize
|
5
|
-
super('OO.configuration.
|
5
|
+
super('OO.configuration.license_max_depth must be a Fixnum '\
|
6
6
|
'greater than 0')
|
7
7
|
end
|
8
8
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module OO
|
2
2
|
module Errors
|
3
|
-
class
|
4
|
-
attr_reader :user_data, :
|
3
|
+
class LicenseMissing < StandardError
|
4
|
+
attr_reader :user_data, :license_key
|
5
5
|
|
6
6
|
def initialize(attrs = {})
|
7
7
|
@user_data = attrs[:user_data]
|
8
|
-
@
|
8
|
+
@license_key = attrs.fetch(:license_key)
|
9
9
|
super(error_message)
|
10
10
|
end
|
11
11
|
|
@@ -14,7 +14,7 @@ module OO
|
|
14
14
|
def error_message
|
15
15
|
msg = "User "
|
16
16
|
msg << "#{user_data} " unless user_data.nil?
|
17
|
-
msg << "is missing permission '#{
|
17
|
+
msg << "is missing permission '#{license_key}'. " \
|
18
18
|
'Therefore he is not allowed to perform this activity.'
|
19
19
|
end
|
20
20
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module OO
|
2
|
+
module LicenseCheckers
|
3
|
+
def self.included(base)
|
4
|
+
base.class_eval do
|
5
|
+
def licensed?(attrs = {})
|
6
|
+
user = attrs.fetch(:user, license_checkers_default_user)
|
7
|
+
key = attrs.fetch(:to, license_checkers_default_key)
|
8
|
+
user.licensed?(to: key)
|
9
|
+
end
|
10
|
+
|
11
|
+
def check_license!(attrs = {})
|
12
|
+
user = attrs.fetch(:user, license_checkers_default_user)
|
13
|
+
key = attrs.fetch(:to, license_checkers_default_key)
|
14
|
+
license_missing_reaction.call(key, user) unless licensed?(user: user,
|
15
|
+
to: key)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def license_checkers_default_user
|
21
|
+
OO.configuration.license_checkers_default_user.call(self)
|
22
|
+
end
|
23
|
+
|
24
|
+
def license_checkers_default_key
|
25
|
+
OO.configuration.license_checkers_default_key.call(self)
|
26
|
+
end
|
27
|
+
|
28
|
+
def license_missing_reaction
|
29
|
+
OO.configuration.license_missing_reaction
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
module OO
|
2
|
-
module
|
2
|
+
module LicenseUser
|
3
3
|
def self.included(base)
|
4
4
|
base.class_eval do
|
5
|
-
field :
|
6
|
-
default: OO.configuration.
|
5
|
+
field :license_keys, type: :array,
|
6
|
+
default: OO.configuration.default_license_keys
|
7
7
|
|
8
8
|
def licensed?(attrs = {})
|
9
9
|
required_key = attrs.fetch(:to)
|
10
|
-
|
10
|
+
CheckLicense.call(key: required_key, in: license_keys).any?
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
data/lib/oo/version.rb
CHANGED
data/spec/factories/licences.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
FactoryGirl.define do
|
2
|
-
factory :
|
2
|
+
factory :license, class: OO::License do
|
3
3
|
key 'action'
|
4
4
|
|
5
5
|
initialize_with { new(attributes) }
|
6
6
|
end
|
7
7
|
|
8
|
-
factory :glass_take_with_juice, parent: :
|
8
|
+
factory :glass_take_with_juice, parent: :license do
|
9
9
|
key 'glass.take.with_juice'
|
10
10
|
end
|
11
11
|
end
|
@@ -1,43 +1,43 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
|
4
|
-
describe OO::
|
4
|
+
describe OO::CheckLicense do
|
5
5
|
|
6
6
|
describe '.new(attrs = {})' do
|
7
7
|
let(:service_object) { described_class.new(attrs) }
|
8
|
-
let(:
|
8
|
+
let(:license_key) { 'glass.take' }
|
9
9
|
|
10
10
|
subject { service_object }
|
11
11
|
|
12
12
|
context 'when required attrs are missing' do
|
13
|
-
context 'when :key (checked
|
13
|
+
context 'when :key (checked license key) is missing' do
|
14
14
|
let(:attrs) { { in: [] } }
|
15
15
|
it { expect { subject }.to raise_error(KeyError) }
|
16
16
|
end
|
17
17
|
|
18
|
-
context 'when :in (
|
19
|
-
let(:attrs) { { key:
|
18
|
+
context 'when :in (license keys list) is missing' do
|
19
|
+
let(:attrs) { { key: license_key } }
|
20
20
|
it { expect { subject }.to raise_error(KeyError) }
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
context 'when all required attrs were passed' do
|
25
|
-
let(:attrs) { { key:
|
25
|
+
let(:attrs) { { key: license_key, in: [] } }
|
26
26
|
|
27
27
|
it { is_expected.to be_a(described_class) }
|
28
28
|
|
29
|
-
describe 'builds a
|
30
|
-
let(:
|
29
|
+
describe 'builds a license' do
|
30
|
+
let(:license_class) { OO::License }
|
31
31
|
|
32
|
-
describe '@
|
33
|
-
let(:
|
32
|
+
describe '@license' do
|
33
|
+
let(:license) { service_object.instance_variable_get(:@license) }
|
34
34
|
|
35
|
-
subject {
|
36
|
-
it { is_expected.to be_a(
|
35
|
+
subject { license }
|
36
|
+
it { is_expected.to be_a(license_class) }
|
37
37
|
|
38
38
|
describe '#key' do
|
39
|
-
subject {
|
40
|
-
it { is_expected.to eq(
|
39
|
+
subject { license.key }
|
40
|
+
it { is_expected.to eq(license_key) }
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
@@ -45,33 +45,33 @@ describe OO::CheckLicence do
|
|
45
45
|
end
|
46
46
|
|
47
47
|
describe '#call' do
|
48
|
-
let(:service_object) { described_class.new(key:
|
49
|
-
let(:
|
50
|
-
let(:
|
48
|
+
let(:service_object) { described_class.new(key: license_key, in: license_keys) }
|
49
|
+
let(:license) { OO::License.new(key: license_key) }
|
50
|
+
let(:license_key) { 'glass.take' }
|
51
51
|
|
52
52
|
subject { service_object.call }
|
53
53
|
|
54
54
|
describe 'returns all keys wider or equal to given key found in given list' do
|
55
|
-
context 'when
|
55
|
+
context 'when license key is included in license keys list' do
|
56
56
|
context 'and is an only match' do
|
57
|
-
let(:
|
58
|
-
it { is_expected.to eq([
|
57
|
+
let(:license_keys) { [license_key] }
|
58
|
+
it { is_expected.to eq([license_key]) }
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
context 'when exact
|
62
|
+
context 'when exact license key is missing in given list' do
|
63
63
|
context 'but there are wider keys' do
|
64
|
-
let(:
|
65
|
-
it { is_expected.to eq(
|
64
|
+
let(:license_keys) { license.genre_masks }
|
65
|
+
it { is_expected.to eq(license.genre_masks) }
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
context 'when
|
70
|
-
let(:
|
69
|
+
context 'when license key is missing in given list' do
|
70
|
+
let(:license_keys) { %w(a b c d) }
|
71
71
|
it { is_expected.to eq([]) }
|
72
72
|
|
73
73
|
context 'but found parent key' do
|
74
|
-
let(:
|
74
|
+
let(:license_keys) { [license.parent.key] }
|
75
75
|
it { is_expected.to eq([]) }
|
76
76
|
end
|
77
77
|
end
|
@@ -3,119 +3,119 @@ require 'spec_helper'
|
|
3
3
|
describe OO::Configuration do
|
4
4
|
describe '.new' do
|
5
5
|
let(:configuration) { described_class.new }
|
6
|
-
let(:
|
7
|
-
let(:
|
8
|
-
let(:
|
9
|
-
-> { :
|
6
|
+
let(:default_license_max_depth) { 4 }
|
7
|
+
let(:default_license_keys) { [] }
|
8
|
+
let(:default_license_missing_reaction) do
|
9
|
+
-> { :license_missing_reaction_not_configured }
|
10
10
|
end
|
11
11
|
|
12
|
-
let(:
|
13
|
-
-> { :
|
12
|
+
let(:default_license_checkers_default_user) do
|
13
|
+
-> { :license_checkers_default_user_not_configured }
|
14
14
|
end
|
15
15
|
|
16
|
-
let(:
|
17
|
-
-> { :
|
16
|
+
let(:default_license_checkers_default_key) do
|
17
|
+
-> { :license_checkers_default_key_not_configured }
|
18
18
|
end
|
19
19
|
|
20
20
|
subject { configuration }
|
21
21
|
|
22
22
|
it { is_expected.to be_a(described_class) }
|
23
23
|
describe 'it is set to default values' do
|
24
|
-
describe '
|
25
|
-
subject { configuration.
|
26
|
-
it { is_expected.to eq(
|
24
|
+
describe 'license_max_depth' do
|
25
|
+
subject { configuration.license_max_depth }
|
26
|
+
it { is_expected.to eq(default_license_max_depth) }
|
27
27
|
end
|
28
28
|
|
29
|
-
describe '
|
30
|
-
subject { configuration.
|
31
|
-
it { is_expected.to eq(
|
29
|
+
describe 'default_license_keys' do
|
30
|
+
subject { configuration.default_license_keys }
|
31
|
+
it { is_expected.to eq(default_license_keys) }
|
32
32
|
end
|
33
33
|
|
34
|
-
describe '
|
35
|
-
let(:
|
36
|
-
subject {
|
34
|
+
describe 'license_missing_reaction' do
|
35
|
+
let(:license_missing_reaction) { configuration.license_missing_reaction }
|
36
|
+
subject { license_missing_reaction }
|
37
37
|
it { is_expected.to be_a(Proc) }
|
38
38
|
describe "#call" do
|
39
|
-
subject {
|
40
|
-
it { is_expected.to eq(:
|
39
|
+
subject { license_missing_reaction.call }
|
40
|
+
it { is_expected.to eq(:license_missing_reaction_not_configured) }
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
describe '
|
45
|
-
let(:
|
46
|
-
subject {
|
44
|
+
describe 'license_checkers_default_user' do
|
45
|
+
let(:license_checkers_default_user) { configuration.license_checkers_default_user }
|
46
|
+
subject { license_checkers_default_user }
|
47
47
|
it { is_expected.to be_a(Proc) }
|
48
48
|
describe "#call" do
|
49
|
-
subject {
|
50
|
-
it { is_expected.to eq(:
|
49
|
+
subject { license_checkers_default_user.call }
|
50
|
+
it { is_expected.to eq(:license_checkers_default_user_not_configured) }
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
describe '
|
55
|
-
let(:
|
56
|
-
subject {
|
54
|
+
describe 'license_checkers_default_key' do
|
55
|
+
let(:license_checkers_default_key) { configuration.license_checkers_default_key }
|
56
|
+
subject { license_checkers_default_key }
|
57
57
|
it { is_expected.to be_a(Proc) }
|
58
58
|
describe "#call" do
|
59
|
-
subject {
|
60
|
-
it { is_expected.to eq(:
|
59
|
+
subject { license_checkers_default_key.call }
|
60
|
+
it { is_expected.to eq(:license_checkers_default_key_not_configured) }
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
describe '#
|
65
|
+
describe '#license_max_depth=(depth)' do
|
66
66
|
context 'when depth is not a fixnum' do
|
67
67
|
let(:depth) { 'a' }
|
68
|
-
let(:error) { OO::Errors::
|
68
|
+
let(:error) { OO::Errors::LicenseMaxDepthInvalid }
|
69
69
|
|
70
|
-
subject { -> { configuration.
|
70
|
+
subject { -> { configuration.license_max_depth = depth } }
|
71
71
|
it { is_expected.to raise_error(error) }
|
72
72
|
end
|
73
73
|
|
74
74
|
context 'when depth is not greater than 0' do
|
75
75
|
let(:depth) { 0 }
|
76
|
-
let(:error) { OO::Errors::
|
76
|
+
let(:error) { OO::Errors::LicenseMaxDepthInvalid }
|
77
77
|
|
78
|
-
subject { -> { configuration.
|
78
|
+
subject { -> { configuration.license_max_depth = depth } }
|
79
79
|
it { is_expected.to raise_error(error) }
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
|
-
describe '#
|
83
|
+
describe '#license_missing_reaction=(action)' do
|
84
84
|
context 'when action is not a Proc object' do
|
85
85
|
let(:action) { :invalid }
|
86
|
-
let(:error) { OO::Errors::
|
86
|
+
let(:error) { OO::Errors::LicenseMissingReactionInvalid }
|
87
87
|
|
88
|
-
subject { -> { configuration.
|
88
|
+
subject { -> { configuration.license_missing_reaction = action } }
|
89
89
|
it { is_expected.to raise_error(error) }
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
|
-
describe '#
|
93
|
+
describe '#license_checkers_default_user=(action)' do
|
94
94
|
context 'when action is not a Proc object' do
|
95
95
|
let(:action) { :invalid }
|
96
|
-
let(:error) { OO::Errors::
|
96
|
+
let(:error) { OO::Errors::LicenseCheckersDefaultUserInvalid }
|
97
97
|
|
98
|
-
subject { -> { configuration.
|
98
|
+
subject { -> { configuration.license_checkers_default_user = action } }
|
99
99
|
it { is_expected.to raise_error(error) }
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
103
|
-
describe '#
|
103
|
+
describe '#license_checkers_default_key=(action)' do
|
104
104
|
context 'when action is not a Proc object' do
|
105
105
|
let(:action) { :invalid }
|
106
|
-
let(:error) { OO::Errors::
|
106
|
+
let(:error) { OO::Errors::LicenseCheckersDefaultKeyInvalid }
|
107
107
|
|
108
|
-
subject { -> { configuration.
|
108
|
+
subject { -> { configuration.license_checkers_default_key = action } }
|
109
109
|
it { is_expected.to raise_error(error) }
|
110
110
|
end
|
111
111
|
end
|
112
112
|
|
113
|
-
describe '#
|
114
|
-
context 'when
|
115
|
-
let(:
|
116
|
-
let(:error) { OO::Errors::
|
113
|
+
describe '#default_license_keys=(license_keys)' do
|
114
|
+
context 'when license_keys is not an array' do
|
115
|
+
let(:license_keys) { :invalid }
|
116
|
+
let(:error) { OO::Errors::DefaultLicenseKeysInvalid }
|
117
117
|
|
118
|
-
subject { -> { configuration.
|
118
|
+
subject { -> { configuration.default_license_keys = license_keys } }
|
119
119
|
it { is_expected.to raise_error(error) }
|
120
120
|
end
|
121
121
|
end
|
data/spec/oo/licence_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe OO::
|
3
|
+
describe OO::License do
|
4
4
|
let(:separator) { described_class.separator }
|
5
5
|
let(:mask_mark) { described_class.mask_mark }
|
6
6
|
|
@@ -17,7 +17,7 @@ describe OO::Licence do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
describe '.max_depth' do
|
20
|
-
let(:max_depth) { OO.configuration.
|
20
|
+
let(:max_depth) { OO.configuration.license_max_depth }
|
21
21
|
subject { described_class.max_depth }
|
22
22
|
|
23
23
|
context 'for default configuration' do
|
@@ -29,7 +29,7 @@ describe OO::Licence do
|
|
29
29
|
subject { described_class.masks }
|
30
30
|
|
31
31
|
describe 'returns all possible top-level masks basing on max depth' do
|
32
|
-
before(:each) { OO.configure { |c| c.
|
32
|
+
before(:each) { OO.configure { |c| c.license_max_depth = max_depth } }
|
33
33
|
|
34
34
|
context 'when max_depth is set to 1' do
|
35
35
|
let(:max_depth) { 1 }
|
@@ -63,22 +63,22 @@ describe OO::Licence do
|
|
63
63
|
end
|
64
64
|
|
65
65
|
describe '#separator' do
|
66
|
-
let(:
|
67
|
-
subject {
|
66
|
+
let(:license) { build(:glass_take_with_juice) }
|
67
|
+
subject { license.separator }
|
68
68
|
it { is_expected.to eq(described_class.separator) }
|
69
69
|
end
|
70
70
|
|
71
71
|
describe '#mask_mark' do
|
72
|
-
let(:
|
73
|
-
subject {
|
72
|
+
let(:license) { build(:glass_take_with_juice) }
|
73
|
+
subject { license.mask_mark }
|
74
74
|
it { is_expected.to eq(described_class.mask_mark) }
|
75
75
|
end
|
76
76
|
|
77
77
|
describe '#key' do
|
78
78
|
context 'for :glass_take_with_juice factory' do
|
79
|
-
let(:
|
79
|
+
let(:license) { build(:glass_take_with_juice) }
|
80
80
|
|
81
|
-
subject {
|
81
|
+
subject { license.key }
|
82
82
|
|
83
83
|
it { is_expected.to be_a(String) }
|
84
84
|
it { is_expected.to eq('glass.take.with_juice') }
|
@@ -87,9 +87,9 @@ describe OO::Licence do
|
|
87
87
|
|
88
88
|
describe '#to_s' do
|
89
89
|
context 'for :glass_take_with_juice factory' do
|
90
|
-
let(:
|
90
|
+
let(:license) { build(:glass_take_with_juice) }
|
91
91
|
|
92
|
-
subject {
|
92
|
+
subject { license.to_s }
|
93
93
|
|
94
94
|
it { is_expected.to be_a(String) }
|
95
95
|
it { is_expected.to eq('glass.take.with_juice') }
|
@@ -98,9 +98,9 @@ describe OO::Licence do
|
|
98
98
|
|
99
99
|
describe '#to_a' do
|
100
100
|
context 'for :glass_take_with_juice factory' do
|
101
|
-
let(:
|
101
|
+
let(:license) { build(:glass_take_with_juice) }
|
102
102
|
|
103
|
-
subject {
|
103
|
+
subject { license.to_a }
|
104
104
|
|
105
105
|
it { is_expected.to be_an(Array) }
|
106
106
|
it { is_expected.to eq(%w(glass take with_juice)) }
|
@@ -109,9 +109,9 @@ describe OO::Licence do
|
|
109
109
|
|
110
110
|
describe '#depth' do
|
111
111
|
context 'for :glass_take_with_juice factory' do
|
112
|
-
let(:
|
112
|
+
let(:license) { build(:glass_take_with_juice) }
|
113
113
|
|
114
|
-
subject {
|
114
|
+
subject { license.depth }
|
115
115
|
|
116
116
|
it { is_expected.to be_a(Fixnum) }
|
117
117
|
it { is_expected.to eq(3) }
|
@@ -126,18 +126,18 @@ describe OO::Licence do
|
|
126
126
|
depth_3: %W(#{m}#{s}#{m}#{s}#{m} #{m}#{s}#{m}#{s}#{m}#{s}#{m}) }
|
127
127
|
end
|
128
128
|
|
129
|
-
subject {
|
129
|
+
subject { license.genre_masks }
|
130
130
|
|
131
|
-
describe 'should return the most general masks for
|
131
|
+
describe 'should return the most general masks for license' do
|
132
132
|
context 'for :glass_take_with_juice factory (depth: 3)' do
|
133
|
-
let(:
|
133
|
+
let(:license) { build(:glass_take_with_juice) }
|
134
134
|
|
135
135
|
it { is_expected.to be_an(Array) }
|
136
136
|
it { is_expected.to eq(genre_masks[:depth_3]) }
|
137
137
|
end
|
138
138
|
|
139
|
-
context 'for :
|
140
|
-
let(:
|
139
|
+
context 'for :license factory (depth: 1)' do
|
140
|
+
let(:license) { build(:license) }
|
141
141
|
|
142
142
|
it { is_expected.to be_an(Array) }
|
143
143
|
it { is_expected.to eq(genre_masks[:depth_1]) }
|
@@ -149,44 +149,44 @@ describe OO::Licence do
|
|
149
149
|
let(:m) { mask_mark }
|
150
150
|
let(:s) { separator }
|
151
151
|
|
152
|
-
subject {
|
152
|
+
subject { license.mask_key(mask) }
|
153
153
|
|
154
|
-
describe 'for n-deep
|
155
|
-
context 'when mask key is deeper than
|
154
|
+
describe 'for n-deep license should replace mask\'s n chars with key\'s' do
|
155
|
+
context 'when mask key is deeper than license' do
|
156
156
|
let(:mask) { "#{m}#{s}#{m}#{s}#{m}#{s}#{m}" }
|
157
157
|
|
158
158
|
context 'for :glass_take_with_juice factory' do
|
159
|
-
let(:
|
159
|
+
let(:license) { build(:glass_take_with_juice) }
|
160
160
|
|
161
161
|
it { is_expected.to be_a(String) }
|
162
|
-
it { is_expected.to eq(
|
162
|
+
it { is_expected.to eq(license.key + "#{s}#{m}") }
|
163
163
|
end
|
164
164
|
|
165
|
-
context 'for :
|
166
|
-
let(:
|
165
|
+
context 'for :license factory' do
|
166
|
+
let(:license) { build(:license) }
|
167
167
|
|
168
168
|
it { is_expected.to be_an(String) }
|
169
|
-
it { is_expected.to eq(
|
169
|
+
it { is_expected.to eq(license.key + "#{s}#{m}#{s}#{m}#{s}#{m}") }
|
170
170
|
end
|
171
171
|
end
|
172
172
|
|
173
|
-
context 'when mask depth equals
|
174
|
-
context 'for :
|
175
|
-
let(:
|
173
|
+
context 'when mask depth equals license depth' do
|
174
|
+
context 'for :license factory' do
|
175
|
+
let(:license) { build(:license) }
|
176
176
|
let(:mask) { "#{m}" }
|
177
177
|
|
178
178
|
it { is_expected.to be_an(String) }
|
179
|
-
it { is_expected.to eq(
|
179
|
+
it { is_expected.to eq(license.key) }
|
180
180
|
end
|
181
181
|
end
|
182
182
|
|
183
|
-
context 'when mask depth is less than
|
183
|
+
context 'when mask depth is less than license depth' do
|
184
184
|
context 'for :glass_take_with_juice factory' do
|
185
|
-
let(:
|
185
|
+
let(:license) { build(:glass_take_with_juice) }
|
186
186
|
let(:mask) { "#{m}#{s}#{m}" }
|
187
187
|
|
188
188
|
it { is_expected.to be_an(String) }
|
189
|
-
it { is_expected.to eq(
|
189
|
+
it { is_expected.to eq(license.key) }
|
190
190
|
end
|
191
191
|
end
|
192
192
|
end
|
@@ -196,35 +196,35 @@ describe OO::Licence do
|
|
196
196
|
let(:mask_mark) { described_class.mask_mark }
|
197
197
|
|
198
198
|
context 'for :glass_take_with_juice factory' do
|
199
|
-
let(:
|
200
|
-
let(:
|
199
|
+
let(:license) { build(:glass_take_with_juice) }
|
200
|
+
let(:parent_license) { license.parent }
|
201
201
|
|
202
|
-
subject {
|
202
|
+
subject { parent_license }
|
203
203
|
|
204
204
|
it { is_expected.to be_a(described_class) }
|
205
205
|
|
206
206
|
describe '#key' do
|
207
|
-
subject {
|
207
|
+
subject { parent_license.key }
|
208
208
|
it { is_expected.to eq('glass.take') }
|
209
209
|
end
|
210
210
|
end
|
211
211
|
|
212
|
-
context 'for :
|
213
|
-
let(:
|
214
|
-
let(:
|
212
|
+
context 'for :license factory' do
|
213
|
+
let(:license) { build(:license) }
|
214
|
+
let(:parent_license) { license.parent }
|
215
215
|
|
216
216
|
describe '#key' do
|
217
|
-
subject {
|
217
|
+
subject { parent_license.key }
|
218
218
|
it { is_expected.to eq(mask_mark) }
|
219
219
|
end
|
220
220
|
end
|
221
221
|
|
222
222
|
context 'when key equals single mask mark' do
|
223
|
-
let(:
|
224
|
-
let(:
|
223
|
+
let(:license) { build(:license, key: mask_mark) }
|
224
|
+
let(:parent_license) { license.parent }
|
225
225
|
|
226
226
|
describe '#key' do
|
227
|
-
subject {
|
227
|
+
subject { parent_license.key }
|
228
228
|
it { is_expected.to eq(mask_mark) }
|
229
229
|
end
|
230
230
|
end
|
data/spec/oo_spec.rb
CHANGED
@@ -17,11 +17,11 @@ describe OO do
|
|
17
17
|
context 'when block was given' do
|
18
18
|
let(:depth) { 5 }
|
19
19
|
before(:each) do
|
20
|
-
described_class.configure { |c| c.
|
20
|
+
described_class.configure { |c| c.license_max_depth = depth }
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'updates configuration' do
|
24
|
-
expect(described_class.configuration.
|
24
|
+
expect(described_class.configuration.license_max_depth).to eq(depth)
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Krzysztof Buszewicz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -86,17 +86,17 @@ files:
|
|
86
86
|
- lib/generators/oo/install_generator.rb
|
87
87
|
- lib/generators/oo/templates/initializer.rb
|
88
88
|
- lib/oo.rb
|
89
|
-
- lib/oo/
|
89
|
+
- lib/oo/check_license.rb
|
90
90
|
- lib/oo/configuration.rb
|
91
|
-
- lib/oo/errors/
|
92
|
-
- lib/oo/errors/
|
93
|
-
- lib/oo/errors/
|
94
|
-
- lib/oo/errors/
|
95
|
-
- lib/oo/errors/
|
96
|
-
- lib/oo/errors/
|
97
|
-
- lib/oo/
|
98
|
-
- lib/oo/
|
99
|
-
- lib/oo/
|
91
|
+
- lib/oo/errors/default_license_keys_invalid.rb
|
92
|
+
- lib/oo/errors/license_checkers_default_key_invalid.rb
|
93
|
+
- lib/oo/errors/license_checkers_default_user_invalid.rb
|
94
|
+
- lib/oo/errors/license_max_depth_invalid.rb
|
95
|
+
- lib/oo/errors/license_missing.rb
|
96
|
+
- lib/oo/errors/license_missing_reaction_invalid.rb
|
97
|
+
- lib/oo/license.rb
|
98
|
+
- lib/oo/license_checkers.rb
|
99
|
+
- lib/oo/license_user.rb
|
100
100
|
- lib/oo/version.rb
|
101
101
|
- oo.gemspec
|
102
102
|
- spec/factories/licences.rb
|
data/lib/oo/check_licence.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
module OO
|
2
|
-
class CheckLicence
|
3
|
-
attr_reader :licence_key, :licence_keys, :licence
|
4
|
-
|
5
|
-
def self.call(attrs = {})
|
6
|
-
new(attrs).call
|
7
|
-
end
|
8
|
-
|
9
|
-
def initialize(attrs = {})
|
10
|
-
@licence_key = attrs.fetch(:key)
|
11
|
-
@licence_keys = attrs.fetch(:in)
|
12
|
-
@licence = Licence.new(key: licence_key)
|
13
|
-
end
|
14
|
-
|
15
|
-
def call
|
16
|
-
licence.masks & licence_keys
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
data/lib/oo/licence_checkers.rb
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
module OO
|
2
|
-
module LicenceCheckers
|
3
|
-
def self.included(base)
|
4
|
-
base.class_eval do
|
5
|
-
def licensed?(attrs = {})
|
6
|
-
user = attrs.fetch(:user, licence_checkers_default_user)
|
7
|
-
key = attrs.fetch(:to, licence_checkers_default_key)
|
8
|
-
user.licensed?(to: key)
|
9
|
-
end
|
10
|
-
|
11
|
-
def check_licence!(attrs = {})
|
12
|
-
user = attrs.fetch(:user, licence_checkers_default_user)
|
13
|
-
key = attrs.fetch(:to, licence_checkers_default_key)
|
14
|
-
licence_missing_reaction.call(key, user) unless licensed?(user: user,
|
15
|
-
to: key)
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def licence_checkers_default_user
|
21
|
-
OO.configuration.licence_checkers_default_user.call(self)
|
22
|
-
end
|
23
|
-
|
24
|
-
def licence_checkers_default_key
|
25
|
-
OO.configuration.licence_checkers_default_key.call(self)
|
26
|
-
end
|
27
|
-
|
28
|
-
def licence_missing_reaction
|
29
|
-
OO.configuration.licence_missing_reaction
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|