oo 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b7bda95102461e464f995d2967a3364bbbb1acd9
4
+ data.tar.gz: 6dcc0fdea18c8d6932acc63c3b6e2211335815bf
5
+ SHA512:
6
+ metadata.gz: 3429777334a53028a83e808f004b46adeeac45d44ccf53ba8b7517fb4128789e9d0047f1a53b2a88de5df14ce4a9c7c7e976421d82341ca64b5333832740cdb7
7
+ data.tar.gz: fbb5e2d95222646a67d08c281b5d233034a54fcd297310e93e823f04b7c02c7df3a30c6d322bd81f2eab35d961a95373534e5113022060e9b6ebce281d3bf0f4
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,8 @@
1
+ Metrics/LineLength:
2
+ Max: 100
3
+
4
+ Style/Documentation:
5
+ Enabled: false
6
+
7
+ Style/SignalException:
8
+ EnforcedStyle: only_raise
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ before_install: gem install bundler -v 1.11.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in licence.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Krzysztof Buszewicz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,40 @@
1
+ # OO
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/oo`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'oo'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install oo
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome.
36
+
37
+
38
+ ## License
39
+
40
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'oo'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,13 @@
1
+ require 'rails/generators'
2
+
3
+ module OO
4
+ class InstallGenerator < ::Rails::Generators::Base
5
+ namespace 'oo:install'
6
+ source_root File.expand_path('../templates', __FILE__)
7
+ desc 'Generates OO (licence) gem initializer.'
8
+
9
+ def install
10
+ template 'initializer.rb', 'config/initializers/oo_licence.rb'
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ OO.configure do |c|
2
+ c.licence_max_depth = 4
3
+
4
+ c.licence_checkers_default_user = ->(base) { base.current_user }
5
+ c.licence_checkers_default_key = lambda do |base|
6
+ base.controller_path.gsub('/', '_') +
7
+ OO::Licence.separator +
8
+ base.action_name
9
+ end
10
+
11
+ c.licence_missing_reaction = lambda do |licence_key, user|
12
+ raise OO::Errors::LicenceMissing, licence_key: licence_key,
13
+ user_data: user.id
14
+ end
15
+
16
+ c.default_licence_keys = []
17
+ end
@@ -0,0 +1,25 @@
1
+ require 'oo/version'
2
+ require 'oo/configuration'
3
+ require 'oo/errors/licence_missing'
4
+ require 'oo/errors/licence_max_depth_invalid'
5
+ require 'oo/errors/licence_missing_reaction_invalid'
6
+ require 'oo/errors/licence_checkers_default_user_invalid'
7
+ require 'oo/errors/licence_checkers_default_key_invalid'
8
+ require 'oo/errors/default_licence_keys_invalid'
9
+ require 'oo/licence'
10
+ require 'oo/check_licence'
11
+ require 'oo/licence_user'
12
+ require 'oo/licence_checkers'
13
+
14
+ module OO
15
+ class << self
16
+ def configuration
17
+ @configuration ||= Configuration.new
18
+ end
19
+
20
+ def configure
21
+ yield(configuration) if block_given?
22
+ configuration
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,19 @@
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
@@ -0,0 +1,46 @@
1
+ module OO
2
+ class Configuration
3
+ attr_reader :licence_max_depth, :default_licence_keys,
4
+ :licence_missing_reaction, :licence_checkers_default_user,
5
+ :licence_checkers_default_key
6
+
7
+ def initialize
8
+ @licence_max_depth = 4
9
+ @default_licence_keys = []
10
+ @licence_missing_reaction =
11
+ -> { :licence_missing_reaction_not_configured }
12
+
13
+ @licence_checkers_default_user =
14
+ -> { :licence_checkers_default_user_not_configured }
15
+
16
+ @licence_checkers_default_key =
17
+ -> { :licence_checkers_default_key_not_configured }
18
+ end
19
+
20
+ def licence_max_depth=(depth)
21
+ raise Errors::LicenceMaxDepthInvalid unless depth.is_a?(Fixnum) &&
22
+ depth > 0
23
+ @licence_max_depth = depth
24
+ end
25
+
26
+ def default_licence_keys=(licence_keys)
27
+ raise Errors::DefaultLicenceKeysInvalid unless licence_keys.is_a?(Array)
28
+ @default_licence_keys = licence_keys
29
+ end
30
+
31
+ def licence_missing_reaction=(action)
32
+ raise Errors::LicenceMissingReactionInvalid unless action.is_a?(Proc)
33
+ @licence_missing_reaction = action
34
+ end
35
+
36
+ def licence_checkers_default_user=(action)
37
+ raise Errors::LicenceCheckersDefaultUserInvalid unless action.is_a?(Proc)
38
+ @licence_checkers_default_user = action
39
+ end
40
+
41
+ def licence_checkers_default_key=(action)
42
+ raise Errors::LicenceCheckersDefaultKeyInvalid unless action.is_a?(Proc)
43
+ @licence_checkers_default_key = action
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,9 @@
1
+ module OO
2
+ module Errors
3
+ class DefaultLicenceKeysInvalid < StandardError
4
+ def initialize
5
+ super('OO.configuration.default_licence_keys must be an Array.')
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module OO
2
+ module Errors
3
+ class LicenceCheckersDefaultKeyInvalid < StandardError
4
+ def initialize
5
+ super('OO.configuration.licence_checkers_default_key must be a Proc.')
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module OO
2
+ module Errors
3
+ class LicenceCheckersDefaultUserInvalid < StandardError
4
+ def initialize
5
+ super('OO.configuration.licence_checkers_default_user must be a Proc.')
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ module OO
2
+ module Errors
3
+ class LicenceMaxDepthInvalid < StandardError
4
+ def initialize
5
+ super('OO.configuration.licence_max_depth must be a Fixnum '\
6
+ 'greater than 0')
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,22 @@
1
+ module OO
2
+ module Errors
3
+ class LicenceMissing < StandardError
4
+ attr_reader :user_data, :licence_key
5
+
6
+ def initialize(attrs = {})
7
+ @user_data = attrs[:user_data]
8
+ @licence_key = attrs.fetch(:licence_key)
9
+ super(error_message)
10
+ end
11
+
12
+ private
13
+
14
+ def error_message
15
+ msg = "User "
16
+ msg << "#{user_data} " unless user_data.nil?
17
+ msg << "is missing permission '#{licence_key}'. " \
18
+ 'Therefore he is not allowed to perform this activity.'
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,9 @@
1
+ module OO
2
+ module Errors
3
+ class LicenceMissingReactionInvalid < StandardError
4
+ def initialize
5
+ super('OO.configuration.licence_missing_reaction must be a Proc.')
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,75 @@
1
+ module OO
2
+ class Licence
3
+ class << self
4
+ def separator
5
+ '.'
6
+ end
7
+
8
+ def mask_mark
9
+ '*'
10
+ end
11
+
12
+ def max_depth
13
+ OO.configuration.licence_max_depth
14
+ end
15
+
16
+ def masks
17
+ masks = {}
18
+ max_depth.times do |t|
19
+ masks["#{t + 1}"] = mask_mark + "#{separator}#{mask_mark}" * t
20
+ end
21
+ masks
22
+ end
23
+ end
24
+
25
+ attr_reader :key
26
+
27
+ alias_method :to_s, :key
28
+
29
+ def initialize(attrs = {})
30
+ @key = attrs.fetch(:key)
31
+ end
32
+
33
+ def masks
34
+ masks = []
35
+ gen_masks = genre_masks
36
+ current = self
37
+ while current.key != mask_mark
38
+ gen_masks.each { |mask| masks << current.mask_key(mask) }
39
+ current = current.parent
40
+ end
41
+ (masks + gen_masks).uniq
42
+ end
43
+
44
+ def parent
45
+ return self.class.new(key: mask_mark) if depth == 1
46
+ self.class.new(key: to_a[0..-2].join(separator))
47
+ end
48
+
49
+ def to_a
50
+ key.split(separator)
51
+ end
52
+
53
+ def depth
54
+ to_a.size
55
+ end
56
+
57
+ def separator
58
+ self.class.separator
59
+ end
60
+
61
+ def mask_mark
62
+ self.class.mask_mark
63
+ end
64
+
65
+ def genre_masks
66
+ (depth..self.class.masks.size).map { |n| self.class.masks[n.to_s] }
67
+ end
68
+
69
+ def mask_key(mask)
70
+ mask = mask.split(separator)
71
+ mask[0..depth - 1] = *to_a
72
+ mask.join(separator)
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,34 @@
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
@@ -0,0 +1,15 @@
1
+ module OO
2
+ module LicenceUser
3
+ def self.included(base)
4
+ base.class_eval do
5
+ field :licence_keys, type: :array,
6
+ default: OO.configuration.default_licence_keys
7
+
8
+ def licensed?(attrs = {})
9
+ required_key = attrs.fetch(:to)
10
+ CheckLicence.call(key: required_key, in: licence_keys).any?
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ module OO
2
+ VERSION = '0.9.0'
3
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
3
+
4
+ require 'oo/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = 'oo'
8
+ s.version = OO::VERSION
9
+ s.summary = 'Simple Activity Based Authorization'
10
+ s.homepage = 'https://github.com/buszu/oo'
11
+ s.license = 'MIT'
12
+
13
+ s.authors = ['Krzysztof Buszewicz']
14
+ s.email = ['krzysztof.buszewicz@gmail.com']
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- spec/*`.split("\n")
18
+ s.require_paths = ['lib']
19
+
20
+ s.add_development_dependency 'bundler', '~> 1.11'
21
+ s.add_development_dependency 'rake', '~> 10.0'
22
+ s.add_development_dependency 'rspec', '~> 3.0'
23
+ s.add_development_dependency 'factory_girl', '~> 4.0'
24
+ end
@@ -0,0 +1,11 @@
1
+ FactoryGirl.define do
2
+ factory :licence, class: OO::Licence do
3
+ key 'action'
4
+
5
+ initialize_with { new(attributes) }
6
+ end
7
+
8
+ factory :glass_take_with_juice, parent: :licence do
9
+ key 'glass.take.with_juice'
10
+ end
11
+ end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe OO::CheckLicence do
5
+
6
+ describe '.new(attrs = {})' do
7
+ let(:service_object) { described_class.new(attrs) }
8
+ let(:licence_key) { 'glass.take' }
9
+
10
+ subject { service_object }
11
+
12
+ context 'when required attrs are missing' do
13
+ context 'when :key (checked licence key) is missing' do
14
+ let(:attrs) { { in: [] } }
15
+ it { expect { subject }.to raise_error(KeyError) }
16
+ end
17
+
18
+ context 'when :in (licence keys list) is missing' do
19
+ let(:attrs) { { key: licence_key } }
20
+ it { expect { subject }.to raise_error(KeyError) }
21
+ end
22
+ end
23
+
24
+ context 'when all required attrs were passed' do
25
+ let(:attrs) { { key: licence_key, in: [] } }
26
+
27
+ it { is_expected.to be_a(described_class) }
28
+
29
+ describe 'builds a licence' do
30
+ let(:licence_class) { OO::Licence }
31
+
32
+ describe '@licence' do
33
+ let(:licence) { service_object.instance_variable_get(:@licence) }
34
+
35
+ subject { licence }
36
+ it { is_expected.to be_a(licence_class) }
37
+
38
+ describe '#key' do
39
+ subject { licence.key }
40
+ it { is_expected.to eq(licence_key) }
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ describe '#call' do
48
+ let(:service_object) { described_class.new(key: licence_key, in: licence_keys) }
49
+ let(:licence) { OO::Licence.new(key: licence_key) }
50
+ let(:licence_key) { 'glass.take' }
51
+
52
+ subject { service_object.call }
53
+
54
+ describe 'returns all keys wider or equal to given key found in given list' do
55
+ context 'when licence key is included in licence keys list' do
56
+ context 'and is an only match' do
57
+ let(:licence_keys) { [licence_key] }
58
+ it { is_expected.to eq([licence_key]) }
59
+ end
60
+ end
61
+
62
+ context 'when exact licence key is missing in given list' do
63
+ context 'but there are wider keys' do
64
+ let(:licence_keys) { licence.genre_masks }
65
+ it { is_expected.to eq(licence.genre_masks) }
66
+ end
67
+ end
68
+
69
+ context 'when licence key is missing in given list' do
70
+ let(:licence_keys) { %w(a b c d) }
71
+ it { is_expected.to eq([]) }
72
+
73
+ context 'but found parent key' do
74
+ let(:licence_keys) { [licence.parent.key] }
75
+ it { is_expected.to eq([]) }
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,123 @@
1
+ require 'spec_helper'
2
+
3
+ describe OO::Configuration do
4
+ describe '.new' do
5
+ let(:configuration) { described_class.new }
6
+ let(:default_licence_max_depth) { 4 }
7
+ let(:default_licence_keys) { [] }
8
+ let(:default_licence_missing_reaction) do
9
+ -> { :licence_missing_reaction_not_configured }
10
+ end
11
+
12
+ let(:default_licence_checkers_default_user) do
13
+ -> { :licence_checkers_default_user_not_configured }
14
+ end
15
+
16
+ let(:default_licence_checkers_default_key) do
17
+ -> { :licence_checkers_default_key_not_configured }
18
+ end
19
+
20
+ subject { configuration }
21
+
22
+ it { is_expected.to be_a(described_class) }
23
+ describe 'it is set to default values' do
24
+ describe 'licence_max_depth' do
25
+ subject { configuration.licence_max_depth }
26
+ it { is_expected.to eq(default_licence_max_depth) }
27
+ end
28
+
29
+ describe 'default_licence_keys' do
30
+ subject { configuration.default_licence_keys }
31
+ it { is_expected.to eq(default_licence_keys) }
32
+ end
33
+
34
+ describe 'licence_missing_reaction' do
35
+ let(:licence_missing_reaction) { configuration.licence_missing_reaction }
36
+ subject { licence_missing_reaction }
37
+ it { is_expected.to be_a(Proc) }
38
+ describe "#call" do
39
+ subject { licence_missing_reaction.call }
40
+ it { is_expected.to eq(:licence_missing_reaction_not_configured) }
41
+ end
42
+ end
43
+
44
+ describe 'licence_checkers_default_user' do
45
+ let(:licence_checkers_default_user) { configuration.licence_checkers_default_user }
46
+ subject { licence_checkers_default_user }
47
+ it { is_expected.to be_a(Proc) }
48
+ describe "#call" do
49
+ subject { licence_checkers_default_user.call }
50
+ it { is_expected.to eq(:licence_checkers_default_user_not_configured) }
51
+ end
52
+ end
53
+
54
+ describe 'licence_checkers_default_key' do
55
+ let(:licence_checkers_default_key) { configuration.licence_checkers_default_key }
56
+ subject { licence_checkers_default_key }
57
+ it { is_expected.to be_a(Proc) }
58
+ describe "#call" do
59
+ subject { licence_checkers_default_key.call }
60
+ it { is_expected.to eq(:licence_checkers_default_key_not_configured) }
61
+ end
62
+ end
63
+ end
64
+
65
+ describe '#licence_max_depth=(depth)' do
66
+ context 'when depth is not a fixnum' do
67
+ let(:depth) { 'a' }
68
+ let(:error) { OO::Errors::LicenceMaxDepthInvalid }
69
+
70
+ subject { -> { configuration.licence_max_depth = depth } }
71
+ it { is_expected.to raise_error(error) }
72
+ end
73
+
74
+ context 'when depth is not greater than 0' do
75
+ let(:depth) { 0 }
76
+ let(:error) { OO::Errors::LicenceMaxDepthInvalid }
77
+
78
+ subject { -> { configuration.licence_max_depth = depth } }
79
+ it { is_expected.to raise_error(error) }
80
+ end
81
+ end
82
+
83
+ describe '#licence_missing_reaction=(action)' do
84
+ context 'when action is not a Proc object' do
85
+ let(:action) { :invalid }
86
+ let(:error) { OO::Errors::LicenceMissingReactionInvalid }
87
+
88
+ subject { -> { configuration.licence_missing_reaction = action } }
89
+ it { is_expected.to raise_error(error) }
90
+ end
91
+ end
92
+
93
+ describe '#licence_checkers_default_user=(action)' do
94
+ context 'when action is not a Proc object' do
95
+ let(:action) { :invalid }
96
+ let(:error) { OO::Errors::LicenceCheckersDefaultUserInvalid }
97
+
98
+ subject { -> { configuration.licence_checkers_default_user = action } }
99
+ it { is_expected.to raise_error(error) }
100
+ end
101
+ end
102
+
103
+ describe '#licence_checkers_default_key=(action)' do
104
+ context 'when action is not a Proc object' do
105
+ let(:action) { :invalid }
106
+ let(:error) { OO::Errors::LicenceCheckersDefaultKeyInvalid }
107
+
108
+ subject { -> { configuration.licence_checkers_default_key = action } }
109
+ it { is_expected.to raise_error(error) }
110
+ end
111
+ end
112
+
113
+ describe '#default_licence_keys=(licence_keys)' do
114
+ context 'when licence_keys is not an array' do
115
+ let(:licence_keys) { :invalid }
116
+ let(:error) { OO::Errors::DefaultLicenceKeysInvalid }
117
+
118
+ subject { -> { configuration.default_licence_keys = licence_keys } }
119
+ it { is_expected.to raise_error(error) }
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,232 @@
1
+ require 'spec_helper'
2
+
3
+ describe OO::Licence do
4
+ let(:separator) { described_class.separator }
5
+ let(:mask_mark) { described_class.mask_mark }
6
+
7
+ describe '.separator' do
8
+ let(:separator) { '.' }
9
+ subject { described_class.separator }
10
+ it { is_expected.to eq(separator) }
11
+ end
12
+
13
+ describe '.mask_mark' do
14
+ let(:mask_mark) { '*' }
15
+ subject { described_class.mask_mark }
16
+ it { is_expected.to eq(mask_mark) }
17
+ end
18
+
19
+ describe '.max_depth' do
20
+ let(:max_depth) { OO.configuration.licence_max_depth }
21
+ subject { described_class.max_depth }
22
+
23
+ context 'for default configuration' do
24
+ it { is_expected.to eq(max_depth) }
25
+ end
26
+ end
27
+
28
+ describe '.masks' do
29
+ subject { described_class.masks }
30
+
31
+ describe 'returns all possible top-level masks basing on max depth' do
32
+ before(:each) { OO.configure { |c| c.licence_max_depth = max_depth } }
33
+
34
+ context 'when max_depth is set to 1' do
35
+ let(:max_depth) { 1 }
36
+ let(:masks) { { '1' => mask_mark } }
37
+ it { is_expected.to eq(masks) }
38
+ end
39
+
40
+ context 'when max_depth is set to 2' do
41
+ let(:max_depth) { 2 }
42
+ let(:masks) do
43
+ { '1' => mask_mark,
44
+ '2' => "#{mask_mark}#{separator}#{mask_mark}" }
45
+ end
46
+
47
+ it { is_expected.to eq(masks) }
48
+ end
49
+
50
+ context 'when max_depth is set to 3' do
51
+ let(:max_depth) { 3 }
52
+ let(:masks) do
53
+ {
54
+ '1' => mask_mark,
55
+ '2' => "#{mask_mark}#{separator}#{mask_mark}",
56
+ '3' => "#{mask_mark}#{separator}#{mask_mark}#{separator}#{mask_mark}"
57
+ }
58
+ end
59
+
60
+ it { is_expected.to eq(masks) }
61
+ end
62
+ end
63
+ end
64
+
65
+ describe '#separator' do
66
+ let(:licence) { build(:glass_take_with_juice) }
67
+ subject { licence.separator }
68
+ it { is_expected.to eq(described_class.separator) }
69
+ end
70
+
71
+ describe '#mask_mark' do
72
+ let(:licence) { build(:glass_take_with_juice) }
73
+ subject { licence.mask_mark }
74
+ it { is_expected.to eq(described_class.mask_mark) }
75
+ end
76
+
77
+ describe '#key' do
78
+ context 'for :glass_take_with_juice factory' do
79
+ let(:licence) { build(:glass_take_with_juice) }
80
+
81
+ subject { licence.key }
82
+
83
+ it { is_expected.to be_a(String) }
84
+ it { is_expected.to eq('glass.take.with_juice') }
85
+ end
86
+ end
87
+
88
+ describe '#to_s' do
89
+ context 'for :glass_take_with_juice factory' do
90
+ let(:licence) { build(:glass_take_with_juice) }
91
+
92
+ subject { licence.to_s }
93
+
94
+ it { is_expected.to be_a(String) }
95
+ it { is_expected.to eq('glass.take.with_juice') }
96
+ end
97
+ end
98
+
99
+ describe '#to_a' do
100
+ context 'for :glass_take_with_juice factory' do
101
+ let(:licence) { build(:glass_take_with_juice) }
102
+
103
+ subject { licence.to_a }
104
+
105
+ it { is_expected.to be_an(Array) }
106
+ it { is_expected.to eq(%w(glass take with_juice)) }
107
+ end
108
+ end
109
+
110
+ describe '#depth' do
111
+ context 'for :glass_take_with_juice factory' do
112
+ let(:licence) { build(:glass_take_with_juice) }
113
+
114
+ subject { licence.depth }
115
+
116
+ it { is_expected.to be_a(Fixnum) }
117
+ it { is_expected.to eq(3) }
118
+ end
119
+ end
120
+
121
+ describe '#genre_masks' do
122
+ let(:m) { mask_mark }
123
+ let(:s) { separator }
124
+ let(:genre_masks) do
125
+ { depth_1: %W(#{m} #{m}#{s}#{m} #{m}#{s}#{m}#{s}#{m} #{m}#{s}#{m}#{s}#{m}#{s}#{m}),
126
+ depth_3: %W(#{m}#{s}#{m}#{s}#{m} #{m}#{s}#{m}#{s}#{m}#{s}#{m}) }
127
+ end
128
+
129
+ subject { licence.genre_masks }
130
+
131
+ describe 'should return the most general masks for licence' do
132
+ context 'for :glass_take_with_juice factory (depth: 3)' do
133
+ let(:licence) { build(:glass_take_with_juice) }
134
+
135
+ it { is_expected.to be_an(Array) }
136
+ it { is_expected.to eq(genre_masks[:depth_3]) }
137
+ end
138
+
139
+ context 'for :licence factory (depth: 1)' do
140
+ let(:licence) { build(:licence) }
141
+
142
+ it { is_expected.to be_an(Array) }
143
+ it { is_expected.to eq(genre_masks[:depth_1]) }
144
+ end
145
+ end
146
+ end
147
+
148
+ describe '#mask_key(mask)' do
149
+ let(:m) { mask_mark }
150
+ let(:s) { separator }
151
+
152
+ subject { licence.mask_key(mask) }
153
+
154
+ describe 'for n-deep licence should replace mask\'s n chars with key\'s' do
155
+ context 'when mask key is deeper than licence' do
156
+ let(:mask) { "#{m}#{s}#{m}#{s}#{m}#{s}#{m}" }
157
+
158
+ context 'for :glass_take_with_juice factory' do
159
+ let(:licence) { build(:glass_take_with_juice) }
160
+
161
+ it { is_expected.to be_a(String) }
162
+ it { is_expected.to eq(licence.key + "#{s}#{m}") }
163
+ end
164
+
165
+ context 'for :licence factory' do
166
+ let(:licence) { build(:licence) }
167
+
168
+ it { is_expected.to be_an(String) }
169
+ it { is_expected.to eq(licence.key + "#{s}#{m}#{s}#{m}#{s}#{m}") }
170
+ end
171
+ end
172
+
173
+ context 'when mask depth equals licence depth' do
174
+ context 'for :licence factory' do
175
+ let(:licence) { build(:licence) }
176
+ let(:mask) { "#{m}" }
177
+
178
+ it { is_expected.to be_an(String) }
179
+ it { is_expected.to eq(licence.key) }
180
+ end
181
+ end
182
+
183
+ context 'when mask depth is less than licence depth' do
184
+ context 'for :glass_take_with_juice factory' do
185
+ let(:licence) { build(:glass_take_with_juice) }
186
+ let(:mask) { "#{m}#{s}#{m}" }
187
+
188
+ it { is_expected.to be_an(String) }
189
+ it { is_expected.to eq(licence.key) }
190
+ end
191
+ end
192
+ end
193
+ end
194
+
195
+ describe '#parent' do
196
+ let(:mask_mark) { described_class.mask_mark }
197
+
198
+ context 'for :glass_take_with_juice factory' do
199
+ let(:licence) { build(:glass_take_with_juice) }
200
+ let(:parent_licence) { licence.parent }
201
+
202
+ subject { parent_licence }
203
+
204
+ it { is_expected.to be_a(described_class) }
205
+
206
+ describe '#key' do
207
+ subject { parent_licence.key }
208
+ it { is_expected.to eq('glass.take') }
209
+ end
210
+ end
211
+
212
+ context 'for :licence factory' do
213
+ let(:licence) { build(:licence) }
214
+ let(:parent_licence) { licence.parent }
215
+
216
+ describe '#key' do
217
+ subject { parent_licence.key }
218
+ it { is_expected.to eq(mask_mark) }
219
+ end
220
+ end
221
+
222
+ context 'when key equals single mask mark' do
223
+ let(:licence) { build(:licence, key: mask_mark) }
224
+ let(:parent_licence) { licence.parent }
225
+
226
+ describe '#key' do
227
+ subject { parent_licence.key }
228
+ it { is_expected.to eq(mask_mark) }
229
+ end
230
+ end
231
+ end
232
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe OO do
4
+ describe '.configuration' do
5
+ subject { described_class.configuration }
6
+ it { is_expected.to be_a(described_class::Configuration) }
7
+ end
8
+
9
+ describe '.configure' do
10
+ context 'when no block was given' do
11
+ subject { described_class.configure }
12
+ it 'returns current configuration' do
13
+ is_expected.to eq(described_class.configuration)
14
+ end
15
+ end
16
+
17
+ context 'when block was given' do
18
+ let(:depth) { 5 }
19
+ before(:each) do
20
+ described_class.configure { |c| c.licence_max_depth = depth }
21
+ end
22
+
23
+ it 'updates configuration' do
24
+ expect(described_class.configuration.licence_max_depth).to eq(depth)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,16 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'factory_girl'
3
+ require 'oo'
4
+
5
+ RSpec.configure do |c|
6
+ c.include FactoryGirl::Syntax::Methods
7
+
8
+ c.before(:suite) do
9
+ FactoryGirl.find_definitions
10
+ OO.instance_variable_set(:@configuration, OO::Configuration.new)
11
+ end
12
+
13
+ c.after(:each) do
14
+ OO.instance_variable_set(:@configuration, OO::Configuration.new)
15
+ end
16
+ end
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: oo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0
5
+ platform: ruby
6
+ authors:
7
+ - Krzysztof Buszewicz
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-03-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: factory_girl
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '4.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '4.0'
69
+ description:
70
+ email:
71
+ - krzysztof.buszewicz@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - .rspec
78
+ - .rubocop.yml
79
+ - .travis.yml
80
+ - Gemfile
81
+ - LICENSE.txt
82
+ - README.md
83
+ - Rakefile
84
+ - bin/console
85
+ - bin/setup
86
+ - lib/generators/oo/install_generator.rb
87
+ - lib/generators/oo/templates/initializer.rb
88
+ - lib/oo.rb
89
+ - lib/oo/check_licence.rb
90
+ - lib/oo/configuration.rb
91
+ - lib/oo/errors/default_licence_keys_invalid.rb
92
+ - lib/oo/errors/licence_checkers_default_key_invalid.rb
93
+ - lib/oo/errors/licence_checkers_default_user_invalid.rb
94
+ - lib/oo/errors/licence_max_depth_invalid.rb
95
+ - lib/oo/errors/licence_missing.rb
96
+ - lib/oo/errors/licence_missing_reaction_invalid.rb
97
+ - lib/oo/licence.rb
98
+ - lib/oo/licence_checkers.rb
99
+ - lib/oo/licence_user.rb
100
+ - lib/oo/version.rb
101
+ - oo.gemspec
102
+ - spec/factories/licences.rb
103
+ - spec/oo/check_licence_spec.rb
104
+ - spec/oo/configuration_spec.rb
105
+ - spec/oo/licence_spec.rb
106
+ - spec/oo_spec.rb
107
+ - spec/spec_helper.rb
108
+ homepage: https://github.com/buszu/oo
109
+ licenses:
110
+ - MIT
111
+ metadata: {}
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubyforge_project:
128
+ rubygems_version: 2.0.14
129
+ signing_key:
130
+ specification_version: 4
131
+ summary: Simple Activity Based Authorization
132
+ test_files:
133
+ - spec/factories/licences.rb
134
+ - spec/oo/check_licence_spec.rb
135
+ - spec/oo/configuration_spec.rb
136
+ - spec/oo/licence_spec.rb
137
+ - spec/oo_spec.rb
138
+ - spec/spec_helper.rb