diff --git a/consentium/build.gradle.kts b/consentium/build.gradle.kts
index d4d5e77..e020f67 100644
--- a/consentium/build.gradle.kts
+++ b/consentium/build.gradle.kts
@@ -3,6 +3,7 @@ plugins {
alias(libs.plugins.kotlin.android)
alias(libs.plugins.hilt)
alias(libs.plugins.ksp)
+ alias(libs.plugins.serialization)
}
android {
@@ -43,6 +44,22 @@ dependencies {
implementation(libs.hilt.android)
ksp(libs.hilt.compiler)
+ // Serialization
+ implementation(libs.serializationJson)
+
+ // Retrofit
+ api(libs.retrofit)
+ implementation(libs.retrofitConverter)
+ implementation(libs.logging.interceptor)
+
+ // OkHttp
+ api(libs.okhttp)
+ implementation(platform(libs.okhttp.bom))
+ implementation(libs.okhttp)
+
+ // Timber
+ implementation(libs.timber)
+
// Test
testImplementation(libs.test.junit)
androidTestImplementation(libs.androidx.junit)
diff --git a/consentium/src/debug/kotlin/fr/openium/consentium/DebugNetworkModule.kt b/consentium/src/debug/kotlin/fr/openium/consentium/DebugNetworkModule.kt
new file mode 100644
index 0000000..c09d32a
--- /dev/null
+++ b/consentium/src/debug/kotlin/fr/openium/consentium/DebugNetworkModule.kt
@@ -0,0 +1,37 @@
+package fr.openium.consentium
+
+import android.content.Context
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.android.qualifiers.ApplicationContext
+import dagger.hilt.components.SingletonComponent
+import fr.openium.consentium.data.di.ConsentiumUrl
+import fr.openium.consentium.data.di.NetworkModule
+import okhttp3.HttpUrl
+import okhttp3.HttpUrl.Companion.toHttpUrl
+import okhttp3.OkHttpClient
+import okhttp3.logging.HttpLoggingInterceptor
+import timber.log.Timber
+
+@Module
+@InstallIn(SingletonComponent::class)
+class DebugNetworkModule {
+
+ @Provides
+ fun provideOkHttpBuilder(
+ @ApplicationContext context: Context,
+ ): OkHttpClient.Builder =
+ NetworkModule.standardOkHttpBuilder(context)
+ .addNetworkInterceptor(HttpLoggingInterceptor { message ->
+ Timber.tag("OkHttp")
+ Timber.v(message)
+ }.apply {
+ level = HttpLoggingInterceptor.Level.BODY
+ })
+
+ @ConsentiumUrl
+ @Provides
+ fun okHttpUrlConsentium(@ApplicationContext context: Context): HttpUrl =
+ context.getString(R.string.backend_url).toHttpUrl()
+}
\ No newline at end of file
diff --git a/consentium/src/debug/res/values/strings.xml b/consentium/src/debug/res/values/strings.xml
new file mode 100644
index 0000000..c04ccc1
--- /dev/null
+++ b/consentium/src/debug/res/values/strings.xml
@@ -0,0 +1,4 @@
+
+
+ https://consentium-api-dev.openium.fr/api/v1/app
+
\ No newline at end of file
diff --git a/consentium/src/main/java/fr/openium/consentium/data/di/NetworkModule.kt b/consentium/src/main/java/fr/openium/consentium/data/di/NetworkModule.kt
new file mode 100644
index 0000000..3680992
--- /dev/null
+++ b/consentium/src/main/java/fr/openium/consentium/data/di/NetworkModule.kt
@@ -0,0 +1,78 @@
+package fr.openium.consentium.data.di
+
+import android.content.Context
+import dagger.Lazy
+import dagger.Module
+import dagger.Provides
+import dagger.Reusable
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import fr.openium.consentium.data.remote.ConsentiumApi
+import kotlinx.serialization.json.Json
+import okhttp3.Cache
+import okhttp3.HttpUrl
+import okhttp3.MediaType.Companion.toMediaType
+import okhttp3.OkHttpClient
+import retrofit2.Retrofit
+import retrofit2.converter.kotlinx.serialization.asConverterFactory
+import java.util.concurrent.TimeUnit
+import javax.inject.Qualifier
+import javax.inject.Singleton
+
+private val json by lazy {
+ Json {
+ isLenient = true
+ ignoreUnknownKeys = true
+ }
+}
+
+@Module
+@InstallIn(SingletonComponent::class)
+internal object NetworkModule {
+
+ @OkHttpClientDefault
+ @Provides
+ @Singleton
+ fun okHttpClientDefault(
+ okHttpBuilder: OkHttpClient.Builder,
+ ): OkHttpClient = okHttpBuilder.build()
+
+ fun standardOkHttpBuilder(
+ context: Context,
+ ): OkHttpClient.Builder {
+ val cacheSize = (20 * 1024 * 1024).toLong() // 20 MiB
+ val cache = Cache(context.cacheDir, cacheSize)
+ return OkHttpClient.Builder()
+ .cache(cache)
+ .connectTimeout(10, TimeUnit.SECONDS)
+ .readTimeout(10, TimeUnit.SECONDS)
+ .writeTimeout(10, TimeUnit.SECONDS)
+ }
+
+ @Reusable
+ @Provides
+ fun provideConsentiumApi(
+ @ConsentiumUrl url: HttpUrl,
+ @OkHttpClientDefault okHttpClient: Lazy,
+ ): ConsentiumApi =
+ createRetrofit(
+ url,
+ okHttpClient
+ ).create(ConsentiumApi::class.java)
+
+ private fun createRetrofit(url: HttpUrl, okHttpClient: Lazy): Retrofit =
+ Retrofit.Builder()
+ .callFactory { request ->
+ okHttpClient.get().newCall(request)
+ }.addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
+ .baseUrl(url)
+ .build()
+}
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+internal annotation class ConsentiumUrl
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+internal annotation class OkHttpClientDefault
diff --git a/consentium/src/main/java/fr/openium/consentium/data/remote/ConsentiumApi.kt b/consentium/src/main/java/fr/openium/consentium/data/remote/ConsentiumApi.kt
new file mode 100644
index 0000000..4f3847d
--- /dev/null
+++ b/consentium/src/main/java/fr/openium/consentium/data/remote/ConsentiumApi.kt
@@ -0,0 +1,25 @@
+package fr.openium.consentium.data.remote
+
+import fr.openium.consentium.data.remote.model.GetConsent
+import fr.openium.consentium.data.remote.model.PatchConsent
+import retrofit2.http.Body
+import retrofit2.http.GET
+import retrofit2.http.PATCH
+
+
+internal interface ConsentiumApi {
+
+ @GET("/consents")
+ suspend fun getConsents(
+ applicationId: String,
+ installationId: String,
+ ): GetConsent.GetConsentPayloadDTO
+
+ @PATCH("/consents")
+ suspend fun setConsents(
+ applicationId: String,
+ installationId: String,
+ @Body patchConsent: PatchConsent.PatchConsentPayloadDTO,
+ ): Any
+
+}
\ No newline at end of file
diff --git a/consentium/src/main/java/fr/openium/consentium/data/remote/model/GetConsentPayloadDTO.kt b/consentium/src/main/java/fr/openium/consentium/data/remote/model/GetConsentPayloadDTO.kt
new file mode 100644
index 0000000..3206996
--- /dev/null
+++ b/consentium/src/main/java/fr/openium/consentium/data/remote/model/GetConsentPayloadDTO.kt
@@ -0,0 +1,44 @@
+package fr.openium.consentium.data.remote.model
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+internal sealed interface GetConsent {
+
+ @Serializable
+ data class GetConsentPayloadDTO(
+ @SerialName("installationId") val installationId: String,
+ @SerialName("purposes") val purposes: List? = null,
+ @SerialName("isValid") val isValid: Boolean,
+ )
+
+ @Serializable
+ data class PurposeDTO(
+ @SerialName("identifier") val identifier: String,
+ @SerialName("isRequired") val isRequired: Boolean,
+ @SerialName("isAccepted") val isAccepted: PurposeStatus,
+ @SerialName("vendors") val vendors: List? = null,
+ )
+
+ @Serializable
+ data class VendorDTO(
+ @SerialName("identifier") val identifier: String,
+ @SerialName("isRequired") val isRequired: Boolean,
+ @SerialName("isAccepted") val isAccepted: Boolean,
+ )
+
+ @Serializable
+ enum class PurposeStatus {
+ @SerialName("ACCEPTED")
+ ACCEPTED,
+
+ @SerialName("REJECTED")
+ REJECTED,
+
+ @SerialName("NOT_DEFINED")
+ NOT_DEFINED,
+ }
+
+}
+
+
diff --git a/consentium/src/main/java/fr/openium/consentium/data/remote/model/PatchConsentPayloadDTO.kt b/consentium/src/main/java/fr/openium/consentium/data/remote/model/PatchConsentPayloadDTO.kt
new file mode 100644
index 0000000..f7a6202
--- /dev/null
+++ b/consentium/src/main/java/fr/openium/consentium/data/remote/model/PatchConsentPayloadDTO.kt
@@ -0,0 +1,27 @@
+package fr.openium.consentium.data.remote.model
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+internal sealed interface PatchConsent {
+
+ @Serializable
+ data class PatchConsentPayloadDTO(
+ @SerialName("installationId") val installationId: String,
+ @SerialName("purposes") val purposes: List? = null,
+ )
+
+ @Serializable
+ data class PurposeDTO(
+ @SerialName("identifier") val identifier: String,
+ @SerialName("isAccepted") val isAccepted: Boolean,
+ @SerialName("vendors") val vendors: List? = null,
+ )
+
+ @Serializable
+ data class VendorDTO(
+ @SerialName("identifier") val identifier: String,
+ @SerialName("isAccepted") val isAccepted: Boolean,
+ )
+
+}
diff --git a/consentium/src/main/java/fr/openium/consentium/data/repository/ConsentiumRepository.kt b/consentium/src/main/java/fr/openium/consentium/data/repository/ConsentiumRepository.kt
new file mode 100644
index 0000000..f553d83
--- /dev/null
+++ b/consentium/src/main/java/fr/openium/consentium/data/repository/ConsentiumRepository.kt
@@ -0,0 +1,13 @@
+package fr.openium.consentium.data.repository
+
+import fr.openium.consentium.data.local.ConsentiumDataStore
+import fr.openium.consentium.data.remote.ConsentiumApi
+import javax.inject.Inject
+
+internal class ConsentiumRepository @Inject constructor(
+ private val consentiumApi: ConsentiumApi,
+ private val consentiumDataStore: ConsentiumDataStore,
+) {
+
+
+}
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index b58fe56..363d9b1 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -26,6 +26,17 @@ timber = "5.0.1"
# Material
material = "1.12.0"
+# Serialization
+serialization = "2.0.21"
+jsonSerialization = "1.7.3"
+
+# Retrofit
+retrofit = "2.11.0"
+loggingInterceptor = "4.12.0"
+
+# Okhttp
+okhttpBom = "4.12.0"
+
# Test
junit = "4.13.2"
espressoCore = "3.6.1"
@@ -94,6 +105,18 @@ androidx-navigation-compose = { group = "androidx.navigation", name = "navigatio
# Preferences DataStore
preferencesDataStore = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "preferencesDataStore" }
+# Json serialization
+serializationJson = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "jsonSerialization" }
+
+# Retrofit
+retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }
+retrofitConverter = { group = "com.squareup.retrofit2", name = "converter-kotlinx-serialization", version.ref = "retrofit" }
+logging-interceptor = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "loggingInterceptor" }
+
+# Okhttp
+okhttp-bom = { module = "com.squareup.okhttp3:okhttp-bom", version.ref = "okhttpBom" }
+okhttp = { module = "com.squareup.okhttp3:okhttp" }
+
# Test
test-junit = { group = "junit", name = "junit", version.ref = "junit" }
test-androidx-junit = { group = "androidx.test.ext", name = "junit-ktx", version.ref = "junitExtVersion" }
@@ -107,9 +130,7 @@ kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "ko
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
android-library = { id = "com.android.library", version.ref = "agp" }
hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
-kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
-
-
+serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "serialization" }
[bundles]
androidx = ["androidx-core-ktx", "androidx-activity-compose"]