feat(CON-223) : Ajouter l'auth
feat(CON-262) : Aligner les flux avec les nouveaux dev back
This commit is contained in:
parent
5303e594da
commit
c57c9b7d05
@ -72,6 +72,10 @@ android {
|
||||
dimension = "version"
|
||||
}
|
||||
|
||||
create("dev") {
|
||||
dimension = "version"
|
||||
}
|
||||
|
||||
create("demo") {
|
||||
dimension = "version"
|
||||
}
|
||||
|
@ -14,7 +14,9 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import fr.openium.consentium.R
|
||||
import fr.openium.consentium.api.Consentium
|
||||
import fr.openium.consentium.api.state.FetchConsentiumState
|
||||
|
||||
@ -25,14 +27,17 @@ fun SplashScreen(
|
||||
) {
|
||||
// Property
|
||||
val context = LocalContext.current
|
||||
val consentium = remember { Consentium(context = context, applicationId = "DemoApplicationId") }
|
||||
val consentiumKey = stringResource(R.string.consentium_api_key)
|
||||
val consentium = remember { Consentium(context = context, applicationId = consentiumKey) }
|
||||
|
||||
// Effect
|
||||
LaunchedEffect(Unit) {
|
||||
consentium.fetchConsentState.collect { consentState ->
|
||||
when (consentState) {
|
||||
FetchConsentiumState.Idle,
|
||||
FetchConsentiumState.Loading -> {}
|
||||
FetchConsentiumState.Loading,
|
||||
-> {
|
||||
}
|
||||
|
||||
FetchConsentiumState.Error -> {
|
||||
// Handle error
|
||||
|
@ -1,3 +1,4 @@
|
||||
<resources>
|
||||
<string name="app_name">Consentium</string>
|
||||
<string translatable="false" name="consentium_api_key">01938ce4-331a-7592-9e90-f09201ff4f36</string>
|
||||
</resources>
|
@ -34,6 +34,10 @@ android {
|
||||
dimension = "version"
|
||||
}
|
||||
|
||||
create("dev") {
|
||||
dimension = "version"
|
||||
}
|
||||
|
||||
create("demo") {
|
||||
dimension = "version"
|
||||
}
|
||||
|
@ -34,6 +34,10 @@ android {
|
||||
dimension = "version"
|
||||
}
|
||||
|
||||
create("dev") {
|
||||
dimension = "version"
|
||||
}
|
||||
|
||||
create("demo") {
|
||||
dimension = "version"
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package fr.openium.consentium.api
|
||||
|
||||
import android.content.Context
|
||||
import dagger.hilt.android.EntryPointAccessors
|
||||
import fr.openium.consentium.api.model.ConsentState
|
||||
import fr.openium.consentium.api.model.PurposeChoice
|
||||
import fr.openium.consentium.api.state.FetchConsentiumState
|
||||
import fr.openium.consentium.api.state.SetConsentiumState
|
||||
@ -35,7 +36,7 @@ class Consentium(
|
||||
ConsentiumRepositoryGetResponse.Error -> _fetchConsentState.value = FetchConsentiumState.Error
|
||||
|
||||
is ConsentiumRepositoryGetResponse.GetConsentsSuccess -> {
|
||||
val areConsentsValid = consentResponse.isValid
|
||||
val areConsentsValid = consentResponse.state == ConsentState.VALID
|
||||
if (areConsentsValid) {
|
||||
_fetchConsentState.value = FetchConsentiumState.Valid(purposes = consentResponse.purposes)
|
||||
} else {
|
||||
|
@ -0,0 +1,11 @@
|
||||
package fr.openium.consentium.api.adapter
|
||||
|
||||
import fr.openium.consentium.api.model.ConsentState
|
||||
import fr.openium.consentium.data.remote.model.GetConsent
|
||||
|
||||
internal fun GetConsent.ConsentStateDTO.toConsentState(): ConsentState = when (this) {
|
||||
GetConsent.ConsentStateDTO.UNSET -> ConsentState.UNSET
|
||||
GetConsent.ConsentStateDTO.VALID -> ConsentState.VALID
|
||||
GetConsent.ConsentStateDTO.EXPIRED -> ConsentState.EXPIRED
|
||||
GetConsent.ConsentStateDTO.NEW_VERSION -> ConsentState.NEW_VERSION
|
||||
}
|
@ -5,7 +5,6 @@ import fr.openium.consentium.data.remote.model.GetConsent
|
||||
|
||||
internal fun GetConsent.PurposeDTO.toPurpose() = Purpose(
|
||||
identifier = identifier,
|
||||
isRequired = isRequired,
|
||||
isAccepted = isAccepted.toPurposeStatus(),
|
||||
choice = choice.toPurposeStatus(),
|
||||
vendors = vendors?.map { it.toVendor() } ?: emptyList(),
|
||||
)
|
||||
|
@ -4,7 +4,7 @@ import fr.openium.consentium.api.model.PurposeChoice
|
||||
import fr.openium.consentium.data.remote.model.PatchConsent
|
||||
|
||||
internal fun PurposeChoice.toPatchConsentPurposeDTO() = PatchConsent.PurposeDTO(
|
||||
identifier = purposeIdentifier.toString(),
|
||||
isAccepted = isAccepted,
|
||||
identifier = purposeIdentifier,
|
||||
choice = choice.toPurposeStatusDTO(),
|
||||
vendors = vendors.map { it.toPatchConsentVendorDTO() }
|
||||
)
|
@ -2,9 +2,16 @@ package fr.openium.consentium.api.adapter
|
||||
|
||||
import fr.openium.consentium.api.model.PurposeStatus
|
||||
import fr.openium.consentium.data.remote.model.GetConsent
|
||||
import fr.openium.consentium.data.remote.model.PatchConsent
|
||||
|
||||
internal fun GetConsent.PurposeStatusDTO.toPurposeStatus() = when (this) {
|
||||
GetConsent.PurposeStatusDTO.ACCEPTED -> PurposeStatus.ACCEPTED
|
||||
GetConsent.PurposeStatusDTO.REJECTED -> PurposeStatus.REJECTED
|
||||
GetConsent.PurposeStatusDTO.NOT_DEFINED -> PurposeStatus.NOT_DEFINED
|
||||
GetConsent.PurposeStatusDTO.PARTIAL -> PurposeStatus.PARTIAL
|
||||
}
|
||||
|
||||
internal fun PurposeStatus.toPurposeStatusDTO() = when (this) {
|
||||
PurposeStatus.ACCEPTED -> PatchConsent.PurposeStatusDTO.ACCEPTED
|
||||
PurposeStatus.REJECTED -> PatchConsent.PurposeStatusDTO.REJECTED
|
||||
PurposeStatus.PARTIAL -> PatchConsent.PurposeStatusDTO.PARTIAL
|
||||
}
|
@ -4,6 +4,6 @@ import fr.openium.consentium.api.model.VendorChoice
|
||||
import fr.openium.consentium.data.remote.model.PatchConsent
|
||||
|
||||
internal fun VendorChoice.toPatchConsentVendorDTO() = PatchConsent.VendorDTO(
|
||||
identifier = vendorIdentifier.toString(),
|
||||
identifier = vendorIdentifier,
|
||||
isAccepted = isAccepted,
|
||||
)
|
@ -0,0 +1,8 @@
|
||||
package fr.openium.consentium.api.model
|
||||
|
||||
enum class ConsentState {
|
||||
UNSET,
|
||||
VALID,
|
||||
EXPIRED,
|
||||
NEW_VERSION,
|
||||
}
|
@ -2,7 +2,6 @@ package fr.openium.consentium.api.model
|
||||
|
||||
data class Purpose(
|
||||
val identifier: String,
|
||||
val isRequired: Boolean,
|
||||
val isAccepted: PurposeStatus,
|
||||
val choice: PurposeStatus,
|
||||
val vendors: List<Vendor>,
|
||||
)
|
@ -2,6 +2,6 @@ package fr.openium.consentium.api.model
|
||||
|
||||
data class PurposeChoice(
|
||||
val purposeIdentifier: String,
|
||||
val isAccepted: Boolean,
|
||||
val choice: PurposeStatus,
|
||||
val vendors: List<VendorChoice>,
|
||||
)
|
@ -3,6 +3,5 @@ package fr.openium.consentium.api.model
|
||||
enum class PurposeStatus {
|
||||
ACCEPTED,
|
||||
REJECTED,
|
||||
NOT_DEFINED,
|
||||
UNKNOWN,
|
||||
PARTIAL,
|
||||
}
|
@ -5,20 +5,20 @@ import fr.openium.consentium.data.remote.model.PatchConsent
|
||||
import retrofit2.Response
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.PATCH
|
||||
import retrofit2.http.Header
|
||||
import retrofit2.http.POST
|
||||
|
||||
|
||||
internal interface ConsentiumApi {
|
||||
|
||||
@GET("/consents")
|
||||
suspend fun getConsents(
|
||||
applicationId: String,
|
||||
installationId: String,
|
||||
@Header("Authorization") token: String,
|
||||
): Response<GetConsent.GetConsentPayloadDTO>
|
||||
|
||||
@PATCH("/consents")
|
||||
@POST("/consents")
|
||||
suspend fun setConsents(
|
||||
applicationId: String,
|
||||
@Header("Authorization") token: String,
|
||||
@Body patchConsent: PatchConsent.PatchConsentPayloadDTO,
|
||||
): Response<Any>
|
||||
|
||||
|
@ -10,41 +10,29 @@ import java.util.UUID
|
||||
internal object ConsentiumMockApi : ConsentiumApi {
|
||||
|
||||
private val consents = GetConsent.GetConsentPayloadDTO(
|
||||
id = UUID.randomUUID().toString(),
|
||||
installationId = UUID.randomUUID().toString(),
|
||||
purposes = listOf(
|
||||
GetConsent.PurposeDTO(
|
||||
identifier = "purpose-audience",
|
||||
isRequired = true,
|
||||
isAccepted = GetConsent.PurposeStatusDTO.ACCEPTED,
|
||||
vendors = listOf(
|
||||
GetConsent.VendorDTO(
|
||||
identifier = "vendor-clarity",
|
||||
isAccepted = true,
|
||||
isRequired = true,
|
||||
),
|
||||
GetConsent.VendorDTO(
|
||||
identifier = "vendor-matomo",
|
||||
isAccepted = true,
|
||||
isRequired = false,
|
||||
)
|
||||
)
|
||||
vendors = null,
|
||||
choice = GetConsent.PurposeStatusDTO.ACCEPTED,
|
||||
),
|
||||
GetConsent.PurposeDTO(
|
||||
identifier = "purpose-required",
|
||||
isRequired = true,
|
||||
isAccepted = GetConsent.PurposeStatusDTO.REJECTED,
|
||||
vendors = null
|
||||
vendors = null,
|
||||
choice = GetConsent.PurposeStatusDTO.REJECTED,
|
||||
),
|
||||
),
|
||||
isValid = false,
|
||||
state = GetConsent.ConsentStateDTO.VALID,
|
||||
)
|
||||
|
||||
override suspend fun getConsents(applicationId: String, installationId: String): Response<GetConsent.GetConsentPayloadDTO> {
|
||||
override suspend fun getConsents(token: String): Response<GetConsent.GetConsentPayloadDTO> {
|
||||
delay(2000)
|
||||
return Response.success(consents)
|
||||
}
|
||||
|
||||
override suspend fun setConsents(applicationId: String, patchConsent: PatchConsent.PatchConsentPayloadDTO): Response<Any> {
|
||||
override suspend fun setConsents(token: String, patchConsent: PatchConsent.PatchConsentPayloadDTO): Response<Any> {
|
||||
delay(2000)
|
||||
return Response.success(Unit)
|
||||
}
|
||||
|
@ -7,16 +7,17 @@ internal sealed interface GetConsent {
|
||||
|
||||
@Serializable
|
||||
data class GetConsentPayloadDTO(
|
||||
@SerialName("id") val id: String,
|
||||
@SerialName("installationId") val installationId: String,
|
||||
@SerialName("state") val state: ConsentStateDTO? = null,
|
||||
@SerialName("acceptedDate") val acceptedData: Long? = null,
|
||||
@SerialName("purposes") val purposes: List<PurposeDTO>? = null,
|
||||
@SerialName("isValid") val isValid: Boolean,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class PurposeDTO(
|
||||
@SerialName("identifier") val identifier: String,
|
||||
@SerialName("isRequired") val isRequired: Boolean,
|
||||
@SerialName("isAccepted") val isAccepted: PurposeStatusDTO,
|
||||
@SerialName("choice") val choice: PurposeStatusDTO,
|
||||
@SerialName("vendors") val vendors: List<VendorDTO>? = null,
|
||||
)
|
||||
|
||||
@ -29,16 +30,30 @@ internal sealed interface GetConsent {
|
||||
|
||||
@Serializable
|
||||
enum class PurposeStatusDTO {
|
||||
@SerialName("ACCEPTED")
|
||||
@SerialName("accepted")
|
||||
ACCEPTED,
|
||||
|
||||
@SerialName("REJECTED")
|
||||
@SerialName("refused")
|
||||
REJECTED,
|
||||
|
||||
@SerialName("NOT_DEFINED")
|
||||
NOT_DEFINED,
|
||||
@SerialName("partial")
|
||||
PARTIAL,
|
||||
}
|
||||
|
||||
@Serializable
|
||||
enum class ConsentStateDTO {
|
||||
@SerialName("unset")
|
||||
UNSET,
|
||||
|
||||
@SerialName("valid")
|
||||
VALID,
|
||||
|
||||
@SerialName("expired")
|
||||
EXPIRED,
|
||||
|
||||
@SerialName("new_version")
|
||||
NEW_VERSION,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -7,14 +7,13 @@ internal sealed interface PatchConsent {
|
||||
|
||||
@Serializable
|
||||
data class PatchConsentPayloadDTO(
|
||||
@SerialName("installationId") val installationId: String,
|
||||
@SerialName("purposes") val purposes: List<PurposeDTO>? = null,
|
||||
@SerialName("consentPurposes") val purposes: List<PurposeDTO>? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class PurposeDTO(
|
||||
@SerialName("identifier") val identifier: String,
|
||||
@SerialName("isAccepted") val isAccepted: Boolean,
|
||||
@SerialName("choice") val choice: PurposeStatusDTO,
|
||||
@SerialName("vendors") val vendors: List<VendorDTO>? = null,
|
||||
)
|
||||
|
||||
@ -24,4 +23,16 @@ internal sealed interface PatchConsent {
|
||||
@SerialName("isAccepted") val isAccepted: Boolean,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
enum class PurposeStatusDTO {
|
||||
@SerialName("accepted")
|
||||
ACCEPTED,
|
||||
|
||||
@SerialName("refused")
|
||||
REJECTED,
|
||||
|
||||
@SerialName("partial")
|
||||
PARTIAL,
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,22 +1,24 @@
|
||||
package fr.openium.consentium.domain.repository
|
||||
|
||||
import fr.openium.consentium.api.adapter.toConsentState
|
||||
import fr.openium.consentium.api.adapter.toPatchConsentPurposeDTO
|
||||
import fr.openium.consentium.api.adapter.toPurpose
|
||||
import fr.openium.consentium.api.model.ConsentState
|
||||
import fr.openium.consentium.api.model.Purpose
|
||||
import fr.openium.consentium.api.model.PurposeChoice
|
||||
import fr.openium.consentium.data.local.ConsentiumDataStore
|
||||
import fr.openium.consentium.data.remote.ConsentiumApi
|
||||
import fr.openium.consentium.data.remote.model.PatchConsent
|
||||
import fr.openium.consentium.domain.useCase.GetAuthTokenUseCase
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class ConsentiumRepository @Inject constructor(
|
||||
private val consentiumApi: ConsentiumApi,
|
||||
private val consentiumDataStore: ConsentiumDataStore,
|
||||
private val getAuthTokenUseCase: GetAuthTokenUseCase,
|
||||
) {
|
||||
|
||||
suspend fun getConsents(applicationId: String): ConsentiumRepositoryGetResponse {
|
||||
val installationId = consentiumDataStore.getInstallationUniqueId()
|
||||
val consentsResponse = consentiumApi.getConsents(applicationId, installationId)
|
||||
val authToken = getAuthTokenUseCase(applicationId)
|
||||
val consentsResponse = consentiumApi.getConsents(authToken)
|
||||
return try {
|
||||
val consentsBody = if (consentsResponse.isSuccessful) {
|
||||
consentsResponse.body() ?: throw Exception()
|
||||
@ -25,7 +27,7 @@ internal class ConsentiumRepository @Inject constructor(
|
||||
}
|
||||
|
||||
return ConsentiumRepositoryGetResponse.GetConsentsSuccess(
|
||||
isValid = consentsBody.isValid,
|
||||
state = consentsBody.state?.toConsentState() ?: ConsentState.UNSET,
|
||||
purposes = consentsBody.purposes?.map { purpose -> purpose.toPurpose() } ?: emptyList()
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
@ -37,12 +39,11 @@ internal class ConsentiumRepository @Inject constructor(
|
||||
applicationId: String,
|
||||
consents: List<PurposeChoice>,
|
||||
): ConsentiumRepositorySetResponse {
|
||||
val installationId = consentiumDataStore.getInstallationUniqueId()
|
||||
val authToken = getAuthTokenUseCase(applicationId)
|
||||
|
||||
val setConsentResponse = consentiumApi.setConsents(
|
||||
applicationId = applicationId,
|
||||
token = authToken,
|
||||
patchConsent = PatchConsent.PatchConsentPayloadDTO(
|
||||
installationId = installationId,
|
||||
purposes = consents.map { it.toPatchConsentPurposeDTO() },
|
||||
)
|
||||
)
|
||||
@ -61,7 +62,7 @@ internal interface ConsentiumRepositoryGetResponse {
|
||||
data object Error : ConsentiumRepositoryGetResponse
|
||||
|
||||
data class GetConsentsSuccess(
|
||||
val isValid: Boolean,
|
||||
val state: ConsentState,
|
||||
val purposes: List<Purpose>,
|
||||
) : ConsentiumRepositoryGetResponse
|
||||
|
||||
|
@ -0,0 +1,23 @@
|
||||
package fr.openium.consentium.domain.useCase
|
||||
|
||||
import javax.inject.Inject
|
||||
import kotlin.io.encoding.Base64
|
||||
import kotlin.io.encoding.ExperimentalEncodingApi
|
||||
|
||||
interface GetAuthTokenUseCase {
|
||||
suspend operator fun invoke(applicationId: String): String
|
||||
}
|
||||
|
||||
class GetAuthTokenUseCaseImpl @Inject internal constructor(
|
||||
private val getConsentiumUniqueInstallationIdUseCase: GetConsentiumUniqueInstallationIdUseCase,
|
||||
) : GetAuthTokenUseCase {
|
||||
|
||||
@OptIn(ExperimentalEncodingApi::class)
|
||||
override suspend operator fun invoke(applicationId: String): String {
|
||||
val uniqueInstallationId = getConsentiumUniqueInstallationIdUseCase()
|
||||
val clearToken = "$applicationId.$uniqueInstallationId"
|
||||
val cipheredToken = Base64.Default.encode(clearToken.toByteArray())
|
||||
return "Bearer $cipheredToken"
|
||||
}
|
||||
|
||||
}
|
@ -4,14 +4,14 @@ import fr.openium.consentium.data.local.ConsentiumDataStore
|
||||
import javax.inject.Inject
|
||||
|
||||
interface GetConsentiumUniqueInstallationIdUseCase {
|
||||
suspend fun invoke(): String
|
||||
suspend operator fun invoke(): String
|
||||
}
|
||||
|
||||
class GetConsentiumUniqueInstallationIdUseCaseImpl @Inject internal constructor(
|
||||
private val consentiumDataStore: ConsentiumDataStore,
|
||||
) : GetConsentiumUniqueInstallationIdUseCase {
|
||||
|
||||
override suspend fun invoke(): String {
|
||||
override suspend operator fun invoke(): String {
|
||||
return consentiumDataStore.getInstallationUniqueId()
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,8 @@ import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import fr.openium.consentium.domain.useCase.GetAuthTokenUseCase
|
||||
import fr.openium.consentium.domain.useCase.GetAuthTokenUseCaseImpl
|
||||
import fr.openium.consentium.domain.useCase.GetConsentiumUniqueInstallationIdUseCase
|
||||
import fr.openium.consentium.domain.useCase.GetConsentiumUniqueInstallationIdUseCaseImpl
|
||||
|
||||
@ -16,4 +18,8 @@ interface ConsentiumUseCaseModule {
|
||||
getUniqueInstallationIdUseCaseImpl: GetConsentiumUniqueInstallationIdUseCaseImpl,
|
||||
): GetConsentiumUniqueInstallationIdUseCase
|
||||
|
||||
@Binds
|
||||
fun bindGetAuthTokenUseCase(
|
||||
getAuthTokenUseCaseImpl: GetAuthTokenUseCaseImpl,
|
||||
): GetAuthTokenUseCase
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user