socialcast 1.1.6 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,6 +4,7 @@ require "thor"
4
4
  require 'json'
5
5
  require 'rest_client'
6
6
  require 'highline'
7
+ require 'net/ldap'
7
8
  require 'socialcast'
8
9
  require 'socialcast/message'
9
10
  require File.join(File.dirname(__FILE__), 'net_ldap_ext')
@@ -12,7 +13,7 @@ require 'zlib'
12
13
  require 'logger'
13
14
  require 'builder'
14
15
  require 'set'
15
- require 'net/ldap'
16
+ require 'fileutils'
16
17
 
17
18
  # uncomment to debug HTTP traffic
18
19
  # class ActiveResource::Connection
@@ -99,6 +100,7 @@ module Socialcast
99
100
  method_option :skip_emails, :type => :boolean
100
101
  method_option :force, :type => :boolean, :aliases => '-f', :default => false
101
102
  method_option :sanity_check, :type => :boolean, :default => false
103
+ method_option :plugins, :type => :array, :desc => "Pass in an array of plugins. Can be either the gem require or the absolute path to a ruby file."
102
104
  def provision
103
105
  config_file = File.expand_path options[:config]
104
106
 
@@ -115,6 +117,14 @@ module Socialcast
115
117
  config = load_configuration config_file
116
118
  http_config = config.fetch('http', {})
117
119
 
120
+ Array.wrap(options[:plugins]).each do |plugin|
121
+ begin
122
+ require plugin
123
+ rescue LoadError => e
124
+ fail "Unable to load #{plugin}: #{e}"
125
+ end
126
+ end
127
+
118
128
  required_mappings = %w{email first_name last_name}
119
129
  mappings = config.fetch 'mappings', {}
120
130
  required_mappings.each do |field|
@@ -5,15 +5,24 @@ class Net::LDAP::Entry
5
5
  # grab a *single* value of an attribute
6
6
  # abstracts away ldap multivalue attributes
7
7
  def grab(attribute)
8
+ attribute = begin
9
+ attribute.classify.constantize
10
+ rescue NameError
11
+ attribute
12
+ end
13
+
8
14
  case attribute
9
15
  when Hash
10
16
  value = attribute.delete("value")
11
17
  value % Hash[attribute.map {|k,v| [k, grab(v)]}].symbolize_keys
12
18
  when String
13
19
  Array.wrap(self[attribute]).compact.first
20
+ when Class, Module
21
+ return nil unless attribute.respond_to?(:run)
22
+ attribute.run(self)
14
23
  end
15
24
  end
16
-
25
+
17
26
  def dereference_mail(ldap_connection, dn_field, mail_attribute)
18
27
  dn = grab(dn_field)
19
28
  ldap_connection.search(:base => dn, :scope => Net::LDAP::SearchScope_BaseObject) do |entry|
@@ -1,3 +1,3 @@
1
1
  module Socialcast
2
- VERSION = "1.1.6"
2
+ VERSION = "1.2.0"
3
3
  end
data/spec/cli_spec.rb CHANGED
@@ -123,6 +123,43 @@ describe Socialcast::CLI do
123
123
  end
124
124
  it 'resolves absolute path without using current process directory' do end # see expectations
125
125
  end
126
+ context 'with plugins option used with non-existent ruby files' do
127
+ before do
128
+ @entry = Net::LDAP::Entry.new("dc=example,dc=com")
129
+ @entry[:mail] = 'ryan@example.com'
130
+ Net::LDAP.any_instance.stub(:search).and_yield(@entry)
131
+
132
+ @result = ''
133
+ Zlib::GzipWriter.stub(:open).and_yield(@result)
134
+ Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
135
+ Socialcast::CLI.any_instance.should_receive(:load_configuration).with('/my/path/to/ldap.yml').and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'ldap_without_permission_mappings.yml')))
136
+ File.should_receive(:exists?).with('/my/path/to/ldap.yml').and_return(true)
137
+ File.stub(:open).with(/users.xml.gz/, anything).and_yield(@result)
138
+ RestClient::Resource.any_instance.stub(:post)
139
+
140
+ end
141
+ it 'does not post to Socialcast and throws Kernel.abort' do
142
+ lambda { Socialcast::CLI.start ['provision', '-c', '/my/path/to/ldap.yml', '--plugins', ['does_not_exist.rb', 'also_does_not_exist.rb']] }.should raise_error
143
+ end
144
+ end
145
+ context 'with plugins option used with existent ruby file' do
146
+ before do
147
+ @entry = Net::LDAP::Entry.new("dc=example,dc=com")
148
+ @entry[:mail] = 'ryan@example.com'
149
+ Net::LDAP.any_instance.stub(:search).and_yield(@entry)
150
+
151
+ @result = ''
152
+ Zlib::GzipWriter.stub(:open).and_yield(@result)
153
+ Socialcast.stub(:credentials).and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml')))
154
+ Socialcast::CLI.any_instance.should_receive(:load_configuration).with('/my/path/to/ldap.yml').and_return(YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'ldap_without_permission_mappings.yml')))
155
+ File.should_receive(:exists?).with('/my/path/to/ldap.yml').and_return(true)
156
+ File.stub(:open).with(/users.xml.gz/, anything).and_yield(@result)
157
+ RestClient::Resource.any_instance.stub(:post)
158
+
159
+ Socialcast::CLI.start ['provision', '-c', '/my/path/to/ldap.yml', '--plugins', [File.join(File.dirname(__FILE__), 'fixtures', 'fake_attribute_map')]]
160
+ end
161
+ it 'successfully processes' do end # see expectations
162
+ end
126
163
  context 'with ldap.yml configuration excluding permission_mappings' do
