ige_isb_api 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,164 @@
1
+ #!/user/bin/env ruby
2
+ #coding: utf-8
3
+
4
+ require "net/http"
5
+ require "uri"
6
+ require "ige_isb_api"
7
+ require "ige_isb_api/constants"
8
+ require "ige_isb_api/validation"
9
+
10
+ module IGE_ISB_API
11
+ class Request
12
+ attr_accessor :params, :request
13
+
14
+ DEFAULT_PARAMS = {
15
+ 'secretkey' => IGE_ISB_API::Constants::SECRET_KEY
16
+ }
17
+
18
+ COMMON_FIELDS = {
19
+ 'command' => {:required => true, :type => 'string', :length => 32},
20
+ 'idrequest' => {:required => true, :type => 'string', :length => 32},
21
+ 'secretkey' => {:required => true, :type => 'string', :length => 128},
22
+ 'username' => {:required => true, :type => 'username', :length => 32},
23
+ 'password' => {:required => true, :type => 'password', :length => 32}, # this differs from the docs but testing shows it's true.
24
+ 'txid' => {:required => true, :type => 'int'}
25
+ }
26
+
27
+ COMMANDS = {
28
+ 'registration' => {
29
+ 'email' => {:required => true, :type => 'email', :length => 140},
30
+ 'name' => {:required => true, :type => 'name', :length => 140},
31
+ 'firstname' => {:required => true, :type => 'name', :length => 140},
32
+ 'zip' => {:required => true, :type => 'string', :length => 10},
33
+ 'city' => {:required => true, :type => 'string', :length => 140},
34
+ 'phone' => {:required => true, :type => 'phone', :length => 32},
35
+ 'dob' => {:required => true, :type => 'datestring', :length => 10},
36
+ 'country' => {:required => true, :type => 'country'},
37
+ 'ip' => {:required => true, :type => 'ip4', :length => 32},
38
+ 'cur' => {:required => true, :type => 'currency_code', :length => 3},
39
+ 'status' => {:required => true, :type => 'int', values: [0, 1, 2]},
40
+ 'carte' => {:required => true, :type => 'string', :length => 32},
41
+ 'lang' => {:required => true, :type => 'string', :length => 2},
42
+ 'gender' => {:required => true, :type => 'int', values: [0, 1]},
43
+ 'idaffiliation' => {:required => true, :type => 'int'}
44
+ },
45
+ 'login' => {
46
+ 'carte' => {:required => true, :type => 'string', :length => 32}
47
+ },
48
+ 'deposit' => {
49
+ 'amount' => {:required => true, :type => 'int'},
50
+ 'reference' => {:required => true, :type => 'string', :length => 32},
51
+ 'cur' => {:required => true, :type => 'string', :length => 3},
52
+ 'wallet' => {:required => true, :type => 'string', :length => 32}
53
+ },
54
+ 'withdrawal' => {
55
+ 'amount' => {:required => true, :type => 'int'},
56
+ 'reference' => {:required => true, :type => 'string', :length => 32},
57
+ 'cur' => {:required => true, :type => 'currency_code', :length => 3},
58
+ 'wallet' => {:required => true, :type => 'string', :length => 32}
59
+ },
60
+ 'limits' => {
61
+ 'limitationtype' => {:required => true, :type => 'limit'},
62
+ 'amount' => {:required => true, :type => 'int'},
63
+ 'frequency' => {:required => true, :type => 'timespan'},
64
+ 'until' => {:required => true, :type => 'string', :length => 32}
65
+ },
66
+ 'userstatus' => {
67
+ 'flag' => {:required => true, :type => 'int'}
68
+ },
69
+ 'pass' => {
70
+ 'newpassword' => {:required => true, :type => 'string', :length => 32}
71
+ },
72
+ 'get_vip_points' => {
73
+ # nothing special
74
+ },
75
+ 'save_friend_email' => {
76
+ 'invitedname' => {:required => true, :type => 'string', :length => 32},
77
+ 'invitedemail' => {:required => true, :type => 'string', :length => 140}
78
+ }
79
+ }
80
+
81
+ def initialize(params = {})
82
+ self.params = self.class::DEFAULT_PARAMS.merge(self.convert_symbols_to_strings(params))
83
+ self.validate_parameters
84
+ # a bunch of stuff
85
+
86
+ self.construct_request
87
+ end
88
+
89
+ def send
90
+ uri = URI.parse(IGE_ISB_API::Constants::API_SERVER)
91
+ http = Net::HTTP.new(uri.host, uri.port)
92
+ # see http://www.rubyinside.com/nethttp-cheat-sheet-2940.html
93
+ # http.use_ssl = true
94
+ # http.cert = OpenSSL::X509::Certificate.new(pem)
95
+ # http.key = OpenSSL::PKey::RSA.new(pem)
96
+ # http.verify_mode = OpenSSL::SSL::VERIFY_PEER
97
+ return http.request(self.request)
98
+ end
99
+
100
+ protected
101
+
102
+ def convert_symbols_to_strings(a_hash = {})
103
+ return {} if a_hash.empty?
104
+ result = {}
105
+ a_hash.each {|key, value| result[key.to_s] = value }
106
+ return result
107
+ end
108
+
109
+ def validate_parameters
110
+ command = params['command']
111
+ raise ValidationException, "No command in params #{params.inspect}." if command.nil? || command.empty?
112
+ comfields = self.class::COMMANDS[command]
113
+ raise ValidationException, "Invalid command #{command}." if comfields.nil?
114
+ fields = self.class::COMMON_FIELDS.merge(comfields)
115
+ self.validate_fields(fields)
116
+ self.validate_no_extra_fields(fields)
117
+ end
118
+
119
+ def validate_fields(against)
120
+ against.each do |name, meta|
121
+ required = (meta[:required] === true)
122
+ # Check that all required parameters are present
123
+ if required && !self.params.keys.include?(name)
124
+ raise ValidationException, "Parameter #{name} is required, but missing from #{self.params.keys}"
125
+ end
126
+ if self.params.keys.include? name
127
+ p = self.params[name]
128
+ if p != nil
129
+ case meta[:type]
130
+ when 'timestamp'
131
+ self.params[name] = p = p.to_time.utc.to_i if p.is_a? Date
132
+ self.params[name] = p = p.utc.to_i if p.is_a?(Time)
133
+ self.params[name] = p = p.to_i if p.is_a?(String)
134
+ when 'currency'
135
+ p = p.to_f if p.is_a? String
136
+ if (p.is_a?(Float) || p.is_a?(Integer)) && p > 0
137
+ self.params[name] = p = "%.2f" % p
138
+ end
139
+ end
140
+ opts = {}
141
+ opts[:length] = meta[:length] if meta[:length]
142
+ opts[:values] = meta[:values] if meta[:values]
143
+ IGE_ISB_API::Validation.test name, self.params[name], meta[:type], opts
144
+ end
145
+ end
146
+ end
147
+ end
148
+
149
+ def validate_no_extra_fields(against)
150
+ allowed_fields = against.keys
151
+ self.params.each do |key, value|
152
+ raise InternalException, "Field #{key} is not supported" if !allowed_fields.include?(key)
153
+ end
154
+ end
155
+
156
+ def construct_request
157
+ uri = URI.parse(IGE_ISB_API::Constants::API_SERVER)
158
+ # http = Net::HTTP.new(uri.host, uri.port)
159
+ self.request = Net::HTTP::Post.new(uri)
160
+ self.request.set_form_data(self.params)
161
+ end
162
+
163
+ end
164
+ end
@@ -0,0 +1,251 @@
1
+ #!/user/bin/env ruby
2
+ #coding: utf-8
3
+
4
+ module IGE_ISB_API
5
+ class UserAPI
6
+
7
+ # the following options *must* be passed in.
8
+ # username: "some_username specific to iSoftBet",
9
+ # password: "should be specific to iSoftBet",
10
+ # The following options may be passed in and are presented here with their defaults.
11
+ # cur: IGE_ISB_API::Constants::DEFAULT_CURRENCY_CODE,
12
+ # carte: IGE_ISB_API::Constants::CASINO,
13
+ # lang: IGE_ISB_API::Constants::DEFAULT_LANGUAGE,
14
+ def initialize(player_status = IGE_ISB_API::Constants::TEST, opts = {})
15
+ raise ArgumentError, "Missing options." if opts.empty?
16
+ @options = {
17
+ cur: IGE_ISB_API::Constants::DEFAULT_CURRENCY_CODE,
18
+ carte: IGE_ISB_API::Constants::CASINO,
19
+ lang: IGE_ISB_API::Constants::DEFAULT_LANGUAGE,
20
+ status: player_status
21
+ }.merge(opts)
22
+ end
23
+
24
+ # Each command has a label which is used by the casino to tag a group of interactions with ISB
25
+ # Additionally each transaction must include a unique transaction ID.
26
+ # the following options *must* be passed in.
27
+ # email: "the user's email address",
28
+ # name: "the user's surname",
29
+ # firstname: "the user's first name",,
30
+ # zip: "the user's postcode",
31
+ # city: "the user's city",
32
+ # phone: "the user's phone number",
33
+ # dob: "in 2011-11-21 format",
34
+ # country: "the ISO country code for the user",
35
+ # ip: request.ip
36
+ #
37
+ # The following may be passed in and are presented here with their defaults.
38
+ # cur: IGE_ISB_API::Constants::DEFAULT_CURRENCY_CODE,
39
+ # status: IGE_ISB_API::Constants::TEST,
40
+ # carte: IGE_ISB_API::Constants::CASINO,
41
+ # lang: 'en',
42
+ # gender: IGE_ISB_API::Constants::MALE,
43
+ def register(label = '', txid = 0, opts = {})
44
+ validate_params!(label, txid)
45
+ raise ArgumentError, "Missing options." if opts.empty?
46
+ @params = { idrequest: label,
47
+ username: @options[:username],
48
+ password: @options[:password],
49
+ status: @options[:status],
50
+ cur: @options[:cur],
51
+ lang: @options[:lang],
52
+ carte: @options[:carte],
53
+ gender: IGE_ISB_API::Constants::MALE,
54
+ txid: txid}.merge(opts).merge({ command: 'registration', idaffiliation: IGE_ISB_API::Constants::LICENSEE_ID })
55
+ request = IGE_ISB_API.request(@params)
56
+ resp = request.send
57
+ response = JSON.parse(resp.body)
58
+ return response
59
+ end
60
+
61
+ # Each command has a label which is used by the casino to tag a group of interactions with ISB
62
+ # Additionally each transaction must include a unique transaction ID.
63
+ # The following may be passed in and is presented here with its default.
64
+ # carte: defaults to IGE_ISB_API::Constants::CASINO can can be overridden if user is logging in from
65
+ # a different casino under the control of the same licensee.
66
+ def login(label = '', txid = 0, opts = {})
67
+ validate_params!(label, txid)
68
+ @params = { idrequest: label,
69
+ username: @options[:username],
70
+ password: @options[:password],
71
+ carte: @options[:carte],
72
+ txid: txid}.merge(opts).merge({ command: 'login' })
73
+ request = IGE_ISB_API.request(@params)
74
+ resp = request.send
75
+ response = JSON.parse(resp.body)
76
+ return response
77
+ end
78
+
79
+ # Each command has a label which is used by the casino to tag a group of interactions with ISB
80
+ # Additionally each transaction must include a unique transaction ID.
81
+ # the following options *must* be passed in.
82
+ # wallet: "the name of the payment processor being used",
83
+ # amount: a positive floating point number,
84
+ # reference: "for logging purposes",
85
+ #
86
+ # The following may be passed in and are presented here with their defaults.
87
+ # cur: defaults to IGE_ISB_API::Constants::DEFAULT_CURRENCY_CODE
88
+ def deposit(label = '', txid = 0, opts = {})
89
+ validate_params!(label, txid)
90
+ raise ArgumentError, "Missing options." if opts.empty?
91
+ @params = { idrequest: label,
92
+ username: @options[:username],
93
+ password: @options[:password],
94
+ cur: @options[:cur],
95
+ txid: txid}.merge(opts).merge({ command: 'deposit' })
96
+ reference = "#{@params[:wallet]}:#{@params[:reference]}#{@params[:cur]}"
97
+ @params.merge!(reference: reference)
98
+ request = IGE_ISB_API.request(@params)
99
+ resp = request.send
100
+ response = JSON.parse(resp.body)
101
+ return response
102
+ end
103
+
104
+ # Each command has a label which is used by the casino to tag a group of interactions with ISB
105
+ # Additionally each transaction must include a unique transaction ID.
106
+ # the following options *must* be passed in.
107
+ # wallet: "the name of the payment processor being used",
108
+ # amount: a positive floating point number,
109
+ # reference: "for logging purposes",
110
+ #
111
+ # The following may be passed in and are presented here with their defaults.
112
+ # cur: defaults to IGE_ISB_API::Constants::DEFAULT_CURRENCY_CODE
113
+ def withdrawal(label = '', txid = 0, opts = {})
114
+ validate_params!(label, txid)
115
+ raise ArgumentError, "Missing options." if opts.empty?
116
+ @params = { idrequest: label,
117
+ username: @options[:username],
118
+ password: @options[:password],
119
+ cur: @options[:cur],
120
+ txid: txid}.merge(opts).merge({ command: 'withdrawal' })
121
+ reference = "#{@params[:reference]}#{@params[:cur]}"
122
+ @params.merge!(reference: reference)
123
+ request = IGE_ISB_API.request(@params)
124
+ resp = request.send
125
+ response = JSON.parse(resp.body)
126
+ return response
127
+ end
128
+
129
+ # Each command has a label which is used by the casino to tag a group of interactions with ISB
130
+ # Additionally each transaction must include a unique transaction ID.
131
+ # the following options *must* be passed in.
132
+ # limitationtype: 'DEPOSIT', 'DEPOSIT_EXTRA', 'BET', 'LOSS', 'TIME', 'EXCLUSION'
133
+ # amount: a positive floating point number,
134
+ # frequency: "WEEKLY", DAILY, MONTHLY, 1..n days - for exclusion
135
+ # until: "YYYY-MM-DD" or -1 for unlimited.
136
+ #
137
+ # The following may be passed in and are presented here with their defaults.
138
+ # cur: defaults to IGE_ISB_API::Constants::DEFAULT_CURRENCY_CODE
139
+ def limits(label = '', txid = 0, opts = {})
140
+ validate_params!(label, txid)
141
+ raise ArgumentError, "Missing options." if opts.empty?
142
+ @params = { idrequest: label,
143
+ username: @options[:username],
144
+ password: @options[:password],
145
+ txid: txid}.merge(opts).merge({ command: 'limits' })
146
+ request = IGE_ISB_API.request(@params)
147
+ resp = request.send
148
+ response = JSON.parse(resp.body)
149
+ return response
150
+ end
151
+
152
+ # Each command has a label which is used by the casino to tag a group of interactions with ISB
153
+ # Additionally each transaction must include a unique transaction ID.
154
+ def deactivate(label = '', txid = 0)
155
+ validate_params!(label, txid)
156
+ @params = { idrequest: label,
157
+ username: @options[:username],
158
+ password: @options[:password],
159
+ txid: txid}.merge({ command: 'userstatus', flag: IGE_ISB_API::Constants::USER_INACTIVE })
160
+ request = IGE_ISB_API.request(@params)
161
+ resp = request.send
162
+ response = JSON.parse(resp.body)
163
+ return response
164
+ end
165
+
166
+ # Each command has a label which is used by the casino to tag a group of interactions with ISB
167
+ # Additionally each transaction must include a unique transaction ID.
168
+ def activate(label = '', txid = 0)
169
+ validate_params!(label, txid)
170
+ @params = { idrequest: label,
171
+ username: @options[:username],
172
+ password: @options[:password],
173
+ txid: txid}.merge({ command: 'userstatus', flag: IGE_ISB_API::Constants::USER_ACTIVE })
174
+ request = IGE_ISB_API.request(@params)
175
+ resp = request.send
176
+ response = JSON.parse(resp.body)
177
+ return response
178
+ end
179
+
180
+ # Each command has a label which is used by the casino to tag a group of interactions with ISB
181
+ # Additionally each transaction must include a unique transaction ID.
182
+ def ban(label = '', txid = 0)
183
+ validate_params!(label, txid)
184
+ @params = { idrequest: label,
185
+ username: @options[:username],
186
+ password: @options[:password],
187
+ txid: txid}.merge({ command: 'userstatus', flag: IGE_ISB_API::Constants::USER_BANNED })
188
+ request = IGE_ISB_API.request(@params)
189
+ resp = request.send
190
+ response = JSON.parse(resp.body)
191
+ return response
192
+ end
193
+
194
+ # Each command has a label which is used by the casino to tag a group of interactions with ISB
195
+ # Additionally each transaction must include a unique transaction ID.
196
+ # the following option *must* be passed in.
197
+ # newpassword: 'some new password',
198
+ def change_password(label = '', txid = 0, opts = {})
199
+ validate_params!(label, txid)
200
+ raise ArgumentError, "Missing options." if opts.empty?
201
+ @params = { idrequest: label,
202
+ username: @options[:username],
203
+ password: @options[:password],
204
+ txid: txid}.merge(opts).merge({ command: 'pass'})
205
+ request = IGE_ISB_API.request(@params)
206
+ resp = request.send
207
+ response = JSON.parse(resp.body)
208
+ return response
209
+ end
210
+
211
+ # Each command has a label which is used by the casino to tag a group of interactions with ISB
212
+ # Additionally each transaction must include a unique transaction ID.
213
+ def get_vip_points(label = '', txid = 0)
214
+ validate_params!(label, txid)
215
+ @params = { idrequest: label,
216
+ username: @options[:username],
217
+ password: @options[:password],
218
+ txid: txid}.merge({ command: 'get_vip_points' })
219
+ request = IGE_ISB_API.request(@params)
220
+ resp = request.send
221
+ response = JSON.parse(resp.body)
222
+ return response
223
+ end
224
+
225
+ # Each command has a label which is used by the casino to tag a group of interactions with ISB
226
+ # Additionally each transaction must include a unique transaction ID.
227
+ # the following options *must* be passed in.
228
+ # invitedname: 'some new password',
229
+ # invitedemail: 'some new password',
230
+ def save_friend_email(label = '', txid = 0, opts = {})
231
+ validate_params!(label, txid)
232
+ raise ArgumentError, "Missing options." if opts.empty?
233
+ @params = { idrequest: label,
234
+ username: @options[:username],
235
+ password: @options[:password],
236
+ txid: txid}.merge(opts).merge({ command: 'save_friend_email'})
237
+ request = IGE_ISB_API.request(@params)
238
+ resp = request.send
239
+ response = JSON.parse(resp.body)
240
+ return response
241
+ end
242
+
243
+ private
244
+
245
+ def validate_params!(label, txid)
246
+ raise ArgumentError, "Missing a valid label." if label.empty?
247
+ raise ArgumentError, "Missing a valid transaction ID." if txid <= 0
248
+ end
249
+
250
+ end
251
+ end
@@ -0,0 +1,130 @@
1
+ #!/user/bin/env ruby
2
+ #coding: utf-8
3
+
4
+ require 'ige_isb_api'
5
+ require 'ige_isb_api/constants'
6
+
7
+ module IGE_ISB_API
8
+ class Validation
9
+
10
+ def self.is_valid_username?(a_username)
11
+ # Username must be alphanumeric
12
+ return false if a_username.size > 32
13
+ return !a_username.match(/^[[:alpha:]|[0-9]|\-_]+$/).nil?
14
+ end
15
+
16
+ def self.is_valid_password?(a_password)
17
+ # Password must be over 6 and less than 20 characters long; Password must be alphanumeric
18
+ return false unless a_password.size.between?(6,20)
19
+ return !a_password.match(/^[[:alpha:]|[0-9]]+$/).nil?
20
+ end
21
+
22
+ def self.is_valid_email?(an_email)
23
+ # see http://stackoverflow.com/questions/703060/valid-email-address-regular-expression
24
+ return false if an_email.empty?
25
+ email_regex = /(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*:(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)(?:,\s*(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*))*)?;\s*)/
26
+ return !an_email.match(email_regex).nil?
27
+ end
28
+
29
+ def self.is_valid_name?(a_name)
30
+ "0123456789!@#$%^&*()[]\\/+=?<>~;:{}".split('').each do |ch|
31
+ return false if a_name.include?(ch)
32
+ end
33
+ return true
34
+ end
35
+
36
+ def self.is_valid_phonenumber?(a_phonenumber)
37
+ # phone can start with +
38
+ # TODO: Awaiting feedback from ISB
39
+ numb_regex = /^\+?[0-9\(\s\)-]{5,21}$/
40
+ return !a_phonenumber.match(numb_regex).nil?
41
+ end
42
+
43
+ def self.is_valid_ip4?(an_ip)
44
+ # valid IP4 address
45
+ vip = an_ip.match /^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/
46
+ return false if vip.nil?
47
+ return false unless $1.to_i.between?(0,255) && $2.to_i.between?(0,255) && $3.to_i.between?(0,255)
48
+ return true
49
+ end
50
+
51
+ def self.is_valid_datestring?(a_datestring)
52
+ dm = a_datestring.match /^((19|20)[0-9][0-9])-([0-9]{2})-([0-9]{2})\.([0-9]{2}):([0-9]{2}):([0-9]{2})$/
53
+ if dm.nil?
54
+ dm = a_datestring.match /^((19|20)[0-9][0-9])-([0-9]{2})-([0-9]{2})$/
55
+ return false if dm.nil?
56
+ else
57
+ return false unless $5.to_i.between?(0,23)
58
+ return false unless $6.to_i.between?(0,59)
59
+ return false unless $7.to_i.between?(0,59)
60
+ end
61
+ return false unless $1.to_i.between?(1900,2099)
62
+ return false unless $3.to_i.between?(1,12)
63
+ return false unless $4.to_i.between?(1,31)
64
+ return false if [9, 4, 6, 11].include?($3.to_i) && !$4.to_i.between?(1,30)
65
+ return false if $3.to_i == 2 && $1.to_i % 4 == 0 && !$4.to_i.between?(1,29) # leap year
66
+ return false if $3.to_i == 2 && !$4.to_i.between?(1,28) # non leap year
67
+ return true
68
+ end
69
+
70
+ def self.is_valid_currency?(an_amount)
71
+ vc = an_amount.match /^[1-9][0-9]*\.[0-9][0-9]$/
72
+ return !vc.nil?
73
+ end
74
+
75
+ def self.test(a_fieldname, a_value, a_type, opts = {})
76
+ correct_type = true
77
+ begin
78
+ case a_type
79
+ when 'username'
80
+ correct_type = a_value.is_a?(String) && is_valid_username?(a_value)
81
+ when 'password'
82
+ correct_type = a_value.is_a?(String) && is_valid_password?(a_value)
83
+ when 'boolstring'
84
+ correct_type = a_value.is_a?(String) && ['True', 'False'].include?(a_value)
85
+ when 'country'
86
+ correct_type = a_value.is_a?(String) && !IGE_ISB_API::Constants::ALLOWED_COUNTRY_CODES[a_value.to_sym].nil?
87
+ when 'limit'
88
+ correct_type = a_value.is_a?(String) && IGE_ISB_API::Constants::ALLOWED_LIMITATIONS.include?(a_value)
89
+ when 'timespan'
90
+ correct_type = a_value.is_a?(String) && IGE_ISB_API::Constants::ALLOWED_FREQUENCIES.include?(a_value)
91
+ when 'string'
92
+ correct_type = a_value.is_a? String
93
+ raise ValidationException, sprintf("Value '%s' in field '%s' is too long.", a_value, a_fieldname) if opts[:length] && a_value.size > opts[:length]
94
+ raise ValidationException, "#{a_value} is invalid for #{a_fieldname}" if opts[:values] && !opts[:values].include?(a_value)
95
+ when 'currency_code'
96
+ correct_type = a_value.is_a?(String) && IGE_ISB_API::Constants::ALLOWED_CURRENCIES.include?(a_value)
97
+ when 'currency'
98
+ correct_type = is_valid_currency?(a_value)
99
+ when 'percent'
100
+ correct_type = a_value.is_a?(Float) || a_value.is_a?(Integer)
101
+ raise ValidationException, "#{a_fieldname} must be positive" if a_value < 0
102
+ when 'int'
103
+ correct_type = a_value.is_a? Integer
104
+ raise ValidationException, "#{a_fieldname} only allows positive integers" if a_value < 0
105
+ raise ValidationException, "#{a_value} is invalid for #{a_fieldname}" if opts[:values] && !opts[:values].include?(a_value)
106
+ when 'boolint'
107
+ correct_type = a_value.is_a?(Integer) && [0, 1].include?(a_value)
108
+ when 'datestring'
109
+ correct_type = a_value.is_a? String
110
+ raise ValidationException, "#{a_value} is not a valid date string." unless is_valid_datestring?(a_value)
111
+ when 'timestamp'
112
+ correct_type = a_value.is_a? Integer
113
+ raise ValidationException, "#{a_value} is not a valid timestamp." unless a_value > 0
114
+ when 'phone'
115
+ correct_type = a_value.is_a?(String) && is_valid_phonenumber?(a_value)
116
+ when 'ip4'
117
+ correct_type = a_value.is_a?(String) && is_valid_ip4?(a_value)
118
+ when 'email'
119
+ correct_type = a_value.is_a?(String) && is_valid_email?(a_value)
120
+ end
121
+ rescue ArgumentError => ae
122
+ raise ValidationException, sprintf("Value '%s' in field '%s' is not of expected type '%s' Error: %s", a_value, a_fieldname, a_type, ae.message)
123
+ end
124
+
125
+ raise ValidationException, sprintf("Value '%s' in field '%s' is not of expected type '%s'", a_value, a_fieldname, a_type) unless correct_type
126
+
127
+ end
128
+
129
+ end
130
+ end