All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.com.algolia.search.model.apikey.SecuredAPIKeyRestriction.kt Maven / Gradle / Ivy

Go to download

"Algolia is a powerful search-as-a-service solution, made easy to use with API clients, UI libraries, and pre-built integrations. Algolia API Client for Kotlin lets you easily use the Algolia Search REST API from your JVM project, such as Android or backend implementations."

There is a newer version: 3.12.2
Show newest version
package com.algolia.search.model.apikey

import com.algolia.search.model.APIKey
import com.algolia.search.model.IndexName
import com.algolia.search.model.insights.UserToken
import com.algolia.search.model.search.Query
import com.algolia.search.serialize.internal.toJsonNoDefaults
import io.ktor.http.Parameters
import io.ktor.http.formUrlEncode
import io.ktor.util.InternalAPI
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.jsonPrimitive

/**
 * Create restrictions for an [APIKey].
 *
 * @param query A mapping of search parameters that will be forced at query time.
 * @param restrictIndices List of [IndexName] that can be queried.
 * @param restrictSources IPv4 network allowed to use the generated key. This is used for more protection against
 * [APIKey] leaking and reuse.
 * @param validUntil A Unix timestamp used to define the expiration date of the [APIKey].
 * @param userToken Specify a user identifier. This is often used with rate limits. By default, rate limits will only
 * use the IP. This can be an issue when several of your end users are using the same IP. To avoid that, you can set a
 * userToken query parameter when generating the key. When set, a unique user will be identified by his IP + user_token
 * instead of only by his IP. This allows you to restrict a single user to performing a maximum of N API calls per hour,
 * even if he shares his IP with another user.
 */
public data class SecuredAPIKeyRestriction(
    val query: Query? = null,
    val restrictIndices: List? = null,
    val restrictSources: List? = null,
    val validUntil: Long? = null,
    val userToken: UserToken? = null
) {

    @OptIn(InternalAPI::class) // https://youtrack.jetbrains.com/issue/KT-48127
    internal fun buildRestrictionString(): String {
        return Parameters.build {
            query?.let { query ->
                query.toJsonNoDefaults().forEach { (key, element) ->
                    when (element) {
                        is JsonArray -> appendAll(key, element.jsonPrimitive.content.map { it.toString() })
                        else -> append(key, element.jsonPrimitive.content)
                    }
                }
            }
            restrictIndices?.let { append(RESTRICT_INDICES, it.joinToString(";") { indexName -> indexName.raw }) }
            restrictSources?.let { append(RESTRICT_SOURCES, it.joinToString(";")) }
            userToken?.let { append(USER_TOKEN, it.raw) }
            validUntil?.let { append(VALID_UNTIL, it.toString()) }
        }.formUrlEncode()
    }

    public companion object {
        private const val RESTRICT_INDICES = "restrictIndices"
        private const val RESTRICT_SOURCES = "restrictSources"
        private const val USER_TOKEN = "userToken"
        private const val VALID_UNTIL = "validUntil"

        /**
         * Create restrictions for an [APIKey].
         */
        public operator fun invoke(
            query: Query? = null,
            restrictIndices: String? = null,
            restrictSources: String? = null,
            validUntil: Long? = null,
            userToken: UserToken? = null
        ): SecuredAPIKeyRestriction = SecuredAPIKeyRestriction(
            query = query,
            restrictIndices = restrictIndices?.split(";")?.map(::IndexName),
            restrictSources = restrictSources?.split(";"),
            validUntil = validUntil,
            userToken = userToken
        )
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy