oo 0.9.0 → 1.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/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
|