127
164
  before do
128
165
  @entry = Net::LDAP::Entry.new("dc=example,dc=com")
@@ -0,0 +1,7 @@
1
+ module Socialcast
2
+ class FakeAttributeMap
3
+ def self.run(entry)
4
+ return "#{entry[:mail].first.gsub(/a/,'b')}"
5
+ end
6
+ end
7
+ end
@@ -18,4 +18,90 @@ describe Net::LDAP::Entry do
18
18
  end
19
19
  end
20
20
  end
21
+ describe "#grab" do
22
+ context "passed hash for attribute" do
23
+ subject {
24
+ entry = Net::LDAP::Entry.new("cn=sean,dc=example,dc=com")
25
+ entry[:mail] = 'sean@example.com'
26
+ entry
27
+ }
28
+ it "returns a string that used defined string template" do
29
+ subject.grab({"value" => "123%{mail}", "mail" => "mail"}).should == "123sean@example.com"
30
+ end
31
+ end
32
+ context "passed string for attribute" do
33
+ subject {
34
+ entry = Net::LDAP::Entry.new("cn=sean,dc=example,dc=com")
35
+ entry[:mail] = 'sean@example.com'
36
+ entry
37
+ }
38
+ it "returns exact string stored in entry" do
39
+ subject.grab("mail").should == "sean@example.com"
40
+ end
41
+ end
42
+ context "passed string that can be constantized and the resulting Class responds to run" do
43
+ subject {
44
+ entry = Net::LDAP::Entry.new("cn=sean,dc=example,dc=com")
45
+ entry[:mail] = 'sean@example.com'
46
+ entry
47
+ }
48
+ it "returns result of run method" do
49
+ module Socialcast
50
+ class FakeAttributeMap
51
+ def self.run(entry)
52
+ return "#{entry[:mail].first.gsub(/a/,'b')}"
53
+ end
54
+ end
55
+ end
56
+ subject.grab("Socialcast::FakeAttributeMap").should == "sebn@exbmple.com"
57
+ end
58
+ end
59
+ context "passed string that must be classified and the resulting Class responds to run" do
60
+ subject {
61
+ entry = Net::LDAP::Entry.new("cn=sean,dc=example,dc=com")
62
+ entry[:mail] = 'sean@example.com'
63
+ entry
64
+ }
65
+ it "returns result of run method" do
66
+ module Socialcast
67
+ class FakeAttributeMap
68
+ def self.run(entry)
69
+ return "#{entry[:mail].first.gsub(/a/,'b')}"
70
+ end
71
+ end
72
+ end
73
+ subject.grab("socialcast/fake_attribute_map").should == "sebn@exbmple.com"
74
+ end
75
+ end
76
+ context "attribute passed has a collision between string and Class" do
77
+ subject {
78
+ entry = Net::LDAP::Entry.new("cn=sean,dc=example,dc=com")
79
+ entry[:mail] = 'sean@example.com'
80
+ entry
81
+ }
82
+ it "returns the result of the Class run method" do
83
+ class Mail
84
+ def self.run(entry)
85
+ return "#{entry[:mail].first.gsub(/a/,'b')}"
86
+ end
87
+ end
88
+ subject.grab("mail").should == "sebn@exbmple.com"
89
+ end
90
+ end
91
+ context "attribute passed constantizes to a module instead of a class" do
92
+ subject {
93
+ entry = Net::LDAP::Entry.new("cn=sean,dc=example,dc=com")
94
+ entry[:mail] = 'sean@example.com'
95
+ entry
96
+ }
97
+ it "returns the result of the Module run method" do
98
+ module FakeAttributeMap
99
+ def self.run(entry)
100
+ return "#{entry[:mail].first.gsub(/a/,'b')}"
101
+ end
102
+ end
103
+ subject.grab("FakeAttributeMap").should == "sebn@exbmple.com"
104
+ end
105
+ end
106
+ end
21
107
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: socialcast
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.6
4
+ version: 1.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-08-15 00:00:00.000000000 Z
13
+ date: 2012-09-24 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rest-client
17
- requirement: &2159242000 !ruby/object:Gem::Requirement
17
+ requirement: &2159242780 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 1.4.0
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *2159242000
25
+ version_requirements: *2159242780
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: json
28
- requirement: &2159241000 !ruby/object:Gem::Requirement
28
+ requirement: &2159241780 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: 1.4.6
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *2159241000
36
+ version_requirements: *2159241780
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: thor
39
- requirement: &2159240520 !ruby/object:Gem::Requirement
39
+ requirement: &2159241300 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: 0.14.6
45
45
  type: :runtime
