queueit_knownuserv3 3.3.0 → 3.6.1

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,43 @@
1
+ #-------------------------------------------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
4
+ #-------------------------------------------------------------------------------------------------------------
5
+
6
+ FROM ruby:1.9.3
7
+
8
+ # Avoid warnings by switching to noninteractive
9
+ ENV DEBIAN_FRONTEND=noninteractive
10
+
11
+ # This Dockerfile adds a non-root 'vscode' user with sudo access. However, for Linux,
12
+ # this user's GID/UID must match your local user UID/GID to avoid permission issues
13
+ # with bind mounts. Update USER_UID / USER_GID if yours is not 1000. See
14
+ # https://aka.ms/vscode-remote/containers/non-root-user for details.
15
+ ARG USERNAME=vscode
16
+ ARG USER_UID=1000
17
+ ARG USER_GID=$USER_UID
18
+
19
+ # Configure apt and install packages
20
+ RUN apt-get update \
21
+ && apt-get -y install --no-install-recommends apt-utils dialog 2>&1 \
22
+ # Verify git, process tools installed
23
+ && apt-get -y install git iproute2 procps lsb-release \
24
+ #
25
+ # Install ruby-debug-ide and ruby-debug-base19x
26
+ #&& gem install ruby-debug-ide \
27
+ #&& gem install ruby-debug-base19x \
28
+ #
29
+ # Create a non-root user to use if preferred - see https://aka.ms/vscode-remote/containers/non-root-user.
30
+ && groupadd --gid $USER_GID $USERNAME \
31
+ && useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME \
32
+ # [Optional] Add sudo support for the non-root user
33
+ && apt-get install -y sudo \
34
+ && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME\
35
+ && chmod 0440 /etc/sudoers.d/$USERNAME \
36
+ #
37
+ # Clean up
38
+ && apt-get autoremove -y \
39
+ && apt-get clean -y \
40
+ && rm -rf /var/lib/apt/lists/*
41
+
42
+ # Switch back to dialog for any ad-hoc use of apt-get
43
+ ENV DEBIAN_FRONTEND=
@@ -0,0 +1,30 @@
1
+ // For format details, see https://aka.ms/vscode-remote/devcontainer.json or the definition README at
2
+ // https://github.com/microsoft/vscode-dev-containers/tree/master/containers/ruby-2
3
+ {
4
+ "name": "Ruby",
5
+ "dockerFile": "Dockerfile",
6
+
7
+ // Use 'settings' to set *default* container specific settings.json values on container create.
8
+ // You can edit these settings after create using File > Preferences > Settings > Remote.
9
+ "settings": {
10
+ "terminal.integrated.shell.linux": "/bin/bash"
11
+ },
12
+
13
+ "workspaceMount": "src=${localWorkspaceFolder},dst=/workspace,type=bind,consistency=delegated",
14
+ "workspaceFolder": "/workspace",
15
+ // Uncomment the next line if you want to publish any ports.
16
+ // "appPort": [],
17
+
18
+ // Uncomment the next line to run commands after the container is created.
19
+ "postCreateCommand": "bundle install; gem install ruby-debug-ide -v 0.6.0; gem install ruby-debug-base19x",
20
+
21
+ // Uncomment the next line to use a non-root user. On Linux, this will prevent
22
+ // new files getting created as root, but you may need to update the USER_UID
23
+ // and USER_GID in .devcontainer/Dockerfile to match your user if not 1000.
24
+ // "runArgs": [ "-u", "vscode" ],
25
+
26
+ // Add the IDs of extensions you want installed when the container is created in the array below.
27
+ "extensions": [
28
+ "rebornix.Ruby"
29
+ ]
30
+ }
@@ -0,0 +1,5 @@
1
+ ################################################################################
2
+ # This .gitignore file was automatically created by Microsoft(R) Visual Studio.
3
+ ################################################################################
4
+
5
+ /.vs
@@ -0,0 +1,15 @@
1
+ {
2
+ // Use IntelliSense to learn about possible attributes.
3
+ // Hover to view descriptions of existing attributes.
4
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
+ "version": "0.2.0",
6
+ "configurations": [
7
+ {
8
+ "name": "Debug",
9
+ "type": "Ruby",
10
+ "request": "launch",
11
+ "program": "${workspaceRoot}/test/test_queueit_knownuserv3.rb",
12
+ "cwd": "${workspaceRoot}"
13
+ }
14
+ ]
15
+ }
@@ -0,0 +1,17 @@
1
+ # Starter pipeline
2
+ # Start with a minimal pipeline that you can customize to build and deploy your code.
3
+ # Add steps that build, run tests, deploy, and more:
4
+ # https://aka.ms/yaml
5
+
6
+ trigger:
7
+ - master
8
+
9
+ pool:
10
+ name: 'Default'
11
+
12
+ steps:
13
+ - task: Docker@2
14
+ inputs:
15
+ command: 'buildAndPush'
16
+ Dockerfile: '**/test/Dockerfile'
17
+ buildContext: './'
@@ -1,5 +1,6 @@
1
1
  require_relative "queueit_knownuserv3/known_user"
