diff --git a/.github/workflows/test.java.yml b/.github/workflows/test.java.yml index c0ad13bd5..76fcbe458 100644 --- a/.github/workflows/test.java.yml +++ b/.github/workflows/test.java.yml @@ -16,17 +16,17 @@ jobs: run: working-directory: ./sdk/java/core steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Java ${{ matrix.java-version }} - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: 'zulu' java-version: ${{ matrix.java-version }} - name: Setup, Build and Test - uses: gradle/gradle-build-action@v2 + uses: gradle/actions/setup-gradle@v3 with: - gradle-version: 8.4 + gradle-version: '8.14' arguments: build test build-root-directory: ./sdk/java/core diff --git a/sdk/java/core/README.md b/sdk/java/core/README.md index d58986a90..cb7a54c40 100644 --- a/sdk/java/core/README.md +++ b/sdk/java/core/README.md @@ -4,6 +4,9 @@ For more information see our official documentation page https://docs.keeper.io/ # Change Log +## 17.0.1 +- KSM-634 - Added links2Remove parameter for files removal + ## 17.0.0 - KSM-580 - Added new PAM fields diff --git a/sdk/java/core/build.gradle.kts b/sdk/java/core/build.gradle.kts index 2dcf84bed..c866d6160 100644 --- a/sdk/java/core/build.gradle.kts +++ b/sdk/java/core/build.gradle.kts @@ -7,12 +7,12 @@ import java.util.* group = "com.keepersecurity.secrets-manager" // During publishing, If version ends with '-SNAPSHOT' then it will be published to Maven snapshot repository -version = "17.0.0" +version = "17.0.1" plugins { `java-library` - kotlin("jvm") version "2.0.20" - kotlin("plugin.serialization") version "2.0.20" + kotlin("jvm") version "2.2.0" + kotlin("plugin.serialization") version "2.2.0" `maven-publish` signing id("io.github.gradle-nexus.publish-plugin") version "2.0.0" @@ -43,20 +43,20 @@ repositories { dependencies { // Align versions of all Kotlin components - implementation(platform("org.jetbrains.kotlin:kotlin-bom:2.0.20")) + implementation(platform("org.jetbrains.kotlin:kotlin-bom:2.2.0")) // Use the Kotlin JDK 8 standard library. - api("org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.0.20") - implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.2") - implementation("org.jetbrains.kotlin:kotlin-reflect:2.0.20") + api("org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.2.0") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0") + implementation("org.jetbrains.kotlin:kotlin-reflect:2.2.0") // Use the Kotlin test library. - testImplementation("org.jetbrains.kotlin:kotlin-test:2.0.20") + testImplementation("org.jetbrains.kotlin:kotlin-test:2.2.0") // Use the Kotlin JUnit integration. - testImplementation("org.jetbrains.kotlin:kotlin-test-junit:2.0.20") + testImplementation("org.jetbrains.kotlin:kotlin-test-junit:2.2.0") - testImplementation("org.bouncycastle:bc-fips:2.0.0") + testImplementation("org.bouncycastle:bc-fips:2.1.0") // testImplementation("org.bouncycastle:bcprov-jdk15on:1.70") } diff --git a/sdk/java/core/gradle/wrapper/gradle-wrapper.properties b/sdk/java/core/gradle/wrapper/gradle-wrapper.properties index 793ed65e1..994b22a0b 100644 --- a/sdk/java/core/gradle/wrapper/gradle-wrapper.properties +++ b/sdk/java/core/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/sdk/java/core/settings.gradle.kts b/sdk/java/core/settings.gradle.kts index 7c2709aac..f705909ce 100644 --- a/sdk/java/core/settings.gradle.kts +++ b/sdk/java/core/settings.gradle.kts @@ -1,7 +1,10 @@ rootProject.name = "core" plugins { - id("org.gradle.toolchains.foojay-resolver") version "0.8.0" + // Note: Versions prior to 1.0.0 require Java 8 or later and Gradle 7.6 or later. + // Versions 1.0.0 and after require Java 17 or later and Gradle 7.6 or later. + // Upgrade to 1.0.0+ entails moving java-version matrix out of GHA and implementing in Gradle + id("org.gradle.toolchains.foojay-resolver") version "0.9.0" } @Suppress("UnstableApiUsage") diff --git a/sdk/java/core/src/main/kotlin/com/keepersecurity/secretsManager/core/SecretsManager.kt b/sdk/java/core/src/main/kotlin/com/keepersecurity/secretsManager/core/SecretsManager.kt index b65260ff3..19a541e6f 100644 --- a/sdk/java/core/src/main/kotlin/com/keepersecurity/secretsManager/core/SecretsManager.kt +++ b/sdk/java/core/src/main/kotlin/com/keepersecurity/secretsManager/core/SecretsManager.kt @@ -18,7 +18,7 @@ import java.util.* import java.util.concurrent.* import javax.net.ssl.* -const val KEEPER_CLIENT_VERSION = "mj17.0.0" +const val KEEPER_CLIENT_VERSION = "mj17.0.1" const val KEY_HOSTNAME = "hostname" // base url for the Secrets Manager service const val KEY_SERVER_PUBIC_KEY_ID = "serverPublicKeyId" @@ -59,6 +59,11 @@ data class CreateOptions @JvmOverloads constructor( val subFolderUid: String? = null, ) +data class UpdateOptions @JvmOverloads constructor( + val transactionType: UpdateTransactionType? = null, + val linksToRemove: List? = null, +) + typealias QueryFunction = (url: String, transmissionKey: TransmissionKey, payload: EncryptedPayload) -> KeeperHttpResponse data class TransmissionKey(var publicKeyId: Int, var key: ByteArray, val encryptedKey: ByteArray) @@ -94,7 +99,8 @@ private data class UpdatePayload( val recordUid: String, val data: String, val revision: Long, - val transactionType: UpdateTransactionType? = null + val transactionType: UpdateTransactionType? = null, + val links2Remove: List? = null ): CommonPayload() @Serializable @@ -159,6 +165,7 @@ private data class FileUploadPayload( val fileRecordData: String, val ownerRecordUid: String, val ownerRecordData: String, + val ownerRecordRevision: Long, val linkKey: String, val fileSize: Int, // we will not allow upload size > 2GB due to memory constraints ): CommonPayload() @@ -585,7 +592,12 @@ fun deleteFolder(options: SecretsManagerOptions, folderUids: List, force @ExperimentalSerializationApi fun updateSecret(options: SecretsManagerOptions, record: KeeperRecord, transactionType: UpdateTransactionType? = null) { - val payload = prepareUpdatePayload(options.storage, record, transactionType) + updateSecretWithOptions(options, record, UpdateOptions(transactionType, null)) +} + +@ExperimentalSerializationApi +fun updateSecretWithOptions(options: SecretsManagerOptions, record: KeeperRecord, updateOptions: UpdateOptions? = null) { + val payload = prepareUpdatePayload(options.storage, record, updateOptions) postQuery(options, "update_secret", payload) } @@ -948,12 +960,29 @@ private fun prepareDeleteFolderPayload( private fun prepareUpdatePayload( storage: KeyValueStorage, record: KeeperRecord, - transactionType: UpdateTransactionType? = null + updateOptions: UpdateOptions? = null ): UpdatePayload { val clientId = storage.getString(KEY_CLIENT_ID) ?: throw Exception("Client Id is missing from the configuration") + + updateOptions?.linksToRemove?.takeIf { it.isNotEmpty() }?.let { + val frefs = record.data.getField() + if (frefs?.value?.isNotEmpty() == true){ + frefs.value.removeAll(it) + } + } + val recordBytes = stringToBytes(Json.encodeToString(record.data)) val encryptedRecord = encrypt(recordBytes, record.recordKey) - return UpdatePayload(KEEPER_CLIENT_VERSION, clientId, record.recordUid, webSafe64FromBytes(encryptedRecord), record.revision, transactionType) + + return UpdatePayload( + clientVersion = KEEPER_CLIENT_VERSION, + clientId = clientId, + recordUid = record.recordUid, + data = webSafe64FromBytes(encryptedRecord), + revision = record.revision, + transactionType = updateOptions?.transactionType, + links2Remove = updateOptions?.linksToRemove + ) } @ExperimentalSerializationApi @@ -1066,6 +1095,7 @@ private fun prepareFileUploadPayload( webSafe64FromBytes(encryptedFileRecord), ownerRecord.recordUid, webSafe64FromBytes(encryptedOwnerRecord), + ownerRecord.revision, bytesToBase64(encryptedLinkKey), encryptedFileData.size ),