xmlservice 1.3.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.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +19 -0
  3. data/README_IBM_i +62 -0
  4. data/lib/adapters/abstract_adapter.rb +82 -0
  5. data/lib/adapters/db2_adapter.rb +70 -0
  6. data/lib/adapters/rest_adapter.rb +32 -0
  7. data/lib/password/password.rb +229 -0
  8. data/lib/xmlservice.rb +2477 -0
  9. data/test/README_IBM_i +3 -0
  10. data/test/Rakefile +42 -0
  11. data/test/genpassword.rb +111 -0
  12. data/test/test_60000_toolkit_driver/Rakefile +11 -0
  13. data/test/test_60000_toolkit_driver/test_60010_DriverCallPgmZZCALL.rb +403 -0
  14. data/test/test_60000_toolkit_driver/test_60110_DriverCallSrvPgmZZARRAY.rb +149 -0
  15. data/test/test_60000_toolkit_driver/test_60310_DriverCMD.rb +77 -0
  16. data/test/test_60000_toolkit_driver/test_60510_DriverDataQueue.rb +126 -0
  17. data/test/test_60000_toolkit_driver/test_60610_DriverCallSrvPgmZZBINARY.rb +59 -0
  18. data/test/test_60000_toolkit_driver/test_60710_DriverSH.rb +73 -0
  19. data/test/test_60000_toolkit_driver/test_60910_DriverCallPgmZZMISS.rb +44 -0
  20. data/test/test_60000_toolkit_driver/test_65010_DriverCallDB2.rb +265 -0
  21. data/test/test_60000_toolkit_driver/zzassign.rb +66 -0
  22. data/test/test_60000_toolkit_driver/zzquick.rb +149 -0
  23. data/test/test_60000_toolkit_driver/zztestrest.rb +45 -0
  24. data/test/test_60000_toolkit_driver/zzthreadold.rb +78 -0
  25. data/test/test_70000_toolkit_testonly/Rakefile +11 -0
  26. data/test/test_70000_toolkit_testonly/test_70010_DriverCallPgmTestOnly.rb +270 -0
  27. data/test/test_80000_toolkit_dsl/Rakefile +11 -0
  28. data/test/test_80000_toolkit_dsl/test_80010_DSLCallPgmZZCALL.rb +162 -0
  29. data/test/test_80000_toolkit_dsl/test_80110_DSLCallSrvPgmZZARRAY.rb +150 -0
  30. data/test/test_authorization/README_IBM_i +15 -0
  31. data/test/test_authorization/auth.rb +101 -0
  32. data/test/test_authorization/key.yml +2 -0
  33. data/test/test_authorization/password.yml +3 -0
  34. data/test/test_authorization/xmlservice.yml +69 -0
  35. data/test/test_data/rowcol.rb +57 -0
  36. data/version.txt +1 -0
  37. metadata +92 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 114a61cefcaa6e77f1e035ab1e9050c0c71ceacf