2
2
  require_relative "queueit_knownuserv3/models"
3
+ require_relative "queueit_knownuserv3/connector_diagnostics"
3
4
  require_relative "queueit_knownuserv3/queue_url_params"
4
5
  require_relative "queueit_knownuserv3/user_in_queue_state_cookie_repository"
5
6
  require_relative "queueit_knownuserv3/user_in_queue_service"
@@ -0,0 +1,69 @@
1
+ module QueueIt
2
+ class ConnectorDiagnostics
3
+ attr_accessor :isEnabled
4
+ attr_accessor :hasError
5
+ attr_accessor :validationResult
6
+
7
+ def initialize
8
+ @isEnabled = false
9
+ @hasError = false
10
+ @validationResult = nil
11
+ end
12
+
13
+ def setStateWithTokenError(customerId, errorCode)
14
+ @hasError = true
15
+ @validationResult = RequestValidationResult.new(
16
+ "ConnectorDiagnosticsRedirect",
17
+ nil, nil,
18
+ "https://" + customerId + ".api2.queue-it.net/" + customerId + "/diagnostics/connector/error/?code=" + errorCode,
19
+ nil, nil)
20
+ end
21
+
22
+ def setStateWithSetupError()
23
+ @hasError = true
24
+ @validationResult = RequestValidationResult.new(
25
+ "ConnectorDiagnosticsRedirect",
26
+ nil, nil,
27
+ "https://api2.queue-it.net/diagnostics/connector/error/?code=setup",
28
+ nil, nil)
29
+ end
30
+
31
+ def self.verify(customerId, secretKey, queueitToken)
32
+ diagnostics = ConnectorDiagnostics.new
33
+
34
+ qParams = QueueUrlParams.extractQueueParams(queueitToken)
35
+
36
+ if(qParams == nil)
37
+ return diagnostics
38
+ end
39
+
40
+ if(qParams.redirectType == nil)
41
+ return diagnostics
42
+ end
43
+
44
+ if(not qParams.redirectType.upcase.eql?("DEBUG"))
45
+ return diagnostics
46
+ end
47
+
48
+ if(Utils.isNilOrEmpty(customerId) or Utils.isNilOrEmpty(secretKey))
49
+ diagnostics.setStateWithSetupError()
50
+ return diagnostics
51
+ end
52
+
53
+ calculatedHash = OpenSSL::HMAC.hexdigest('sha256', secretKey, qParams.queueITTokenWithoutHash)
54
+ if(not qParams.hashCode.eql?(calculatedHash))
55
+ diagnostics.setStateWithTokenError(customerId, "hash")
56
+ return diagnostics
57
+ end
58
+
59
+ if(qParams.timeStamp < Time.now.getutc.tv_sec)
60
+ diagnostics.setStateWithTokenError(customerId, "timestamp")
61
+ return diagnostics
62
+ end
63
+
64
+ diagnostics.isEnabled = true
65
+
66
+ return diagnostics
67
+ end
68
+ end
69
+ end
@@ -75,14 +75,14 @@ module QueueIt
75
75
 
76
76
  class UrlValidatorHelper
77
77
  def self.evaluate(triggerPart, url)
78
- if (!triggerPart.key?("Operator") ||
78
+ if (triggerPart.nil? ||
79
+ !triggerPart.key?("Operator") ||
79
80
  !triggerPart.key?("IsNegative") ||
80
81
  !triggerPart.key?("IsIgnoreCase") ||
81
- !triggerPart.key?("ValueToCompare") ||
82
82
  !triggerPart.key?("UrlPart"))
83
- return false;
83
+ return false
84
84
  end
85
-
85
+
86
86
  urlPart = UrlValidatorHelper.getUrlPart(triggerPart["UrlPart"], url)
87
87
 
88
88
  return ComparisonOperatorHelper.evaluate(
@@ -90,7 +90,8 @@ module QueueIt
90
90
  triggerPart["IsNegative"],
91
91
  triggerPart["IsIgnoreCase"],
92
92
  urlPart,
93
- triggerPart["ValueToCompare"])
93
+ triggerPart["ValueToCompare"],
94
+ triggerPart["ValuesToCompare"])
94
95
  end
95
96
 
96
97
  def self.getUrlPart(urlPart, url)
@@ -115,12 +116,12 @@ module QueueIt
115
116
  class CookieValidatorHelper
