kennethkalmer-postini 0.1.0

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.
@@ -0,0 +1,22 @@
1
+ == 0.0.4 2008-10-02
2
+
3
+ * Minor internal reworkings
4
+
5
+ == 0.0.3 2008-08-21
6
+
7
+ * Added options to allow for the capturing of soap4r wiredumps
8
+ * Added missing validations to domain creation
9
+
10
+ == 0.0.2 2008-08-19
11
+
12
+ * Fixed broken code for adding new users, with the most basic of validations
13
+ * Fixed broken code for removing existing users
14
+
15
+ == 0.0.1 2008-08-18
16
+
17
+ * Initial release
18
+ * Support for the Postini Endpoint Resolver API
19
+ * wsdl2ruby for the Automated Batch Service API
20
+ * (Very) Rough support for adding/removing users
21
+ * Support for adding/removing aliases
22
+ * RDoc's to help get around
@@ -0,0 +1,29 @@
1
+ = LICENSE
2
+
3
+ Copyright (c) 2008 Clear Planet Information Solutions (Pty) Ltd & ISP in a Box CC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ 'Software'), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ = TRADEMARKS
25
+
26
+ Postini, the Postini Logo, Perimeter Manager, Security Manager, Network Edition,
27
+ AirPostini, and Postini Message Platform are either registered trademarks or
28
+ trademarks of Postini Inc. Postini is a registered trademark of Postini, Inc.
29
+ All other trademarks are the property of their respective holders.
@@ -0,0 +1,34 @@
1
+ History.txt
2
+ License.txt
3
+ Manifest.txt
4
+ PostInstall.txt
5
+ README.txt
6
+ Rakefile
7
+ TODO
8
+ features/development.feature
9
+ features/step_definitions/common_steps.rb
10
+ features/support/common.rb
11
+ features/support/env.rb
12
+ features/support/matchers.rb
13
+ lib/postini.rb
14
+ lib/postini/automated_batch_service.rb
15
+ lib/postini/configuration_check.rb
16
+ lib/postini/endpoint_resolver_service.rb
17
+ lib/postini/endpoints.rb
18
+ lib/postini/exceptions.rb
19
+ script/console
20
+ script/destroy
21
+ script/generate
22
+ script/txt2html
23
+ setup.rb
24
+ spec/exceptions_spec.rb
25
+ spec/postini_spec.rb
26
+ spec/rcov.opts
27
+ spec/spec.opts
28
+ spec/spec_helper.rb
29
+ tasks/deployment.rake
30
+ tasks/environment.rake
31
+ tasks/rspec.rake
32
+ tasks/website.rake
33
+ vendor/automatedbatch.wsdl
34
+ vendor/endpointresolver.wsdl
@@ -0,0 +1,8 @@
1
+
2
+ For more information on postini4r's postini gem, see
3
+ http://postini4r.rubyforge.org/postini
4
+
5
+ Remember to contact your Postini provider, or Postini directly, to gain access
6
+ to the Postini Early Access Program. You'll need a unique API key to make use
7
+ of this gem.
8
+
@@ -0,0 +1,62 @@
1
+ = postini Gem
2
+
3
+ * http://postini4r.rubyforge.org/
4
+
5
+ == DESCRIPTION:
6
+
7
+ A Ruby wrapper library to make the Postini SOAP API more palatable.
8
+
9
+ Postini is the world leader in email message scanning, filtering and archiving.
10
+ This library provides users of Postini with a convenient Ruby library that
11
+ exposes the Postini SOAP API (Early Access Program) through more familiar
12
+ Rubyisms.
13
+
14
+ == FEATURES/PROBLEMS:
15
+
16
+ * FIX (list of features or problems)
17
+
18
+ == SYNOPSIS:
19
+
20
+ FIX
21
+
22
+ == REQUIREMENTS:
23
+
24
+ * Approved access to the Postini Early Access Program (contact your Postini
25
+ provider)
26
+ * soap4r
27
+
28
+ == INSTALL:
29
+
30
+ * sudo gem install postini
31
+
32
+ == TRADEMARKS:
33
+
34
+ Postini, the Postini Logo, Perimeter Manager, Security Manager, Network Edition,
35
+ AirPostini, and Postini Message Platform are either registered trademarks or
36
+ trademarks of Postini Inc. Postini is a registered trademark of Postini, Inc.
37
+ All other trademarks are the property of their respective holders.
38
+
39
+ == LICENSE:
40
+
41
+ (The MIT License)
42
+
43
+ Copyright (c) 2008 Clear Planet Information Solutions (Pty) Ltd & ISP in a Box CC
44
+
45
+ Permission is hereby granted, free of charge, to any person obtaining
46
+ a copy of this software and associated documentation files (the
47
+ 'Software'), to deal in the Software without restriction, including
48
+ without limitation the rights to use, copy, modify, merge, publish,
49
+ distribute, sublicense, and/or sell copies of the Software, and to
50
+ permit persons to whom the Software is furnished to do so, subject to
51
+ the following conditions:
52
+
53
+ The above copyright notice and this permission notice shall be
54
+ included in all copies or substantial portions of the Software.
55
+
56
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
57
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
58
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
59
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
60
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
61
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
62
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
1
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
2
+ %w[rake rake/clean fileutils newgem rubigen].each { |f| require f }
3
+ require File.dirname(__FILE__) + '/lib/postini'
4
+
5
+ # Generate all the Rake tasks
6
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
7
+ $hoe = Hoe.new('postini', Postini::VERSION) do |p|
8
+ p.developer('Kenneth Kalmer', 'kenneth.kalmer@gmail.com')
9
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
10
+ p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
11
+ p.rubyforge_name = 'postini4r' # TODO this is default value
12
+ # p.extra_deps = [
13
+ # ['activesupport','>= 2.0.2'],
14
+ # ]
15
+ p.extra_dev_deps = [
16
+ ['newgem', ">= #{::Newgem::VERSION}"]
17
+ ]
18
+
19
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
20
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
21
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
22
+ p.rsync_args = '-av --delete --ignore-errors'
23
+ end
24
+
25
+ require 'newgem/tasks' # load /tasks/*.rake
26
+ Dir['tasks/**/*.rake'].each { |t| load t }
27
+
28
+ # TODO - want other tests/tasks run by default? Add them to the list
29
+ # task :default => [:spec, :features]
data/TODO ADDED
@@ -0,0 +1,37 @@
1
+ TODO LIST
2
+ =========
3
+
4
+ Handle exceptions properly, make our own exception classes
5
+ Duplicate domain exception looks like this:
6
+ SOAP::FaultError: Batch: code:general, message: A domain record already exists for 'inx.co.za'. () (Request ID 5328153A-6BBD-11DD-A41F-AE53A6E672CE)
7
+ from #<SOAP::Mapping::Object:0xb7614344>
8
+ Unknown user exception:
9
+ SOAP::FaultError: Batch: code:general, message: No user 'sarie@inx.co.za'. () (Request ID F81C4176-6C88-11DD-8917-A059A6E672CE)
10
+ from #<SOAP::Mapping::Object:0xb75e736c>
11
+
12
+ Prevent unneeded operations:
13
+ * Don't disable an already disabled user
14
+
15
+ Add support for org management
16
+
17
+ Support for lazy-loading:
18
+ * Orgs users => user details
19
+ * Convert search results into fully useable objects
20
+
21
+ Work out a nice set of class+instance method combinations. The API's aren't
22
+ really geared for instance-level stuff. So User.destroy( address ) and
23
+ @user.destroy should essentially be the same thing.
24
+
25
+ PROPER ATTRIBUTE HANDLING, NOT INSTANCE VARIABLES:
26
+
27
+ ActiveRecord-like validations (possible external library)
28
+
29
+ Map remote types to native Ruby types:
30
+ * User#created_on from Unix timestamp to Time instance
31
+ * User#approved_senders 'empty' to []
32
+
33
+ Support for changed attribute tracking, so we can implement a #save method and
34
+ call only the needed API calls or only send the changed paramters.
35
+
36
+ Would it not be cleaner to wrap the records from soap4r (eg UserRecord,
37
+ DomainRecord) inside our own classes instead of having duplicates lying around?
@@ -0,0 +1,13 @@
1
+ Feature: Development processes of newgem itself (rake tasks)
2
+
3
+ As a Newgem maintainer or contributor
4
+ I want rake tasks to maintain and release the gem
5
+ So that I can spend time on the tests and code, and not excessive time on maintenance processes
6
+
7
+ Scenario: Generate RubyGem
8
+ Given this project is active project folder
9
+ And "pkg" folder is deleted
10
+ When I invoke task "rake gem"
11
+ Then folder "pkg" is created
12
+ And file with name matching "pkg/*.gem" is created else you should run "rake manifest" to fix this
13
+ And gem spec key "rdoc_options" contains /--mainREADME.rdoc/
@@ -0,0 +1,172 @@
1
+ Given /^a safe folder/ do
2
+ FileUtils.rm_rf @tmp_root = File.dirname(__FILE__) + "/../../tmp"
3
+ FileUtils.mkdir_p @tmp_root
4
+ FileUtils.mkdir_p @home_path = File.expand_path(File.join(@tmp_root, "home"))
5
+ @lib_path = File.expand_path(File.dirname(__FILE__) + '/../../lib')
6
+ Given %Q{env variable $HOME set to "#{@home_path}"}
7
+ end
8
+
9
+ Given /^this project is active project folder/ do
10
+ Given "a safe folder"
11
+ @active_project_folder = File.expand_path(File.dirname(__FILE__) + "/../..")
12
+ end
13
+
14
+ Given /^env variable \$([\w_]+) set to "(.*)"/ do |env_var, value|
15
+ ENV[env_var] = value
16
+ end
17
+
18
+ Given /"(.*)" folder is deleted/ do |folder|
19
+ in_project_folder { FileUtils.rm_rf folder }
20
+ end
21
+
22
+ When /^I invoke "(.*)" generator with arguments "(.*)"$/ do |generator, arguments|
23
+ @stdout = StringIO.new
24
+ in_project_folder do
25
+ if Object.const_defined?("APP_ROOT")
26
+ APP_ROOT.replace(FileUtils.pwd)
27
+ else
28
+ APP_ROOT = FileUtils.pwd
29
+ end
30
+ run_generator(generator, arguments.split(' '), SOURCES, :stdout => @stdout)
31
+ end
32
+ File.open(File.join(@tmp_root, "generator.out"), "w") do |f|
33
+ @stdout.rewind
34
+ f << @stdout.read
35
+ end
36
+ end
37
+
38
+ When /^I run executable "(.*)" with arguments "(.*)"/ do |executable, arguments|
39
+ @stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
40
+ in_project_folder do
41
+ system "#{executable} #{arguments} > #{@stdout} 2> #{@stdout}"
42
+ end
43
+ end
44
+
45
+ When /^I run project executable "(.*)" with arguments "(.*)"/ do |executable, arguments|
46
+ @stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
47
+ in_project_folder do
48
+ system "ruby #{executable} #{arguments} > #{@stdout} 2> #{@stdout}"
49
+ end
50
+ end
51
+
52
+ When /^I run local executable "(.*)" with arguments "(.*)"/ do |executable, arguments|
53
+ @stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
54
+ executable = File.expand_path(File.join(File.dirname(__FILE__), "/../../bin", executable))
55
+ in_project_folder do
56
+ system "ruby #{executable} #{arguments} > #{@stdout} 2> #{@stdout}"
57
+ end
58
+ end
59
+
60
+ When /^I invoke task "rake (.*)"/ do |task|
61
+ @stdout = File.expand_path(File.join(@tmp_root, "tests.out"))
62
+ in_project_folder do
63
+ system "rake #{task} --trace > #{@stdout} 2> #{@stdout}"
64
+ end
65
+ end
66
+
67
+ Then /^folder "(.*)" (is|is not) created/ do |folder, is|
68
+ in_project_folder do
69
+ File.exists?(folder).should(is == 'is' ? be_true : be_false)
70
+ end
71
+ end
72
+
73
+ Then /^file "(.*)" (is|is not) created/ do |file, is|
74
+ in_project_folder do
75
+ File.exists?(file).should(is == 'is' ? be_true : be_false)
76
+ end
77
+ end
78
+
79
+ Then /^file with name matching "(.*)" is created/ do |pattern|
80
+ in_project_folder do
81
+ Dir[pattern].should_not be_empty
82
+ end
83
+ end
84
+
85
+ Then /^file "(.*)" contents (does|does not) match \/(.*)\// do |file, does, regex|
86
+ in_project_folder do
87
+ actual_output = File.read(file)
88
+ (does == 'does') ?
89
+ actual_output.should(match(/#{regex}/)) :
90
+ actual_output.should_not(match(/#{regex}/))
91
+ end
92
+ end
93
+
94
+ Then /gem file "(.*)" and generated file "(.*)" should be the same/ do |gem_file, project_file|
95
+ File.exists?(gem_file).should be_true
96
+ File.exists?(project_file).should be_true
97
+ gem_file_contents = File.read(File.dirname(__FILE__) + "/../../#{gem_file}")
98
+ project_file_contents = File.read(File.join(@active_project_folder, project_file))
99
+ project_file_contents.should == gem_file_contents
100
+ end
101
+
102
+ Then /^(does|does not) invoke generator "(.*)"$/ do |does_invoke, generator|
103
+ actual_output = File.read(@stdout)
104
+ does_invoke == "does" ?
105
+ actual_output.should(match(/dependency\s+#{generator}/)) :
106
+ actual_output.should_not(match(/dependency\s+#{generator}/))
107
+ end
108
+
109
+ Then /help options "(.*)" and "(.*)" are displayed/ do |opt1, opt2|
110
+ actual_output = File.read(@stdout)
111
+ actual_output.should match(/#{opt1}/)
112
+ actual_output.should match(/#{opt2}/)
113
+ end
114
+
115
+ Then /^I should see$/ do |text|
116
+ actual_output = File.read(@stdout)
117
+ actual_output.should contain(text)
118
+ end
119
+
120
+ Then /^I should not see$/ do |text|
121
+ actual_output = File.read(@stdout)
122
+ actual_output.should_not contain(text)
123
+ end
124
+
125
+ Then /^I should see exactly$/ do |text|
126
+ actual_output = File.read(@stdout)
127
+ actual_output.should == text
128
+ end
129
+
130
+ Then /^I should see all (\d+) tests pass/ do |expected_test_count|
131
+ expected = %r{^#{expected_test_count} tests, \d+ assertions, 0 failures, 0 errors}
132
+ actual_output = File.read(@stdout)
133
+ actual_output.should match(expected)
134
+ end
135
+
136
+ Then /^I should see all (\d+) examples pass/ do |expected_test_count|
137
+ expected = %r{^#{expected_test_count} examples?, 0 failures}
138
+ actual_output = File.read(@stdout)
139
+ actual_output.should match(expected)
140
+ end
141
+
142
+ Then /^yaml file "(.*)" contains (\{.*\})/ do |file, yaml|
143
+ in_project_folder do
144
+ yaml = eval yaml
145
+ YAML.load(File.read(file)).should == yaml
146
+ end
147
+ end
148
+
149
+ Then /^Rakefile can display tasks successfully/ do
150
+ @stdout = File.expand_path(File.join(@tmp_root, "rakefile.out"))
151
+ in_project_folder do
152
+ system "rake -T > #{@stdout} 2> #{@stdout}"
153
+ end
154
+ actual_output = File.read(@stdout)
155
+ actual_output.should match(/^rake\s+\w+\s+#\s.*/)
156
+ end
157
+
158
+ Then /^task "rake (.*)" is executed successfully/ do |task|
159
+ @stdout.should_not be_nil
160
+ actual_output = File.read(@stdout)
161
+ actual_output.should_not match(/^Don't know how to build task '#{task}'/)
162
+ actual_output.should_not match(/Error/i)
163
+ end
164
+
165
+ Then /^gem spec key "(.*)" contains \/(.*)\// do |key, regex|
166
+ in_project_folder do
167
+ gem_file = Dir["pkg/*.gem"].first
168
+ gem_spec = Gem::Specification.from_yaml(`gem spec #{gem_file}`)
169
+ spec_value = gem_spec.send(key.to_sym)
170
+ spec_value.to_s.should match(/#{regex}/)
171
+ end
172
+ end
@@ -0,0 +1,29 @@
1
+ module CommonHelpers
2
+ def in_tmp_folder(&block)
3
+ FileUtils.chdir(@tmp_root, &block)
4
+ end
5
+
6
+ def in_project_folder(&block)
7
+ project_folder = @active_project_folder || @tmp_root
8
+ FileUtils.chdir(project_folder, &block)
9
+ end
10
+
11
+ def in_home_folder(&block)
12
+ FileUtils.chdir(@home_path, &block)
13
+ end
14
+
15
+ def force_local_lib_override(project_name = @project_name)
16
+ rakefile = File.read(File.join(project_name, 'Rakefile'))
17
+ File.open(File.join(project_name, 'Rakefile'), "w+") do |f|
18
+ f << "$:.unshift('#{@lib_path}')\n"
19
+ f << rakefile
20
+ end
21
+ end
22
+
23
+ def setup_active_project_folder project_name
24
+ @active_project_folder = File.join(@tmp_root, project_name)
25
+ @project_name = project_name
26
+ end
27
+ end
28
+
29
+ World(CommonHelpers)