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

Build execution #791

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
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
4 changes: 3 additions & 1 deletion .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ inputs:
java:
description: The Java version to use
required: false
default: 8.0.382-tem
default: 8.0.432-tem
gradle:
description: The Gradle version to use
required: false
Expand All @@ -23,6 +23,8 @@ runs:
curl -s "https://get.sdkman.io" | bash
source "/home/runner/.sdkman/bin/sdkman-init.sh"
sdk list java
sdk list kotlin
sdk list gradle
sdk install java ${{ inputs.java }} && sdk default java ${{ inputs.java }}
sdk install gradle ${{ inputs.gradle }} && sdk default gradle ${{ inputs.gradle }}
sdk install kotlin ${{ inputs.kotlin }} && sdk default kotlin ${{ inputs.kotlin }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ jobs:

- uses: ./.github/actions/setup

- run: ./gradlew clean test jacocoTestReport lint --continue --console=plain --max-workers=1 --no-daemon
- run: ./gradlew clean test jacocoTestReport lint --continue --console=plain --max-workers=1 --no-daemon --debug

- uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # [email protected]
6 changes: 3 additions & 3 deletions .snyk
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ ignore:
SNYK-JAVA-COMFASTERXMLWOODSTOX-3091135:
- '*':
reason: Latest version of dokka has this vulnerability
expires: 2024-12-31T12:54:23.000Z
expires: 2025-02-21T12:54:23.000Z
created: 2024-08-01T12:08:37.770Z
SNYK-JAVA-ORGJETBRAINSKOTLIN-2393744:
- '*':
reason: Latest version of dokka has this vulnerability
expires: 2024-12-31T12:54:23.000Z
expires: 2025-02-21T12:54:23.000Z
created: 2024-08-01T12:08:55.927Z
SNYK-JAVA-COMFASTERXMLJACKSONCORE-7569538:
- '*':
reason: Latest version of dokka has this vulnerability
expires: 2024-12-31T1:54:23.000Z
expires: 2025-02-21T1:54:23.000Z
created: 2024-08-01T12:08:02.973Z
patch: {}
1 change: 1 addition & 0 deletions auth0/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ android {
lintOptions {
htmlReport true
abortOnError true
checkReleaseBuilds false
}
testOptions {
unitTests {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
* ```
* client.signinWithPasskey("{authSession}", "{authResponse}","{realm}")
* .validateClaims() //mandatory
* .addParameter("scope","scope")
* .setScope("{scope}")
* .start(object: Callback<Credentials, AuthenticationException> {
* override fun onFailure(error: AuthenticationException) { }
* override fun onSuccess(result: Credentials) { }
Expand Down Expand Up @@ -211,7 +211,7 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
* ```
* client.signinWithPasskey("{authSession}", "{authResponse}","{realm}")
* .validateClaims() //mandatory
* .addParameter("scope","scope")
* .setScope("{scope}")
* .start(object: Callback<Credentials, AuthenticationException> {
* override fun onFailure(error: AuthenticationException) { }
* override fun onSuccess(result: Credentials) { }
Expand Down Expand Up @@ -457,13 +457,7 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
* @return a request to configure and start that will yield [Credentials]
*/
public fun loginWithNativeSocialToken(token: String, tokenType: String): AuthenticationRequest {
val parameters = ParameterBuilder.newAuthenticationBuilder()
.setGrantType(ParameterBuilder.GRANT_TYPE_TOKEN_EXCHANGE)
.setClientId(clientId)
.set(SUBJECT_TOKEN_KEY, token)
.set(SUBJECT_TOKEN_TYPE_KEY, tokenType)
.asDictionary()
return loginWithToken(parameters)
return tokenExchange(tokenType, token)
}

/**
Expand Down Expand Up @@ -707,6 +701,34 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
.addParameters(parameters)
}

/**
* The Custom Token Exchange feature allows clients to exchange their existing tokens for Auth0 tokens by calling the `/oauth/token` endpoint with specific parameters.
* The default scope used is 'openid profile email'.
*
* Example usage:
*
* ```
* client.customTokenExchange("{subject token type}", "{subject token}")
* .validateClaims() //mandatory
* .setScope("{scope}")
* .setAudience("{audience}")
* .start(object: Callback<Credentials, AuthenticationException> {
* override fun onSuccess(result: Credentials) { }
* override fun onFailure(error: AuthenticationException) { }
* })
* ```
*
* @param subjectTokenType the subject token type that is associated with the existing Identity Provider. e.g. 'http://acme.com/legacy-token'
* @param subjectToken the subject token, typically obtained through the Identity Provider's SDK
* @return a request to configure and start that will yield [Credentials]
*/
public fun customTokenExchange(
subjectTokenType: String,
subjectToken: String,
): AuthenticationRequest {
return tokenExchange(subjectTokenType, subjectToken)
}

/**
* Requests new Credentials using a valid Refresh Token. The received token will have the same audience and scope as first requested.
*
Expand Down Expand Up @@ -922,6 +944,21 @@ public class AuthenticationAPIClient @VisibleForTesting(otherwise = VisibleForTe
return request
}

/**
* Helper function to make a request to the /oauth/token endpoint with the token exchange grant type.
*/
private fun tokenExchange(
subjectTokenType: String,
subjectToken: String
): AuthenticationRequest {
val parameters = ParameterBuilder.newAuthenticationBuilder()
.setGrantType(ParameterBuilder.GRANT_TYPE_TOKEN_EXCHANGE)
.set(SUBJECT_TOKEN_TYPE_KEY, subjectTokenType)
.set(SUBJECT_TOKEN_KEY, subjectToken)
.asDictionary()
return loginWithToken(parameters)
}

private fun profileRequest(): Request<UserProfile, AuthenticationException> {
val url =
auth0.getDomainUrl().toHttpUrl().newBuilder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2272,6 +2272,87 @@ public class AuthenticationAPIClientTest {
assertThat(body, Matchers.hasEntry("token", "refreshToken"))
}

@Test
public fun shouldCustomTokenExchange() {
mockAPI.willReturnSuccessfulLogin()
val callback = MockAuthenticationCallback<Credentials>()
client.customTokenExchange( "subject-token-type","subject-token")
.start(callback)
ShadowLooper.idleMainLooper()
val request = mockAPI.takeRequest()
assertThat(
request.getHeader("Accept-Language"), Matchers.`is`(
defaultLocale
)
)
assertThat(request.path, Matchers.equalTo("/oauth/token"))
val body = bodyFromRequest<String>(request)
assertThat(body, Matchers.hasEntry("client_id", CLIENT_ID))
assertThat(
body,
Matchers.hasEntry("grant_type", ParameterBuilder.GRANT_TYPE_TOKEN_EXCHANGE)
)
assertThat(body, Matchers.hasEntry("subject_token", "subject-token"))
assertThat(body, Matchers.hasEntry("subject_token_type", "subject-token-type"))
assertThat(body, Matchers.hasEntry("scope", "openid profile email"))
assertThat(
callback, AuthenticationCallbackMatcher.hasPayloadOfType(
Credentials::class.java
)
)
}

@Test
public fun shouldCustomTokenExchangeSync() {
mockAPI.willReturnSuccessfulLogin()
val credentials = client
.customTokenExchange("subject-token-type", "subject-token")
.execute()
val request = mockAPI.takeRequest()
assertThat(
request.getHeader("Accept-Language"), Matchers.`is`(
defaultLocale
)
)
assertThat(request.path, Matchers.equalTo("/oauth/token"))
val body = bodyFromRequest<String>(request)
assertThat(body, Matchers.hasEntry("client_id", CLIENT_ID))
assertThat(
body,
Matchers.hasEntry("grant_type", ParameterBuilder.GRANT_TYPE_TOKEN_EXCHANGE)
)
assertThat(body, Matchers.hasEntry("subject_token", "subject-token"))
assertThat(body, Matchers.hasEntry("subject_token_type", "subject-token-type"))
assertThat(body, Matchers.hasEntry("scope", "openid profile email"))
assertThat(credentials, Matchers.`is`(Matchers.notNullValue()))
}

@Test
@ExperimentalCoroutinesApi
public fun shouldAwaitCustomTokenExchnage(): Unit = runTest {
mockAPI.willReturnSuccessfulLogin()
val credentials = client
.customTokenExchange("subject-token-type", "subject-token")
.await()
val request = mockAPI.takeRequest()
assertThat(
request.getHeader("Accept-Language"), Matchers.`is`(
defaultLocale
)
)
assertThat(request.path, Matchers.equalTo("/oauth/token"))
val body = bodyFromRequest<String>(request)
assertThat(body, Matchers.hasEntry("client_id", CLIENT_ID))
assertThat(
body,
Matchers.hasEntry("grant_type", ParameterBuilder.GRANT_TYPE_TOKEN_EXCHANGE)
)
assertThat(body, Matchers.hasEntry("subject_token", "subject-token"))
assertThat(body, Matchers.hasEntry("subject_token_type", "subject-token-type"))
assertThat(body, Matchers.hasEntry("scope", "openid profile email"))
assertThat(credentials, Matchers.`is`(Matchers.notNullValue()))
}

@Test
public fun shouldRenewAuthWithOAuthToken() {
val auth0 = auth0
Expand Down
11 changes: 9 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,17 @@ POM_DEVELOPER_ID=auth0
POM_DEVELOPER_NAME=Auth0
[email protected]

#org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8

org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 \
--add-exports=java.base/sun.nio.ch=ALL-UNNAMED \
--add-opens=java.base/java.lang=ALL-UNNAMED \
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED \
--add-opens=java.base/java.io=ALL-UNNAMED \
--add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=false
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
kotlin.code.style=official

Loading