116
117
  def self.evaluate(triggerPart, cookieJar)
117
118
  begin
118
- if (!triggerPart.key?("Operator") ||
119
+ if (triggerPart.nil? ||
120
+ !triggerPart.key?("Operator") ||
119
121
  !triggerPart.key?("IsNegative") ||
120
122
  !triggerPart.key?("IsIgnoreCase") ||
121
- !triggerPart.key?("ValueToCompare") ||
122
123
  !triggerPart.key?("CookieName"))
123
- return false;
124
+ return false
124
125
  end
125
126
 
126
127
  if(cookieJar.nil?)
@@ -137,7 +138,8 @@ module QueueIt
137
138
  triggerPart["IsNegative"],
138
139
  triggerPart["IsIgnoreCase"],
139
140
  cookieValue,
140
- triggerPart["ValueToCompare"])
141
+ triggerPart["ValueToCompare"],
142
+ triggerPart["ValuesToCompare"])
141
143
  rescue
142
144
  return false
143
145
  end
@@ -147,33 +149,43 @@ module QueueIt
147
149
  class UserAgentValidatorHelper
148
150
  def self.evaluate(triggerPart, userAgent)
149
151
  begin
150
- if (!triggerPart.key?("Operator") ||
152
+ if (triggerPart.nil? ||
153
+ !triggerPart.key?("Operator") ||
151
154
  !triggerPart.key?("IsNegative") ||
152
- !triggerPart.key?("IsIgnoreCase") ||
153
- !triggerPart.key?("ValueToCompare"))
154
- return false;
155
+ !triggerPart.key?("IsIgnoreCase"))
156
+ return false
155
157
  end
156
-
158
+
157
159
  return ComparisonOperatorHelper.evaluate(
158
160
  triggerPart["Operator"],
159
161
  triggerPart["IsNegative"],
160
162
  triggerPart["IsIgnoreCase"],
161
163
  userAgent,
162
- triggerPart["ValueToCompare"])
164
+ triggerPart["ValueToCompare"],
165
+ triggerPart["ValuesToCompare"])
163
166
  end
164
167
  end
165
168
  end
166
169
 
167
170
  class HttpHeaderValidatorHelper
168
171
  def self.evaluate(triggerPart, headers)
169
- begin
172
+ begin
173
+ if (triggerPart.nil? ||
174
+ !triggerPart.key?("Operator") ||
175
+ !triggerPart.key?("IsNegative") ||
176
+ !triggerPart.key?("IsIgnoreCase")
177
+ !triggerPart.key?("HttpHeaderName"))
178
+ return false
179
+ end
180
+
170
181
  headerValue = headers[triggerPart['HttpHeaderName']]
171
182
  return ComparisonOperatorHelper.evaluate(
172
183
  triggerPart["Operator"],
173
184
  triggerPart["IsNegative"],
174
185
  triggerPart["IsIgnoreCase"],
175
186
  headerValue,
176
- triggerPart["ValueToCompare"])
187
+ triggerPart["ValueToCompare"],
188
+ triggerPart["ValuesToCompare"])
177
189
  rescue
178
190
  return false
179
191
  end
@@ -181,35 +193,38 @@ module QueueIt
181
193
  end
182
194
 
183
195
  class ComparisonOperatorHelper
184
- def self.evaluate(opt, isNegative, ignoreCase, left, right)
185
- if(left.nil?)
186
- left = ''
196
+ def self.evaluate(opt, isNegative, ignoreCase, value, valueToCompare, valuesToCompare)
197
+ if (value.nil?)
198
+ value = ''
199
+ end
200
+
201
+ if (valueToCompare.nil?)
202
+ valueToCompare = ''
187
203
  end
188
- if(right.nil?)
189
- right = ''
204
+
205
+ if (valuesToCompare.nil?)
206
+ valuesToCompare = []
190
207
  end
191
208
 
192
209
  case opt
193
210
  when "Equals"
194
- return ComparisonOperatorHelper.equals(left, right, isNegative, ignoreCase)
211
+ return ComparisonOperatorHelper.equals(value, valueToCompare, isNegative, ignoreCase)
195
212
  when "Contains"
196
- return ComparisonOperatorHelper.contains(left, right, isNegative, ignoreCase)
197
- when "StartsWith"
198
- return ComparisonOperatorHelper.startsWith(left, right, isNegative, ignoreCase)
199
- when "EndsWith"
200
- return ComparisonOperatorHelper.endsWith(left, right, isNegative, ignoreCase)
201
- when "MatchesWith"
202
- return ComparisonOperatorHelper.matchesWith(left, right, isNegative, ignoreCase)
213
+ return ComparisonOperatorHelper.contains(value, valueToCompare, isNegative, ignoreCase)
214
+ when "EqualsAny"
215
+ return ComparisonOperatorHelper.equalsAny(value, valuesToCompare, isNegative, ignoreCase)
216
+ when "ContainsAny"
217
+ return ComparisonOperatorHelper.containsAny(value, valuesToCompare, isNegative, ignoreCase)
203
218
  else
