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

Refactor JWKs related tests #215

Merged
merged 2 commits into from
May 7, 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
2 changes: 1 addition & 1 deletion .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ jobs:
env:
packageUser: ${{ github.actor }}
packagePAT: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew.bat build
run: ./gradlew.bat test
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ This repository only contains the source code for the module.
export packagePAT=<Personal Access Token>
```

3. Download and install [Docker](https://www.docker.com/).

### Building the Source

Execute the commands below to build from the source.
Expand Down
62 changes: 62 additions & 0 deletions jwt-ballerina/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,14 @@ task initializeVariables {
needPublishToCentral = true
}

// This check is added to disable the 'jwks' group tests in Windows OS since the Docker image does not support
// for Windows OS.
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
if (disableGroups == "") {
disableGroups = "--disable-groups"
}
disableGroups += " jwks"
}
gradle.taskGraph.whenReady { graph ->
if (graph.hasTask(":${packageName}-ballerina:build") || graph.hasTask(":${packageName}-ballerina:publish") ||
graph.hasTask(":${packageName}-ballerina:publishToMavenLocal")) {
Expand Down Expand Up @@ -299,11 +307,65 @@ publishing {
}
}

task startBallerinaSTS() {
doLast {
// This check is added to prevent starting the server in Windows OS, since the Docker image does not support
// for Windows OS.
if (!Os.isFamily(Os.FAMILY_WINDOWS)) {
def stdOut = new ByteArrayOutputStream()
exec {
commandLine 'sh', '-c', "docker ps --filter name=ballerina-sts"
standardOutput = stdOut
}
if (!stdOut.toString().contains("ballerina-sts")) {
println "Starting Ballerina STS."
exec {
commandLine 'sh', '-c', "docker run --rm -d -p 9445:9445 --name ballerina-sts ldclakmal/ballerina-sts:latest"
standardOutput = stdOut
}
println stdOut.toString()
println "Waiting 10s until the Ballerina STS get initiated."
sleep(10 * 1000)
} else {
println "Ballerina STS is already started."
}
}
}
}

task stopBallerinaSTS() {
doLast {
// This check is added to prevent trying to stop the server in Windows OS, since the Docker image not started
// in Windows OS.
if (!Os.isFamily(Os.FAMILY_WINDOWS)) {
def stdOut = new ByteArrayOutputStream()
exec {
commandLine 'sh', '-c', "docker ps --filter name=ballerina-sts"
standardOutput = stdOut
}
if (stdOut.toString().contains("ballerina-sts")) {
println "Stopping Ballerina STS."
exec {
commandLine 'sh', '-c', "docker stop ballerina-sts"
standardOutput = stdOut
}
println stdOut.toString()
println "Waiting 15s until the Ballerina STS get stopped."
sleep(15 * 1000)
} else {
println "Ballerina STS is not started."
}
}
}
}

unpackStdLibs.dependsOn unpackJballerinaTools
copyStdlibs.dependsOn unpackStdLibs
updateTomlVersions.dependsOn copyStdlibs

ballerinaBuild.finalizedBy revertTomlFile
ballerinaBuild.finalizedBy stopBallerinaSTS
ballerinaBuild.dependsOn startBallerinaSTS
ballerinaBuild.dependsOn initializeVariables
ballerinaBuild.dependsOn updateTomlVersions
ballerinaBuild.dependsOn ":${packageName}-native:build"
Expand Down
123 changes: 80 additions & 43 deletions jwt-ballerina/tests/jwt_validator_test.bal
Original file line number Diff line number Diff line change
Expand Up @@ -141,32 +141,37 @@ isolated function testValidateJwtWithInvalidSignature() {
}
}

@test:Config {}
isolated function testValidateJwtSignatureWithJwk() {
@test:Config {
groups: ["jwks"]
}
isolated function testValidateJwtSignatureWithJwkWithoutSecureSocket() {
ValidatorConfig validatorConfig = {
issuer: "ballerina",
audience: "vEwzbcasJVQm1jVYHUHCjhxZ4tYa",
signatureConfig: {
jwksConfig: {
url: "https://asb0zigfg2.execute-api.us-west-2.amazonaws.com/v1/jwks"
url: "https://localhost:9445/oauth2/jwks"
}
}
};
Payload|Error result = validate(JWT2, validatorConfig);
if (result is Error) {
string? errMsg = result.message();
test:assertFail(msg = errMsg is string ? errMsg : "Error in validating JWT.");
assertContains(result, "Failed to send the request to the endpoint. PKIX path building failed:");
} else {
test:assertFail(msg = "Error in validating JWT.");
}
}

@test:Config {}
@test:Config {
groups: ["jwks"]
}
isolated function testValidateJwtSignatureWithJwkWithSslDisabled() {
ValidatorConfig validatorConfig = {
issuer: "ballerina",
audience: "vEwzbcasJVQm1jVYHUHCjhxZ4tYa",
signatureConfig: {
jwksConfig: {
url: "https://asb0zigfg2.execute-api.us-west-2.amazonaws.com/v1/jwks",
url: "https://localhost:9445/oauth2/jwks",
clientConfig: {
httpVersion: HTTP_2,
secureSocket: {
Expand All @@ -183,14 +188,16 @@ isolated function testValidateJwtSignatureWithJwkWithSslDisabled() {
}
}

@test:Config {}
@test:Config {
groups: ["jwks"]
}
isolated function testValidateJwtSignatureWithJwkWithEmptySecureSocket() {
ValidatorConfig validatorConfig = {
issuer: "ballerina",
audience: "vEwzbcasJVQm1jVYHUHCjhxZ4tYa",
signatureConfig: {
jwksConfig: {
url: "https://asb0zigfg2.execute-api.us-west-2.amazonaws.com/v1/jwks",
url: "https://localhost:9445/oauth2/jwks",
clientConfig: {
httpVersion: HTTP_2,
secureSocket: {
Expand All @@ -207,14 +214,16 @@ isolated function testValidateJwtSignatureWithJwkWithEmptySecureSocket() {
}
}

@test:Config {}
@test:Config {
groups: ["jwks"]
}
isolated function testValidateJwtSignatureWithJwkWithValidTrustStore() {
ValidatorConfig validatorConfig = {
issuer: "ballerina",
audience: "vEwzbcasJVQm1jVYHUHCjhxZ4tYa",
signatureConfig: {
jwksConfig: {
url: "https://asb0zigfg2.execute-api.us-west-2.amazonaws.com/v1/jwks",
url: "https://localhost:9445/oauth2/jwks",
clientConfig: {
httpVersion: HTTP_2,
secureSocket: {
Expand All @@ -234,25 +243,20 @@ isolated function testValidateJwtSignatureWithJwkWithValidTrustStore() {
}
}

@test:Config {}
isolated function testValidateJwtSignatureWithJwkWithValidTrustStoreAndValidKeyStore() {
@test:Config {
groups: ["jwks"]
}
isolated function testValidateJwtSignatureWithJwkWithValidCert() {
ValidatorConfig validatorConfig = {
issuer: "ballerina",
audience: "vEwzbcasJVQm1jVYHUHCjhxZ4tYa",
signatureConfig: {
jwksConfig: {
url: "https://asb0zigfg2.execute-api.us-west-2.amazonaws.com/v1/jwks",
url: "https://localhost:9445/oauth2/jwks",
clientConfig: {
httpVersion: HTTP_2,
secureSocket: {
cert: {
path: TRUSTSTORE_PATH,
password: "ballerina"
},
key: {
path: KEYSTORE_PATH,
password: "ballerina"
}
cert: PUBLIC_CERT_PATH
}
}
}
Expand All @@ -265,14 +269,43 @@ isolated function testValidateJwtSignatureWithJwkWithValidTrustStoreAndValidKeyS
}
}

@test:Config {}
isolated function testValidateJwtSignatureWithJwkWithValidTrustStoreAndValidCertAndKey() {
@test:Config {
groups: ["jwks"]
}
isolated function testValidateJwtSignatureWithJwkWithInvalidCert() {
ValidatorConfig validatorConfig = {
issuer: "ballerina",
audience: "vEwzbcasJVQm1jVYHUHCjhxZ4tYa",
signatureConfig: {
jwksConfig: {
url: "https://asb0zigfg2.execute-api.us-west-2.amazonaws.com/v1/jwks",
url: "https://localhost:9445/oauth2/jwks",
clientConfig: {
httpVersion: HTTP_2,
secureSocket: {
cert: INVALID_PUBLIC_CERT_PATH
}
}
}
}
};
Payload|Error result = validate(JWT2, validatorConfig);
if (result is Error) {
assertContains(result, "Failed to send the request to the endpoint. PKIX path building failed:");
} else {
test:assertFail(msg = "Error in validating JWT.");
}
}

@test:Config {
groups: ["jwks"]
}
isolated function testValidateJwtSignatureWithJwkWithValidTrustStoreAndValidKeyStore() {
ValidatorConfig validatorConfig = {
issuer: "ballerina",
audience: "vEwzbcasJVQm1jVYHUHCjhxZ4tYa",
signatureConfig: {
jwksConfig: {
url: "https://localhost:9445/oauth2/jwks",
clientConfig: {
httpVersion: HTTP_2,
secureSocket: {
Expand All @@ -281,8 +314,8 @@ isolated function testValidateJwtSignatureWithJwkWithValidTrustStoreAndValidCert
password: "ballerina"
},
key: {
certFile: PUBLIC_CERT_PATH,
keyFile: PRIVATE_KEY_PATH
path: KEYSTORE_PATH,
password: "ballerina"
}
}
}
Expand All @@ -296,25 +329,23 @@ isolated function testValidateJwtSignatureWithJwkWithValidTrustStoreAndValidCert
}
}

@test:Config {}
isolated function testValidateJwtSignatureWithJwkWithValidTrustStoreAndValidCertAndEncryptedKey() {
@test:Config {
groups: ["jwks"]
}
isolated function testValidateJwtSignatureWithJwkWithValidCertsAndKey() {
ValidatorConfig validatorConfig = {
issuer: "ballerina",
audience: "vEwzbcasJVQm1jVYHUHCjhxZ4tYa",
signatureConfig: {
jwksConfig: {
url: "https://asb0zigfg2.execute-api.us-west-2.amazonaws.com/v1/jwks",
url: "https://localhost:9445/oauth2/jwks",
clientConfig: {
httpVersion: HTTP_2,
secureSocket: {
cert: {
path: TRUSTSTORE_PATH,
password: "ballerina"
},
cert: PUBLIC_CERT_PATH,
key: {
certFile: PUBLIC_CERT_PATH,
keyFile: ENCRYPTED_PRIVATE_KEY_PATH,
keyPassword: "ballerina"
keyFile: PRIVATE_KEY_PATH
}
}
}
Expand All @@ -328,28 +359,34 @@ isolated function testValidateJwtSignatureWithJwkWithValidTrustStoreAndValidCert
}
}

@test:Config {}
isolated function testValidateJwtSignatureWithJwkWithClientInvalidCertificate() {
@test:Config {
groups: ["jwks"]
}
isolated function testValidateJwtSignatureWithJwkWithValidCertsAndEncryptedKey() {
ValidatorConfig validatorConfig = {
issuer: "ballerina",
audience: "vEwzbcasJVQm1jVYHUHCjhxZ4tYa",
signatureConfig: {
jwksConfig: {
url: "https://asb0zigfg2.execute-api.us-west-2.amazonaws.com/v1/jwks",
url: "https://localhost:9445/oauth2/jwks",
clientConfig: {
httpVersion: HTTP_2,
secureSocket: {
cert: PUBLIC_CERT_PATH
cert: PUBLIC_CERT_PATH,
key: {
certFile: PUBLIC_CERT_PATH,
keyFile: ENCRYPTED_PRIVATE_KEY_PATH,
keyPassword: "ballerina"
}
}
}
}
}
};
Payload|Error result = validate(JWT2, validatorConfig);
if (result is Error) {
assertContains(result, "Failed to call JWKS endpoint 'https://asb0zigfg2.execute-api.us-west-2.amazonaws.com/v1/jwks'. Failed to send the request to the endpoint.");
} else {
test:assertFail(msg = "Error in validating JWT.");
string? errMsg = result.message();
test:assertFail(msg = errMsg is string ? errMsg : "Error in validating JWT.");
}
}

Expand Down
7 changes: 4 additions & 3 deletions jwt-ballerina/tests/listener_jwt_auth_provider_test.bal
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ isolated function testListenerJwtAuthProviderSuccess() {
}
}

@test:Config {}
@test:Config {
groups: ["jwks"]
}
isolated function testListenerJwtAuthProviderSuccessWithJwk() {
ValidatorConfig jwtConfig = {
issuer: "ballerina",
Expand All @@ -76,7 +78,7 @@ isolated function testListenerJwtAuthProviderSuccessWithJwk() {
},
signatureConfig: {
jwksConfig: {
url: "https://asb0zigfg2.execute-api.us-west-2.amazonaws.com/v1/jwks",
url: "https://localhost:9445/oauth2/jwks",
cacheConfig: {
capacity: 10,
evictionFactor: 0.25,
Expand All @@ -85,7 +87,6 @@ isolated function testListenerJwtAuthProviderSuccessWithJwk() {
cleanupInterval: 3600
},
clientConfig: {
httpVersion: HTTP_2,
secureSocket: {
cert: {
path: TRUSTSTORE_PATH,
Expand Down