Skip to content

Commit

Permalink
feat: read license information from the jwt instead of the remote air…
Browse files Browse the repository at this point in the history
…byte license server (#13979)
  • Loading branch information
malikdiarra committed Sep 19, 2024
1 parent cd3da32 commit 62313c6
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 3 deletions.
2 changes: 1 addition & 1 deletion airbyte-api/server-api/src/main/openapi/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12702,6 +12702,7 @@ components:
- initialSetupComplete
- trackingStrategy
- version
- licenseStatus
properties:
edition:
type: string
Expand All @@ -12713,7 +12714,6 @@ components:
type: string
licenseStatus:
$ref: "#/components/schemas/LicenseStatus"
nullable: true
licenseExpirationDate:
type: integer
format: int64
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
@RequiresAirbyteProEnabled
public class AirbyteLicenseContextService {

public AirbyteLicenseContextService(final AirbyteLicenseFetcher airbyteLicenseFetcher, final ActiveAirbyteLicense activeAirbyteLicense) {
activeAirbyteLicense.setLicense(airbyteLicenseFetcher.fetchLicense());
public AirbyteLicenseContextService(final AirbyteLicenseReader licenseReader, final ActiveAirbyteLicense activeAirbyteLicense) {
activeAirbyteLicense.setLicense(licenseReader.extractLicense());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2020-2024 Airbyte, Inc., all rights reserved.
*/

package io.airbyte.commons.license;

import io.airbyte.commons.json.Jsons;
import io.airbyte.commons.license.annotation.RequiresAirbyteProEnabled;
import jakarta.inject.Named;
import jakarta.inject.Singleton;
import java.nio.charset.Charset;
import java.sql.Date;
import java.time.Instant;
import java.util.Base64;
import java.util.Optional;
import lombok.extern.slf4j.Slf4j;

@Singleton
@Slf4j
@RequiresAirbyteProEnabled
public class AirbyteLicenseReader {

private static final AirbyteLicense INVALID_LICENSE = new AirbyteLicense(AirbyteLicense.LicenseType.INVALID,
Optional.empty(),
Optional.empty(),
Optional.empty());
public static final int EXPECTED_FRAGMENTS = 3;

public record LicenseJwt(
AirbyteLicense.LicenseType license,
Optional<Integer> maxNodes,
Optional<Integer> maxEditors,
Long exp) {}

private final String licenceKey;

public AirbyteLicenseReader(@Named("licenseKey") final String licenceKey) {
this.licenceKey = licenceKey;
}

public AirbyteLicense extractLicense() {
final String[] fragments = licenceKey.split("\\.");
if (fragments.length != EXPECTED_FRAGMENTS) {
return INVALID_LICENSE;
}
final String body = fragments[1];
final String jsonContent = new String(Base64.getDecoder().decode(body), Charset.defaultCharset());
final LicenseJwt jwt = Jsons.deserialize(jsonContent, LicenseJwt.class);
if (jwt.license != null && jwt.exp != null) {
return new AirbyteLicense(jwt.license,
Optional.of(Date.from(Instant.ofEpochMilli(jwt.exp))),
jwt.maxNodes,
jwt.maxEditors);
}
return INVALID_LICENSE;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2020-2024 Airbyte, Inc., all rights reserved.
*/

package io.airbyte.commons.license;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;

import java.time.ZoneOffset;
import java.time.temporal.ChronoField;
import org.junit.jupiter.api.Test;

class AirbyteLicenseReaderTest {

@Test
void testDeserializeValidLicense() {
final String licenseKey =
"eyJhbGciOiJIUzI1NiJ9.eyJsaWNlbnNlIjoicHJvIiwibWF4Tm9kZXMiOjUsIm1heEVkaXRvcnMiOjUsImlhd"
+ "CI6MTcyNTM4ODE3NSwiaXNzIjoiQWlyYnl0ZSIsImF1ZCI6IkFpcmJ5dGUhIiwic3ViIjoibWFsaWtAYWlyYn"
+ "l0ZS5pbyIsImV4cCI6MTc1NjMyODI5NjczMX0.yoIedwLBWFySl5zZxLWQ4FdtVot7IbGOspzLhpIFhZo";
final AirbyteLicense license = new AirbyteLicenseReader(licenseKey).extractLicense();
assertEquals(5, license.maxEditors().get());
assertEquals(5, license.maxNodes().get());
assertEquals(2025, license.expirationDate().get().toInstant().atOffset(ZoneOffset.UTC).get(ChronoField.YEAR));
assertEquals(8, license.expirationDate().get().toInstant().atOffset(ZoneOffset.UTC).get(ChronoField.MONTH_OF_YEAR));
assertSame(AirbyteLicense.LicenseType.PRO, license.type());
}

@Test
void testDeserializeInvalidJwt() {
final String licenseKey =
"eyJhbGciOiJIUzI1NiJ9.eyJsaWNlbnNlIjoicHJvIiwibWF4Tm9kZXMiOjUsIm1heEVkaXRvcnMiOjUsImlhdC"
+ "I6MTcyNTM4ODE3NSwiaXNzIjoiQWlyYnl0ZSIsImF1ZCI6IkFpcmJ5dGUhIiwic3ViIjoibWFsaWtAYWlyYnl0"
+ "ZS5pbyIsImV4cCI6MTc1NjMyODI5NjczMX0";
final AirbyteLicense license = new AirbyteLicenseReader(licenseKey).extractLicense();
assertSame(AirbyteLicense.LicenseType.INVALID, license.type());
}

@Test
void testDeserializeInvalidLicense() {
final String licenseKey =
"eyJhbGciOiJIUzI1NiJ9.eyJtYXhOb2RlcyI6NSwibWF4RWRpdG9ycyI6NSwiaWF0IjoxNzI1Mzg4MTc1LCJpc3M"
+ "iOiJBaXJieXRlIiwiYXVkIjoiQWlyYnl0ZSEiLCJzdWIiOiJtYWxpa0BhaXJieXRlLmlvIiwiZXhwIjoxNzU2MzI"
+ "4Mjk2NzMxfQ.FM_kuEhbA0SGgIZBPDjN9B_hX-a0LBSNvcgeIh4RCyg";
final AirbyteLicense license = new AirbyteLicenseReader(licenseKey).extractLicense();
assertSame(AirbyteLicense.LicenseType.INVALID, license.type());
}

}

0 comments on commit 62313c6

Please sign in to comment.