204
219
  return false
205
220
  end
206
221
  end
207
222
 
208
- def self.equals(left, right, isNegative, ignoreCase)
223
+ def self.equals(value, valueToCompare, isNegative, ignoreCase)
209
224
  if(ignoreCase)
210
- evaluation = left.upcase.eql? right.upcase
225
+ evaluation = value.upcase.eql? valueToCompare.upcase
211
226
  else
212
- evaluation = left.eql? right
227
+ evaluation = value.eql? valueToCompare
213
228
  end
214
229
 
215
230
  if(isNegative)
@@ -219,31 +234,17 @@ module QueueIt
219
234
  end
220
235
  end
221
236
 
222
- def self.contains(left, right, isNegative, ignoreCase)
223
- if(right.eql? "*")
237
+ def self.contains(value, valueToCompare, isNegative, ignoreCase)
238
+ if((valueToCompare.eql? "*") && !(value.empty? || value.nil?))
224
239
  return true
225
240
  end
226
241
 
227
242
  if(ignoreCase)
228
- left = left.upcase
229
- right = right.upcase
230
- end
231
-
232
- evaluation = left.include? right
233
- if(isNegative)
234
- return !evaluation
235
- else
236
- return evaluation
237
- end
238
- end
239
-
240
- def self.startsWith(left, right, isNegative, ignoreCase)
241
- if(ignoreCase)
242
- evaluation = left.upcase.start_with? right.upcase
243
- else
244
- evaluation = left.start_with? right
243
+ value = value.upcase
244
+ valueToCompare = valueToCompare.upcase
245
245
  end
246
246
 
247
+ evaluation = value.include? valueToCompare
247
248
  if(isNegative)
248
249
  return !evaluation
249
250
  else
@@ -251,33 +252,22 @@ module QueueIt
251
252
  end
252
253
  end
253
254
 
254
- def self.endsWith(left, right, isNegative, ignoreCase)
255
- if(ignoreCase)
256
- evaluation = left.upcase.end_with? right.upcase
257
- else
258
- evaluation = left.end_with? right
259
- end
260
-
261
- if(isNegative)
262
- return !evaluation
263
- else
264
- return evaluation
255
+ def self.equalsAny(value, valuesToCompare, isNegative, ignoreCase)
256
+ valuesToCompare.each do |valueToCompare|
257
+ if (ComparisonOperatorHelper.equals(value, valueToCompare, false, ignoreCase))
258
+ return !isNegative
259
+ end
265
260
  end
261
+ return isNegative
266
262
  end
267
263
 
268
- def self.matchesWith(left, right, isNegative, ignoreCase)
269
- if(ignoreCase)
270
- pattern = Regexp.new(right, Regexp::IGNORECASE)
271
- else
272
- pattern = Regexp.new(right)
273
- end
274
-
275
- evaluation = pattern.match(left) != nil
276
- if(isNegative)
277
- return !evaluation
278
- else
279
- return evaluation
264
+ def self.containsAny(value, valuesToCompare, isNegative, ignoreCase)
265
+ valuesToCompare.each do |valueToCompare|
266
+ if (ComparisonOperatorHelper.contains(value, valueToCompare, false, ignoreCase))
267
+ return !isNegative
268
+ end
280
269
  end
270
+ return isNegative
281
271
  end
282
272
  end
283
273
  end
@@ -1,9 +1,11 @@
1
+ require 'cgi'
1
2
  require 'json'
2
3
 
3
4
  module QueueIt
4
5
  class KnownUser
5
6
  QUEUEIT_TOKEN_KEY = "queueittoken"
6
7
  QUEUEIT_DEBUG_KEY = "queueitdebug"
8
+ QUEUEIT_AJAX_HEADER_KEY = "x-queueit-ajaxpageurl"
7
9
 
8
10
  @@userInQueueService = nil
9
11
  def self.getUserInQueueService(cookieJar)
@@ -15,6 +17,19 @@ module QueueIt
15
17
  end
16
18
  private_class_method :getUserInQueueService
17
19
 
20
+ def self.isQueueAjaxCall(request)
21
+ return request.headers[QUEUEIT_AJAX_HEADER_KEY] != nil
22
+ end
23
+ private_class_method :isQueueAjaxCall
24
+
25
+ def self.generateTargetUrl(originalTargetUrl, request)
26
+ unless isQueueAjaxCall(request)
27
+ return originalTargetUrl
28
+ end
29
+ return CGI::unescape(request.headers[QUEUEIT_AJAX_HEADER_KEY])
30
+ end
31
+ private_class_method :generateTargetUrl
32
+
18
33
  def self.convertToInt(value)
