Skip to content

Commit fae6362

Browse files
committed
Fix App FIT contract
- Remove deprecated `version` property from `App` payload - Add new `appVersion` and `license` property to `App` payload - Update tests
1 parent c4b63f9 commit fae6362

File tree

6 files changed

+66
-42
lines changed

6 files changed

+66
-42
lines changed

modules/core/app/io/toolsplus/atlassian/connect/play/auth/frc/jwt/ForgeInvocationContext.scala

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,32 @@ final case class Environment(`type`: String, id: String)
1818
*/
1919
final case class Module(`type`: String, key: String)
2020

21+
/**
22+
* Contains information about the license of the app. This field is only present for paid apps in the production environment.
23+
* `license` is undefined for free apps, apps in DEVELOPMENT and STAGING environments, and apps that are not listed on
24+
* the Atlassian Marketplace.
25+
*
26+
* @param isActive Specifies if the license is active.
27+
*/
28+
final case class License(isActive: Boolean)
29+
2130
/**
2231
*
2332
* @param installationId Identifier for the specific installation of an app. This is the value that any remote storage should be keyed against.
2433
* @param apiBaseUrl Base URL where all product API requests should be routed
2534
* @param id Forge application ID matching the value in the Forge manifest.yml
26-
* @param version Forge application version being invoked
35+
* @param appVersion Forge application version being invoked
2736
* @param environment Information about the environment the app is running in
2837
* @param module Information about the module that initiated this remote call
38+
* @param license Information about the license associated with the app. This field is only present for paid apps in the production environment.
2939
*/
3040
final case class App(installationId: String,
3141
apiBaseUrl: String,
3242
id: String,
33-
version: Int,
43+
appVersion: String,
3444
environment: Environment,
35-
module: Module)
45+
module: Module,
46+
license: Option[License])
3647

