Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds CORS filter and Functional test #1274

Merged
merged 1 commit into from
Sep 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Implements a WARequestFilter that adds support to handle CORS requests.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
methods
addAllowedMethod: httpMethod

self allowedMethods add: httpMethod


Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
headers
addAllowedMethodsHeadersTo: aResponse

self allowedMethods ifNotEmpty: [:allowed |
aResponse
headerAt: 'Access-Control-Allow-Methods'
put: (', ' join: allowed) ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
origins
addAllowedOrigin: originUrlString

self allowedOrigins add: originUrlString asString


Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
headers
addAllowedOriginHeadersTo: aResponse

self allowedOrigins ifNotEmpty: [ :allowed |
| allowedOrigin |
allowedOrigin := allowed first.
aResponse headerAt: 'Access-Control-Allow-Origin' put: allowedOrigin.
allowedOrigin = '*' ifFalse: [
aResponse headerAt: 'Vary' put: 'Origin' ] ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
headers
addCORSHeadersTo: response

self addAllowedOriginHeadersTo: response.
self addAllowedMethodsHeadersTo: response
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
headers
addExposedHeadersTo: aResponse

self exposedHeaders ifNotEmpty: [ :exposed |
aResponse
headerAt: 'Access-Control-Expose-Headers'
put: (', ' join: exposed) ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
origins
allowAnyOrigin

self addAllowedOrigin: '*'


Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
accessing
allowedHeaders: anObject

allowedHeaders := anObject
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
accessing
allowedHeaders

^allowedHeaders
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
accessing
allowedMethods: anObject

allowedMethods := anObject
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
accessing
allowedMethods

^allowedMethods
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
accessing
allowedOrigins: anObject

allowedOrigins := anObject
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
accessing
allowedOrigins

^allowedOrigins ifNil: [ allowedOrigins := OrderedCollection new ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
testing
allowsAnyOrigin

^self allowedOrigins anySatisfy: [ :origin | origin = '*' ]


Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
accessing
allowsCredentials: anObject

allowsCredentials := anObject
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
accessing
allowsCredentials

^ allowsCredentials
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
origins
denyAllOrigins

self allowedOrigins removeAll


Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
methods
explicitMethods

^#('GET' 'POST' 'HEAD')
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
accessing
exposedHeaders: anObject

exposedHeaders := anObject
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
accessing
exposedHeaders

^exposedHeaders
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
handling
handleCORSFiltered: aRequestContext

self addCORSHeadersTo: aRequestContext response.
super handleFiltered: aRequestContext.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
handling
handleCORSPreflight: aRequestContext

| response |
response := aRequestContext response.
self addCORSHeadersTo: response.
aRequestContext respond
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
handling
handleFiltered: aRequestContext

"Pass on the aRequestContext to the next filter or handler. Subclasses might override this method to customize the request and response handling."

(self isPreflight: aRequestContext request)
ifTrue: [ self handleCORSPreflight: aRequestContext ]
ifFalse: [
(self isCORS: aRequestContext request)
ifTrue: [ self handleCORSFiltered: aRequestContext ]
ifFalse: [ super handleFiltered: aRequestContext ]]
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
private
initialize

super initialize.
allowedOrigins := OrderedCollection new.
allowedHeaders := OrderedCollection new.
allowedMethods := OrderedCollection new.
exposedHeaders := OrderedCollection new.
allowsCredentials := false
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
testing
isCORS: aRequest

^ (aRequest headerAt: 'origin') notNil
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
testing
isPreflight: aRequest

^ aRequest method = 'OPTIONS' and: [ self isCORS: aRequest ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
methods
removeAllMethods

self allowedMethods removeAll
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
origins
removeAllowedOrigin: originUrlString

self allowedOrigins remove: originUrlString asString ifAbsent: [ ]


Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
methods
useExplicitMethods

self allowedMethods addAll: self explicitMethods
17 changes: 17 additions & 0 deletions repository/Seaside-Core.package/WACORSFilter.class/properties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"commentStamp" : "EstebanMaringolo 8/11/2021 10:50",
"super" : "WARequestFilter",
"category" : "Seaside-Core-Filter",
"classinstvars" : [ ],
"pools" : [ ],
"classvars" : [ ],
"instvars" : [
"allowedOrigins",
"allowedMethods",
"allowedHeaders",
"exposedHeaders",
"allowsCredentials"
],
"name" : "WACORSFilter",
"type" : "normal"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
copying
withoutResource

^ self copy
path: OrderedCollection new;
queryFields: nil;
fragment: nil;
yourself
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
tests-copy
testWithoutResource
| copy |
url addField: 'foo' value: 'bar'.
url scheme: 'http'.
url host: 'localhost'.
url port: 9000.

copy := url withoutResource.
url addToPath: 'zork'.
url addField: 'zork'.
self assert: url printString equals: 'http://localhost:9000/zork?foo=bar&zork'.
self assert: copy printString equals: 'http://localhost:9000/'
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
initialization
register
<script>

WAAdmin register: self asApplicationAt: 'corsTest'
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
accessing-urls
baseUrl

| parts url |
parts := self requestContext request host findTokens: ':'.
url := self requestContext request url withoutSeasideQueryFields
path: OrderedCollection new.

url host: parts first.
parts size > 1 ifTrue: [ url port: parts last asInteger ].

^ url
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
accessing-urls
buildDataUrlFor: host crossOrigin: crossOrigin

| port |
port := crossOrigin
ifTrue: [ WACORSResourceExample corsAdaptorPort ]
ifFalse: [WACORSResourceExample originAdaptorPort ].
^self baseUrl
port: port;
addToPath: 'tests';
addToPath: 'corsData';
addToPath: 'entries';
yourself
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
private
corsFilter

^ [
(WADispatcher default handlerAtAll: #( 'tests' 'corsData' ))
filters detect: [ :each | each isKindOf: WACORSFilter ] ]
on: Error
do: [ :ex | ex return: nil ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
accessing-urls
crossOriginDataUrl

| parts host crossOrigin |
parts := self requestContext request host findTokens: ':'.
host := parts first.
crossOrigin := parts last asInteger == WACORSResourceExample originAdaptorPort.
^ self buildDataUrlFor: host crossOrigin: crossOrigin
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
javascript
errorHandlerFunction

^(JSStream on: 'console.error(arguments[0])') , (JSStream on:
'document.getElementById("result").style.backgroundColor = "red"')
, (JSStream on:
'document.getElementById("result").innerHTML = "<p>Error</p>"')
asFunction: #( 'result' )
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
private
initialize

super initialize.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
accessing
originTextToUrlTable

^ OrderedDictionary
with: 'Same Origin' -> self sameOriginDataUrl
with: 'Cross Origin' -> self crossOriginDataUrl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
rendering
renderAdaptorSetupOn: html

html paragraph:
'This test needs to setup a separate Seaside server adaptor, to handle requests at a different host:port, in order to make requests cross-origin.'.

html form: [
html button
callback: [
WACORSResourceExample
register;
registerCorsAdaptor ];
with: 'Register CORS Server adaptor' ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
rendering-configuration
renderCORSFilterMethodsOn: html

html heading
level2;
with: 'Currently allowed Methods.'.
self corsFilter allowedMethods
ifEmpty: [ html text: 'None' ]
ifNotEmpty: [ :allowed | html unorderedList list: allowed ].

html form: [
html button
callback: [
self corsFilter
addAllowedMethod: 'DELETE' ];
with: 'Allow DELETE'.
html space.

html button
callback: [ self corsFilter removeAllMethods ];
with: 'Remove all methods' ]
Loading