19
34
  begin
20
35
  converted = Integer(value)
@@ -25,25 +40,16 @@ module QueueIt
25
40
  end
26
41
  private_class_method :convertToInt
27
42
 
28
- def self.getIsDebug(queueitToken, secretKey)
29
- qParams = QueueUrlParams.extractQueueParams(queueitToken)
30
- if(qParams == nil)
31
- return false
32
- end
33
-
34
- redirectType = qParams.redirectType
35
- if(redirectType == nil)
36
- return false
37
- end
38
-
39
- if (redirectType.upcase.eql?("DEBUG"))
40
- calculatedHash = OpenSSL::HMAC.hexdigest('sha256', secretKey, qParams.queueITTokenWithoutHash)
41
- valid = qParams.hashCode.eql?(calculatedHash)
42
- return valid
43
- end
44
- return false
43
+ def self.logMoreRequestDetails(debugEntries, request)
44
+ debugEntries["ServerUtcTime"] = Time.now.utc.iso8601
45
+ debugEntries["RequestIP"] = request.remote_ip
46
+ debugEntries["RequestHttpHeader_Via"] = request.headers["via"]
47
+ debugEntries["RequestHttpHeader_Forwarded"] = request.headers["forwarded"]
48
+ debugEntries["RequestHttpHeader_XForwardedFor"] = request.headers["x-forwarded-for"]
49
+ debugEntries["RequestHttpHeader_XForwardedHost"] = request.headers["x-forwarded-host"]
50
+ debugEntries["RequestHttpHeader_XForwardedProto"] = request.headers["x-forwarded-proto"]
45
51
  end
46
- private_class_method :getIsDebug
52
+ private_class_method :logMoreRequestDetails
47
53
 
48
54
  def self.setDebugCookie(debugEntries, cookieJar)
49
55
  if(debugEntries == nil || debugEntries.length == 0)
@@ -60,17 +66,20 @@ module QueueIt
60
66
  end
61
67
  private_class_method :setDebugCookie
62
68
 
63
- def self._resolveQueueRequestByLocalConfig(targetUrl, queueitToken, queueConfig, customerId, secretKey, request, debugEntries)
64
- isDebug = getIsDebug(queueitToken, secretKey)
69
+ def self._resolveQueueRequestByLocalConfig(targetUrl, queueitToken, queueConfig, customerId, secretKey, request, debugEntries, isDebug)
70
+
65
71
  if(isDebug)
72
+ debugEntries["SdkVersion"] = UserInQueueService::SDK_VERSION
73
+ debugEntries["Runtime"] = getRuntime()
66
74
  debugEntries["TargetUrl"] = targetUrl
67
75
  debugEntries["QueueitToken"] = queueitToken
68
- debugEntries["OriginalUrl"] = request.original_url
76
+ debugEntries["OriginalUrl"] = getRealOriginalUrl(request)
69
77
  if(queueConfig == nil)
70
78
  debugEntries["QueueConfig"] = "NULL"
71
79
  else
72
80
  debugEntries["QueueConfig"] = queueConfig.toString()
73
81
  end
82
+ logMoreRequestDetails(debugEntries, request)
74
83
  end
75
84
 
76
85
  if(Utils.isNilOrEmpty(customerId))
@@ -103,21 +112,28 @@ module QueueIt
103
112
  end
104
113
 
105
114
  userInQueueService = getUserInQueueService(request.cookie_jar)
106
- userInQueueService.validateQueueRequest(targetUrl, queueitToken, queueConfig, customerId, secretKey)
115
+ result = userInQueueService.validateQueueRequest(targetUrl, queueitToken, queueConfig, customerId, secretKey)
116
+ result.isAjaxResult = isQueueAjaxCall(request)
117
+
118
+ return result
107
119
  end
108
120
  private_class_method :_resolveQueueRequestByLocalConfig
109
121
 
110
- def self._cancelRequestByLocalConfig(targetUrl, queueitToken, cancelConfig, customerId, secretKey, request, debugEntries)
111
- isDebug = getIsDebug(queueitToken, secretKey)
122
+ def self._cancelRequestByLocalConfig(targetUrl, queueitToken, cancelConfig, customerId, secretKey, request, debugEntries, isDebug)
123
+ targetUrl = generateTargetUrl(targetUrl, request)
124
+
112
125
  if(isDebug)
126
+ debugEntries["SdkVersion"] = UserInQueueService::SDK_VERSION
127
+ debugEntries["Runtime"] = getRuntime()
113
128
  debugEntries["TargetUrl"] = targetUrl
114
129
  debugEntries["QueueitToken"] = queueitToken
