From aea6157a31240b1f15d4cd29a58bd60b3cd80712 Mon Sep 17 00:00:00 2001 From: mattgd Date: Thu, 14 Nov 2024 15:43:05 -0500 Subject: [PATCH] Add widgets package and get widget token API support. --- src/main/kotlin/com/workos/WorkOS.kt | 7 +++ .../kotlin/com/workos/widgets/WidgetsApi.kt | 23 ++++++++ .../builders/GetTokenOptionsBuilder.kt | 53 +++++++++++++++++++ .../com/workos/widgets/models/WidgetScope.kt | 15 ++++++ .../com/workos/widgets/models/WidgetToken.kt | 14 +++++ .../workos/widgets/types/GetTokenOptions.kt | 30 +++++++++++ .../com/workos/test/widgets/WidgetsApiTest.kt | 43 +++++++++++++++ 7 files changed, 185 insertions(+) create mode 100644 src/main/kotlin/com/workos/widgets/WidgetsApi.kt create mode 100644 src/main/kotlin/com/workos/widgets/builders/GetTokenOptionsBuilder.kt create mode 100644 src/main/kotlin/com/workos/widgets/models/WidgetScope.kt create mode 100644 src/main/kotlin/com/workos/widgets/models/WidgetToken.kt create mode 100644 src/main/kotlin/com/workos/widgets/types/GetTokenOptions.kt create mode 100644 src/test/kotlin/com/workos/test/widgets/WidgetsApiTest.kt diff --git a/src/main/kotlin/com/workos/WorkOS.kt b/src/main/kotlin/com/workos/WorkOS.kt index f529ed10..4ef78ec2 100644 --- a/src/main/kotlin/com/workos/WorkOS.kt +++ b/src/main/kotlin/com/workos/WorkOS.kt @@ -24,6 +24,7 @@ import com.workos.portal.PortalApi import com.workos.sso.SsoApi import com.workos.usermanagement.UserManagementApi import com.workos.webhooks.WebhooksApi +import com.workos.widgets.WidgetsApi import org.apache.http.client.utils.URIBuilder import java.io.IOException import java.lang.IllegalArgumentException @@ -119,6 +120,12 @@ class WorkOS( @JvmField val webhooks = WebhooksApi() + /** + * Module for interacting with the Widgets API. + */ + @JvmField + val widgets = WidgetsApi(this) + /** * Module for interacting with the FGA API. */ diff --git a/src/main/kotlin/com/workos/widgets/WidgetsApi.kt b/src/main/kotlin/com/workos/widgets/WidgetsApi.kt new file mode 100644 index 00000000..3775b1f1 --- /dev/null +++ b/src/main/kotlin/com/workos/widgets/WidgetsApi.kt @@ -0,0 +1,23 @@ +package com.workos.widgets + +import com.workos.WorkOS +import com.workos.common.http.RequestConfig +import com.workos.widgets.models.WidgetToken +import com.workos.widgets.types.GetTokenOptions + +/** + * The WidgetsApi class provides convenience methods for working with the WorkOS + * Widgets product. + */ +class WidgetsApi(private val workos: WorkOS) { + /** + * Generates a widget token. + */ + fun getToken(options: GetTokenOptions): WidgetToken { + return workos.post( + "/widgets/token", + WidgetToken::class.java, + RequestConfig.builder().data(options).build() + ) + } +} diff --git a/src/main/kotlin/com/workos/widgets/builders/GetTokenOptionsBuilder.kt b/src/main/kotlin/com/workos/widgets/builders/GetTokenOptionsBuilder.kt new file mode 100644 index 00000000..10cab3f6 --- /dev/null +++ b/src/main/kotlin/com/workos/widgets/builders/GetTokenOptionsBuilder.kt @@ -0,0 +1,53 @@ +package com.workos.widgets.builders + +import com.workos.widgets.models.WidgetScope +import com.workos.widgets.types.GetTokenOptions + +/** + * Builder for options when generating a widget token. + * + * @param organizationId The ID of the organization to generate a token for. + * @param userId The ID of the user to generate a token for. + * @param scopes The scopes to generate a token for. + */ +class GetTokenOptionsBuilder @JvmOverloads constructor( + private var organizationId: String, + private var userId: String, + private var scopes: List, +) { + /** + * Organization ID + */ + fun organizationId(value: String) = apply { organizationId = value } + + /** + * User ID + */ + fun userId(value: String) = apply { userId = value } + + /** + * Widget scopes + */ + fun scopes(value: List) = apply { scopes = value } + + /** + * Generates the GetTokenOptions object. + */ + fun build(): GetTokenOptions { + return GetTokenOptions( + organizationId = this.organizationId, + userId = this.userId, + scopes = this.scopes, + ) + } + + /** + * @suppress + */ + companion object { + @JvmStatic + fun create(organizationId: String, userId: String, scopes: List): GetTokenOptionsBuilder { + return GetTokenOptionsBuilder(organizationId, userId, scopes) + } + } +} diff --git a/src/main/kotlin/com/workos/widgets/models/WidgetScope.kt b/src/main/kotlin/com/workos/widgets/models/WidgetScope.kt new file mode 100644 index 00000000..cb4bbdc0 --- /dev/null +++ b/src/main/kotlin/com/workos/widgets/models/WidgetScope.kt @@ -0,0 +1,15 @@ +package com.workos.widgets.models + +import com.fasterxml.jackson.annotation.JsonValue + +/** + * WidgetScope of the widget token. + * + * @param value The string value of the widgetscope. + */ +enum class WidgetScope(@JsonValue val value: String) { + /** + * Manage users via the users table widget. + */ + UsersTableManagement("widgets:users-table:manage"), +} diff --git a/src/main/kotlin/com/workos/widgets/models/WidgetToken.kt b/src/main/kotlin/com/workos/widgets/models/WidgetToken.kt new file mode 100644 index 00000000..18adc776 --- /dev/null +++ b/src/main/kotlin/com/workos/widgets/models/WidgetToken.kt @@ -0,0 +1,14 @@ +package com.workos.widgets.models + +import com.fasterxml.jackson.annotation.JsonCreator + +/** + * The response object from creating a widget token. + * + * @param token The generated widget token. + */ +data class WidgetToken +@JsonCreator constructor( + @JvmField + val token: String +) diff --git a/src/main/kotlin/com/workos/widgets/types/GetTokenOptions.kt b/src/main/kotlin/com/workos/widgets/types/GetTokenOptions.kt new file mode 100644 index 00000000..987e0c5b --- /dev/null +++ b/src/main/kotlin/com/workos/widgets/types/GetTokenOptions.kt @@ -0,0 +1,30 @@ +package com.workos.widgets.types + +import com.fasterxml.jackson.annotation.JsonProperty +import com.workos.widgets.models.WidgetScope + +class GetTokenOptions( + /** + * The ID of the organization to generate a token for. + */ + @JsonProperty("organization_id") + val organizationId: String, + + /** + * The ID of the user to generate a token for. + */ + @JsonProperty("user_id") + val userId: String, + + /** + * The scopes to generate a token for. + */ + @JsonProperty("scopes") + val scopes: List, +) { + init { + require(organizationId.isNotBlank()) { "Organization ID is required" } + require(userId.isNotBlank()) { "User ID is required" } + require(scopes.isNotEmpty()) { "At least one scope is required" } + } +} diff --git a/src/test/kotlin/com/workos/test/widgets/WidgetsApiTest.kt b/src/test/kotlin/com/workos/test/widgets/WidgetsApiTest.kt new file mode 100644 index 00000000..9943686b --- /dev/null +++ b/src/test/kotlin/com/workos/test/widgets/WidgetsApiTest.kt @@ -0,0 +1,43 @@ +package com.workos.test.widgets + +import com.workos.test.TestBase +import com.workos.widgets.builders.GetTokenOptionsBuilder +import com.workos.widgets.models.WidgetScope +import kotlin.test.Test +import kotlin.test.assertEquals + +class WidgetsApiTest : TestBase() { + private fun prepareGetTokenTest(body: String): String { + val token = "abc123456" + + stubResponse( + url = "/widgets/token", + responseBody = """{ + "token": "$token" + }""", + requestBody = body + ) + + return token + } + + @Test + fun getTokenShouldReturnPayload() { + val workos = createWorkOSClient() + + val token = prepareGetTokenTest( + """{ + "organization_id": "organizationId", + "user_id": "userId", + "scopes": ["widgets:users-table:manage"] + }""" + ) + + val options = GetTokenOptionsBuilder("organizationId", "userId", listOf(WidgetScope.UsersTableManagement)) + .build() + + val response = workos.widgets.getToken(options) + + assertEquals(response.token, token) + } +}