Skip to content

Commit

Permalink
Fix #48 Logout
Browse files Browse the repository at this point in the history
  • Loading branch information
herrbert74 committed Dec 26, 2024
1 parent 46ddbc8 commit bf2c7ce
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface AccountDataSource {

fun saveAccessToken(accessToken: String)
fun getAccessToken(): String?
fun deleteAccessToken()

fun saveAccount(account: Account)
fun getAccount(): Account?
Expand All @@ -19,6 +20,8 @@ interface AccountDataSource {

suspend fun createSessionId(username: String, password: String): Outcome<String>

suspend fun deleteSessionId(sessionId: String): Outcome<Boolean>

suspend fun getAccountDetails(sessionToken: String): Outcome<Account>

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ class AccountLocalDataSource @Inject constructor(
return sharedPreferences.getString("access_token", null)
}

override fun deleteAccessToken() {
val sharedPreferences = context.getSharedPreferences("Account", Context.MODE_PRIVATE)
sharedPreferences.edit().remove("access_token").apply()
}

override fun saveAccount(account: Account) {
val sharedPreferences = context.getSharedPreferences("Account", Context.MODE_PRIVATE)
sharedPreferences.edit().putString("account_name", account.name).apply()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ class AccountRemoteDataSource @Inject constructor(
}
}

override suspend fun deleteSessionId(sessionId: String): Outcome<Boolean> {
return runCatchingApi {
accountService.deleteSession(createDeleteSessionRequestBody(sessionId))
}.map { it.success }
}

override suspend fun getAccountDetails(sessionToken: String): Outcome<Account> {
return runCatchingApi {
accountService.getAccountDetails(sessionToken)
Expand All @@ -67,3 +73,12 @@ private fun createValidateRequestTokenWithLoginRequestBody(
}
return body.toString().toRequestBody("application/json; charset=UTF-8".toMediaType())
}

private fun createDeleteSessionRequestBody(
sessionId: String,
): RequestBody {
val body = buildJsonObject {
put("session_id", sessionId)
}
return body.toString().toRequestBody("application/json; charset=UTF-8".toMediaType())
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ package com.zsoltbertalan.flickslate.account.data.network
import com.zsoltbertalan.flickslate.account.data.network.model.AccountDetailsReplyDto
import com.zsoltbertalan.flickslate.account.data.network.model.CreateRequestTokenReplyDto
import com.zsoltbertalan.flickslate.account.data.network.model.CreateSessionReplyDto
import com.zsoltbertalan.flickslate.account.data.network.model.DeleteSessionReplyDto
import okhttp3.RequestBody
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.HTTP
import retrofit2.http.POST
import retrofit2.http.Query

const val URL_CREATE_REQUEST_TOKEN = "authentication/token/new"
const val URL_VALIDATE_REQUEST_TOKEN_WITH_LOGIN = "authentication/token/validate_with_login"
const val URL_CREATE_SESSION = "authentication/session/new"
const val URL_DELETE_SESSION = "authentication/session"
const val URL_GET_ACCOUNT_DETAILS = "account"

/**
Expand Down Expand Up @@ -39,6 +42,11 @@ interface AccountService {
@Query("request_token") requestToken: String,
): CreateSessionReplyDto

@HTTP(method = "DELETE", path = URL_DELETE_SESSION, hasBody = true)
suspend fun deleteSession(
@Body requestBody: RequestBody
): DeleteSessionReplyDto

@GET(URL_GET_ACCOUNT_DETAILS)
suspend fun getAccountDetails(
@Query("session_id") sessionToken: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.zsoltbertalan.flickslate.account.data.network.model

import kotlinx.serialization.Serializable

@Suppress("ConstructorParameterNaming")
@Serializable
data class DeleteSessionReplyDto(val success: Boolean)
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,18 @@ class AccountAccessor @Inject constructor(
override suspend fun login(username: String, password: String): Outcome<Account> {
return accountRemoteDataSource.createSessionId(username, password)
.andThen {
accountLocalDataSource.saveAccessToken(it)
val account = accountRemoteDataSource.getAccountDetails(it)
accountLocalDataSource.saveAccount(account.value)
account
}
}

override fun logout() {
// Do nothing
override suspend fun logout() {
val accessToken = accountLocalDataSource.getAccessToken()
if (accessToken != null) {
val success = accountRemoteDataSource.deleteSessionId(accessToken)
if(success.isOk) accountLocalDataSource.getAccessToken()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ interface AccountRepository {

suspend fun getAccount(): Account?
suspend fun login(username: String, password: String): Outcome<Account>
fun logout()
suspend fun logout()

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import com.zsoltbertalan.flickslate.shared.model.Account
fun AccountScreen(
account: Account?,
login: (String, String) -> Unit,
logout: () -> Unit,
modifier: Modifier = Modifier,
) {
if (account != null) {
LoggedInComponent(Colors, account, modifier)
LoggedInComponent(Colors, account, modifier, logout)
} else {
LoginComponent(Colors, modifier, login)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,12 @@ class AccountViewModel @Inject constructor(private val accountRepository: Accoun
}
}
}

fun logout() {
viewModelScope.launch {
accountRepository.logout()
_loggedInEvent.emit(null)
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,27 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.ColorScheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.zsoltbertalan.flickslate.shared.compose.component.ListTitle
import com.zsoltbertalan.flickslate.shared.compose.component.autosizetext.AutoSizeText
import com.zsoltbertalan.flickslate.shared.compose.design.Colors
import com.zsoltbertalan.flickslate.shared.compose.design.FlickSlateTheme
import com.zsoltbertalan.flickslate.shared.compose.design.FlickSlateTypography
import com.zsoltbertalan.flickslate.shared.model.Account

@Composable
fun LoggedInComponent(
colorScheme: ColorScheme,
account: Account,
modifier: Modifier = Modifier
modifier: Modifier = Modifier,
logout: () -> Unit
) {
Column(
modifier = modifier
Expand All @@ -42,17 +40,22 @@ fun LoggedInComponent(
alignment = Alignment.Center,
maxLines = 1,
)

Button(logout) {
Text("Logout")
}
}
}

@Preview()
@Preview
@Composable
private fun PreviewAutoSizeTextWithMaxLinesSetToOne() {
FlickSlateTheme {
LoggedInComponent(
modifier = Modifier.fillMaxSize(),
colorScheme = Colors,
account = Account(name="John Doe"),
account = Account(name = "John Doe"),
logout = {},
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ fun NavHostContainer(
val account by accountViewModel.loggedInEvent.collectAsStateWithLifecycle(null)
AccountScreen(
account = account,
login = { username, password -> accountViewModel.login(username, password) }
login = { username, password -> accountViewModel.login(username, password) },
logout = { accountViewModel.logout() }
)
}
composable<Destination.MovieDetails>(
Expand Down

0 comments on commit bf2c7ce

Please sign in to comment.