Skip to content

Commit

Permalink
Merge branch 'master' into github-actions
Browse files Browse the repository at this point in the history
  • Loading branch information
jimmyjames authored Aug 4, 2023
2 parents e076ae5 + f41662f commit 8bed2f4
Show file tree
Hide file tree
Showing 10 changed files with 172 additions and 32 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/gradle-wrapper-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ jobs:
name: "validation/gradlew"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: gradle/wrapper-validation-action@v1
- uses: actions/checkout@v3
- uses: gradle/wrapper-validation-action@8d49e559aae34d3e0eb16cde532684bc9702762b # [email protected]
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Change Log

## [2.5.0](https://github.com/auth0/auth0-java/tree/2.5.0) (2023-07-18)
[Full Changelog](https://github.com/auth0/auth0-java/compare/2.4.0...2.5.0)

**Added**
- Support Organization Name on Authorize URL [\#550](https://github.com/auth0/auth0-java/pull/550) ([vasantteja](https://github.com/vasantteja))

**Fixed**
- Fix deleteAuthenticationMethodById [\#552](https://github.com/auth0/auth0-java/pull/552) ([jimmyjames](https://github.com/jimmyjames))

## [2.4.0](https://github.com/auth0/auth0-java/tree/2.4.0) (2023-06-15)
[Full Changelog](https://github.com/auth0/auth0-java/compare/2.3.0...2.4.0)

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ Add the dependency via Maven:
<dependency>
<groupId>com.auth0</groupId>
<artifactId>auth0</artifactId>
<version>2.4.0</version>
<version>2.5.0</version>
</dependency>
```

or Gradle:

```gradle
implementation 'com.auth0:auth0:2.4.0'
implementation 'com.auth0:auth0:2.5.0'
```

### Configure the SDK
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public AuthorizeUrlBuilder withResponseType(String responseType) {
/**
* Sets the organization query string parameter value used to login to an organization.
*
* @param organization The ID of the organization to log the user in to.
* @param organization The ID or name of the organization to log the user in to.
* @return the builder instance.
*/
public AuthorizeUrlBuilder withOrganization(String organization) {
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/com/auth0/client/mgmt/UsersEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -732,8 +732,7 @@ public Request<Void> deleteAuthenticationMethodById(String userId, String authen
.build()
.toString();

return new BaseRequest<>(this.client, tokenProvider, url, HttpMethod.DELETE, new TypeReference<Void>() {
});
return new VoidRequest(this.client, tokenProvider, url, HttpMethod.DELETE);
}

/**
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/com/auth0/json/mgmt/client/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public class Client {
private String tenant;
@JsonProperty("global")
private Boolean global;
@JsonProperty("cross_origin_auth")
@JsonProperty("cross_origin_authentication")
private Boolean crossOriginAuth;
@JsonProperty("cross_origin_loc")
private String crossOriginLoc;
Expand Down Expand Up @@ -766,7 +766,7 @@ public void setOrganizationRequireBehavior(String organizationRequireBehavior) {
* Setter whether this client can be used to make cross-origin authentication requests (true) or it is not allowed to make such requests (false).
* @param crossOriginAuth whether an application can make cross-origin authentication requests or not
*/
@JsonProperty("cross_origin_auth")
@JsonProperty("cross_origin_authentication")
public void setCrossOriginAuth(Boolean crossOriginAuth) {
this.crossOriginAuth = crossOriginAuth;
}
Expand All @@ -775,7 +775,7 @@ public void setCrossOriginAuth(Boolean crossOriginAuth) {
* Whether this client can be used to make cross-origin authentication requests (true) or it is not allowed to make such requests (false).
* @return true if application can make cross-origin authentication requests, false otherwise
*/
@JsonProperty("cross_origin_auth")
@JsonProperty("cross_origin_authentication")
public Boolean getCrossOriginAuth() {
return crossOriginAuth;
}
Expand Down
26 changes: 19 additions & 7 deletions src/main/java/com/auth0/utils/tokens/IdTokenVerifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,26 @@ public void verify(String token, String nonce, Integer maxAuthenticationAge) thr

// Org verification
if (this.organization != null) {
String orgClaim = decoded.getClaim("org_id").asString();
if (isEmpty(orgClaim)) {
throw new IdTokenValidationException("Organization Id (org_id) claim must be a string present in the ID token");
String org = this.organization.trim();
if (org.startsWith("org_")) {
// org ID
String orgClaim = decoded.getClaim("org_id").asString();
if (isEmpty(orgClaim)) {
throw new IdTokenValidationException("Organization Id (org_id) claim must be a string present in the ID token");
}
if (!this.organization.equals(orgClaim)) {
throw new IdTokenValidationException(String.format("Organization (org_id) claim mismatch in the ID token; expected \"%s\" but found \"%s\"", this.organization, orgClaim));
}
} else {
// org name
String orgNameClaim = decoded.getClaim("org_name").asString();
if (isEmpty(orgNameClaim)) {
throw new IdTokenValidationException("Organization name (org_name) claim must be a string present in the ID token");
}
if (!org.toLowerCase().equals(orgNameClaim)) {
throw new IdTokenValidationException(String.format("Organization (org_name) claim mismatch in the ID token; expected \"%s\" but found \"%s\"", this.organization, orgNameClaim));
}
}
if (!this.organization.equals(orgClaim)) {
throw new IdTokenValidationException(String.format("Organization (org_id) claim mismatch in the ID token; expected \"%s\" but found \"%s\"", this.organization, orgClaim));
}

}

final Calendar cal = Calendar.getInstance();
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/com/auth0/client/mgmt/UsersEntityTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1300,8 +1300,8 @@ public void shouldDeleteUserAuthenticationMethodById() throws Exception {
Request<Void> request = api.users().deleteAuthenticationMethodById("1", "1");
assertThat(request, is(notNullValue()));

server.jsonResponse(AUTHENTICATOR_METHOD_UPDATE_BY_ID, 200);
Void response = request.execute().getBody();
server.noContentResponse();
request.execute().getBody();
RecordedRequest recordedRequest = server.takeRequest();

assertThat(recordedRequest, hasMethodAndPath(HttpMethod.DELETE, "/api/v2/users/1/authentication-methods/1"));
Expand Down
144 changes: 132 additions & 12 deletions src/test/java/com/auth0/utils/tokens/IdTokenVerifierTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,87 @@ public void succeedsWithValidTokenUsingDefaultClockAndHttpsDomain() {
}

@Test
public void succeedsWhenOrganizationMatchesExpected() {
public void succeedsWhenOrganizationNamdMatchesExpected() {
String token = JWT.create()
.withSubject("auth0|sdk458fks")
.withAudience(AUDIENCE)
.withIssuedAt(getYesterday())
.withExpiresAt(getTomorrow())
.withIssuer("https://" + DOMAIN + "/")
.withClaim("org_name", "my org")
.sign(Algorithm.HMAC256("secret"));

String jwt = JWT.decode(token).getToken();

configureVerifier(jwt)
.withOrganization("my org")
.build()
.verify(jwt);
}

@Test
public void failsWhenOrganizationNameDoesNotMatchExpected() {
String token = JWT.create()
.withSubject("auth0|sdk458fks")
.withAudience(AUDIENCE)
.withIssuedAt(getYesterday())
.withExpiresAt(getTomorrow())
.withIssuer("https://" + DOMAIN + "/")
.withClaim("org_name", "my org")
.sign(Algorithm.HMAC256("secret"));

String jwt = JWT.decode(token).getToken();

AssertsUtil.verifyThrows(IdTokenValidationException.class,
() -> configureVerifier(jwt)
.withOrganization("your org")
.build()
.verify(jwt),
"Organization (org_name) claim mismatch in the ID token; expected \"your org\" but found \"my org\"");
}

@Test
public void failsWhenOrganizationNameExpectedButClaimIsNotString() {
String token = JWT.create()
.withSubject("auth0|sdk458fks")
.withAudience(AUDIENCE)
.withIssuedAt(getYesterday())
.withExpiresAt(getTomorrow())
.withIssuer("https://" + DOMAIN + "/")
.withClaim("org_name", 42)
.sign(Algorithm.HMAC256("secret"));

String jwt = JWT.decode(token).getToken();

AssertsUtil.verifyThrows(IdTokenValidationException.class, () -> {
configureVerifier(jwt)
.withOrganization("my org")
.build()
.verify(jwt);
},
"Organization name (org_name) claim must be a string present in the ID token");
}

@Test
public void succeedsWhenOrganizationNameNotSpecifiedButIsPresent() {
String token = JWT.create()
.withSubject("auth0|sdk458fks")
.withAudience(AUDIENCE)
.withIssuedAt(getYesterday())
.withExpiresAt(getTomorrow())
.withIssuer("https://" + DOMAIN + "/")
.withClaim("org_name", "my org")
.sign(Algorithm.HMAC256("secret"));

String jwt = JWT.decode(token).getToken();

configureVerifier(jwt)
.build()
.verify(jwt);
}

@Test
public void succeedsWhenOrganizationIdMatchesExpected() {
String token = JWT.create()
.withSubject("auth0|sdk458fks")
.withAudience(AUDIENCE)
Expand All @@ -439,7 +519,7 @@ public void succeedsWhenOrganizationMatchesExpected() {
}

@Test
public void failsWhenOrganizationDoesNotMatchExpected() {
public void failsWhenOrganizationIdDoesNotMatchExpected() {
String token = JWT.create()
.withSubject("auth0|sdk458fks")
.withAudience(AUDIENCE)
Expand All @@ -453,34 +533,74 @@ public void failsWhenOrganizationDoesNotMatchExpected() {

AssertsUtil.verifyThrows(IdTokenValidationException.class,
() -> configureVerifier(jwt)
.withOrganization("org_abc")
.build()
.verify(jwt),
.withOrganization("org_abc")
.build()
.verify(jwt),
"Organization (org_id) claim mismatch in the ID token; expected \"org_abc\" but found \"org_123\"");
}

@Test
public void failsWhenOrganizationExpectedButNotPresent() {
public void failsWhenOrganizationIdDoesNotMatchExpected_caseSensitive() {
String token = JWT.create()
.withSubject("auth0|sdk458fks")
.withAudience(AUDIENCE)
.withIssuedAt(getYesterday())
.withExpiresAt(getTomorrow())
.withIssuer("https://" + DOMAIN + "/")
.withClaim("org_id", "oRg_123")
.sign(Algorithm.HMAC256("secret"));

String jwt = JWT.decode(token).getToken();

AssertsUtil.verifyThrows(IdTokenValidationException.class,
() -> configureVerifier(jwt)
.withOrganization("org_123")
.build()
.verify(jwt),
.withOrganization("org_123")
.build()
.verify(jwt),
"Organization (org_id) claim mismatch in the ID token; expected \"org_123\" but found \"oRg_123\"");
}

@Test
public void failsWhenOrganizationIdExpectedButNotPresent() {
String token = JWT.create()
.withSubject("auth0|sdk458fks")
.withAudience(AUDIENCE)
.withIssuedAt(getYesterday())
.withExpiresAt(getTomorrow())
.withIssuer("https://" + DOMAIN + "/")
.sign(Algorithm.HMAC256("secret"));

String jwt = JWT.decode(token).getToken();

AssertsUtil.verifyThrows(IdTokenValidationException.class,
() -> configureVerifier(jwt)
.withOrganization("org_123")
.build()
.verify(jwt),
"Organization Id (org_id) claim must be a string present in the ID token");
}

@Test
public void failsWhenOrganizationExpectedButClaimIsNotString() {
public void succeedsWhenOrganizationNameDoesNotMatchExpected_caseInsensitive() {
String token = JWT.create()
.withSubject("auth0|sdk458fks")
.withAudience(AUDIENCE)
.withIssuedAt(getYesterday())
.withExpiresAt(getTomorrow())
.withIssuer("https://" + DOMAIN + "/")
.withClaim("org_name", "my org")
.sign(Algorithm.HMAC256("secret"));

String jwt = JWT.decode(token).getToken();

configureVerifier(jwt)
.withOrganization("My org")
.build()
.verify(jwt);
}

@Test
public void failsWhenOrganizationIdExpectedButClaimIsNotString() {
String token = JWT.create()
.withSubject("auth0|sdk458fks")
.withAudience(AUDIENCE)
Expand All @@ -497,12 +617,12 @@ public void failsWhenOrganizationExpectedButClaimIsNotString() {
.withOrganization("org_123")
.build()
.verify(jwt);
},
},
"Organization Id (org_id) claim must be a string present in the ID token");
}

@Test
public void succeedsWhenOrganizationNotSpecifiedButIsPresent() {
public void succeedsWhenOrganizationIdNotSpecifiedButIsPresent() {
String token = JWT.create()
.withSubject("auth0|sdk458fks")
.withAudience(AUDIENCE)
Expand Down
2 changes: 1 addition & 1 deletion src/test/resources/mgmt/clients_list.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"is_heroku_app": false,
"tenant": "auth0",
"global": false,
"cross_origin_auth": false,
"cross_origin_authentication": false,
"cross_origin_loc": "https://auth0.com/auth/callback-cross-auth",
"addons": {
"rms": {},
Expand Down

0 comments on commit 8bed2f4

Please sign in to comment.