4
+ data.tar.gz: a51dcc0231ce9bfefa0de147b0735682fde3bb85
5
+ SHA512:
6
+ metadata.gz: 553705198c19344a963e5512dab5d962c5b62e2e40d5d4cfea3b65ce95b63ead5c2205f59dd45050a57df1e7090944426419a5ed083226292ae462b4963b2799
7
+ data.tar.gz: fde89c8f5fd22cb3aab8bf0315c71d354c91530be1647851a119cda82ffcbb055eb81b17b0548b8eb4f27bb65b8d7806529e68525ba97caced9572b5ce413d04
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2013 IBM Corporation
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the "Software"),
5
+ to deal in the Software without restriction, including without limitation
6
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
7
+ and/or sell copies of the Software, and to permit persons to whom the Software
8
+ is furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included
11
+ in all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
14
+ INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
15
+ PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
16
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
18
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
+
@@ -0,0 +1,62 @@
1
+ ==================
2
+ Introduction
3
+ ==================
4
+ The following notes Ruby with IBM i.
5
+
6
+ ==================
7
+ install
8
+ ==================
9
+ > cd xmlservice
10
+ > gem install ./xmlservice-1.3.0.gem --local --force --ignore-dependencies --no-rdoc
11
+ -- or --
12
+ > cd xmlservice
13
+ > ./zzall.sh
14
+
15
+ =================
16
+ run tests (script)
17
+ =================
18
+ -- change values --
19
+ > cd xmlservice
20
+ > edit zztestdb2.sh zztestrest.sh
21
+ export TEST_URL=http://174.79.32.155/cgi-bin/xmlcgi.pgm
22
+ export TEST_USER=DB2
23
+ export TEST_PWD=PWD
24
+
25
+ -- run --
26
+ > cd xmlservice
27
+ > ./zztestdb2.sh (test db2 driver)
28
+ > ./zztestrest.sh (test rest driver)
29
+
30
+
31
+ =================
32
+ run tests (manually)
33
+ =================
34
+ -- set up --
35
+ > export PATH=/PowerRuby/{version}/bin:$PATH
36
+ > export LIBPATH=/PowerRuby/{version}/lib
37
+ > export TEST_URL=http://174.79.32.155/cgi-bin/xmlcgi.pgm --or-- ibm_db
38
+ > export TEST_DATABASE=*LOCAL
39
+ > export TEST_USER=*NONE
40
+ > export TEST_PWD=*NONE
41
+ -- optional --
42
+ > export TEST_CTL=*here --or-- *sbmjob
43
+ > export TEST_IPC=*na --or-- /tmp/privatextoolkitjobroute (*sbmjob)
44
+ > export TEST_XMLSERVICE=XMLSERVICE
45
+ > export TEST_LIB=RUBYTEST
46
+
47
+ -- main directory --
48
+ > cd xmlservice
49
+ > rake
50
+
51
+ -- test directory --
52
+ > cd xmlservice/test
53
+ > rake test
54
+
55
+ -- individual --
56
+ > xmlservice/test/test_60000_toolkit_driver
57
+ > ruby test_60310_DriverCMD.rb
58
+
59
+
60
+
61
+
62
+
@@ -0,0 +1,82 @@
1
+ require "rexml/document"
2
+
3
+ module XMLServiceAdapters
4
+ # adapter factory (singleton)
5
+ def self.adapter_factory(config)
6
+ conn = config[:connection]
7
+ # rest adapter (no db2 connections)
8
+ if conn.to_s.include?"/"
9
+ require 'adapters/rest_adapter'
10
+ adapter = RESTAdapter.new(conn, config)
11
+ # assume db2 adpater
12
+ else
13
+ require 'adapters/db2_adapter'
14
+ adapter = IBM_DBAdapter.new(conn, config)
15
+ end
16
+ adapter
17
+ end
18
+ class AbstractAdapter
19
+ def initialize(conn,options)
20
+ @xml_conn = conn
21
+ @xml_options = options
22
+ if !options.has_key?(:install)
23
+ options[:install] = ActiveXMLService::XINSTALL
24
+ end
25
+ if !options.has_key?(:ctl)
26
+ options[:ctl] = ActiveXMLService::XCTL
27
+ end
28
+ if !options.has_key?(:ipc)
29
+ options[:ipc] = ActiveXMLService::XIPC
30
+ end
31
+ if !options.has_key?(:size)
32
+ options[:size] = ActiveXMLService::XSIZE
33
+ end
34
+ if !options.has_key?(:head)
35
+ options[:head] = ActiveXMLService::XHEAD
36
+ end
37
+ if !options.has_key?(:database)
38
+ options[:database] = ActiveXMLService::XDATABASE
39
+ end
40
+ if !options.has_key?(:username)
41
+ options[:username] = ActiveXMLService::XUSERNAME
42
+ end
43
+ if !options.has_key?(:password)
44
+ options[:password] = ActiveXMLService::XPASSWORD
45
+ end
46
+ @xml_install = options[:install]
47
+ @xml_ctl = options[:ctl]
48
+ @xml_ipc = options[:ipc]
49
+ @xml_size = options[:size]
50
+ @xml_head = options[:head]
51
+ @xml_database = options[:database]
52
+ @xml_username = options[:username]
53
+ @xml_password = options[:password]
54
+ @xml_xmlin = ""
55
+ @xml_xmlin << @xml_head
56
+ @xml_xmlout = ""
57
+ @xml_xmlout << @xml_head
58
+ @xml_doc = nil
59
+ end
60
+ def adapter_name
61
+ 'Abstract'
62
+ end
63
+ def xmlservice(callme)
64
+ end
65
+ def raw_connection
66
+ @xml_conn
67
+ end
68
+ def raw_options
69
+ @xml_options
70
+ end
71
+ def out_xml
72
+ @xml_xmlout
73
+ end
74
+ def out_doc
75
+ if @xml_doc == nil
76
+ @xml_doc = REXML::Document.new(@xml_xmlout)
77
+ end
78
+ @xml_doc
79
+ end
80
+ end # class AbstractAdapter
81
+ end # module XMLServiceAdapters
82
+
@@ -0,0 +1,70 @@
1
+ require 'adapters/abstract_adapter'
2
+ require 'active_record'
3
+ require 'ibm_db'
4
+
5
+ module XMLServiceAdapters
6
+ class IBM_DBAdapter < AbstractAdapter
7
+ def initialize(conn,options)
8
+ # yaml connection string "ActiveRecord",
9
+ # so use if active, or start new connection
10
+ if conn.to_s == "ActiveRecord"
11
+ for i in 0..1
12
+ begin
13
+ conn = ActiveRecord::Base.connection
14
+ rescue
15
+ ActiveRecord::Base.establish_connection(options)
16
+ end
17
+ end
18
+ end
19
+ # raw_connection gives access to actual IBM_DB::Connection
20
+ if conn.is_a?(ActiveRecord::ConnectionAdapters::IBM_DBAdapter)
21
+ super(conn.raw_connection, options)
22
+ elsif conn.is_a?(IBM_DB::Connection)
23
+ super(conn, options)
24
+ else
25
+ raise "#{self.class.name} invalid connection."
26
+ end
27
+ end
28
+ def adapter_name
29
+ 'XMLSERVICE_IBM_DB'
30
+ end
31
+ def xmlservice(callme)
32
+ case @xml_size
33
+ when @xml_size<=4096
34
+ sql = "CALL #{@xml_install}.iPLUG4K(?,?,?,?)"
35
+ when @xml_size>4096 && @xml_size<=32768
36
+ sql = "CALL #{@xml_install}.iPLUG32K(?,?,?,?)"
37
+ when @xml_size>32768 && @xml_size<=65536
38
+ sql = "CALL #{@xml_install}.iPLUG65K(?,?,?,?)"
39
+ when @xml_size>65536 && @xml_size<=524288
40
+ sql = "CALL #{@xml_install}.iPLUG512K(?,?,?,?)"
41
+ when @xml_size>524288 && @xml_size<=1048576
42
+ sql = "CALL #{@xml_install}.iPLUG1M(?,?,?,?)"
43
+ when @xml_size>1048576 && @xml_size<=5242880
44
+ sql = "CALL #{@xml_install}.iPLUG5M(?,?,?,?)"
45
+ when @xml_size>5242880 && @xml_size<=10485760
46
+ sql = "CALL #{@xml_install}.iPLUG10M(?,?,?,?)"
47
+ when @xml_size>10485760
48
+ sql = "CALL #{@xml_install}.iPLUG15M(?,?,?,?)"
49
+ else
50
+ sql = "CALL #{@xml_install}.iPLUG512K(?,?,?,?)"
51
+ end
52
+ ctl = @xml_ctl
53
+ ipc = @xml_ipc
54
+ xmlin = ""
55
+ xmlin << @xml_head
56
+ xmlin << "\n<myscript>\n"
57
+ xmlin << callme.to_xml
58
+ xmlin << "</myscript>\n"
59
+ xmlout = ""
60
+ stmt = IBM_DB::prepare(@xml_conn, sql)
61
+ ret = IBM_DB::bind_param(stmt, 1, "ipc", IBM_DB::SQL_PARAM_INPUT)
62
+ ret = IBM_DB::bind_param(stmt, 2, "ctl", IBM_DB::SQL_PARAM_INPUT)
63
+ ret = IBM_DB::bind_param(stmt, 3, "xmlin", IBM_DB::SQL_PARAM_INPUT)
64
+ ret = IBM_DB::bind_param(stmt, 4, "xmlout", IBM_DB::SQL_PARAM_OUTPUT)
65
+ ret = IBM_DB::execute(stmt)
66
+ @xml_xmlout = xmlout
67
+ @xml_doc = nil
68
+ end
69
+ end
70
+ end # module XMLServiceAdapters
@@ -0,0 +1,32 @@
1
+ require 'adapters/abstract_adapter'
2
+ require 'net/http'
3
+ require 'uri'
4
+
5
+ module XMLServiceAdapters
6
+ class RESTAdapter < AbstractAdapter
7
+ def adapter_name
8
+ 'XMLSERVICE_REST'
9
+ end
10
+ def xmlservice(callme)
11
+ xmlin = ""
12
+ xmlin << @xml_head
13
+ xmlin << "\n<myscript>\n"
14
+ xmlin << callme.to_xml
15
+ xmlin << "</myscript>\n"
16
+ xmlout = ""
17
+ post_args = {
18
+ :db2 => @xml_database,
19
+ :uid => @xml_username,
20
+ :pwd => @xml_password,
21
+ :ipc => @xml_ipc,
22
+ :ctl => @xml_ctl,
23
+ :xmlin => URI::encode(xmlin),
24
+ :xmlout => @xml_size
25
+ }
26
+ uri = URI(@xml_conn)
27
+ res = Net::HTTP.post_form(uri, post_args)
28
+ @xml_xmlout = res.body
29
+ @xml_doc = nil
30
+ end
31
+ end
32
+ end # module XMLServiceAdapters
@@ -0,0 +1,229 @@
1
+ require 'openssl'
2
+ require "base64"
3
+ require "uri"
4
+ require 'pathname'
5
+
6
+ # Sample utility for encrypted password
7
+ # require 'active_record'
8
+ # require 'ibm_db'
9
+ # $db = "LP0364D"
10
+ # $user = "DB2"
11
+ # $pass = "NICE2DB2"
12
+ # ActiveXMLService::Base.establish_connection(
13
+ # :adapter => 'ibm_db',
14
+ # :database => $db,
15
+ # :username => $user,
16
+ # :password => $pass
17
+ # :connection => "ActiveRecord"
18
+ # :install => XMLSERVICE
19
+ # :ctl => "*sbmjob"
20
+ # :ipc => /tmp/ruby042
21
+ # :size => 15000000
22
+ # :head => "<?xml version='1.0'?>"
23
+ # )
24
+ # key = ActiveXMLService::Base.generate_key()
25
+ # puts "key is #{key}"
26
+ # penc = ActiveXMLService::Base.generate_password($pass,key)
27
+ # puts "password ( #{$pass} ) + ( key #{key} ) = encrypted password ( #{penc} )"
28
+
29
+ # Sample yaml files
30
+ # 1) config/database.yml -- standard config/database.yml loaded by Rails automatic
31
+ # 2) /path/password.yml -- operator maintained user/password/attributes file (QTMHHTTP access only)
32
+ # 3) /path/key.yml -- operator maintained passkey file used in runtime decode password (QTMHHTTP access only)
33
+ # ==== file 1) standard database.yml (key="development" RAILS_ENV) =====
34
+ # xmlservice: &xmlservice
35
+ # connection: "ActiveRecord"
36
+ # install: XMLSERVICE
37
+ # ctl: "*sbmjob"
38
+ # ipc: /tmp/ruby042
39
+ # size: 15000000
40
+ # head: "<?xml version='1.0'?>"
41
+ # development:
42
+ # adapter: ibm_db
43
+ # database: LP0364D
44
+ # username: DB2
45
+ # pwd_yaml: /path/password.yml
46
+ # <<: *xmlservice
47
+ # production:
48
+ # adapter: ibm_db
49
+ # database: LP0364D
50
+ # username: DB2
51
+ # pwd_yaml: /path/password.yml
52
+ # <<: *xmlservice
53
+ # test:
54
+ # adapter: ibm_db
55
+ # database: LP0364D
56
+ # username: DB2
57
+ # pwd_yaml: /path/password.yml
58
+ # <<: *xmlservice
59
+ # ==== file 2) password.yml (key="username")=====
60
+ # key_yaml: /path/key.yml
61
+ # DB2:
62
+ # pwd_enc: "YiYNfodSh5MGZVX7TXktEPSrnVlrAPjoyzzn48SdC/k=%0A"
63
+ # ... possibly other attributes custom DB2, db2_yaml.yml, etc
64
+ # user2:
65
+ # pwd_enc: "YiYNfodSh5MGOHBOYFLINROCKIlrAPjoyzzn48SdC/k=%0A"
66
+ # ... possibly other attributes custom DB2, db2_yaml.yml, etc
67
+ # ==== file 3) key.yml (key="*ALL") ===== (used runtime)
68
+ # pwd_key: "YIPS4321AAAAAAAAAAAAAAA132424245"
69
+ # ... possibly other attributes, DB2, etc ...
70
+ module XMLSERVICEPassword
71
+ PWD_TYPE = "aes-256-cbc" # encryption type
72
+ PWD_KEY = "YIPS4321AAAAAAAAAAAAAAA132424245" # 32 characters required
73
+ # of course PWD_KEY should not be in script
74
+ # but this is an example (people read)
75
+ class Encrypt
76
+ @xml_pwdkey = nil
77
+
78
+ # ------------------
79
+ # callable functions
80
+ # ------------------
81
+
82
+ # decrypt using password.yml (possible key.yml) (see top module)
83
+ def self.parse_user_config(config)
84
+ if config.has_key?(:username)
85
+ if config.has_key?(:pwd_yaml)
86
+ # password.yml file
87
+ config = XMLSERVICEPassword::Encrypt.parse_yaml(config, config[:pwd_yaml].to_s, config[:username].to_s)
88
+ config = XMLSERVICEPassword::Encrypt.symbolize_keys(config)
89
+ end
90
+ if config.has_key?(:pwd_enc)
91
+ if !config.has_key?(:pwd_key)
92
+ config[:pwd_key] = "*DEFAULT"
93
+ end
94
+ config[:password] = XMLSERVICEPassword::Encrypt.decrypt(config[:pwd_enc].to_s, config[:pwd_key].to_s)
95
+ end
96
+ end
97
+ config
98
+ end
99
+
100
+ # password decrypt
101
+ def self.decrypt(encoded, key = "*DEFAULT")
102
+ XMLSERVICEPassword::Encrypt.establish_key(key);
103
+ decoded = XMLSERVICEPassword::Encrypt.decode(encoded)
104
+ cipher = OpenSSL::Cipher::Cipher.new(PWD_TYPE)
105
+ cipher.decrypt
106
+ cipher.key = @xml_pwdkey
107
+ cipher.iv = decoded.slice!(0,16) # Remove the IV from the encrypted data
108
+ decrypted = cipher.update(decoded) + cipher.final
109
+ decrypted
110
+ end
111
+
112
+ # generate a pass key
113
+ def self.gen_key()
114
+ XMLSERVICEPassword::Encrypt.establish_key("*DEFAULT");
115
+ cipher = OpenSSL::Cipher::Cipher.new(PWD_TYPE)
116
+ cipher.encrypt
117
+ cipher.key = @xml_pwdkey
118
+ all = " "
119
+ for i in 1..3
120
+ cipher.iv = iv = cipher.random_iv
121
+ raw = XMLSERVICEPassword::Encrypt.encode(iv)
122
+ all << raw.to_s
123
+ end
124
+ encode = all.slice!(1..32)
125
+ encode
126
+ end
127
+
128
+ # generate a encrypted password
129
+ def self.gen_password(plaintext, key = "*DEFAULT")
130
+ XMLSERVICEPassword::Encrypt.establish_key(key);
131
+ cipher = OpenSSL::Cipher::Cipher.new(PWD_TYPE)
132
+ cipher.encrypt
133
+ cipher.key = @xml_pwdkey
134
+ cipher.iv = iv = cipher.random_iv
135
+ encrypted = cipher.update(plaintext) + cipher.final
136
+ encrypted = iv + encrypted # Send along the IV
137
+ encoded = XMLSERVICEPassword::Encrypt.encode(encrypted)
138
+ encoded
139
+ end
140
+
141
+ # ------------------
142
+ # helper function (maybe should be private)
143
+ # ------------------
144
+
145
+ # assure valid iv and key
146
+ def self.establish_key(key = "*DEFAULT")
147
+ if key && key != '*DEFAULT'
148
+ @xml_pwdkey = key
149
+ else
150
+ @xml_pwdkey = PWD_KEY
151
+ end
152
+ end
153
+
154
+ # base64 encode for web/yaml usage
155
+ def self.encode(item)
156
+ encrypted = Base64.encode64(item)
157
+ encoded = URI.escape(encrypted)
158
+ encoded
159
+ end
160
+
161
+ # base64 decode from web/yaml
162
+ def self.decode(item)
163
+ encrypted = URI.unescape(item)
164
+ decoded = Base64.decode64(encrypted)
165
+ decoded
166
+ end
167
+
168
+ # Converts all +config+ keys to symbols
169
+ def self.symbolize_keys(config)
170
+ # config = config.symbolize_keys
171
+ config.keys.each do |key|
172
+ config[(key.to_sym rescue key) || key] = config.delete(key)
173
+ end
174
+ config
175
+ end
176
+
177
+
178
+ # recursive *_yaml: /path/thing.yml
179
+ def self.nest_yaml(config,key,value)
180
+ if key.include? "_yaml" or (value != nil and value.instance_of? String and value.to_s.include? ".yml")
181
+ # recursive /path/password.yml
182
+ if value.include? "password.yml"
183
+ if !config.has_key?(:username)
184
+ if config.has_key?("username")
185
+ config[:username] = config["username"]
186
+ end
187
+ end
188
+ if config.has_key?(:username)
189
+ config = XMLSERVICEPassword::Encrypt.parse_yaml(config, value, config[:username])
190
+ end
191
+ # recursive *_yaml: /path/thing.yml
192
+ else
193
+ config = XMLSERVICEPassword::Encrypt.parse_yaml(config, value, "*ALL")
194
+ end
195
+ end
196
+ config
197
+ end
198
+
199
+ # parse nested yaml files
200
+ def self.parse_yaml(config, yaml_file, yaml_key)
201
+ rfile = Pathname.new(yaml_file)
202
+ if rfile
203
+ f = open(rfile.to_s)
204
+ doc = YAML::load_stream( f )
205
+ doc.each do |key, value|
206
+ key.each do |key0, value0|
207
+ # recursive *_yaml
208
+ config = XMLSERVICEPassword::Encrypt.nest_yaml(config,key0,value0)
209
+ # take everything
210
+ if yaml_key == "*ALL"
211
+ config[key0] = value0
212
+ # found target key="username"
213
+ elsif yaml_key == key0
214
+ value0.each do |key1, value1|
215
+ # recursive *_yaml
216
+ config = XMLSERVICEPassword::Encrypt.nest_yaml(config,key1,value1)
217
+ # take everything
218
+ config[key1] = value1
219
+ end
220
+ end
221
+ end
222
+ end
223
+ end
224
+ config
225
+ end
226
+ end # Encrypt
227
+ end # XMLSERVICEPassword
228
+
229
+