From 20ed4290adf70627f0a8657c0f6b4ef3c74a92a6 Mon Sep 17 00:00:00 2001 From: Iulia Stana Date: Tue, 7 Mar 2023 08:13:28 +0100 Subject: [PATCH] Working request with manual token --- .../main/kotlin/nl/eduid/di/AppQualifiers.kt | 8 +++ .../main/kotlin/nl/eduid/di/api/EduIdApi.kt | 5 +- .../nl/eduid/di/auth/TokenAuthenticator.kt | 42 +++++++++++++++ .../nl/eduid/di/auth/TokenInterceptor.kt | 26 +++++++++ .../kotlin/nl/eduid/di/auth/TokenProvider.kt | 38 +++++++++++++ .../kotlin/nl/eduid/di/model/EduIdModels.kt | 54 ++++++++++++++++++- .../kotlin/nl/eduid/di/module/EduIdModule.kt | 47 ++++++++++++++-- .../eduid/di/repository/StorageRepository.kt | 2 + .../screens/personalinfo/PersonalInfoData.kt | 14 ++--- .../personalinfo/PersonalInfoRepository.kt | 21 ++++++++ .../personalinfo/PersonalInfoScreen.kt | 33 ++++++++++-- .../personalinfo/PersonalInfoViewModel.kt | 25 +++++++-- 12 files changed, 295 insertions(+), 20 deletions(-) create mode 100644 app/src/main/kotlin/nl/eduid/di/AppQualifiers.kt create mode 100644 app/src/main/kotlin/nl/eduid/di/auth/TokenAuthenticator.kt create mode 100644 app/src/main/kotlin/nl/eduid/di/auth/TokenInterceptor.kt create mode 100644 app/src/main/kotlin/nl/eduid/di/auth/TokenProvider.kt create mode 100644 app/src/main/kotlin/nl/eduid/screens/personalinfo/PersonalInfoRepository.kt diff --git a/app/src/main/kotlin/nl/eduid/di/AppQualifiers.kt b/app/src/main/kotlin/nl/eduid/di/AppQualifiers.kt new file mode 100644 index 00000000..19fa310c --- /dev/null +++ b/app/src/main/kotlin/nl/eduid/di/AppQualifiers.kt @@ -0,0 +1,8 @@ +package nl.eduid.di + +import javax.inject.Qualifier + +@Qualifier +@MustBeDocumented +@Retention(AnnotationRetention.RUNTIME) +internal annotation class EduIdScope diff --git a/app/src/main/kotlin/nl/eduid/di/api/EduIdApi.kt b/app/src/main/kotlin/nl/eduid/di/api/EduIdApi.kt index b7c5b034..3f692464 100644 --- a/app/src/main/kotlin/nl/eduid/di/api/EduIdApi.kt +++ b/app/src/main/kotlin/nl/eduid/di/api/EduIdApi.kt @@ -1,7 +1,7 @@ package nl.eduid.di.api import nl.eduid.di.model.RequestNewIdRequest -import org.tiqr.data.api.TokenApi +import nl.eduid.di.model.UserDetails import retrofit2.Response import retrofit2.http.* @@ -11,4 +11,7 @@ import retrofit2.http.* interface EduIdApi { @POST("myconext/api/idp/magic_link_request/") suspend fun requestNewEduId(@Body request: RequestNewIdRequest): Response + + @GET("mobile/api/sp/me") + suspend fun getUserDetails(): Response } \ No newline at end of file diff --git a/app/src/main/kotlin/nl/eduid/di/auth/TokenAuthenticator.kt b/app/src/main/kotlin/nl/eduid/di/auth/TokenAuthenticator.kt new file mode 100644 index 00000000..546b8779 --- /dev/null +++ b/app/src/main/kotlin/nl/eduid/di/auth/TokenAuthenticator.kt @@ -0,0 +1,42 @@ +package nl.eduid.di.auth + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.runBlocking +import okhttp3.Authenticator +import okhttp3.Request +import okhttp3.Response +import okhttp3.Route +import timber.log.Timber +import javax.inject.Inject + +class TokenAuthenticator @Inject constructor( + private val tokenProvider: TokenProvider +) : Authenticator { + + private var currentToken: String? = + "eyJraWQiOiJrZXlfMjAyM18wM18wN18wMF8wMF8wMF8wMTYiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOlsiZGV2LmVnZW5pcS5ubCIsIm15Y29uZXh0LnJzIl0sInN1YiI6ImRldi5lZ2VuaXEubmwiLCJuYmYiOjE2NzgxNzI2MDYsInNjb3BlIjoiZWR1aWQubmxcL21vYmlsZSIsImlzcyI6Imh0dHBzOlwvXC9jb25uZWN0LnRlc3QyLnN1cmZjb25leHQubmwiLCJjbGFpbXMiOiJBUTkxeUt6RTRRTW5odTdkaXZuMGRlQ1wvMm5CaWY1M1Jpa1laVWFPWktiNkVaQWJnbzdZY1RKSFNiQTVWeVwvejg4Y3JOYmZSQmJscnNqNDk3eGc2cXhaNll2YStXNkdoOFpTXC8xakxRQ2QzV3E1b05hajlkZkFJQjVLWDRBXC9hSEhXUDN6M0wycmlUSitJTlF5Uk5BOTkrUDZ0UWFPSWd3aFwvYmRUcllRZEVNQU1GeXVwSkh1b0tDU0pZR2kwNDY3Nnp5aGNkeXVncU9WOG1nR3JvTVFWZExKdTBFRzJ3V0laSVhUUmlsbXJmdzhqYittaW5wS01mY0pRb1NQYWVLbVNJdWx1OUU3WW14YmI3Z09kMEpMN3BkY2lrZUFId1pvazBCdDg5XC8rcnNzNlFxbUxWQVRGa1Qyb0YzK0h6amowVGtmdFFIRW44OGZOS1BoUGQ4U1wvS25EQytpTDlpQ3BEZkdcL2xpWWw4SUJHYUNwRnpOWjROd2JxaEM3YnpiVkZiVEdSK3ZTa2JqRTlFZ00yXC9UZk9KckNRaDM0c1VKXC9nVUJOc1JnV1EyeUpYSkl5Rk9IZWtiR3gyV0o1WkUxZ1wvV0pzcENZYXRUTFhIQ2pvSU9YdkVRRWNmZlNYWlFWbThBb09hbG9OWEFuNDZ1UjBZRXdtNk9xekFkcjlVcEp1Tjg1VVlYZDcxMStCcFEyQW1FQ3BMMWJYXC8zaFlcL1lhZzNMQzZsV2xROERuS1VkXC9xUitJMmdmbzlaZmk2R1NqOVl3dWxhbHBrcjdSOWpnTWNYQTZlRWc0R0JUdEdGK1BGdlwvaFQxMXBLZ3RQWlZqeVA1dlI5KzRDOE1qY1NtU0s1bzg2eitqVkk3Y1RkSk1odjRRSFA2ZUF2aFRoc0dvRElLV2wwbjVIIiwiZXhwIjoxNjc4MTc2MjA2LCJjbGFpbV9rZXlfaWQiOiIyNTkzNzczMjQiLCJpYXQiOjE2NzgxNzI2MDYsImp0aSI6ImJkZWFmOTU2LWExZjUtNDFjZC1hMTVmLWY4MGZhMzM2ZDA0OSJ9.pXguHBZ8eor1CdNmWZKZaJW4jdeGQGrz6XIBZf13-ZUkr3HQu5KlH9RT4wIDF_3cnfmlqqE6tn5DOBG-4xdyVbfcbyEM4seckT55XcturQlrW-QXL9v6jq2jk5QAp0b8Foj7LYGc1pqPIaPQj_WaOBq8ddtrY8uqf4npapM_5nNe8w2z3Y6F3xQ4rkgfyJ1bKtupYJK7aGEBhbN75hkyV4TbkWh9Jwv2cBazxpLfUNbg05W32PFcrTyNIX5lslu-meCzSe6SKctLIjfFdQPpvZlPDXF_hoiyBW-r98SpQOf0CQBHyvYu4YubpQXXP5EvUkLZPM02zLJTUun2EIRAng" + + override fun authenticate(route: Route?, response: Response): Request? { + synchronized(this) { + Timber.e("Authenticator intercept. Running on: ${Thread.currentThread().name}") + val previousToken = currentToken + return response.request.newBuilder().header( + "Authorization", "Bearer $currentToken" + ).build() + +// return runBlocking(Dispatchers.IO) { +// Timber.e("Blocking. Running on: ${Thread.currentThread().name}") +// val token = tokenProvider.refreshToken() +// +// if (token != previousToken) { +// currentToken = token +// response.request.newBuilder().header( +// "Authorization", "Bearer $token" +// ).build() +// } else { +// null +// } +// } + } + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/nl/eduid/di/auth/TokenInterceptor.kt b/app/src/main/kotlin/nl/eduid/di/auth/TokenInterceptor.kt new file mode 100644 index 00000000..f32bf90b --- /dev/null +++ b/app/src/main/kotlin/nl/eduid/di/auth/TokenInterceptor.kt @@ -0,0 +1,26 @@ +package nl.eduid.di.auth + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.runBlocking +import okhttp3.Interceptor +import okhttp3.Response +import javax.inject.Inject + +class TokenInterceptor @Inject constructor(private val tokenProvider: TokenProvider) : Interceptor { + override fun intercept(chain: Interceptor.Chain): Response { + val request = chain.request() + if (request.header("Authorization") == null) { + return runBlocking(Dispatchers.IO) { + val token = tokenProvider.getToken() + if (token != null) { + chain.proceed( + request.newBuilder().addHeader("Authorization", "Bearer $token").build() + ) + } else { + chain.proceed(request) + } + } + } + return chain.proceed(request) + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/nl/eduid/di/auth/TokenProvider.kt b/app/src/main/kotlin/nl/eduid/di/auth/TokenProvider.kt new file mode 100644 index 00000000..594f689f --- /dev/null +++ b/app/src/main/kotlin/nl/eduid/di/auth/TokenProvider.kt @@ -0,0 +1,38 @@ +package nl.eduid.di.auth + +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.firstOrNull +import nl.eduid.di.repository.StorageRepository +import timber.log.Timber +import java.util.* +import kotlin.NoSuchElementException + +class TokenProvider(private val repository: StorageRepository) { + private var token: String? = + "eyJraWQiOiJrZXlfMjAyM18wM18wMl8wMF8wMF8wMF8wMDAiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOlsiZGV2LmVnZW5pcS5ubCIsIm15Y29uZXh0LnJzIl0sInN1YiI6ImRldi5lZ2VuaXEubmwiLCJuYmYiOjE2Nzc3NzMxNjMsInNjb3BlIjoiZWR1aWQubmxcL21vYmlsZSIsImlzcyI6Imh0dHBzOlwvXC9jb25uZWN0LnRlc3QyLnN1cmZjb25leHQubmwiLCJjbGFpbXMiOiJBUTkxeUt4S3UrOEFjcFlhd0lYdTVwK1lFK01RSFpocTJiUVBMYlZMTE9IWmt0dUJBMDFTNXZ4M2dtVmpzdllldFYyMFVtVGJFMDl6SjMzSENKNk1kVjE3SWxGSDdiK1ZpMUkyKzBFQThWVFdWdlwvQkpmcnkxcFBLVGJ4dWdMbFNaN0tHRGdzamp3VU9DWW8wS3JmTmYxK0VZVUMyeWIxdXV0a0lFWWx1WHZRT2RCY1JicjRCellpbkFSMUY3Y0FcL2swVUlWSFpSRU9wVjRCejNuODc0SWZxOFJZT2NsaldkUjF2XC9cL0V3Q00zUDRCM2s4dFRLVnBzaU13Y0tjVlZ6dWhIWkZaZHFONVhUMWZXSHhNMW1RekFoQVpJdnFSbXpYOGx5MFEzTXU4ZEdQSE9SS1h5djgzUkFBRDBXbmpFYWhUXC9zNUppWnowUEtZdm9xSmV0WTZieUF5cVdMQUwzMDVDOUpHaXRCZGxtdjdvcWFWczJDeFNnSGhydFNSQWZSSXAxQURyU2oxWktLaVBBS3NuMDNuZ3duK250d1wvRnBVVU1kQ1Y3SU95QWtxS2lHREJsVUJ4aDlNK0N6M3V5TUtiYmlnUVZHV1pzMUZONmt3b01oTm43MllQbzRCZjBLNnNqVll5VUVzMWlpUUJNckZxS01LQlZFa3V3MkZTV2RvMXVyYmdYKzFsQTZROFpkQlNORlE3WnVPOWU5Q1E5MHhDS2tDV1NjbyswcFdBbHFRWWhLaVEyOHBNOWphblwvcWxsVjJST2dmaE45a0JqejllaldKUUpJK0x1V3kzZUxSQmcyalwvcWlrZmt6elJvRVwvb21Ba1VSOUsxbHNzNTZ6Rm9pUUtSeUZySTBtU0xcL2tHQnhERmR5anBHa3J5Z0FLRUtLVUsyaiIsImV4cCI6MTY3Nzc3Njc2MywiY2xhaW1fa2V5X2lkIjoiMjU5Mzc3MzI0IiwiaWF0IjoxNjc3NzczMTYzLCJqdGkiOiI0YWJmOGRmNy02MzQxLTQ3NjUtYTQyNy1iOTU3MzY5YTRkN2MifQ.V3x94XrR_xBWejsJwlU0HTEO7AejEd770DJoH1iSfIk1ChVgdaZU1XX1BZzPji8pVEuB22aJCps5EAoMX5aNP3qkF7r7FDDqdhsRdT-2n855uOeT_6VGQ10caz5wO4HFOxSUZRn-9EJOfQNb-FYLI8ZlqdGy6JpjCBrHOKzRgFYjQjMmTM2zbx6ahyLk4bj_STU-jPnDgPvL4L05UcuR1WwBfGkcnVOpteZSnb4Hm64ibD9Zp7YdAVPSI39iHoq-z3ZieIbryZbu4FCUdkv0dgi0Oo3ueb0mTD14K2YCdOBw15SbfLertnS8L-aNg08cx-6xcp0S2VXE0K7dcJD_1g" + + suspend fun getToken(): String? = token ?: refreshToken() + + suspend fun refreshToken(): String? { + token = if (!repository.isAuthorized.first()) { + Timber.e("Not authorized. Token missing") + null + } else { + try { + //Todo: to an actual token refresh here + val authState = repository.authState.firstOrNull() + val expiresAt = Date(authState?.accessTokenExpirationTime ?: 0) + val accessToken = authState?.accessToken + Timber.e( + "Is authorized. token is available: $accessToken, expires at $expiresAt" + ) + accessToken + } catch (ex: NoSuchElementException) { + Timber.w(ex, "Error refreshing token") + null + } + } + return token + + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/nl/eduid/di/model/EduIdModels.kt b/app/src/main/kotlin/nl/eduid/di/model/EduIdModels.kt index 214fa821..a733c1b4 100644 --- a/app/src/main/kotlin/nl/eduid/di/model/EduIdModels.kt +++ b/app/src/main/kotlin/nl/eduid/di/model/EduIdModels.kt @@ -1,5 +1,9 @@ package nl.eduid.di.model +import android.os.Parcelable +import com.squareup.moshi.JsonClass +import kotlinx.parcelize.Parcelize + data class RequestNewIdRequest( val user: User, @@ -12,4 +16,52 @@ data class RequestNewIdRequest( ) } -//{"user":{"email":"test4@test.com","givenName":"Tester","familyName":"Testerson"},"authenticationRequestId":"48e0eb5f-62ae-429e-b103-444ad24f2cc0"} \ No newline at end of file +//{"user":{"email":"test4@test.com","givenName":"Tester","familyName":"Testerson"},"authenticationRequestId":"48e0eb5f-62ae-429e-b103-444ad24f2cc0"} + + +@Parcelize +@JsonClass(generateAdapter = true) +data class UserDetails( + val id: String, + val email: String, + val givenName: String, + val familyName: String, + val usePassword: Boolean, + val usePublicKey: Boolean, + val forgottenPassword: Boolean, +// val publicKeyCredentials: List, + val linkedAccounts: List, + val schacHomeOrganization: String, + val uid: String, + val rememberMe: Boolean, + val created: Long, + + val eduIdPerServiceProvider: Map, + + val loginOptions: List, +// val registration: JsonObject +) : Parcelable + +@Parcelize +@JsonClass(generateAdapter = true) +data class EduIdPerServiceProvider( + val serviceProviderEntityId: String, + val value: String, + val serviceName: String, + val serviceNameNl: String, + val serviceLogoUrl: String, + val createdAt: Long +) : Parcelable + +@Parcelize +@JsonClass(generateAdapter = true) +data class LinkedAccount( + val institutionIdentifier: String, + val schacHomeOrganization: String, + val eduPersonPrincipalName: String, + val givenName: String, + val familyName: String, + val eduPersonAffiliations: List, + val createdAt: Long, + val expiresAt: Long +) : Parcelable \ No newline at end of file diff --git a/app/src/main/kotlin/nl/eduid/di/module/EduIdModule.kt b/app/src/main/kotlin/nl/eduid/di/module/EduIdModule.kt index 525d5645..b61d8936 100644 --- a/app/src/main/kotlin/nl/eduid/di/module/EduIdModule.kt +++ b/app/src/main/kotlin/nl/eduid/di/module/EduIdModule.kt @@ -8,11 +8,18 @@ import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent +import nl.eduid.di.EduIdScope import nl.eduid.di.api.EduIdApi import nl.eduid.di.assist.AuthenticationAssistant +import nl.eduid.di.auth.TokenAuthenticator +import nl.eduid.di.auth.TokenInterceptor +import nl.eduid.di.auth.TokenProvider import nl.eduid.di.repository.EduIdRepository import nl.eduid.di.repository.StorageRepository +import nl.eduid.screens.personalinfo.PersonalInfoRepository import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import org.tiqr.data.BuildConfig import org.tiqr.data.api.response.ApiResponseAdapterFactory import retrofit2.Retrofit import retrofit2.converter.moshi.MoshiConverterFactory @@ -29,7 +36,8 @@ internal object RepositoryModule { @Provides @Singleton - internal fun provideEduApi(retrofit: Retrofit): EduIdApi = retrofit.create(EduIdApi::class.java) + internal fun provideEduApi(@EduIdScope retrofit: Retrofit): EduIdApi = + retrofit.create(EduIdApi::class.java) @Provides @@ -38,12 +46,41 @@ internal object RepositoryModule { api: EduIdApi, ) = EduIdRepository(api) + @Provides + @Singleton + internal fun providesPersonalInfoRepository( + api: EduIdApi, + ) = PersonalInfoRepository(api) + @Provides @Singleton internal fun providesStorageRepository( @ApplicationContext context: Context, ) = StorageRepository(context) + @Provides + @Singleton + internal fun providesTokenProvider( + repository: StorageRepository + ) = TokenProvider(repository) + + @Provides + @EduIdScope + fun providesTokenAuthOkHttp( + tokenAuthenticator: TokenAuthenticator, + tokenInterceptor: TokenInterceptor, + loggingInterceptor: HttpLoggingInterceptor, + okHttpClient: OkHttpClient + ): OkHttpClient { + val builder = okHttpClient.newBuilder() + if (BuildConfig.DEBUG) { + builder.addInterceptor(loggingInterceptor) + } + + return builder.addInterceptor(tokenInterceptor) + .authenticator(tokenAuthenticator).build() + } + @Provides @Singleton internal fun providesAuthenticationAssist( @@ -51,14 +88,15 @@ internal object RepositoryModule { @Provides @Singleton - internal fun provideApiRetrofit( - client: Lazy, moshi: Moshi + @EduIdScope + internal fun provideEduIdRetrofit( + @EduIdScope client: Lazy, moshi: Moshi ): Retrofit { return Retrofit.Builder().callFactory { client.get().newCall(it) } .addCallAdapterFactory(ApiResponseAdapterFactory.create()) .addConverterFactory(ScalarsConverterFactory.create()) .addConverterFactory(MoshiConverterFactory.create(moshi)) - .baseUrl("https://login.eduid.nl/").build() + .baseUrl("https://login.test2.eduid.nl/").build() } @Provides @@ -66,5 +104,4 @@ internal object RepositoryModule { internal fun provideOkHttpClientBuilder(): OkHttpClient { return OkHttpClient.Builder().connectTimeout(15, TimeUnit.SECONDS).build() } - } \ No newline at end of file diff --git a/app/src/main/kotlin/nl/eduid/di/repository/StorageRepository.kt b/app/src/main/kotlin/nl/eduid/di/repository/StorageRepository.kt index 89ff72bd..3df14dd3 100644 --- a/app/src/main/kotlin/nl/eduid/di/repository/StorageRepository.kt +++ b/app/src/main/kotlin/nl/eduid/di/repository/StorageRepository.kt @@ -34,6 +34,8 @@ class StorageRepository(private val context: Context) { } } + val isAuthorized: Flow = authState.map { it != null && it.isAuthorized } + val authRequest: Flow = context.dataStore.data.catch { exception -> if (exception is IOException) { Timber.e(exception, "Error reading preferences.") diff --git a/app/src/main/kotlin/nl/eduid/screens/personalinfo/PersonalInfoData.kt b/app/src/main/kotlin/nl/eduid/screens/personalinfo/PersonalInfoData.kt index e8b931c3..6f5a71b2 100644 --- a/app/src/main/kotlin/nl/eduid/screens/personalinfo/PersonalInfoData.kt +++ b/app/src/main/kotlin/nl/eduid/screens/personalinfo/PersonalInfoData.kt @@ -15,7 +15,7 @@ data class PersonalInfo( val institutionStatus: InfoStatus = InfoStatus.Final, ) { companion object { - fun demoData(): PersonalInfo { + fun demoData(): PersonalInfo { return PersonalInfo( name = "R. van Hamersdonksveer", nameProvider = "Universiteit van Amsterdam", @@ -31,10 +31,12 @@ data class PersonalInfo( institutionStatus = InfoStatus.Final, ) } - sealed class InfoStatus { - object Empty : InfoStatus() - object Editable : InfoStatus() - object Final : InfoStatus() - } } + + sealed class InfoStatus { + object Empty : InfoStatus() + object Editable : InfoStatus() + object Final : InfoStatus() + } + } \ No newline at end of file diff --git a/app/src/main/kotlin/nl/eduid/screens/personalinfo/PersonalInfoRepository.kt b/app/src/main/kotlin/nl/eduid/screens/personalinfo/PersonalInfoRepository.kt new file mode 100644 index 00000000..73bd43dd --- /dev/null +++ b/app/src/main/kotlin/nl/eduid/screens/personalinfo/PersonalInfoRepository.kt @@ -0,0 +1,21 @@ +package nl.eduid.screens.personalinfo + +import nl.eduid.di.api.EduIdApi +import nl.eduid.di.model.UserDetails +import timber.log.Timber + +class PersonalInfoRepository(private val eduIdApi: EduIdApi) { + + suspend fun getUserDetails(): UserDetails? = try { + val response = eduIdApi.getUserDetails() + if (response.isSuccessful) { + response.body() + } else { + Timber.w("User details not available ${response.code()}: ${response.errorBody()}") + null + } + } catch (e: Exception) { + Timber.e(e, "Failed to retrieve user details") + null + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/nl/eduid/screens/personalinfo/PersonalInfoScreen.kt b/app/src/main/kotlin/nl/eduid/screens/personalinfo/PersonalInfoScreen.kt index 719a8054..08ca9e57 100644 --- a/app/src/main/kotlin/nl/eduid/screens/personalinfo/PersonalInfoScreen.kt +++ b/app/src/main/kotlin/nl/eduid/screens/personalinfo/PersonalInfoScreen.kt @@ -113,10 +113,35 @@ fun PersonalInfoScreenContent( ) Spacer(Modifier.height(12.dp)) - InfoTab(header = "Name", title = "R. van Hamersdonksveer", subtitle = "Provided by Universiteit van Amsterdam", onClick = { }, endIcon = R.drawable.shield_tick_blue) - InfoTab(header = "Email", title = personalInfo.email, subtitle = "Provided by " + personalInfo.emailProvider, onClick = { }, endIcon = R.drawable.edit_icon) - InfoTab(header = "Your role at your institution", title = "Student or employee", subtitle = "Not added to your eduID yet", onClick = { }, endIcon = R.drawable.plus_icon_gray, enabled = false) - InfoTab(header = "Your institution", title = "Universiteit van Amsterdam", subtitle = "Provided by Universiteit van Amsterdam", onClick = { }, endIcon = R.drawable.shield_tick_blue) + InfoTab( + header = "Name", + title = personalInfo.name, + subtitle = "Provided by Universiteit van Amsterdam", + onClick = { }, + endIcon = R.drawable.shield_tick_blue + ) + InfoTab( + header = "Email", + title = personalInfo.email, + subtitle = "Provided by " + personalInfo.emailProvider, + onClick = { }, + endIcon = R.drawable.edit_icon + ) + InfoTab( + header = "Your role at your institution", + title = "Student or employee", + subtitle = "Not added to your eduID yet", + onClick = { }, + endIcon = R.drawable.plus_icon_gray, + enabled = false + ) + InfoTab( + header = "Your institution", + title = "Universiteit van Amsterdam", + subtitle = "Provided by Universiteit van Amsterdam", + onClick = { }, + endIcon = R.drawable.shield_tick_blue + ) Spacer(Modifier.height(24.dp)) } diff --git a/app/src/main/kotlin/nl/eduid/screens/personalinfo/PersonalInfoViewModel.kt b/app/src/main/kotlin/nl/eduid/screens/personalinfo/PersonalInfoViewModel.kt index 45ce518e..b22bb815 100644 --- a/app/src/main/kotlin/nl/eduid/screens/personalinfo/PersonalInfoViewModel.kt +++ b/app/src/main/kotlin/nl/eduid/screens/personalinfo/PersonalInfoViewModel.kt @@ -2,16 +2,35 @@ package nl.eduid.screens.personalinfo import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.launch import nl.eduid.BuildConfig +import nl.eduid.di.model.UserDetails import javax.inject.Inject @HiltViewModel -class PersonalInfoViewModel @Inject constructor() : ViewModel() { +class PersonalInfoViewModel @Inject constructor(private val repository: PersonalInfoRepository) : + ViewModel() { val personalInfo = MutableLiveData() + init { - if (BuildConfig.DEBUG) { - personalInfo.value = PersonalInfo.demoData() + viewModelScope.launch { + val userDetails = repository.getUserDetails() + if (userDetails != null) { + val uidata = convertToUiData(userDetails) + personalInfo.postValue(uidata) + } } } + + private fun convertToUiData(userDetails: UserDetails) = + PersonalInfo( + name = userDetails.givenName, + nameProvider = userDetails.schacHomeOrganization, + nameStatus = PersonalInfo.InfoStatus.Final, + email = userDetails.email, + emailProvider = "You", + emailStatus = PersonalInfo.InfoStatus.Editable, + ) } \ No newline at end of file