sbs2003_contacts 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,11 @@
1
+ === 0.1.0 / 2008-12-19
2
+
3
+ * Initial gemification
4
+
5
+ * Birthday!
6
+
7
+ === 0.2.0 /2008-12-23
8
+
9
+ * Refactors based on zenspider's feedback
10
+
11
+ * Removed IP from test data
@@ -0,0 +1,6 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/sbs2003_contacts.rb
6
+ test/test_sbs2003_contacts.rb
@@ -0,0 +1,68 @@
1
+ = SBS2003Contacts
2
+
3
+ * http://rubyforge.org/projects/uwruby/
4
+ * http://urwuby.rubyforge.org/sbs2003_contacts/
5
+
6
+ == DESCRIPTION:
7
+
8
+ * A small utiltity library to help alleviate the tedium of managing the contacts and e-mail lists from a Small Business Server 2003 Active Directory.
9
+
10
+ == FEATURES/PROBLEMS:
11
+
12
+ * Query AD and find out user info ( email, which lists they belong to )
13
+ * Query AD and find out e-mail list info ( list member e-mails )
14
+ * Manage lists ( add/remove e-mails )
15
+ * TODO: Reverse engineer SBS2003 AD schema's and figure out proper way to add new users/lists
16
+
17
+ == SYNOPSIS:
18
+
19
+ #!/usr/bin/env ruby -w
20
+
21
+ require 'rubygems'
22
+ require 'sbs2003_contacts'
23
+
24
+ # new(username, password, base_dn, server, port)
25
+ # assumes dc=com, localhost, 389
26
+ contact = SBS2003Contacts.new("username", "password", "dc=sbs2003,dc=local")
27
+
28
+ contact.find_user_dn_by_name("Some User")
29
+ # => CN=Some User,OU=...
30
+
31
+ contact.list_user_lists("Some User")
32
+ # => [ "CN=List One,OU=...." ]
33
+
34
+ contact.list_lists_member_emails("list@sbs2003.local")
35
+ # => [ [ "CN=User One,OU=...", "user_one@sbs2003.local" ], ... ]
36
+
37
+ == REQUIREMENTS:
38
+
39
+ * ruby-net-ldap >= 0.0.4
40
+
41
+ == INSTALL:
42
+
43
+ * sudo gem install sbs2003_contacts
44
+
45
+ == LICENSE:
46
+
47
+ (The MIT License)
48
+
49
+ Copyright (c) 2008 FIX
50
+
51
+ Permission is hereby granted, free of charge, to any person obtaining
52
+ a copy of this software and associated documentation files (the
53
+ 'Software'), to deal in the Software without restriction, including
54
+ without limitation the rights to use, copy, modify, merge, publish,
55
+ distribute, sublicense, and/or sell copies of the Software, and to
56
+ permit persons to whom the Software is furnished to do so, subject to
57
+ the following conditions:
58
+
59
+ The above copyright notice and this permission notice shall be
60
+ included in all copies or substantial portions of the Software.
61
+
62
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
63
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
64
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
65
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
66
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
67
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
68
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,13 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/sbs2003_contacts.rb'
6
+
7
+ Hoe.new('sbs2003_contacts', SBS2003Contacts::VERSION) do |p|
8
+ p.rubyforge_name = 'uwruby'
9
+ p.developer('John Howe', 'elf-rubyforge@arashi.com')
10
+ p.extra_deps << [ 'ruby-net-ldap' , '>= 0.0.4' ]
11
+ end
12
+
13
+ # vim: syntax=Ruby
@@ -0,0 +1,159 @@
1
+ #!/usr/bin/env ruby -w
2
+
3
+ require 'rubygems'
4
+ require 'net/ldap'
5
+
6
+ SERVER = "localhost"
7
+ PORT = 389
8
+ BASEDN = "dc=com"
9
+ ADMIN = "Manager"
10
+ PASSWD = "secret"
11
+
12
+ class SBS2003Contacts
13
+ VERSION = '0.2.0'
14
+
15
+ attr_accessor :ldap
16
+
17
+ def initialize(user = ADMIN, pass = PASSWD, base = BASEDN, server = SERVER, port = PORT)
18
+ @ldap = Net::LDAP.new :host => server,
19
+ :port => port,
20
+ :base => base,
21
+ :auth => {
22
+ :method => :simple,
23
+ :username => user,
24
+ :password => pass
25
+ }
26
+ # @ldap.bind ? true : false
27
+ end
28
+
29
+ # meta
30
+
31
+ def set_filter(attribute, search_term)
32
+ Net::LDAP::Filter.eq(attribute, search_term)
33
+ end
34
+
35
+ # User management
36
+
37
+ def find_user_dn_by_name(user_name)
38
+ results = ''
39
+ filter = set_filter( "cn", user_name)
40
+ @ldap.search( :filter => filter ) do |entry|
41
+ results = entry.dn
42
+ end
43
+ raise UserNameNotFoundException, "No DN found for user: #{user_name}" if results.empty?
44
+ results
45
+ end
46
+
47
+ def find_user_dn_by_email(user_email)
48
+ results = ''
49
+ filter = set_filter( "mail", user_email)
50
+ @ldap.search( :filter => filter ) do |entry|
51
+ results = entry.dn
52
+ end
53
+ raise UserEmailNotFoundException, "No DN found for e-mail: #{user_email}" if results.empty?
54
+ results
55
+ end
56
+
57
+ def find_user_email_by_cn(user_cn)
58
+ result = ''
59
+ filter = set_filter("cn", user_cn)
60
+ attrs = [ "cn", "mail" ]
61
+ @ldap.search( :filter => filter, :attributes => attrs ) do |entry|
62
+ entry.each do |attr,values|
63
+ if attr.to_s == "mail" then
64
+ values.each do |value|
65
+ result = value.downcase
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ def update_user_email(user_name, new_email)
73
+ target_dn = find_user_dn_by_name(user_name)
74
+ ldap.replace_attribute target_dn, :mail, new_email
75
+ ldap.replace_attribute target_dn, :proxyAddresses, "SMTP:#{new_email}"
76
+ ldap.replace_attribute target_dn, :targetAddress, "SMTP:#{new_email}"
77
+ end
78
+
79
+ def list_user_lists(user_name)
80
+ results = []
81
+ filter = set_filter("cn", user_name)
82
+ attrs = [ "memberOf", "mail", "cn"]
83
+ @ldap.search( :filter => filter, :attributes => attrs ) do |entry|
84
+ entry.each do |attr, values|
85
+ if attr.to_s == "memberof" then
86
+ values.each do |value|
87
+ results.push(value.dup)
88
+ end
89
+ end
90
+ end
91
+ end
92
+ results.sort
93
+ end
94
+
95
+ # def add_new_user
96
+ # # TODO, need to reverse engineer all of AD's magical madness first
97
+ # # since M$ went way off the fraking reservation and changed stadard LDAP schemas
98
+ # end
99
+
100
+ def find_list_dn_by_email(list_email)
101
+ result = ""
102
+ filter = set_filter( "mail", list_email)
103
+ @ldap.search( :filter => filter ) do |entry|
104
+ result = entry.dn
105
+ end
106
+ raise ListEmailNotFoundException, "List e-mail not found: #{list_email}" if result.empty?
107
+ result
108
+ end
109
+
110
+ def list_lists_member_emails(list_email)
111
+ results = []
112
+ filter = set_filter( "mail", list_email)
113
+ attrs = [ "mail", "member", "cn", "objectClass"]
114
+ @ldap.search( :filter => filter, :attributes => attrs ) do |entry|
115
+ entry.each do |attr, values|
116
+ if attr.to_s == "member" then
117
+ values.each do |value|
118
+ user_cn = value.dup.split(",").first.split("=").last
119
+ results.push( [ value.dup, self.find_user_email_by_cn(user_cn) ] )
120
+ end
121
+ end
122
+ end
123
+ end
124
+ results.sort
125
+ end
126
+
127
+ def add_email_to_list(list_email, user_email)
128
+ # 0. Assumes User already exists!
129
+ # 1. Check to see if user is already a member?
130
+ # 2. Add user_dn to list#member:
131
+ # 3. Add list_dn to user#memberOf:
132
+
133
+ list_dn = find_list_dn_by_email(list_email)
134
+ user_dn = find_user_dn_by_email(user_email)
135
+
136
+ if list_lists_member_emails(list_email).include?([user_dn, user_email])
137
+ raise AlreadyListMemberException, "User e-mail already a member: user_email"
138
+ else
139
+ @ldap.add_attribute list_dn, :member, user_dn
140
+ @ldap.add_attribute user_dn, :memberOf, list_dn
141
+ end
142
+ end
143
+
144
+ def remove_email_from_list(list_email, user_email)
145
+ list_dn = find_list_dn_by_email(list_email)
146
+ user_dn = find_user_dn_by_email(user_email)
147
+
148
+ list_ops = [ [ :delete, :member, user_dn ] ]
149
+ user_ops = [ [ :delete, :memberof, list_dn ] ]
150
+
151
+ @ldap.modify :dn => list_dn, :operations => list_ops
152
+ @ldap.modify :dn => user_dn, :operations => user_ops
153
+ end
154
+ end
155
+
156
+ class UserNameNotFoundException < StandardError; end
157
+ class UserEmailNotFoundException < StandardError; end
158
+ class ListEmailNotFoundException < StandardError; end
159
+ class AlreadyListMemberException < StandardError; end
@@ -0,0 +1,123 @@
1
+ #!/usr/bin/env ruby -w
2
+
3
+ $: << 'lib'
4
+
5
+ require 'test/unit'
6
+ require 'sbs2003_contacts'
7
+
8
+ ##
9
+ # Student Name: John Howe
10
+ # Homework Week: 9a
11
+ #
12
+ # To make these tests pass, you will need a working SBS 2003 server and a login
13
+ # capable of making changes to Active Directory
14
+ #
15
+ # I have left examples as an exercise to the reader...
16
+ # You could speed up LDAP searches using the following base DN:
17
+ # OU=MyBusiness,DC=SBS_Domain,DC=local
18
+ #
19
+ # Note, net-ldap returns attributes lowered from AD, I ran into a gotcha with
20
+ # memberOf previously...
21
+ #
22
+
23
+ class TestSBS2003Contacts < Test::Unit::TestCase
24
+ def setup
25
+ @ldap = SBS2003Contacts.new("ldap-admin@sbsdomain.local", "secret", "dc=sbs_domain,dc=local","127.0.0.1",389)
26
+ # this is kind of a race condition for tests below that use the Test User
27
+ @ldap.update_user_email("Test User", "testuser@sbsdomain.tld")
28
+ end
29
+
30
+ def test_set_filter
31
+ actual = @ldap.set_filter("cn", "Admin User")
32
+ assert_instance_of Net::LDAP::Filter, actual
33
+ end
34
+
35
+ def test_find_user_dn_by_name
36
+ actual = @ldap.find_user_dn_by_name("Admin User")
37
+ expected = "CN=Admin User,OU=SBSUsers,OU=Users,OU=MyBusiness,DC=SBS_Domain,DC=local"
38
+ assert_equal expected, actual
39
+ end
40
+
41
+ def test_find_user_dn_by_name_unknown
42
+ assert_raise UserNameNotFoundException do
43
+ @test = @ldap.find_user_dn_by_name("Bogus Dude")
44
+ end
45
+ end
46
+
47
+ def test_find_user_dn_by_email
48
+ actual = @ldap.find_user_dn_by_email("admin@sbsdomain.tld")
49
+ expected = "CN=Admin User,OU=SBSUsers,OU=Users,OU=MyBusiness,DC=SBS_Domain,DC=local"
50
+ assert_equal expected, actual
51
+ end
52
+
53
+ def test_find_user_dn_by_email_unknown
54
+ assert_raise UserEmailNotFoundException do
55
+ @test = @ldap.find_user_dn_by_email("bdude@sbsdomain.tld")
56
+ end
57
+ end
58
+
59
+ def test_find_user_email_by_cn
60
+ actual = @ldap.find_user_email_by_cn("Company CEO")
61
+ expected = "ceo@sbsdomain.tld"
62
+ assert_equal expected, actual
63
+ end
64
+
65
+ def test_update_user_email
66
+ actual = @ldap.update_user_email("Test User", "testusertest@sbsdomain.tld")
67
+ expected = true
68
+ assert_equal expected, actual
69
+ end
70
+
71
+ def test_lists_user_lists
72
+ actual = @ldap.list_user_lists("Company CEO")
73
+ expected = [
74
+ "CN=Remote Web Workplace Users,OU=Security Groups,OU=MyBusiness,DC=SBS_Domain,DC=local",
75
+ "CN=Staff Group,OU=Security Groups,OU=MyBusiness,DC=SBS_Domain,DC=local",
76
+ "CN=Staff,OU=Distribution Groups,OU=MyBusiness,DC=SBS_Domain,DC=local"
77
+ ]
78
+ assert_equal expected, actual
79
+ end
80
+
81
+ def test_find_list_dn_by_email
82
+ actual = @ldap.find_list_dn_by_email("leadership@sbsdomain.tld")
83
+ expected = "CN=Leadership,OU=Distribution Groups,OU=MyBusiness,DC=SBS_Domain,DC=local"
84
+ assert_equal expected, actual
85
+ end
86
+
87
+ def test_find_list_dn_by_email_not_found
88
+ assert_raise ListEmailNotFoundException do
89
+ @test = @ldap.find_list_dn_by_email("bogus-list@sbsdomain.tld")
90
+ end
91
+ end
92
+
93
+ def test_list_lists_member_emails
94
+ actual = @ldap.list_lists_member_emails("leadership@sbsdomain.tld")
95
+ expected = [
96
+ ["CN=Company CEO,OU=SBSUsers,OU=Users,OU=MyBusiness,DC=SBS_Domain,DC=local","ceo@sbsdomain.tld"],
97
+ ]
98
+ assert_equal expected, actual
99
+ end
100
+
101
+ def test_add_email_to_list
102
+ @ldap.remove_email_from_list("testlist@sbsdomain.tld", "testuser@sbsdomain.tld")
103
+ @ldap.add_email_to_list("testlist@sbsdomain.tld", "testuser@sbsdomain.tld")
104
+ actual = @ldap.list_lists_member_emails("testlist@sbsdomain.tld")
105
+ expected = [
106
+ ["CN=Test User,OU=SBSUsers,OU=Users,OU=MyBusiness,DC=SBS_Domain,DC=local","testuser@sbsdomain.tld"]
107
+ ]
108
+ assert_equal expected, actual
109
+ end
110
+
111
+ def test_add_email_to_list_dup
112
+ assert_raise AlreadyListMemberException do
113
+ @test = @ldap.add_email_to_list("testlist@sbsdomain.tld", "testuser@sbsdomain.tld")
114
+ end
115
+ end
116
+
117
+ def test_remove_email_from_list
118
+ @ldap.remove_email_from_list("testlist@sbsdomain.tld", "testuser@sbsdomain.tld")
119
+ actual = @ldap.list_lists_member_emails("testlist@sbsdomain.tld")
120
+ expected = []
121
+ assert_equal expected, actual
122
+ end
123
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sbs2003_contacts
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - John Howe
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-12-23 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: ruby-net-ldap
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.4
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: hoe
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.8.2
34
+ version:
35
+ description: "* A small utiltity library to help alleviate the tedium of managing the contacts and e-mail lists from a Small Business Server 2003 Active Directory."
36
+ email:
37
+ - elf-rubyforge@arashi.com
38
+ executables: []
39
+
40
+ extensions: []
41
+
42
+ extra_rdoc_files:
43
+ - History.txt
44
+ - Manifest.txt
45
+ - README.txt
46
+ files:
47
+ - History.txt
48
+ - Manifest.txt
49
+ - README.txt
50
+ - Rakefile
51
+ - lib/sbs2003_contacts.rb
52
+ - test/test_sbs2003_contacts.rb
53
+ has_rdoc: true
54
+ homepage: http://rubyforge.org/projects/uwruby/
55
+ post_install_message:
56
+ rdoc_options:
57
+ - --main
58
+ - README.txt
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ version:
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: "0"
72
+ version:
73
+ requirements: []
74
+
75
+ rubyforge_project: uwruby
76
+ rubygems_version: 1.3.1
77
+ signing_key:
78
+ specification_version: 2
79
+ summary: "* A small utiltity library to help alleviate the tedium of managing the contacts and e-mail lists from a Small Business Server 2003 Active Directory."
80
+ test_files:
81
+ - test/test_sbs2003_contacts.rb