soar_pl 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +42 -0
- data/Rakefile +6 -0
- data/lib/soar_pl/authorization_policy.rb +148 -0
- data/lib/soar_pl/version.rb +3 -0
- data/lib/soar_pl.rb +5 -0
- data/soar_pl.gemspec +28 -0
- metadata +110 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c635718cebea5cd51e3b6f06355fb3d23f1e3b80
|
4
|
+
data.tar.gz: ede26601dc1055a1b3ab7130fbe5e998c5e0a7f5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 29f328e7bc225aad9f6fa486a64443955dee7f92c33599b61714757f5162795f8b35f63a7065b21c8e6175cba2eb3431a15299c132e9b1bfe87bf66a2781c997
|
7
|
+
data.tar.gz: 96c0599aa1b467be1b27a0ff36b12408731fe4bd6aee799175935d739ce0b018b4eac56441703537bb3ce49b0bac9689bf1da48495e5bb3b5ed56689445310cc
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Ernst van Graan
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# SoarPl
|
2
|
+
|
3
|
+
SoarPl is a generic authorization policy implementation. It was designed for use in the SOAR architecture. Extend the AuthorizationPolicy class with your own, and provide the needed IDM interaction and rule set for interrogating subject_identifier, requestor_identifier, resource_identifier and request in order to make an authorization decision. The policy communicates the result using jsend.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'soar_pl'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
gem install soar_pl
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
spec.add_development_dependency 'soar_pl'
|
21
|
+
bundle exec irb
|
22
|
+
|
23
|
+
Extend the AuthorizationPolicy class to create a policy. Examples can be found here: https://github.hetzner.co.za/hetznerZA/soar_policies/tree/master/production
|
24
|
+
|
25
|
+
The implementation reaches out to the IDM provided and retrieves entity roles and attributes.
|
26
|
+
The IDM provided must adhere to the following API:
|
27
|
+
|
28
|
+
subject_identifier = "string identifier"
|
29
|
+
subject_roles = @idm.get_roles(subject_identifier)
|
30
|
+
# [ 'role1', 'role2']
|
31
|
+
attributes = {}
|
32
|
+
attributes = @idm.get_attributes(subject_identifier, role)
|
33
|
+
# { 'role1' => {'attribute1' => 'value1', 'attribute2' => 'value2'}, 'role2' => {'attribute3' => 'value3', 'attribute4' => 'value4'}}
|
34
|
+
|
35
|
+
## Contributing
|
36
|
+
|
37
|
+
Bug reports and feature requests are welcome by email to ernst dot van dot graan at hetzner dot co dot za. This gem is sponsored by Hetzner (Pty) Ltd (http://hetzner.co.za)
|
38
|
+
|
39
|
+
## License
|
40
|
+
|
41
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
42
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'jsender'
|
2
|
+
|
3
|
+
module SoarPl
|
4
|
+
class AuthorizationPolicy
|
5
|
+
include Jsender
|
6
|
+
|
7
|
+
attr_reader :policy_identifier
|
8
|
+
attr_reader :policy_configuration
|
9
|
+
attr_reader :subject_identifier
|
10
|
+
attr_reader :requestor_identifier
|
11
|
+
attr_reader :request
|
12
|
+
attr_reader :configuration
|
13
|
+
attr_reader :rule_set
|
14
|
+
attr_reader :idm
|
15
|
+
attr_reader :roles
|
16
|
+
attr_accessor :status
|
17
|
+
attr_accessor :request_debug_allow
|
18
|
+
|
19
|
+
def initialize(policy_identifier, policy_configuration)
|
20
|
+
data = { 'dependencies' =>
|
21
|
+
{ 'configuration' => 'invalid',
|
22
|
+
'policy_identifier' => 'invalid',
|
23
|
+
'rule_set' => 'invalid' } }
|
24
|
+
@roles = []
|
25
|
+
@policy_identifier = policy_identifier
|
26
|
+
@configuration = policy_configuration
|
27
|
+
|
28
|
+
valid_policy_identifier = valid_non_empty_string?(policy_identifier)
|
29
|
+
valid_configuration = @configuration.is_a?(Hash)
|
30
|
+
#byebug
|
31
|
+
valid_rule_set = (self.class.name != 'SoarPl::AuthorizationPolicy')
|
32
|
+
|
33
|
+
if (policy_identifier.nil?)
|
34
|
+
@status = fail('no identifier provided')
|
35
|
+
elsif (not valid_policy_identifier)
|
36
|
+
@status = fail('invalid identifier provided')
|
37
|
+
elsif policy_configuration.nil?
|
38
|
+
@status = fail('no configuration provided')
|
39
|
+
elsif not valid_configuration
|
40
|
+
@status = fail('invalid configuration provided', data)
|
41
|
+
elsif not valid_rule_set
|
42
|
+
# Must extend this class and provide a rule set in apply_rule_set(...)
|
43
|
+
@status = fail('invalid rule set provided')
|
44
|
+
else
|
45
|
+
@status = success_data(data)
|
46
|
+
end
|
47
|
+
data['dependencies']['configuration'] = (valid_configuration ? 'valid' : 'invalid')
|
48
|
+
data['dependencies']['rule_set'] = (valid_rule_set ? 'valid' : 'invalid')
|
49
|
+
data['dependencies']['policy_identifier'] = (valid_policy_identifier ? 'valid' : 'invalid')
|
50
|
+
setup
|
51
|
+
end
|
52
|
+
|
53
|
+
def requires_roles(roles)
|
54
|
+
roles = [roles] if not roles.is_a?(Array)
|
55
|
+
|
56
|
+
@roles = roles
|
57
|
+
end
|
58
|
+
|
59
|
+
def has_idm(idm)
|
60
|
+
@idm = idm
|
61
|
+
end
|
62
|
+
|
63
|
+
def authorize(subject_identifier, requestor_identifier, resource_identifier, request)
|
64
|
+
#byebug
|
65
|
+
requested = request
|
66
|
+
begin
|
67
|
+
requested = JSON.parse(request) if not request.is_a?(Hash)
|
68
|
+
rescue => ex
|
69
|
+
return fail("Invalid request", build_result(false, "Invalid request", @idm))
|
70
|
+
end
|
71
|
+
return fail_invalid("resource identifier") if not valid_non_empty_string?(resource_identifier)
|
72
|
+
return fail("Invalid request", build_result(false, "Invalid request", @idm)) if requested and not requested.is_a?(Hash)
|
73
|
+
return fail_invalid("requestor identifier") if not valid_non_empty_string?(requestor_identifier)
|
74
|
+
return fail_invalid("subject identifier") if not valid_non_empty_string?(subject_identifier)
|
75
|
+
|
76
|
+
subject_roles = []
|
77
|
+
attributes = {}
|
78
|
+
begin
|
79
|
+
subject_roles = discover_subject_roles(subject_identifier) if @idm
|
80
|
+
rescue => ex
|
81
|
+
error = 'Entity error (IDM)'
|
82
|
+
return fail(error, build_result(false, error, @idm))
|
83
|
+
end
|
84
|
+
|
85
|
+
return success_data(build_result(false, "Role missing", @idm)) if not roles_present?(subject_roles, @roles)
|
86
|
+
|
87
|
+
begin
|
88
|
+
attributes = discover_subject_role_attributes(subject_identifier, subject_roles) if @idm
|
89
|
+
rescue => ex
|
90
|
+
error = 'Entity error (IDM)'
|
91
|
+
return fail(error, build_result(false, error, @idm))
|
92
|
+
end
|
93
|
+
|
94
|
+
result, message = apply_rule_set(subject_identifier, requestor_identifier, resource_identifier, requested, subject_roles, attributes)
|
95
|
+
|
96
|
+
if (result)
|
97
|
+
success_data(build_result(true, message, @idm))
|
98
|
+
else
|
99
|
+
success_data(build_result(false, message, @idm))
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
protected
|
104
|
+
|
105
|
+
def setup
|
106
|
+
end
|
107
|
+
|
108
|
+
def apply_rule_set(subject_identifier, requestor_identifier, resource_identifier, request, subject_roles, attribures)
|
109
|
+
# override me
|
110
|
+
end
|
111
|
+
|
112
|
+
def discover_subject_roles(subject_identifier)
|
113
|
+
subject_roles = @idm.get_roles(subject_identifier)
|
114
|
+
end
|
115
|
+
|
116
|
+
def discover_subject_role_attributes(subject_identifier, subject_roles)
|
117
|
+
attributes = {}
|
118
|
+
@roles.each do |role|
|
119
|
+
attributes[role] = @idm.get_role_attributes(subject_identifier, role)
|
120
|
+
end
|
121
|
+
attributes
|
122
|
+
end
|
123
|
+
|
124
|
+
private
|
125
|
+
|
126
|
+
def fail_invalid(description)
|
127
|
+
fail("Invalid #{description}", build_result(false, "Invalid #{description}", @idm))
|
128
|
+
end
|
129
|
+
|
130
|
+
def valid_non_empty_string?(value)
|
131
|
+
not (value.nil? or (not value.is_a?(String)) or (value.strip == ''))
|
132
|
+
end
|
133
|
+
|
134
|
+
def build_result(allow, message, idm)
|
135
|
+
{'allowed' => allow, 'detail' => message, 'idm' => idm, 'rule_set' => self.class.name}
|
136
|
+
end
|
137
|
+
|
138
|
+
def roles_present?(subject_roles, required_roles)
|
139
|
+
return true if required_roles.nil? or required_roles.empty?
|
140
|
+
return false if subject_roles.nil?
|
141
|
+
required_roles.each do |role|
|
142
|
+
return false if not subject_roles.include?(role)
|
143
|
+
end
|
144
|
+
true
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
data/lib/soar_pl.rb
ADDED
data/soar_pl.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'soar_pl/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "soar_pl"
|
8
|
+
spec.version = SoarPl::VERSION
|
9
|
+
spec.authors = ["Ernst van Graan"]
|
10
|
+
spec.email = ["ernst.van.graan@hetzner.co.za"]
|
11
|
+
|
12
|
+
spec.summary = %q{Generic implementation of a SOAR authorization policy}
|
13
|
+
spec.description = %q{Generic implementation of a SOAR authorization policy}
|
14
|
+
# spec.homepage = "TODO: Put your gem's website or public repo URL here."
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
# spec.required_ruby_version = ['>=2.0.0']
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
24
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
+
spec.add_development_dependency "rspec"
|
26
|
+
#spec.add_development_dependency "byebug"
|
27
|
+
spec.add_dependency "jsender"
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: soar_pl
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ernst van Graan
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-02-15 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.10'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.10'
|
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: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: jsender
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Generic implementation of a SOAR authorization policy
|
70
|
+
email:
|
71
|
+
- ernst.van.graan@hetzner.co.za
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- Gemfile
|
78
|
+
- LICENSE.txt
|
79
|
+
- README.md
|
80
|
+
- Rakefile
|
81
|
+
- lib/soar_pl.rb
|
82
|
+
- lib/soar_pl/authorization_policy.rb
|
83
|
+
- lib/soar_pl/version.rb
|
84
|
+
- soar_pl.gemspec
|
85
|
+
homepage:
|
86
|
+
licenses:
|
87
|
+
- MIT
|
88
|
+
metadata: {}
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options: []
|
91
|
+
require_paths:
|
92
|
+
- lib
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
requirements: []
|
104
|
+
rubyforge_project:
|
105
|
+
rubygems_version: 2.4.8
|
106
|
+
signing_key:
|
107
|
+
specification_version: 4
|
108
|
+
summary: Generic implementation of a SOAR authorization policy
|
109
|
+
test_files: []
|
110
|
+
has_rdoc:
|