diff --git a/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/PNConfiguration.kt b/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/PNConfiguration.kt index ede7c7ff8..7330321ce 100644 --- a/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/PNConfiguration.kt +++ b/pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/v2/PNConfiguration.kt @@ -59,7 +59,7 @@ interface PNConfiguration : com.pubnub.api.v2.PNConfiguration { val secretKey: String /** - * If Access Manager (deprecated PAM v2) is utilized, client will use this authKey in all restricted requests. + * If Access Manager V2(deprecated PAM v2) is utilized, client will use this authKey in all restricted requests. */ @Deprecated( message = "The authKey parameter is deprecated because it relates to deprecated Access Manager (PAM V2) and will be removed in the future. " + diff --git a/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/v2/PNConfigurationImpl.kt b/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/v2/PNConfigurationImpl.kt index 84dbd38a9..c75f9bf0c 100644 --- a/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/v2/PNConfigurationImpl.kt +++ b/pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/v2/PNConfigurationImpl.kt @@ -25,6 +25,7 @@ class PNConfigurationImpl( override val publishKey: String = "", override val secretKey: String = "", override val authKey: String = "", + override val authToken: String? = null, // this property is not used, user can't create configuration with authToken override val cryptoModule: CryptoModule? = null, override val origin: String = "", override val secure: Boolean = true, diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/EntitiesTest.kt b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/EntitiesTest.kt index 846a630d7..5a386ad88 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/EntitiesTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/commonTest/kotlin/com/pubnub/test/integration/EntitiesTest.kt @@ -57,7 +57,7 @@ class EntitiesTest : BaseIntegrationTest() { } } - @Test + @Test // todo flaky fun can_get_events_from_channel_subscriptionSet() = runTest { pubnub.test(backgroundScope) { val channelSet = setOf(channelName, "abc") diff --git a/pubnub-kotlin/pubnub-kotlin-api/src/jsMain/kotlin/com/pubnub/api/PubNubImpl.kt b/pubnub-kotlin/pubnub-kotlin-api/src/jsMain/kotlin/com/pubnub/api/PubNubImpl.kt index c7a12d821..a319f6d13 100644 --- a/pubnub-kotlin/pubnub-kotlin-api/src/jsMain/kotlin/com/pubnub/api/PubNubImpl.kt +++ b/pubnub-kotlin/pubnub-kotlin-api/src/jsMain/kotlin/com/pubnub/api/PubNubImpl.kt @@ -144,8 +144,8 @@ class PubNubImpl(val jsPubNub: PubNubJs) : PubNub { jsPubNub.asDynamic().configuration.subscribeKey, jsPubNub.asDynamic().configuration.publishKey, jsPubNub.asDynamic().configuration.secretKey, - jsPubNub.asDynamic().configuration.authKey, - jsPubNub.asDynamic().configuration.logVerbosity + jsPubNub.asDynamic().configuration.logVerbosity, + authToken = jsPubNub.asDynamic().configuration.authToken ) override fun addListener(listener: EventListener) { diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/v2/PNConfiguration.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/v2/PNConfiguration.kt index da6aadfa4..a409e904a 100644 --- a/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/v2/PNConfiguration.kt +++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/commonMain/kotlin/com/pubnub/api/v2/PNConfiguration.kt @@ -7,6 +7,10 @@ expect interface PNConfiguration { val userId: UserId val subscribeKey: String val publishKey: String + + /** + * The secretKey should only be used within a server side and never exposed to client devices. + */ val secretKey: String val logVerbosity: PNLogVerbosity @@ -16,6 +20,12 @@ expect interface PNConfiguration { level = DeprecationLevel.WARNING ) val authKey: String + + /** + * Authentication token for the PubNub client. This token is required on the client side when Access Manager (PAM) is enabled for PubNub keys. + * It can be generated using the [PubNub.grantToken] method, which should be executed on the server side with a PubNub instance initialized using the secret key. + */ + val authToken: String? } @Deprecated( @@ -42,4 +52,5 @@ expect fun createPNConfiguration( publishKey: String, secretKey: String? = null, logVerbosity: PNLogVerbosity = PNLogVerbosity.NONE, + authToken: String? = null ): PNConfiguration diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/iosMain/kotlin/com/pubnub/api/v2/PNConfiguration.ios.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/iosMain/kotlin/com/pubnub/api/v2/PNConfiguration.ios.kt index 1f32d243d..06bd89735 100644 --- a/pubnub-kotlin/pubnub-kotlin-core-api/src/iosMain/kotlin/com/pubnub/api/v2/PNConfiguration.ios.kt +++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/iosMain/kotlin/com/pubnub/api/v2/PNConfiguration.ios.kt @@ -4,6 +4,7 @@ import com.pubnub.api.UserId import com.pubnub.api.enums.PNLogVerbosity private const val NO_AUTH_KEY = "" +private const val NO_AUTH_TOKEN = "" actual interface PNConfiguration { actual val userId: UserId @@ -18,6 +19,12 @@ actual interface PNConfiguration { level = DeprecationLevel.WARNING ) actual val authKey: String + + /** + * Authentication token for the PubNub client. This token is required on the client side when Access Manager (PAM) is enabled for PubNub keys. + * It can be generated using the [PubNub.grantToken] method, which should be executed on the server side with a PubNub instance initialized using the secret key. + */ + actual val authToken: String? } @Deprecated( @@ -47,6 +54,8 @@ actual fun createPNConfiguration( get() = authKey.orEmpty() override val logVerbosity: PNLogVerbosity get() = logVerbosity + override val authToken: String? + get() = null } } @@ -55,7 +64,8 @@ actual fun createPNConfiguration( subscribeKey: String, publishKey: String, secretKey: String?, - logVerbosity: PNLogVerbosity + logVerbosity: PNLogVerbosity, + authToken: String? ): PNConfiguration { return object : PNConfiguration { override val userId: UserId = userId @@ -67,5 +77,7 @@ actual fun createPNConfiguration( get() = NO_AUTH_KEY override val logVerbosity: PNLogVerbosity get() = logVerbosity + override val authToken: String? + get() = authToken } } diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/jsMain/kotlin/com/pubnub/api/v2/PNConfiguration.js.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/jsMain/kotlin/com/pubnub/api/v2/PNConfiguration.js.kt index 070c3a0b0..4f03cd54d 100644 --- a/pubnub-kotlin/pubnub-kotlin-core-api/src/jsMain/kotlin/com/pubnub/api/v2/PNConfiguration.js.kt +++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/jsMain/kotlin/com/pubnub/api/v2/PNConfiguration.js.kt @@ -4,6 +4,7 @@ import com.pubnub.api.UserId import com.pubnub.api.enums.PNLogVerbosity private const val NO_AUTH_KEY = "" +private const val NO_AUTH_TOKEN = "" actual interface PNConfiguration { actual val userId: UserId @@ -19,6 +20,12 @@ actual interface PNConfiguration { level = DeprecationLevel.WARNING ) actual val authKey: String + + /** + * Authentication token for the PubNub client. This token is required on the client side when Access Manager (PAM) is enabled for PubNub keys. + * It can be generated using the [PubNub.grantToken] method, which should be executed on the server side with a PubNub instance initialized using the secret key. + */ + actual val authToken: String? } @Deprecated( @@ -49,6 +56,8 @@ actual fun createPNConfiguration( get() = secretKey.orEmpty() override val authKey: String get() = authKey.orEmpty() + override val authToken: String? + get() = null override val enableEventEngine: Boolean get() = false override val logVerbosity: PNLogVerbosity @@ -61,7 +70,8 @@ actual fun createPNConfiguration( subscribeKey: String, publishKey: String, secretKey: String?, - logVerbosity: PNLogVerbosity + logVerbosity: PNLogVerbosity, + authToken: String? ): PNConfiguration { return object : PNConfiguration { override val userId: UserId @@ -74,6 +84,8 @@ actual fun createPNConfiguration( get() = secretKey.orEmpty() override val authKey: String get() = NO_AUTH_KEY + override val authToken: String? + get() = authToken override val enableEventEngine: Boolean get() = false override val logVerbosity: PNLogVerbosity diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/v2/PNConfiguration.jvm.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/v2/PNConfiguration.jvm.kt index b76d07860..24cd8598a 100644 --- a/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/v2/PNConfiguration.jvm.kt +++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/v2/PNConfiguration.jvm.kt @@ -36,7 +36,8 @@ actual fun createPNConfiguration( subscribeKey: String, publishKey: String, secretKey: String?, - logVerbosity: PNLogVerbosity + logVerbosity: PNLogVerbosity, + authToken: String? ): PNConfiguration { return PNConfiguration.builder(userId, subscribeKey) { this.publishKey = publishKey @@ -44,5 +45,6 @@ actual fun createPNConfiguration( this.authKey = NO_AUTH_KEY this.secretKey = secretKey.orEmpty() this.logVerbosity = logVerbosity + this.authToken = authToken.orEmpty() }.build() } diff --git a/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/v2/PNConfiguration.kt b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/v2/PNConfiguration.kt index a5b8b0f03..af2d5c353 100644 --- a/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/v2/PNConfiguration.kt +++ b/pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/v2/PNConfiguration.kt @@ -48,6 +48,12 @@ actual interface PNConfiguration { ) actual val authKey: String + /** + * Authentication token for the PubNub client. This token is required on the client side when Access Manager (PAM) is enabled for PubNub keys. + * It can be generated using the [PubNub.grantToken] method, which should be executed on the server side with a PubNub instance initialized using the secret key. + */ + actual val authToken: String? + /** * CryptoModule is responsible for handling encryption and decryption. * If set, all communications to and from PubNub will be encrypted. @@ -346,6 +352,12 @@ actual interface PNConfiguration { ) var authKey: String + /** + * Authentication token for the PubNub client. This token is required on the client side when Access Manager (PAM) is enabled for PubNub keys. + * It can be generated using the [PubNub.grantToken] method, which should be executed on the server side with a PubNub instance initialized using the secret key. + */ + var authToken: String? + /** * CryptoModule is responsible for handling encryption and decryption. * If set, all communications to and from PubNub will be encrypted. @@ -656,6 +668,12 @@ interface PNConfigurationOverride { ) var authKey: String + /** + * Authentication token for the PubNub client. This token is required on the client side when Access Manager (PAM) is enabled for PubNub keys. + * It can be generated using the [PubNub.grantToken] method, which should be executed on the server side with a PubNub instance initialized using the secret key. + */ + var authToken: String? + /** * CryptoModule is responsible for handling encryption and decryption. * If set, all communications to and from PubNub will be encrypted. diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/PNConfigurationIntegrationTests.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/PNConfigurationIntegrationTests.kt index 350373d61..7b1d56e87 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/PNConfigurationIntegrationTests.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/integrationTest/kotlin/com/pubnub/api/integration/PNConfigurationIntegrationTests.kt @@ -29,23 +29,29 @@ class PNConfigurationIntegrationTests : BaseIntegrationTest() { @Test fun `create configuration with configuration action block`() { val expectedUuid = PubNub.generateUUID() + val expectedAuthToken = "token" val configBuilder = PNConfiguration.builder(UserId(expectedUuid), Keys.subKey) { publishKey = Keys.pubKey + authToken = expectedAuthToken } val pubNub = PubNub.create(configBuilder.build()) Assert.assertEquals(expectedUuid, pubNub.configuration.userId.value) Assert.assertEquals(Keys.subKey, pubNub.configuration.subscribeKey) Assert.assertEquals(Keys.pubKey, pubNub.configuration.publishKey) + Assert.assertEquals(expectedAuthToken, pubNub.configuration.authToken) + Assert.assertEquals(expectedAuthToken, pubNub.getToken()) } @Test fun `create configuration override`() { val expectedUuid = PubNub.generateUUID() + val expectedAuthToken = "token" val configBuilder = PNConfiguration.builder(UserId(expectedUuid), Keys.subKey) { publishKey = Keys.pubKey + authToken = "token$expectedAuthToken" } val config = configBuilder.build() @@ -54,24 +60,29 @@ class PNConfigurationIntegrationTests : BaseIntegrationTest() { val overrideConfig = PNConfigurationOverride.from(config).apply { publishKey = "overridePublishKey" + authToken = expectedAuthToken }.build() Assert.assertEquals(Keys.subKey, overrideConfig.subscribeKey) Assert.assertEquals("overridePublishKey", overrideConfig.publishKey) + Assert.assertEquals(expectedAuthToken, overrideConfig.authToken) } @Test fun `use configuration override with Publish`() { val expectedUuid = PubNub.generateUUID() + val expectedAuthToken = "token" val configBuilder = PNConfiguration.builder(UserId(expectedUuid), Keys.subKey) { publishKey = "rubbishKey" + authToken = "old$expectedAuthToken" } val config = configBuilder.build() val pubnub = PubNub.create(config) val overrideConfig = PNConfigurationOverride.from(config).apply { publishKey = Keys.pubKey + authToken = expectedAuthToken }.build() pubnub.publish(randomChannel(), "message").overrideConfiguration(overrideConfig).sync() @@ -81,13 +92,18 @@ class PNConfigurationIntegrationTests : BaseIntegrationTest() { @Test fun `use configuration override builder with Publish`() { val expectedUuid = PubNub.generateUUID() + val expectedAuthToken = "token" val configBuilder = PNConfiguration.builder(UserId(expectedUuid), Keys.subKey) { publishKey = "rubbishKey" + authToken = "old$expectedAuthToken" } val pubnub = PubNub.create(configBuilder.build()) - pubnub.publish(randomChannel(), "message").overrideConfiguration { publishKey = Keys.pubKey }.sync() + pubnub.publish(randomChannel(), "message").overrideConfiguration { + publishKey = Keys.pubKey + authToken = expectedAuthToken + }.sync() // no exception expected } } diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/EndpointCore.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/EndpointCore.kt index cf4e9141d..b0ff82861 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/EndpointCore.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/EndpointCore.kt @@ -213,7 +213,7 @@ abstract class EndpointCore protected constructor(protected val p } if (isAuthRequired()) { - val token = pubnub.tokenManager.getToken() + val token = configOverride?.authToken?.takeIf { it.isNotEmpty() } ?: pubnub.tokenManager.getToken() if (token != null) { map["auth"] = token } else if (configuration.authKey.isValid()) { diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/PubNubImpl.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/PubNubImpl.kt index 2f81350a8..b3dddcc4f 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/PubNubImpl.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/PubNubImpl.kt @@ -179,6 +179,11 @@ open class PubNubImpl( val pnsdkName: String = PNSDK_PUBNUB_KOTLIN, eventEnginesConf: EventEnginesConf = EventEnginesConf() ) : PubNub { + internal val tokenManager: TokenManager = TokenManager() + + init { + this.setToken(configuration.authToken) + } constructor(configuration: PNConfiguration) : this(configuration, PNSDK_PUBNUB_KOTLIN) val mapper = MapperManager() @@ -189,7 +194,6 @@ open class PubNubImpl( private val basePathManager = BasePathManager(configuration) internal val retrofitManager = RetrofitManager(this, configuration) internal val publishSequenceManager = PublishSequenceManager(MAX_SEQUENCE) - internal val tokenManager: TokenManager = TokenManager() private val tokenParser: TokenParser = TokenParser() private val presenceData = PresenceData() private val subscribe = diff --git a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/v2/PNConfigurationImpl.kt b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/v2/PNConfigurationImpl.kt index 2620096e1..c4c135a27 100644 --- a/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/v2/PNConfigurationImpl.kt +++ b/pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/v2/PNConfigurationImpl.kt @@ -25,6 +25,7 @@ class PNConfigurationImpl( override val publishKey: String = "", override val secretKey: String = "", override val authKey: String = "", + override val authToken: String? = null, override val cryptoModule: CryptoModule? = null, override val origin: String = "", override val secure: Boolean = true, @@ -95,17 +96,10 @@ class PNConfigurationImpl( override var secretKey: String = defaultConfiguration.secretKey - @Deprecated( - message = "The authKey parameter is deprecated because it relates to deprecated Access Manager (PAM V2) and will be removed in the future." + - "Please, use createPNConfiguration without authKey instead and migrate to new Access Manager " + - "(PAM V3) https://www.pubnub.com/docs/general/resources/migration-guides/pam-v3-migration ", - level = DeprecationLevel.WARNING, - replaceWith = ReplaceWith( - "createPNConfiguration(userId, subscribeKey, publishKey, secretKey, logVerbosity)" - ), - ) override var authKey: String = defaultConfiguration.authKey + override var authToken: String? = defaultConfiguration.authToken + override var cryptoModule: CryptoModule? = defaultConfiguration.cryptoModule override var origin: String = defaultConfiguration.origin @@ -196,6 +190,7 @@ class PNConfigurationImpl( publishKey = publishKey, secretKey = secretKey, authKey = authKey, + authToken = authToken, cryptoModule = cryptoModule, origin = origin, secure = secure, diff --git a/pubnub-kotlin/pubnub-kotlin-test/src/commonMain/kotlin/com.pubnub.test/BaseIntegrationTest.kt b/pubnub-kotlin/pubnub-kotlin-test/src/commonMain/kotlin/com.pubnub.test/BaseIntegrationTest.kt index f4f0b31c9..0c72d0b03 100644 --- a/pubnub-kotlin/pubnub-kotlin-test/src/commonMain/kotlin/com.pubnub.test/BaseIntegrationTest.kt +++ b/pubnub-kotlin/pubnub-kotlin-test/src/commonMain/kotlin/com.pubnub.test/BaseIntegrationTest.kt @@ -43,8 +43,20 @@ abstract class BaseIntegrationTest { @BeforeTest open fun before() { - config = createPNConfiguration(UserId(randomString()), Keys.subKey, Keys.pubKey, logVerbosity = PNLogVerbosity.BODY) - config02 = createPNConfiguration(UserId(randomString()), Keys.subKey, Keys.pubKey, logVerbosity = PNLogVerbosity.BODY) + config = createPNConfiguration( + UserId(randomString()), + Keys.subKey, + Keys.pubKey, + logVerbosity = PNLogVerbosity.BODY, + authToken = null + ) + config02 = createPNConfiguration( + UserId(randomString()), + Keys.subKey, + Keys.pubKey, + logVerbosity = PNLogVerbosity.BODY, + authToken = null + ) pubnub = createPubNub(config) pubnub02 = createPubNub(config02) configPamServer = createPNConfiguration( @@ -52,13 +64,14 @@ abstract class BaseIntegrationTest { Keys.pamSubKey, Keys.pamPubKey, Keys.pamSecKey, - logVerbosity = PNLogVerbosity.BODY + PNLogVerbosity.BODY ) configPamClient = createPNConfiguration( UserId(randomString()), Keys.pamSubKey, Keys.pamPubKey, - logVerbosity = PNLogVerbosity.BODY + logVerbosity = PNLogVerbosity.BODY, + authToken = null ) pubnubPamServer = createPubNub(configPamServer) pubnubPamClient = createPubNub(configPamClient)