cratus 0.2.1
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 +7 -0
- data/LICENSE +22 -0
- data/bin/cratus +31 -0
- data/bin/cratus-compare +87 -0
- data/lib/cratus.rb +14 -0
- data/lib/cratus/config.rb +65 -0
- data/lib/cratus/group.rb +131 -0
- data/lib/cratus/ldap.rb +88 -0
- data/lib/cratus/user.rb +91 -0
- data/lib/cratus/version.rb +8 -0
- metadata +126 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: edca85708a85f952e904d928dbaa959fd9788289
|
4
|
+
data.tar.gz: fed75393016468b8451f926fee9836dde5b6b519
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3640dd6ba0f250a6c02be3f8d07b092e0a7235e27b27a62839325b4db6eef546506d6607f7d22065f56b8527ac15d6703269f7b206cdecf6795bf378bc9d0d82
|
7
|
+
data.tar.gz: e4e42674b01a639246e984d13170671550705f75cd2b2af961b788729aeaa0d12e82e8a2aab705c844db8388df7158cb8aba2e068680ae794f15b98088473095
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2016 KnuEdge Corporation
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/bin/cratus
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'cratus'
|
4
|
+
|
5
|
+
include Cratus
|
6
|
+
|
7
|
+
LDAP.connect
|
8
|
+
|
9
|
+
# Read in arguments
|
10
|
+
group_mapping_arg = ARGV[0]
|
11
|
+
raise "Missing Group Mapping Argument!" unless group_mapping_arg
|
12
|
+
group_mapping_file = File.expand_path(group_mapping_arg)
|
13
|
+
raise "Invalid Group Mapping File #{group_mapping_file}" unless File.readable?(group_mapping_file)
|
14
|
+
|
15
|
+
# Load the YAML file(s) for mapping permissions
|
16
|
+
group_permissions = YAML.load_file(group_mapping_file)
|
17
|
+
|
18
|
+
# Gather group memberships and permissions
|
19
|
+
@results = {} # stash all the results here... might get really big
|
20
|
+
User.all.sort.each do |user|
|
21
|
+
key = user.username.to_s
|
22
|
+
user_groups = user.member_of.map { |g| g.name.to_s }
|
23
|
+
|
24
|
+
@results[key] = {'groups' => {}}
|
25
|
+
user_groups.sort.each do |ugroup|
|
26
|
+
group_perm_set = group_permissions[ugroup] ? group_permissions[ugroup].sort : []
|
27
|
+
@results[key]['groups'][ugroup] = group_perm_set
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
puts @results.to_yaml
|
data/bin/cratus-compare
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'tempfile'
|
5
|
+
|
6
|
+
# Used to compare the output of the `cratus` command across multiple runs
|
7
|
+
|
8
|
+
input1 = ARGV[0]
|
9
|
+
input2 = ARGV[1]
|
10
|
+
|
11
|
+
# Find our diff command and break if we don't have one
|
12
|
+
diff_path = `which diff`.chomp
|
13
|
+
raise "Missing diff command in PATH!" unless $?.success?
|
14
|
+
|
15
|
+
# The command we'll use later to see what has changed
|
16
|
+
diff_cmd = "#{diff_path} -U 999999"
|
17
|
+
|
18
|
+
## Methods / Functions
|
19
|
+
def validate_input(input)
|
20
|
+
# Make sure the input is set
|
21
|
+
raise "Missing First Input!" unless input
|
22
|
+
# Make sure the input is a valid file that we can read
|
23
|
+
raise "Invalid Input File #{input}" unless File.readable?(input)
|
24
|
+
# TODO: make sure the input file is valid YAML
|
25
|
+
end
|
26
|
+
|
27
|
+
# Read in some input
|
28
|
+
def read_input(input)
|
29
|
+
begin
|
30
|
+
YAML.load_file(input)
|
31
|
+
rescue => e
|
32
|
+
raise "Unable to open #{input}: #{e.message}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
## Execution
|
37
|
+
validate_input(input1)
|
38
|
+
validate_input(input2)
|
39
|
+
|
40
|
+
data1 = read_input(input1)
|
41
|
+
data2 = read_input(input2)
|
42
|
+
|
43
|
+
if data1 == data2
|
44
|
+
exit 0
|
45
|
+
else
|
46
|
+
STDERR.puts "Looks like things have changed!"
|
47
|
+
|
48
|
+
# Calculate what has actually changed
|
49
|
+
additions_and_differences = (data2.to_a - data1.to_a)
|
50
|
+
removals = (data1.to_a - data2.to_a)
|
51
|
+
results = {}
|
52
|
+
additions_and_differences.each do |user|
|
53
|
+
results[user[0]] = user[1]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Temporary files for a call to `diff`
|
57
|
+
newdata = Tempfile.new('new')
|
58
|
+
olddata = Tempfile.new('old')
|
59
|
+
|
60
|
+
# Add the results from our comparison to the first temp file
|
61
|
+
newdata.write(results.to_yaml)
|
62
|
+
|
63
|
+
# Grab the old data for just our changed users and put it into a new hash
|
64
|
+
oldhash = {}
|
65
|
+
results.each do |user,data|
|
66
|
+
oldhash[user] = data1[user] if data1.key?(user)
|
67
|
+
end
|
68
|
+
# Add things that were removed from the old data (removed users)
|
69
|
+
removals.each do |removed_user|
|
70
|
+
oldhash[removed_user[0]] = removed_user[1]
|
71
|
+
end
|
72
|
+
|
73
|
+
# Write out the old data
|
74
|
+
olddata.write(oldhash.to_yaml)
|
75
|
+
|
76
|
+
# Close and flush our temp files
|
77
|
+
newdata.close
|
78
|
+
olddata.close
|
79
|
+
|
80
|
+
# The actual call to the `diff` command
|
81
|
+
system("#{diff_cmd} #{olddata.path} #{newdata.path}")
|
82
|
+
|
83
|
+
# Destroy the temp files after the diff command finishes
|
84
|
+
newdata.unlink
|
85
|
+
olddata.unlink
|
86
|
+
end
|
87
|
+
|
data/lib/cratus.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Standard Library
|
2
|
+
require 'ostruct'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
# External Requirements
|
6
|
+
require 'net/ldap'
|
7
|
+
|
8
|
+
# Internal Requirements
|
9
|
+
require 'cratus/version'
|
10
|
+
require 'cratus/config'
|
11
|
+
Cratus.config.load
|
12
|
+
require 'cratus/ldap'
|
13
|
+
require 'cratus/group'
|
14
|
+
require 'cratus/user'
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# A generic way of constructing a mergeable configuration
|
2
|
+
class Cratus::Config < OpenStruct
|
3
|
+
# Construct a base config using the following order of precedence:
|
4
|
+
# * environment variables
|
5
|
+
# * YAML file
|
6
|
+
# * defaults
|
7
|
+
def load
|
8
|
+
# First, apply the defaults
|
9
|
+
defaults = {
|
10
|
+
group_dn_attribute: :cn,
|
11
|
+
group_member_attribute: :member,
|
12
|
+
group_description_attribute: :description,
|
13
|
+
group_objectclass: :group,
|
14
|
+
group_basedn: 'ou=groups,dc=example,dc=com',
|
15
|
+
group_memberof_attribute: :memberOf,
|
16
|
+
user_dn_attribute: :samaccountname,
|
17
|
+
user_objectclass: :user,
|
18
|
+
user_basedn: 'ou=users,dc=example,dc=com',
|
19
|
+
user_department_attribute: :department,
|
20
|
+
user_lockout_attribute: :lockouttime,
|
21
|
+
user_mail_attribute: :mail,
|
22
|
+
user_displayname_attribute: :displayName,
|
23
|
+
user_memberof_attribute: :memberOf,
|
24
|
+
host: 'ldap.example.com',
|
25
|
+
port: 389,
|
26
|
+
basedn: 'dc=example,dc=com',
|
27
|
+
username: 'username',
|
28
|
+
password: 'p@assedWard!',
|
29
|
+
}
|
30
|
+
merge defaults
|
31
|
+
|
32
|
+
# Then apply the config file, if one exists
|
33
|
+
begin
|
34
|
+
apprc_dir = File.expand_path('~')
|
35
|
+
config_file = File.expand_path(File.join(apprc_dir, '.cratus.yml'))
|
36
|
+
merge YAML.load_file(config_file) if File.readable?(config_file)
|
37
|
+
rescue => e
|
38
|
+
puts "WARNING: Unable to read from #{config_file}"
|
39
|
+
end
|
40
|
+
|
41
|
+
# Finally, apply any environment variables specified
|
42
|
+
env_conf = {}
|
43
|
+
defaults.keys.each do |key|
|
44
|
+
cratus_key = "CRATUS_#{key}".upcase
|
45
|
+
env_conf[key] = ENV[cratus_key] if ENV.key?(cratus_key)
|
46
|
+
end
|
47
|
+
merge env_conf unless env_conf.empty?
|
48
|
+
end
|
49
|
+
|
50
|
+
def merge(data)
|
51
|
+
raise 'Invalid Config Data' unless data.is_a?(Hash)
|
52
|
+
data.each do |k, v|
|
53
|
+
self[k.to_sym] = v
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Make the config available as a singleton
|
59
|
+
module Cratus
|
60
|
+
class << self
|
61
|
+
def config
|
62
|
+
@config ||= Config.new
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/cratus/group.rb
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
module Cratus
|
2
|
+
class Group
|
3
|
+
include Comparable
|
4
|
+
attr_reader :name, :search_base
|
5
|
+
|
6
|
+
def initialize(name)
|
7
|
+
@name = name
|
8
|
+
@search_base = self.class.ldap_search_base
|
9
|
+
@raw_ldap_data = Cratus::LDAP.search(
|
10
|
+
"(#{self.class.ldap_dn_attribute}=#{@name})",
|
11
|
+
basedn: @search_base,
|
12
|
+
attrs: self.class.ldap_return_attributes
|
13
|
+
).last
|
14
|
+
end
|
15
|
+
|
16
|
+
# LDAP users that are a member of this group
|
17
|
+
def members
|
18
|
+
all_members[:users]
|
19
|
+
end
|
20
|
+
|
21
|
+
def member_groups
|
22
|
+
all_members[:groups]
|
23
|
+
end
|
24
|
+
|
25
|
+
def member_of
|
26
|
+
memrof_attr = Cratus.config.group_memberof_attribute
|
27
|
+
|
28
|
+
# TODO make this work with more things...
|
29
|
+
unless @raw_ldap_data
|
30
|
+
STDERR.puts "WARNING: Group '#{@name}' appears to be invalid or beyond the search scope!"
|
31
|
+
return []
|
32
|
+
end
|
33
|
+
|
34
|
+
# TODO: move the search filter to a configurable param
|
35
|
+
raw_groups = @raw_ldap_data[memrof_attr].reject {|g| g.match /OU=Distribution Groups/ }
|
36
|
+
initial_groups = raw_groups.map do |raw_group|
|
37
|
+
Group.new(raw_group.match(/^#{Group.ldap_dn_attribute.to_s.upcase}=([^,]+),/)[1])
|
38
|
+
end
|
39
|
+
all_the_groups = initial_groups
|
40
|
+
initial_groups.each do |group|
|
41
|
+
all_the_groups.concat(group.member_of) # recursion!
|
42
|
+
end
|
43
|
+
all_the_groups.uniq { |g| g.name }
|
44
|
+
end
|
45
|
+
|
46
|
+
# LDAP description attribute
|
47
|
+
def description
|
48
|
+
@raw_ldap_data[Cratus.config.group_description_attribute].last
|
49
|
+
end
|
50
|
+
|
51
|
+
# All the LDAP Groups
|
52
|
+
def self.all
|
53
|
+
filter = "(#{ldap_dn_attribute}=*)"
|
54
|
+
Cratus::LDAP.search(filter, basedn: ldap_search_base, attrs: ldap_dn_attribute).map do |entry|
|
55
|
+
self.new(entry[ldap_dn_attribute].last)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.ldap_dn_attribute
|
60
|
+
Cratus.config.group_dn_attribute.to_s
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.ldap_object_class
|
64
|
+
Cratus.config.group_objectclass.to_s
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.ldap_return_attributes
|
68
|
+
[
|
69
|
+
Cratus.config.group_dn_attribute.to_s,
|
70
|
+
Cratus.config.group_member_attribute.to_s,
|
71
|
+
Cratus.config.group_description_attribute.to_s,
|
72
|
+
Cratus.config.group_memberof_attribute.to_s
|
73
|
+
]
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.ldap_search_base
|
77
|
+
Cratus.config.group_basedn.to_s
|
78
|
+
end
|
79
|
+
|
80
|
+
def <=>(other)
|
81
|
+
@name <=> other.name
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
# provides a Hash of member users and groups
|
87
|
+
def all_members
|
88
|
+
# filters used to determine if each group member is a User or Group
|
89
|
+
group_filter = "(objectClass=#{Cratus.config.group_objectclass.to_s})"
|
90
|
+
user_filter = "(objectClass=#{Cratus.config.user_objectclass.to_s})"
|
91
|
+
|
92
|
+
# The raw LDAP data (a list of DNs)
|
93
|
+
raw_members = @raw_ldap_data[Cratus.config.group_member_attribute]
|
94
|
+
|
95
|
+
# Somewhere to store users and groups as we gather them
|
96
|
+
results = { users: [], groups: [] }
|
97
|
+
|
98
|
+
# Iterate over the members and provide a user or group
|
99
|
+
raw_members.each do |member|
|
100
|
+
user_result = Cratus::LDAP.search(
|
101
|
+
user_filter,
|
102
|
+
basedn: member,
|
103
|
+
scope: 'object',
|
104
|
+
attrs: User.ldap_return_attributes
|
105
|
+
)
|
106
|
+
|
107
|
+
if !user_result.nil? && !user_result.empty?
|
108
|
+
results[:users] << User.new(user_result.last[User.ldap_dn_attribute].last)
|
109
|
+
else
|
110
|
+
group_result = Cratus::LDAP.search(
|
111
|
+
group_filter,
|
112
|
+
basedn: member,
|
113
|
+
scope: 'object',
|
114
|
+
attrs: self.class.ldap_return_attributes
|
115
|
+
)
|
116
|
+
unless group_result.nil? || group_result.empty?
|
117
|
+
nested_group = Group.new(group_result.last[self.class.ldap_dn_attribute].last)
|
118
|
+
results[:groups] << nested_group
|
119
|
+
results[:groups].concat(nested_group.member_groups)
|
120
|
+
results[:users].concat(nested_group.members)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# deliver the results
|
126
|
+
results[:groups].uniq! { |g| g.name }
|
127
|
+
results[:users].uniq! { |u| u.username }
|
128
|
+
return results
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
data/lib/cratus/ldap.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
module Cratus
|
2
|
+
module LDAP
|
3
|
+
# Define the LDAP connection
|
4
|
+
# Note: does not actually connect (bind), just sets up the connection
|
5
|
+
def self.connection
|
6
|
+
options = {
|
7
|
+
host: Cratus.config.host,
|
8
|
+
port: Cratus.config.port,
|
9
|
+
base: Cratus.config.basedn,
|
10
|
+
auth: {
|
11
|
+
method: :simple,
|
12
|
+
username: Cratus.config.username,
|
13
|
+
password: Cratus.config.password
|
14
|
+
}
|
15
|
+
}
|
16
|
+
# TODO: make the validations do something useful
|
17
|
+
#validate_connection_options(options)
|
18
|
+
@@ldap_connection ||= Net::LDAP.new(options)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Actually connect (bind) to LDAP
|
22
|
+
def self.connect
|
23
|
+
connection
|
24
|
+
validate_ldap_connection
|
25
|
+
@@ldap_connection.bind
|
26
|
+
@@ldap_bound = true
|
27
|
+
end
|
28
|
+
|
29
|
+
# Perform an LDAP search
|
30
|
+
#
|
31
|
+
# Required Options: :basedn
|
32
|
+
# Optional Options: :attrs, :scope
|
33
|
+
def self.search(filter, options = {})
|
34
|
+
validate_ldap_connection
|
35
|
+
validate_ldap_bound
|
36
|
+
validate_search_options(options)
|
37
|
+
|
38
|
+
attrs = options.key?(:attrs) ? options[:attrs] : []
|
39
|
+
scope = options.key?(:scope) ? options[:scope] : 'subtree'
|
40
|
+
|
41
|
+
scope_class = case scope.to_s
|
42
|
+
when 'subtree','recursive','whole_subtree'
|
43
|
+
Net::LDAP::SearchScope_WholeSubtree
|
44
|
+
when 'single','single_level'
|
45
|
+
Net::LDAP::SearchScope_SingleLevel
|
46
|
+
when 'object','base_object'
|
47
|
+
Net::LDAP::SearchScope_BaseObject
|
48
|
+
else
|
49
|
+
fail "Invalid LDAP Scope!"
|
50
|
+
end
|
51
|
+
|
52
|
+
results = @@ldap_connection.search(
|
53
|
+
base: options[:basedn],
|
54
|
+
filter: filter,
|
55
|
+
scope: scope_class,
|
56
|
+
attributes: [*attrs].map(&:to_s)
|
57
|
+
)
|
58
|
+
raise "Search Failed" if results.nil?
|
59
|
+
results.compact
|
60
|
+
end
|
61
|
+
|
62
|
+
# Validation Methods
|
63
|
+
|
64
|
+
def self.validate_ldap_bound
|
65
|
+
raise "LDAP Not Connected" unless defined? @@ldap_bound
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.validate_ldap_connection
|
69
|
+
raise "No LDAP Connection" unless defined? @@ldap_connection
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.validate_search_options(options)
|
73
|
+
raise "Invalid Options" unless options.respond_to?(:key?)
|
74
|
+
|
75
|
+
[:basedn].each do |key|
|
76
|
+
raise "Missing Option: #{key}" unless options.key?(key)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.validate_connection_options(options)
|
81
|
+
raise "Invalid Options" unless options.respond_to?(:key?)
|
82
|
+
|
83
|
+
[:host, :port, :basedn, :username, :password].each do |key|
|
84
|
+
raise "Missing Option: #{key}" unless options.key?(key)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/lib/cratus/user.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
module Cratus
|
2
|
+
class User
|
3
|
+
include Comparable
|
4
|
+
attr_reader :username, :search_base
|
5
|
+
|
6
|
+
def initialize(username)
|
7
|
+
@username = username
|
8
|
+
@search_base = self.class.ldap_search_base
|
9
|
+
@raw_ldap_data = Cratus::LDAP.search(
|
10
|
+
"(#{self.class.ldap_dn_attribute}=#{@username})",
|
11
|
+
basedn: @search_base,
|
12
|
+
attrs: self.class.ldap_return_attributes
|
13
|
+
).last
|
14
|
+
end
|
15
|
+
|
16
|
+
def department
|
17
|
+
@raw_ldap_data[Cratus.config.user_department_attribute].last
|
18
|
+
end
|
19
|
+
|
20
|
+
def email
|
21
|
+
@raw_ldap_data[Cratus.config.user_mail_attribute].last
|
22
|
+
end
|
23
|
+
|
24
|
+
def fullname
|
25
|
+
@raw_ldap_data[Cratus.config.user_displayname_attribute].last
|
26
|
+
end
|
27
|
+
|
28
|
+
def lockouttime
|
29
|
+
@raw_ldap_data[Cratus.config.user_lockout_attribute].last
|
30
|
+
end
|
31
|
+
|
32
|
+
def locked?
|
33
|
+
lockouttime != '0'
|
34
|
+
end
|
35
|
+
|
36
|
+
def member_of
|
37
|
+
memrof_attr = Cratus.config.user_memberof_attribute
|
38
|
+
# TODO: move the search filter to a configurable param
|
39
|
+
raw_groups = @raw_ldap_data[memrof_attr].reject {|g| g.match /OU=Distribution Groups/ }
|
40
|
+
initial_groups = raw_groups.map do |raw_group|
|
41
|
+
Group.new(raw_group.match(/^#{Group.ldap_dn_attribute.to_s.upcase}=([^,]+),/)[1])
|
42
|
+
end
|
43
|
+
all_the_groups = initial_groups
|
44
|
+
initial_groups.each do |group|
|
45
|
+
all_the_groups.concat(group.member_of)
|
46
|
+
end
|
47
|
+
all_the_groups.uniq { |g| g.name }
|
48
|
+
end
|
49
|
+
|
50
|
+
alias_method :groups, :member_of
|
51
|
+
|
52
|
+
def <=>(other)
|
53
|
+
@username <=> other.username
|
54
|
+
end
|
55
|
+
|
56
|
+
# All the LDAP Users
|
57
|
+
def self.all
|
58
|
+
raw_results = Cratus::LDAP.search(
|
59
|
+
"(objectClass=#{ldap_object_class})",
|
60
|
+
basedn: ldap_search_base,
|
61
|
+
attrs: ldap_dn_attribute
|
62
|
+
)
|
63
|
+
raw_results.map do |entry|
|
64
|
+
self.new(entry[ldap_dn_attribute.to_sym].last)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.ldap_dn_attribute
|
69
|
+
Cratus.config.user_dn_attribute.to_s
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.ldap_object_class
|
73
|
+
Cratus.config.user_objectclass.to_s
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.ldap_return_attributes
|
77
|
+
[
|
78
|
+
Cratus.config.user_dn_attribute.to_s,
|
79
|
+
Cratus.config.user_department_attribute.to_s,
|
80
|
+
Cratus.config.user_mail_attribute.to_s,
|
81
|
+
Cratus.config.user_displayname_attribute.to_s,
|
82
|
+
Cratus.config.user_memberof_attribute.to_s,
|
83
|
+
Cratus.config.user_lockout_attribute.to_s
|
84
|
+
]
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.ldap_search_base
|
88
|
+
Cratus.config.user_basedn.to_s
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
metadata
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cratus
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jonathan Gnagy
|
8
|
+
- Daniel Schaaff
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2016-11-08 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: colorize
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0.7'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0.7'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: net-ldap
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0.10'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0.10'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rspec
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '3.1'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '3.1'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: rubocop
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0.35'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0.35'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: yard
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0.8'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0.8'
|
84
|
+
description: The Ruby tool for auditing and reporting on user permissions based on
|
85
|
+
groups
|
86
|
+
email: jgnagy@knuedge.com
|
87
|
+
executables:
|
88
|
+
- cratus
|
89
|
+
- cratus-compare
|
90
|
+
extensions: []
|
91
|
+
extra_rdoc_files: []
|
92
|
+
files:
|
93
|
+
- LICENSE
|
94
|
+
- bin/cratus
|
95
|
+
- bin/cratus-compare
|
96
|
+
- lib/cratus.rb
|
97
|
+
- lib/cratus/config.rb
|
98
|
+
- lib/cratus/group.rb
|
99
|
+
- lib/cratus/ldap.rb
|
100
|
+
- lib/cratus/user.rb
|
101
|
+
- lib/cratus/version.rb
|
102
|
+
homepage:
|
103
|
+
licenses:
|
104
|
+
- MIT
|
105
|
+
metadata: {}
|
106
|
+
post_install_message: Thanks for installing Cratus!
|
107
|
+
rdoc_options: []
|
108
|
+
require_paths:
|
109
|
+
- lib
|
110
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - "~>"
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '2.2'
|
115
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
requirements: []
|
121
|
+
rubyforge_project:
|
122
|
+
rubygems_version: 2.5.1
|
123
|
+
signing_key:
|
124
|
+
specification_version: 4
|
125
|
+
summary: Cratus queries LDAP for users and their memberships, then reports on it.
|
126
|
+
test_files: []
|