3748
/**
3849
* Forge invocation context represents the payload included in the Forge Invocation Token (FIT).

modules/core/app/io/toolsplus/atlassian/connect/play/auth/frc/jwt/ForgeRemoteJwtAuthenticationProvider.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,10 @@ class ForgeRemoteJwtAuthenticationProvider @Inject()(
5656

5757
private def decodeForgeInvocationTokenPayload(fitPayload: String)
5858
: Either[JwtAuthenticationError, ForgeInvocationContext] =
59-
decode[ForgeInvocationContext](fitPayload).leftMap(e =>
60-
InvalidJwtError(e.getMessage))
59+
decode[ForgeInvocationContext](fitPayload).leftMap { e =>
60+
logger.error(s"Decoding of JWT failed: $e")
61+
InvalidJwtError(e.getMessage)
62+
}
6163

6264
private def verifyJwt(credentials: ForgeRemoteCredentials,
6365
invocationContext: ForgeInvocationContext)

modules/core/test/io/toolsplus/atlassian/connect/play/actions/asymmetric/AssociateAtlassianHostUserActionSpec.scala

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import io.toolsplus.atlassian.connect.play.TestSpec
44
import io.toolsplus.atlassian.connect.play.actions.ForgeRemoteRequest
55
import io.toolsplus.atlassian.connect.play.api.models.{
66
AtlassianHost,
7-
AtlassianHostUser,
87
DefaultAtlassianHostUser,
98
DefaultForgeInstallation
109
}
@@ -17,8 +16,6 @@ import io.toolsplus.atlassian.connect.play.auth.frc.jwt.{
1716
Environment,
1817
ForgeInvocationContext,
1918
ForgeInvocationTokenGen,
20-
ForgeJWSVerificationKeySelector,
21-
ForgeRemoteJwtAuthenticationProvider,
2219
Module
2320
}
2421
import io.toolsplus.atlassian.connect.play.auth.frc.{
@@ -30,10 +27,8 @@ import io.toolsplus.atlassian.jwt.generators.util.JwtTestHelper
3027
import org.scalatest.EitherValues
3128
import org.scalatestplus.play.guice.GuiceOneAppPerSuite
3229
import play.api.Configuration
33-
import play.api.http.Status.UNAUTHORIZED
3430
import play.api.mvc.Results.BadRequest
3531
import play.api.test.FakeRequest
36-
import play.api.test.Helpers.{contentAsString, status}
3732

3833
import java.security.interfaces.RSAPublicKey
3934
import java.security.{KeyPair, PrivateKey}
@@ -60,14 +55,17 @@ class AssociateAtlassianHostUserActionSpec
6055
val forgeProperties = new AtlassianForgeProperties(config)
6156

6257
val fakeForgeInvocationContext: ForgeInvocationContext =
63-
ForgeInvocationContext(App("fake-installation-id",
64-
"fake-api-base-url",
65-
appId,
66-
1,
67-
Environment("fake-type", "fake-id"),
68-
Module("fake-type", "fake-key")),
69-
None,
70-
None)
58+
ForgeInvocationContext(
59+
App("fake-installation-id",
60+
"fake-api-base-url",
61+
appId,
62+
"fake-app-version",
63+
Environment("fake-type", "fake-id"),
64+
Module("fake-type", "fake-key"),
65+
None),
66+
None,
67+
None
68+
)
7169

7270
val keyId: String = "0e50fccb-239d-4991-a5db-dc850ba3f236"
7371
val keyPair: KeyPair = JwtTestHelper.generateKeyPair()

modules/core/test/io/toolsplus/atlassian/connect/play/actions/asymmetric/ForgeRemoteSignedForgeRemoteContextActionSpec.scala

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,17 @@ class ForgeRemoteSignedForgeRemoteContextActionSpec
4848
val forgeProperties = new AtlassianForgeProperties(config)
4949

5050
val fakeForgeInvocationContext: ForgeInvocationContext =
51-
ForgeInvocationContext(App("fake-installation-id",
52-
"fake-api-base-url",
53-
appId,
54-
1,
55-
Environment("fake-type", "fake-id"),
56-
Module("fake-type", "fake-key")),
57-
None,
58-
None)
51+
ForgeInvocationContext(
52+
App("fake-installation-id",
53+
"fake-api-base-url",
54+
appId,
55+
"fake-app-version",
56+
Environment("fake-type", "fake-id"),
57+
Module("fake-type", "fake-key"),
58+
None),
59+
None,
60+
None
61+
)
5962

6063
val keyId: String = "0e50fccb-239d-4991-a5db-dc850ba3f236"
6164
val keyPair: KeyPair = JwtTestHelper.generateKeyPair()

modules/core/test/io/toolsplus/atlassian/connect/play/auth/frc/jwt/ForgeInvocationTokenProcessorSpec.scala

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,19 @@ class ForgeInvocationTokenProcessorSpec
2727
mock[ForgeJWSVerificationKeySelector]
2828

2929
val fakeForgeInvocationContext: ForgeInvocationContext =
30-
ForgeInvocationContext(App("fake-installation-id",
31-
"fake-api-base-url",
32-
appId,
33-
1,
34-
Environment("fake-type", "fake-id"),
35-
Module("fake-type", "fake-key")),
36-
None,
37-
None)
30+
ForgeInvocationContext(
31+
App(
32+
"fake-installation-id",
33+
"fake-api-base-url",
34+
appId,
35+
"fake-app-version",
36+
Environment("fake-type", "fake-id"),
37+
Module("fake-type", "fake-key"),
38+
Some(License(true))
39+
),
40+
None,
41+
None
42+
)
3843

3944
"Given a ForgeInvocationTokenProcessor" when {
4045

modules/core/test/io/toolsplus/atlassian/connect/play/auth/frc/jwt/ForgeRemoteJwtAuthenticationProviderSpec.scala

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,19 @@ class ForgeRemoteJwtAuthenticationProviderSpec
4242
mock[ForgeJWSVerificationKeySelector]
4343

4444
val fakeForgeInvocationContext: ForgeInvocationContext =
45-
ForgeInvocationContext(App("fake-installation-id",
46-
"fake-api-base-url",
47-
appId,
48-
1,
49-
Environment("fake-type", "fake-id"),
50-
Module("fake-type", "fake-key")),
51-
None,
52-
None)
45+
ForgeInvocationContext(
46+
App(
47+
"fake-installation-id",
48+
"fake-api-base-url",
49+
appId,
50+
"fake-app-version",
51+
Environment("fake-type", "fake-id"),
52+
Module("fake-type", "fake-key"),
53+
Some(License(true))
54+
),
55+
None,
56+
None
57+
)
5358

5459
val authenticationProvider =
5560
new ForgeRemoteJwtAuthenticationProvider(

0 commit comments

Comments
 (0)