46
46
  prerelease: false
47
- version_requirements: *2159240520
47
+ version_requirements: *2159241300
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: highline
50
- requirement: &2159240060 !ruby/object:Gem::Requirement
50
+ requirement: &2159240840 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ! '>='
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: 1.6.2
56
56
  type: :runtime
57
57
  prerelease: false
58
- version_requirements: *2159240060
58
+ version_requirements: *2159240840
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: socialcast-net-ldap
61
- requirement: &2159239420 !ruby/object:Gem::Requirement
61
+ requirement: &2159240200 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ! '>='
@@ -66,10 +66,10 @@ dependencies:
66
66
  version: 0.1.6
67
67
  type: :runtime
68
68
  prerelease: false
69
- version_requirements: *2159239420
69
+ version_requirements: *2159240200
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: activeresource
72
- requirement: &2159238740 !ruby/object:Gem::Requirement
72
+ requirement: &2159239520 !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ! '>='
@@ -77,10 +77,10 @@ dependencies:
77
77
  version: 2.3.11
78
78
  type: :runtime
79
79
  prerelease: false
80
- version_requirements: *2159238740
80
+ version_requirements: *2159239520
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: rspec
83
- requirement: &2159238080 !ruby/object:Gem::Requirement
83
+ requirement: &2159238860 !ruby/object:Gem::Requirement
84
84
  none: false
85
85
  requirements:
86
86
  - - ! '>='
@@ -88,10 +88,10 @@ dependencies:
88
88
  version: 2.11.0
89
89
  type: :development
90
90
  prerelease: false
91
- version_requirements: *2159238080
91
+ version_requirements: *2159238860
92
92
  - !ruby/object:Gem::Dependency
93
93
  name: webmock
94
- requirement: &2159237620 !ruby/object:Gem::Requirement
94
+ requirement: &2159238400 !ruby/object:Gem::Requirement
95
95
  none: false
96
96
  requirements:
97
97
  - - ! '>='
@@ -99,10 +99,10 @@ dependencies:
99
99
  version: 1.7.7
100
100
  type: :development
101
101
  prerelease: false
102
- version_requirements: *2159237620
102
+ version_requirements: *2159238400
103
103
  - !ruby/object:Gem::Dependency
104
104
  name: rake
105
- requirement: &2159237160 !ruby/object:Gem::Requirement
105
+ requirement: &2159237940 !ruby/object:Gem::Requirement
106
106
  none: false
107
107
  requirements:
108
108
  - - =
@@ -110,7 +110,7 @@ dependencies:
110
110
  version: 0.9.2.2
111
111
  type: :development
112
112
  prerelease: false
113
- version_requirements: *2159237160
113
+ version_requirements: *2159237940
114
114
  description: publish messages to your stream from a command line interface
115
115
  email:
116
116
  - ryan@socialcast.com
@@ -142,6 +142,7 @@ files:
142
142
  - spec/cli_spec.rb
143
143
  - spec/fixtures/credentials.yml
144
144
  - spec/fixtures/credentials_with_proxy.yml
145
+ - spec/fixtures/fake_attribute_map.rb
145
146
  - spec/fixtures/ldap.yml
146
147
  - spec/fixtures/ldap_with_array_permission_mapping.yml
147
148
  - spec/fixtures/ldap_with_interpolated_values.yml
@@ -177,6 +178,7 @@ test_files:
177
178
  - spec/cli_spec.rb
178
179
  - spec/fixtures/credentials.yml
179
180
  - spec/fixtures/credentials_with_proxy.yml
181
+ - spec/fixtures/fake_attribute_map.rb
180
182
  - spec/fixtures/ldap.yml
181
183
  - spec/fixtures/ldap_with_array_permission_mapping.yml
182
184
  - spec/fixtures/ldap_with_interpolated_values.yml