cratus 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|