115
- debugEntries["OriginalUrl"] = request.original_url
130
+ debugEntries["OriginalUrl"] = getRealOriginalUrl(request)
116
131
  if(cancelConfig == nil)
117
132
  debugEntries["CancelConfig"] = "NULL"
118
133
  else
119
134
  debugEntries["CancelConfig"] = cancelConfig.toString()
120
135
  end
136
+ logMoreRequestDetails(debugEntries, request)
121
137
  end
122
138
 
123
139
  if(Utils.isNilOrEmpty(targetUrl))
@@ -145,7 +161,10 @@ module QueueIt
145
161
  end
146
162
 
147
163
  userInQueueService = getUserInQueueService(request.cookie_jar)
148
- userInQueueService.validateCancelRequest(targetUrl, cancelConfig, customerId, secretKey)
164
+ result = userInQueueService.validateCancelRequest(targetUrl, cancelConfig, customerId, secretKey)
165
+ result.isAjaxResult = isQueueAjaxCall(request)
166
+
167
+ return result
149
168
  end
150
169
  private_class_method :_cancelRequestByLocalConfig
151
170
 
@@ -169,38 +188,64 @@ module QueueIt
169
188
 
170
189
  def self.resolveQueueRequestByLocalConfig(targetUrl, queueitToken, queueConfig, customerId, secretKey, request)
171
190
  debugEntries = Hash.new
191
+ connectorDiagnostics = ConnectorDiagnostics.verify(customerId, secretKey, queueitToken)
192
+
193
+ if(connectorDiagnostics.hasError)
194
+ return connectorDiagnostics.validationResult
195
+ end
172
196
  begin
173
- return _resolveQueueRequestByLocalConfig(targetUrl, queueitToken, queueConfig, customerId, secretKey, request, debugEntries)
197
+ targetUrl = generateTargetUrl(targetUrl, request)
198
+ return _resolveQueueRequestByLocalConfig(targetUrl, queueitToken, queueConfig, customerId, secretKey, request, debugEntries, connectorDiagnostics.isEnabled)
199
+ rescue Exception => e
200
+ if(connectorDiagnostics.isEnabled)
201
+ debugEntries["Exception"] = e.message
202
+ end
203
+ raise e
174
204
  ensure
175
205
  setDebugCookie(debugEntries, request.cookie_jar)
176
206
  end
177
207
  end
178
208
 
179
- def self.validateRequestByIntegrationConfig(currentUrlWithoutQueueITToken, queueitToken, integrationsConfigString, customerId, secretKey, request)
180
- if(Utils.isNilOrEmpty(currentUrlWithoutQueueITToken))
181
- raise KnownUserError, "currentUrlWithoutQueueITToken can not be nil or empty."
182
- end
183
-
184
- if(Utils.isNilOrEmpty(integrationsConfigString))
185
- raise KnownUserError, "integrationsConfigString can not be nil or empty."
209
+ def self.validateRequestByIntegrationConfig(currentUrlWithoutQueueITToken, queueitToken, integrationConfigJson, customerId, secretKey, request)
210
+ debugEntries = Hash.new
211
+ customerIntegration = Hash.new
212
+ connectorDiagnostics = ConnectorDiagnostics.verify(customerId, secretKey, queueitToken)
213
+
214
+ if(connectorDiagnostics.hasError)
215
+ return connectorDiagnostics.validationResult
186
216
  end
187
-
188
217
  begin
189
- customerIntegration = JSON.parse(integrationsConfigString)
190
-
191
- debugEntries = Hash.new
192
- isDebug = getIsDebug(queueitToken, secretKey)
193
- if(isDebug)
194
- debugEntries["ConfigVersion"] = customerIntegration["Version"]
218
+ if(connectorDiagnostics.isEnabled)
219
+ debugEntries["SdkVersion"] = UserInQueueService::SDK_VERSION
220
+ debugEntries["Runtime"] = getRuntime()
195
221
  debugEntries["PureUrl"] = currentUrlWithoutQueueITToken
196
222
  debugEntries["QueueitToken"] = queueitToken
197
- debugEntries["OriginalUrl"] = request.original_url
223
+ debugEntries["OriginalUrl"] = getRealOriginalUrl(request)
224
+ logMoreRequestDetails(debugEntries, request)
198
225
  end
