Skip to content

Commit

Permalink
[Chore] Merge develop into sep-6 (#1181)
Browse files Browse the repository at this point in the history
### Description

Merges `develop` into `sep-6`.

### Context

Keep `sep-6` branch up to date.

### Testing

- `./gradlew test`

### Documentation

N/A

### Known limitations

N/A
  • Loading branch information
philipliu authored Nov 1, 2023
2 parents 3165ae2 + bfa145f commit e436286
Show file tree
Hide file tree
Showing 23 changed files with 239 additions and 165 deletions.
7 changes: 7 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@
- `./gradlew test`
- TODO: replace with any additional test steps

### Documentation

TODO: If this pull request adds a feature, describe changes to documentation that has been made

- Attach stellar-docs pull request, documenting new feature
- If it's an urgent feature request, please create a ticket and attach ticket number to this PR

### Known limitations

TODO: describe any limitations or replace with N/A
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/sub_gradle_test_and_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,18 @@ jobs:
run: |
docker run --network host -v ${GITHUB_WORKSPACE}/platform/src/test/resources://config stellar/anchor-tests:v0.6.7 --home-domain http://host.docker.internal:8080 --seps 1 6 10 12 24 31 38 --sep-config //config/stellar-anchor-tests-sep-config.json --verbose
- name: Upload Artifacts
if: always()
uses: actions/upload-artifact@v3
with:
name: gradle-artifact
path: |
/etc/hosts
/home/runner/work/java-stellar-anchor-sdk/java-stellar-anchor-sdk/api-schema/build/reports/
/home/runner/work/java-stellar-anchor-sdk/java-stellar-anchor-sdk/core/build/reports/
/home/runner/work/java-stellar-anchor-sdk/java-stellar-anchor-sdk/platform/build/reports/
/home/runner/work/java-stellar-anchor-sdk/java-stellar-anchor-sdk/integration-tests/build/reports/
analyze:
name: CodeQL Analysis
runs-on: ubuntu-22.04
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/wf_pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ jobs:

complete:
if: always()
needs: [gradle_test_and_build]
needs: [ gradle_test_and_build ]
runs-on: ubuntu-22.04
steps:
- if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
run: exit 1
- if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
run: exit 1
25 changes: 4 additions & 21 deletions api-schema/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,8 @@ dependencies {
annotationProcessor(libs.lombok)
}

tasks.test {
// Enable parallel test execution
systemProperty("junit.jupiter.execution.parallel.enabled", true)
// Allocate thread count based on available processors
systemProperty("junit.jupiter.execution.parallel.config.strategy", "dynamic")
// Set default parallel mode to same thread. All tests within a class are run in sequence.
systemProperty("junit.jupiter.execution.parallel.mode.default", "same_thread")
// Set default parallel mode for classes to concurrent. All test classes are run in parallel.
systemProperty("junit.jupiter.execution.parallel.mode.classes.default", "concurrent")
apply(from = "$rootDir/scripts.gradle.kts")
@Suppress("UNCHECKED_CAST")
val enableTestConcurrency = extra["enableTestConcurrency"] as (Test) -> Unit

// Set default test class order to order annotation. All test classes are run in parallel.
// Some tests take longer to run. Enabling the order will execute long-running tests first to
// shorten the overall test time.
systemProperty(
"junit.jupiter.testclass.order.default",
"org.junit.jupiter.api.ClassOrderer\$OrderAnnotation"
)
maxParallelForks =
(Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1).also {
println("junit5 ... setting maxParallelForks to $it")
}
}
tasks.test { enableTestConcurrency(this) }
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ public class PlatformTransactionData {
@SerializedName("refund_memo_type")
String refundMemoType;

@SerializedName("withdraw_anchor_account")
String withdrawAnchorAccount;

Customers customers;
StellarId creator;

Expand Down
8 changes: 5 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ subprojects {

test {
useJUnitPlatform()
systemProperty(
"junit.jupiter.testclass.order.default",
"org.junit.jupiter.api.ClassOrderer\$OrderAnnotation"
)

exclude("**/AnchorPlatformCustodyEnd2EndTest**")
exclude("**/AnchorPlatformCustodyApiRpcEnd2EndTest**")
Expand Down Expand Up @@ -181,6 +185,4 @@ allprojects {
}
}

tasks.register("printVersionName") {
println(rootProject.version.toString())
}
tasks.register("printVersionName") { println(rootProject.version.toString()) }
38 changes: 7 additions & 31 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ dependencies {
implementation(
libs.scala.library
) // used to force the version of scala-library (used by kafka-json-schema-serializer) to a safer
// one.
// one.
implementation(libs.bundles.kafka)

// TODO: Consider to simplify
Expand Down Expand Up @@ -119,33 +119,9 @@ publishing {
configure<SigningExtension> { sign(publishing.publications) }
}

// TODO: when we enable parallelization for all sub-projects, we can extract the following block.
tasks.test {
// Enable parallel test execution
systemProperty("junit.jupiter.execution.parallel.enabled", true)
// Use PER_METHOD test instance life cycle. This avoids the race condition when tests are run in parallel mode
// if the test class has a non-static fields. The non-static fields are shared across all test methods. If the life
// cycle is not PER_METHOD, the test methods may overwrite the fields and cause test failures.
//
// However, the life cycle can still be over-written by @TestInstance(Lifecycle) annotation.
// See https://junit.org/junit5/docs/current/user-guide/#writing-tests-parallel-execution
systemProperty("junit.jupiter.testinstance.lifecycle.default", "per_method")
// Allocate thread count based on available processors
systemProperty("junit.jupiter.execution.parallel.config.strategy", "dynamic")
// Set default parallel mode to same thread. All tests within a class are run in sequence.
systemProperty("junit.jupiter.execution.parallel.mode.default", "concurrent")
// Set default parallel mode for classes to concurrent. All test classes are run in parallel.
systemProperty("junit.jupiter.execution.parallel.mode.classes.default", "concurrent")

// Set default test class order to order annotation. All test classes are run in parallel.
// Some tests take longer to run. Enabling the order will execute long-running tests first to
// shorten the overall test time.
systemProperty(
"junit.jupiter.testclass.order.default",
"org.junit.jupiter.api.ClassOrderer\$OrderAnnotation"
)
maxParallelForks =
(Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1).also {
println("junit5 ... setting maxParallelForks to $it")
}
}
apply(from = "$rootDir/scripts.gradle.kts")

@Suppress("UNCHECKED_CAST")
val enableTestConcurrency = extra["enableTestConcurrency"] as (Test) -> Unit

tasks.test { enableTestConcurrency(this) }
34 changes: 14 additions & 20 deletions core/src/main/java/org/stellar/anchor/auth/JwtService.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package org.stellar.anchor.auth;

import static java.util.Date.*;

import io.jsonwebtoken.*;
import io.jsonwebtoken.impl.DefaultJwsHeader;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;
import java.util.Calendar;
import java.time.Instant;
import java.util.Map;
import lombok.Getter;
import org.apache.commons.codec.binary.Base64;
Expand Down Expand Up @@ -57,19 +59,15 @@ public JwtService(
}

public String encode(Sep10Jwt token) {
Calendar calIat = Calendar.getInstance();
calIat.setTimeInMillis(1000L * token.getIat());

Calendar calExp = Calendar.getInstance();
calExp.setTimeInMillis(1000L * token.getExp());

Instant timeExp = Instant.ofEpochSecond(token.getExp());
Instant timeIat = Instant.ofEpochSecond(token.getIat());
JwtBuilder builder =
Jwts.builder()
.setId(token.getJti())
.setIssuer(token.getIss())
.setSubject(token.getSub())
.setIssuedAt(calIat.getTime())
.setExpiration(calExp.getTime())
.setIssuedAt(from(timeIat))
.setExpiration(from(timeExp))
.setSubject(token.getSub());

if (token.getClientDomain() != null) {
Expand All @@ -88,12 +86,11 @@ public String encode(Sep24InteractiveUrlJwt token) throws InvalidConfigException
throw new InvalidConfigException(
"Please provide the secret before encoding JWT for Sep24 interactive url");
}
Calendar calExp = Calendar.getInstance();
calExp.setTimeInMillis(1000L * token.getExp());
Instant timeExp = Instant.ofEpochSecond(token.getExp());
JwtBuilder builder =
Jwts.builder()
.setId(token.getJti())
.setExpiration(calExp.getTime())
.setExpiration(from(timeExp))
.setSubject(token.getSub());
for (Map.Entry<String, Object> claim : token.claims.entrySet()) {
builder.claim(claim.getKey(), claim.getValue());
Expand All @@ -107,12 +104,11 @@ public String encode(Sep24MoreInfoUrlJwt token) throws InvalidConfigException {
throw new InvalidConfigException(
"Please provide the secret before encoding JWT for more_info_url");
}
Calendar calExp = Calendar.getInstance();
calExp.setTimeInMillis(1000L * token.getExp());
Instant timeExp = Instant.ofEpochSecond(token.getExp());
JwtBuilder builder =
Jwts.builder()
.setId(token.getJti())
.setExpiration(calExp.getTime())
.setExpiration(from(timeExp))
.setSubject(token.getSub());
for (Map.Entry<String, Object> claim : token.claims.entrySet()) {
builder.claim(claim.getKey(), claim.getValue());
Expand All @@ -139,11 +135,9 @@ private String encode(ApiAuthJwt token, String secret) throws InvalidConfigExcep
"Please provide the secret before encoding JWT for API Authentication");
}

Calendar calNow = Calendar.getInstance();
Calendar calExp = Calendar.getInstance();
calExp.setTimeInMillis(1000L * token.getExp());
JwtBuilder builder =
Jwts.builder().setIssuedAt(calNow.getTime()).setExpiration(calExp.getTime());
Instant timeExp = Instant.ofEpochSecond(token.getExp());
Instant timeIat = Instant.ofEpochSecond(token.getIat());
JwtBuilder builder = Jwts.builder().setIssuedAt(from(timeIat)).setExpiration(from(timeExp));

return builder.signWith(SignatureAlgorithm.HS256, secret).compact();
}
Expand Down
13 changes: 5 additions & 8 deletions core/src/main/java/org/stellar/anchor/config/Sep10Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,20 @@ public interface Sep10Config {
/**
* The `web_auth_domain` property of <a
* href="https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0010.md#response">SEP-10</a>.
* If the `web_auth_domain` is not specified, the `web_auth_domain` will be set to the domain of
* the value of the `home_domain`. `web_auth_domain` value must be equal to the host of the SEP
* server.
* If the `web_auth_domain` is not specified, the `web_auth_domain` will be set to the first value
* of `home_domains`. The `web_auth_domain` value must equal to the host of the SEP server.
*
* @return the web auth domain.
*/
String getWebAuthDomain();

/**
* The `home_domain` property of <a
* The `home_domains` property of <a
* href="https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0010.md#request">SEP-10</a>.
* `home_domain` value must be equal to the host of the toml file. If sep1 is enabled, toml file
* will be hosted on the SEP server.
*
* @return the home domain.
* @return the list of home domains.
*/
String getHomeDomain();
List<String> getHomeDomains();

/**
* Set the authentication challenge transaction timeout in seconds. An expired signed transaction
Expand Down
27 changes: 14 additions & 13 deletions core/src/main/java/org/stellar/anchor/sep10/Sep10Service.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public String validateChallengeTransactionHomeDomain(ChallengeTransaction challe
throw new SepValidationException("Invalid challenge transaction.");
}

if (!Objects.equals(sep10Config.getHomeDomain(), homeDomain)) {
if ((!sep10Config.getHomeDomains().contains(homeDomain))) {
throw new SepValidationException(format("Invalid home_domain. %s", homeDomain));
}

Expand Down Expand Up @@ -257,10 +257,11 @@ String fetchSigningKeyFromClientDomain(String clientDomain) throws SepException

void validateHomeDomain(ChallengeRequest request) throws SepValidationException {
String homeDomain = request.getHomeDomain();
String defaultHomeDomain = sep10Config.getHomeDomains().get(0);
if (homeDomain == null) {
debugF("home_domain is not specified. Will use the default: {}", sep10Config.getHomeDomain());
request.setHomeDomain(sep10Config.getHomeDomain());
} else if (!homeDomain.equalsIgnoreCase(sep10Config.getHomeDomain())) {
debugF("home_domain is not specified. Will use the default: {}", defaultHomeDomain);
request.setHomeDomain(defaultHomeDomain);
} else if (!sep10Config.getHomeDomains().contains(homeDomain)) {
infoF("Bad home_domain: {}", homeDomain);
throw new SepValidationException(format("home_domain [%s] is not supported.", homeDomain));
}
Expand Down Expand Up @@ -295,7 +296,7 @@ void validateChallengeRequest(
request.getTransaction(),
serverAccountId,
new Network(appConfig.getStellarNetworkPassphrase()),
sep10Config.getHomeDomain(),
sep10Config.getHomeDomains().toArray(new String[0]),
sep10Config.getWebAuthDomain(),
threshold,
signers);
Expand Down Expand Up @@ -349,7 +350,7 @@ AccountResponse fetchAccount(
request.getTransaction(),
serverAccountId,
new Network(appConfig.getStellarNetworkPassphrase()),
sep10Config.getHomeDomain(),
sep10Config.getHomeDomains().toArray(new String[0]),
sep10Config.getWebAuthDomain(),
signers);

Expand Down Expand Up @@ -395,7 +396,7 @@ ChallengeTransaction parseChallenge(ValidationRequest request)
transaction,
serverAccountId,
new Network(appConfig.getStellarNetworkPassphrase()),
sep10Config.getHomeDomain(),
sep10Config.getHomeDomains().toArray(new String[0]),
sep10Config.getWebAuthDomain());

debugF(
Expand Down Expand Up @@ -461,35 +462,35 @@ public synchronized ChallengeTransaction readChallengeTransaction(
String challengeXdr,
String serverAccountId,
Network network,
String domainName,
String[] domainNames,
String webAuthDomain)
throws InvalidSep10ChallengeException, IOException {
return Sep10Challenge.readChallengeTransaction(
challengeXdr, serverAccountId, network, domainName, webAuthDomain);
challengeXdr, serverAccountId, network, domainNames, webAuthDomain);
}

public synchronized void verifyChallengeTransactionSigners(
String challengeXdr,
String serverAccountId,
Network network,
String domainName,
String[] domainNames,
String webAuthDomain,
Set<String> signers)
throws InvalidSep10ChallengeException, IOException {
Sep10Challenge.verifyChallengeTransactionSigners(
challengeXdr, serverAccountId, network, domainName, webAuthDomain, signers);
challengeXdr, serverAccountId, network, domainNames, webAuthDomain, signers);
}

public synchronized void verifyChallengeTransactionThreshold(
String challengeXdr,
String serverAccountId,
Network network,
String domainName,
String[] domainNames,
String webAuthDomain,
int threshold,
Set<Sep10Challenge.Signer> signers)
throws InvalidSep10ChallengeException, IOException {
Sep10Challenge.verifyChallengeTransactionThreshold(
challengeXdr, serverAccountId, network, domainName, webAuthDomain, threshold, signers);
challengeXdr, serverAccountId, network, domainNames, webAuthDomain, threshold, signers);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ internal class Sep10ServiceTest {
every { sep10Config.webAuthDomain } returns TEST_WEB_AUTH_DOMAIN
every { sep10Config.authTimeout } returns 900
every { sep10Config.jwtTimeout } returns 900
every { sep10Config.homeDomain } returns TEST_HOME_DOMAIN
every { sep10Config.homeDomains } returns listOf(TEST_HOME_DOMAIN)

every { appConfig.stellarNetworkPassphrase } returns TESTNET.networkPassphrase

Expand Down
13 changes: 13 additions & 0 deletions docs/01 - Contributing/B - Git Guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,16 @@ Resolve: #123
We use the [Gitflow Workflow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) for this
project.

## How to access GitHub workflow artifacts
The following artifacts are available for each workflow run:
- `/etc/hosts`: The hosts file of the runner.
- `/java-stellar-anchor-sdk/api-schema/build/libs`: The build artifact of the `api-schema` subproject.
- `java-stellar-anchor-sdk/core/build/reports`: The test reports of the `core` subproject.
- `java-stellar-anchor-sdk/platform/build/reports`: The test reports of the `platform` subproject.
- `java-stellar-anchor-sdk/integration-tests/build/reports`: The test reports of the `integration-tests` subproject.

To access the artifacts, follow these steps:
1. Go to the `Actions` tab of the repository.
2. Click on the workflow run you want to access.
3. Find the `Artifacts` section on the bottom of the page.
4. Click to download.
3 changes: 2 additions & 1 deletion integration-tests/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ dependencies {
implementation("org.springframework.boot:spring-boot-autoconfigure")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation(
libs.snakeyaml) // used to force the version of snakeyaml (used by springboot) to a safer one.
libs.snakeyaml
) // used to force the version of snakeyaml (used by springboot) to a safer one.
implementation("org.springframework.boot:spring-boot-starter-web")

implementation(libs.commons.cli)
Expand Down
Loading

0 comments on commit e436286

Please sign in to comment.