199
-
226
+
227
+ customerIntegration = JSON.parse(integrationConfigJson)
228
+
229
+ if(connectorDiagnostics.isEnabled)
230
+ if(customerIntegration.length != 0 and customerIntegration["Version"] != nil)
231
+ debugEntries["ConfigVersion"] = customerIntegration["Version"]
232
+ else
233
+ debugEntries["ConfigVersion"] = "NULL"
234
+ end
235
+ end
236
+
237
+ if(Utils.isNilOrEmpty(currentUrlWithoutQueueITToken))
238
+ raise KnownUserError, "currentUrlWithoutQueueITToken can not be nil or empty."
239
+ end
240
+
241
+ if(customerIntegration.length == 0 || customerIntegration["Version"] == nil)
242
+ raise KnownUserError, "integrationConfigJson is not valid json."
243
+ end
244
+
200
245
  integrationEvaluator = IntegrationEvaluator.new
201
246
  matchedConfig = integrationEvaluator.getMatchedIntegrationConfig(customerIntegration, currentUrlWithoutQueueITToken, request)
202
247
 
203
- if(isDebug)
248
+ if(connectorDiagnostics.isEnabled)
204
249
  if(matchedConfig == nil)
205
250
  debugEntries["MatchedConfig"] = "NULL"
206
251
  else
@@ -209,55 +254,99 @@ module QueueIt
209
254
  end
210
255
 
211
256
  if(matchedConfig == nil)
212
- return RequestValidationResult.new(nil, nil, nil, nil)
257
+ return RequestValidationResult.new(nil, nil, nil, nil, nil, nil)
213
258
  end
214
259
 
260
+ # unspecified or 'Queue' specified
215
261
  if(!matchedConfig.key?("ActionType") || Utils.isNilOrEmpty(matchedConfig["ActionType"]) || matchedConfig["ActionType"].eql?(ActionTypes::QUEUE))
216
- queueConfig = QueueEventConfig.new
217
- queueConfig.eventId = matchedConfig["EventId"]
218
- queueConfig.queueDomain = matchedConfig["QueueDomain"]
219
- queueConfig.layoutName = matchedConfig["LayoutName"]
220
- queueConfig.culture = matchedConfig["Culture"]
221
- queueConfig.cookieDomain = matchedConfig["CookieDomain"]
222
- queueConfig.extendCookieValidity = matchedConfig["ExtendCookieValidity"]
223
- queueConfig.cookieValidityMinute = matchedConfig["CookieValidityMinute"]
224
- queueConfig.version = customerIntegration["Version"]
225
-
226
- case matchedConfig["RedirectLogic"]
227
- when "ForcedTargetUrl"
228
- targetUrl = matchedConfig["ForcedTargetUrl"]
229
- when "EventTargetUrl"
230
- targetUrl = ''
231
- else
232
- targetUrl = currentUrlWithoutQueueITToken
233
- end
234
-
235
- return _resolveQueueRequestByLocalConfig(targetUrl, queueitToken, queueConfig, customerId, secretKey, request, debugEntries)
236
-
237
- else # cancel action
238
- cancelConfig = CancelEventConfig.new;
239
- cancelConfig.eventId = matchedConfig["EventId"]
240
- cancelConfig.queueDomain = matchedConfig["QueueDomain"]
241
- cancelConfig.cookieDomain = matchedConfig["CookieDomain"]
242
- cancelConfig.version = customerIntegration["Version"]
243
-
244
- return _cancelRequestByLocalConfig(currentUrlWithoutQueueITToken, queueitToken, cancelConfig, customerId, secretKey, request, debugEntries);
262
+ return handleQueueAction(currentUrlWithoutQueueITToken, queueitToken, customerIntegration,
263
+ customerId, secretKey, matchedConfig, request, debugEntries, connectorDiagnostics.isEnabled)
264
+
265
+ elsif(matchedConfig["ActionType"].eql?(ActionTypes::CANCEL))
266
+ return handleCancelAction(currentUrlWithoutQueueITToken, queueitToken, customerIntegration,
267
+ customerId, secretKey, matchedConfig, request, debugEntries, connectorDiagnostics.isEnabled)
268
+
269
+ # for all unknown types default to 'Ignore'
270
+ else
271
+ userInQueueService = getUserInQueueService(request.cookie_jar)
272
+ result = userInQueueService.getIgnoreActionResult(matchedConfig["Name"])
273
+ result.isAjaxResult = isQueueAjaxCall(request)
274
+
275
+ return result
276
+ end
277
+ rescue Exception => e
278
+ if(connectorDiagnostics.isEnabled)
279
+ debugEntries["Exception"] = e.message
245
280
  end
246
- rescue StandardError => stdErr
247
- raise KnownUserError, "integrationConfiguration text was not valid: " + stdErr.message
281
+ raise e
248
282
  ensure
249
283
  setDebugCookie(debugEntries, request.cookie_jar)
250
284
  end
251
285
  end
252
286
 
287
+ def self.handleQueueAction(currentUrlWithoutQueueITToken, queueitToken, customerIntegration, customerId, secretKey, matchedConfig, request, debugEntries, isDebug)
288
+ queueConfig = QueueEventConfig.new
289
+ queueConfig.eventId = matchedConfig["EventId"]
290
+ queueConfig.queueDomain = matchedConfig["QueueDomain"]
291
+ queueConfig.layoutName = matchedConfig["LayoutName"]
292
+ queueConfig.culture = matchedConfig["Culture"]
293
+ queueConfig.cookieDomain = matchedConfig["CookieDomain"]
294
+ queueConfig.extendCookieValidity = matchedConfig["ExtendCookieValidity"]
295
+ queueConfig.cookieValidityMinute = matchedConfig["CookieValidityMinute"]
296
+ queueConfig.version = customerIntegration["Version"]
297
+ queueConfig.actionName = matchedConfig["Name"]
298
+
299
+ case matchedConfig["RedirectLogic"]
300
+ when "ForcedTargetUrl"
301
+ targetUrl = matchedConfig["ForcedTargetUrl"]
302
+ when "EventTargetUrl"
303
+ targetUrl = ''
304
+ else
305
+ targetUrl = generateTargetUrl(currentUrlWithoutQueueITToken, request)
306
+ end
307
+
308
+ return _resolveQueueRequestByLocalConfig(targetUrl, queueitToken, queueConfig, customerId, secretKey, request, debugEntries, isDebug)
309
+ end
310
+
311
+ def self.handleCancelAction(currentUrlWithoutQueueITToken, queueitToken, customerIntegration, customerId, secretKey, matchedConfig, request, debugEntries, isDebug)
312
+ cancelConfig = CancelEventConfig.new
313
+ cancelConfig.eventId = matchedConfig["EventId"]
314
+ cancelConfig.queueDomain = matchedConfig["QueueDomain"]
315
+ cancelConfig.cookieDomain = matchedConfig["CookieDomain"]
316
+ cancelConfig.version = customerIntegration["Version"]
317
+ cancelConfig.actionName = matchedConfig["Name"]
318
+
319
+ return _cancelRequestByLocalConfig(currentUrlWithoutQueueITToken, queueitToken, cancelConfig, customerId, secretKey, request, debugEntries, isDebug)
320
+ end
321
+
253
322
  def self.cancelRequestByLocalConfig(targetUrl, queueitToken, cancelConfig, customerId, secretKey, request)
254
323
  debugEntries = Hash.new
324
+ connectorDiagnostics = ConnectorDiagnostics.verify(customerId, secretKey, queueitToken)
325
+
326
+ if(connectorDiagnostics.hasError)
327
+ return connectorDiagnostics.validationResult
328
+ end
255
329
  begin
256
- return _cancelRequestByLocalConfig(targetUrl, queueitToken, cancelConfig, customerId, secretKey, request, debugEntries)
330
+ return _cancelRequestByLocalConfig(targetUrl, queueitToken, cancelConfig, customerId, secretKey, request, debugEntries, connectorDiagnostics.isEnabled)
331
+ rescue Exception => e
332
+ if(connectorDiagnostics.isEnabled)
333
+ debugEntries["Exception"] = e.message
334
+ end
335
+ raise e
257
336
  ensure
258
337
  setDebugCookie(debugEntries, request.cookie_jar)
259
338
  end
260
339
  end
340
+
341
+ def self.getRealOriginalUrl(request)
342
+ # RoR could modify request.original_url if request contains x-forwarded-host/proto http headers.
343
+ # Therefore we need this method to be able to access the 'real' original url.
344
+ return request.env["rack.url_scheme"] + "://" + request.env["HTTP_HOST"] + request.original_fullpath
345
+ end
346
+
347
+ def self.getRuntime()
348
+ return RUBY_VERSION.to_s
349
+ end
261
350
  end
262
351
 
263
352
  class CookieManager
@@ -286,9 +375,9 @@ module QueueIt
286
375
  @cookies.delete(key)
287
376
  else
288
377
  if(noExpire)
289
- @cookies[key] = { :value => value }
378
+ @cookies[key] = { :value => value, :httponly => false }
290
379
  else
291
- @cookies[key] = { :value => value, :expires => expire }
380
+ @cookies[key] = { :value => value, :expires => expire, :httponly => false }
292
381
  end
293
382
  end
294
383
  else
@@ -296,9 +385,9 @@ module QueueIt
296
385
  @cookies.delete(key, :domain => domain)
297
386
  else
298
387
  if(noExpire)
299
- @cookies[key] = { :value => value, :domain => domain }
388
+ @cookies[key] = { :value => value, :domain => domain, :httponly => false }
300
389
  else
301
- @cookies[key] = { :value => value, :expires => expire, :domain => domain }
390
+ @cookies[key] = { :value => value, :expires => expire, :domain => domain, :httponly => false }
302
391
  end
303
392
  end
304
393
  end