Add full Basic authorization and sync with backend-server
This commit is contained in:
parent
60a7e7544e
commit
72b3324821
@ -4,7 +4,7 @@ import com.google.gson.annotations.SerializedName
|
||||
|
||||
class LoginDto(
|
||||
@SerializedName("username")
|
||||
val username: String?,
|
||||
val username: String,
|
||||
@SerializedName("password")
|
||||
val password: String?
|
||||
val password: String
|
||||
)
|
5
app/src/main/java/ru/myitschool/work/data/dto/Role.kt
Normal file
5
app/src/main/java/ru/myitschool/work/data/dto/Role.kt
Normal file
@ -0,0 +1,5 @@
|
||||
package ru.myitschool.work.data.dto
|
||||
|
||||
enum class Role {
|
||||
ADMIN, USER
|
||||
}
|
@ -3,12 +3,20 @@ package ru.myitschool.work.data.dto
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
class UserInfoDto(
|
||||
@SerializedName("id")
|
||||
val id: Int,
|
||||
@SerializedName("name")
|
||||
val fullname: String?,
|
||||
val fullname: String,
|
||||
@SerializedName("login")
|
||||
val login: String,
|
||||
@SerializedName("role")
|
||||
val role: Role,
|
||||
@SerializedName("blocked")
|
||||
val blocked: Boolean,
|
||||
@SerializedName("photo")
|
||||
val imageUrl: String?,
|
||||
val imageUrl: String,
|
||||
@SerializedName("position")
|
||||
val position: String?,
|
||||
val position: String,
|
||||
@SerializedName("lastVisit")
|
||||
val lastEntry: String?,
|
||||
val lastEntry: String,
|
||||
)
|
@ -15,18 +15,18 @@ class AccountRepositoryImpl @Inject constructor(
|
||||
private val accountNetworkDataSource: AccountNetworkDataSource,
|
||||
private val userInfoMapper: Lazy<UserInfoMapper>,
|
||||
): UserInfoRepository {
|
||||
override suspend fun getInfo(username: String): Result<UserInfoEntity> {
|
||||
override suspend fun getInfo(basicAuth: String): Result<UserInfoEntity> {
|
||||
return withContext(Dispatchers.IO) {
|
||||
accountNetworkDataSource.getInfo(username).fold(
|
||||
accountNetworkDataSource.getInfo(basicAuth).fold(
|
||||
onSuccess = { value -> userInfoMapper.get().invoke(value) },
|
||||
onFailure = { error -> Result.failure(error) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun openByQr(username: String, content: String): Result<Unit> {
|
||||
override suspend fun openByQr(basicAuth: String, content: String): Result<Unit> {
|
||||
return withContext(Dispatchers.IO) {
|
||||
accountNetworkDataSource.openByQr(username, content)
|
||||
accountNetworkDataSource.openByQr(basicAuth, content)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package ru.myitschool.work.data.repo
|
||||
|
||||
import android.util.Base64
|
||||
import dagger.Reusable
|
||||
import ru.myitschool.work.data.source.AuthorizationNetworkDataSource
|
||||
import ru.myitschool.work.data.source.AuthorizationStorageDataSource
|
||||
@ -19,19 +20,21 @@ class AuthorizationRepositoryImpl @Inject constructor(
|
||||
|
||||
override suspend fun login(data: LoginDto): Result<Unit> {
|
||||
return withContext(Dispatchers.IO) {
|
||||
authorizationNetworkDataSource.get().checkLogin(data.username!!)
|
||||
val basicAuthToken = Base64.encodeToString("${data.username}:${data.password}".toByteArray(), Base64.NO_WRAP)
|
||||
|
||||
authorizationNetworkDataSource.get().checkAuthCredentials(basicAuthToken)
|
||||
.onSuccess {
|
||||
authorizationStorageDataSource.get().updateLogin(data.username)
|
||||
authorizationStorageDataSource.get().updateBasicAuth(basicAuthToken)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun logout() {
|
||||
authorizationStorageDataSource.get().updateLogin(null)
|
||||
authorizationStorageDataSource.get().updateBasicAuth(null)
|
||||
}
|
||||
|
||||
override suspend fun getLogin(): Result<String> {
|
||||
val result = authorizationStorageDataSource.get().login.firstOrNull()
|
||||
val result = authorizationStorageDataSource.get().basicAuthToken.firstOrNull()
|
||||
return if (result == null) {
|
||||
Result.failure(Exception("Not authorize"))
|
||||
} else {
|
||||
|
@ -2,20 +2,21 @@ package ru.myitschool.work.data.source
|
||||
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Header
|
||||
import retrofit2.http.PATCH
|
||||
import retrofit2.http.Path
|
||||
import ru.myitschool.work.data.dto.OpenQrDto
|
||||
import ru.myitschool.work.data.dto.UserInfoDto
|
||||
|
||||
interface AccountApi {
|
||||
@GET("api/{username}/info")
|
||||
@GET("api/employee/info")
|
||||
suspend fun getInfo(
|
||||
@Path("username") username: String
|
||||
@Header("Authorization") basicAuth: String
|
||||
) : UserInfoDto
|
||||
|
||||
@PATCH("api/{username}/open")
|
||||
@PATCH("api/employee/open")
|
||||
suspend fun openByQr(
|
||||
@Path("username") username: String,
|
||||
@Header("Authorization") basicAuth: String,
|
||||
@Body content: OpenQrDto
|
||||
)
|
||||
}
|
@ -14,14 +14,14 @@ class AccountNetworkDataSource @Inject constructor(
|
||||
retrofit.create(AccountApi::class.java)
|
||||
}
|
||||
|
||||
suspend fun getInfo(username: String): Result<UserInfoDto> {
|
||||
return kotlin.runCatching { api.getInfo(username = username) }
|
||||
suspend fun getInfo(basicAuth: String): Result<UserInfoDto> {
|
||||
return kotlin.runCatching { api.getInfo(basicAuth = basicAuth) }
|
||||
}
|
||||
|
||||
suspend fun openByQr(username: String, content: String): Result<Unit> {
|
||||
suspend fun openByQr(basicAuth: String, content: String): Result<Unit> {
|
||||
return kotlin.runCatching {
|
||||
api.openByQr(
|
||||
username = username,
|
||||
basicAuth = basicAuth,
|
||||
content = OpenQrDto(value = content)
|
||||
)
|
||||
}
|
||||
|
@ -1,19 +1,14 @@
|
||||
package ru.myitschool.work.data.source
|
||||
|
||||
import retrofit2.Response
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Header
|
||||
import retrofit2.http.POST
|
||||
import retrofit2.http.Path
|
||||
|
||||
interface AuthorizationApi {
|
||||
@GET("api/{username}/auth")
|
||||
suspend fun checkLogin(
|
||||
@Path("username") username: String
|
||||
) : Response<Unit>
|
||||
|
||||
@GET("api/login")
|
||||
@POST("api/login")
|
||||
suspend fun login(
|
||||
@Body content: AccountApi
|
||||
@Header("Authorization") basicAuthorization: String,
|
||||
): Response<Unit>
|
||||
}
|
@ -13,8 +13,8 @@ class AuthorizationNetworkDataSource @Inject constructor(
|
||||
retrofit.create(AuthorizationApi::class.java)
|
||||
}
|
||||
|
||||
suspend fun checkLogin(username: String): Result<Unit> {
|
||||
return kotlin.runCatching { api.checkLogin(username = username) }.fold(
|
||||
suspend fun checkAuthCredentials(basicAuth: String): Result<Unit> {
|
||||
return kotlin.runCatching { api.login("Basic $basicAuth") }.fold(
|
||||
onSuccess = { response ->
|
||||
when (response.code()) {
|
||||
200 -> Result.success(Unit)
|
||||
|
@ -17,22 +17,22 @@ class AuthorizationStorageDataSource @Inject constructor(
|
||||
@ApplicationContext private val context: Context,
|
||||
) {
|
||||
private val Context.storage: DataStore<Preferences> by preferencesDataStore(name = NAME)
|
||||
val login: Flow<String?> = context.storage.data.map { preferences ->
|
||||
preferences[LOGIN_KEY]
|
||||
val basicAuthToken: Flow<String?> = context.storage.data.map { preferences ->
|
||||
preferences[TOKEN_KEY]
|
||||
}
|
||||
|
||||
suspend fun updateLogin(username: String?) {
|
||||
suspend fun updateBasicAuth(token: String?) {
|
||||
context.storage.edit { settings ->
|
||||
if (username != null) {
|
||||
settings[LOGIN_KEY] = username
|
||||
if (token != null) {
|
||||
settings[TOKEN_KEY] = "Basic $token"
|
||||
} else {
|
||||
settings.remove(LOGIN_KEY)
|
||||
settings.remove(TOKEN_KEY)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val NAME = "auth_data"
|
||||
val LOGIN_KEY = stringPreferencesKey("login")
|
||||
val TOKEN_KEY = stringPreferencesKey("basicAuthToken")
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ class GetUserInfoUseCase @Inject constructor(
|
||||
) {
|
||||
suspend operator fun invoke(): Result<UserInfoEntity> {
|
||||
return getLoginUseCase().fold(
|
||||
onSuccess = { username -> repo.getInfo(username = username) },
|
||||
onSuccess = { basicAuth -> repo.getInfo(basicAuth) },
|
||||
onFailure = { error -> Result.failure(error) }
|
||||
)
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ class OpenByQrUseCase @Inject constructor(
|
||||
) {
|
||||
suspend operator fun invoke(content: String): Result<Unit> {
|
||||
return getLoginUseCase().fold(
|
||||
onSuccess = { username -> repo.openByQr(username = username, content = content) },
|
||||
onSuccess = { basicAuth -> repo.openByQr(basicAuth = basicAuth, content = content) },
|
||||
onFailure = { error -> Result.failure(error) }
|
||||
)
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package ru.myitschool.work.domain.profile.repo
|
||||
import ru.myitschool.work.domain.profile.entities.UserInfoEntity
|
||||
|
||||
interface UserInfoRepository {
|
||||
suspend fun getInfo(username: String) : Result<UserInfoEntity>
|
||||
suspend fun getInfo(basicAuth: String) : Result<UserInfoEntity>
|
||||
|
||||
suspend fun openByQr(username: String, content: String) : Result<Unit>
|
||||
suspend fun openByQr(basicAuth: String, content: String) : Result<Unit>
|
||||
}
|
@ -64,6 +64,11 @@ class LoginFragment : Fragment(R.layout.fragment_login) {
|
||||
viewModel.inputLogin(s.toString())
|
||||
}
|
||||
})
|
||||
binding.password.addTextChangedListener(object : TextChangedListener() {
|
||||
override fun afterTextChanged(s: Editable?) {
|
||||
viewModel.inputPassword(s.toString())
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
@ -32,12 +32,12 @@ class LoginViewModel @Inject constructor(
|
||||
val state = _state.asStateFlow()
|
||||
|
||||
private var login: String = ""
|
||||
private var password: String = "123"//пока пароль по дефалту
|
||||
private var password: String = ""
|
||||
|
||||
fun clickLogin() {
|
||||
viewModelScope.launch {
|
||||
_state.update { State.Loading }
|
||||
val data = LoginDto(login,password)
|
||||
val data = LoginDto(login, password)
|
||||
loginUseCase.get().invoke(data).fold(
|
||||
onSuccess = {
|
||||
_action.emit(Action.OpenProfile)
|
||||
@ -56,7 +56,7 @@ class LoginViewModel @Inject constructor(
|
||||
|
||||
|
||||
|
||||
//Чек пароля на правильность
|
||||
// Чек пароля на правильность
|
||||
fun inputLogin(login: String) {
|
||||
this.login = login
|
||||
viewModelScope.launch {
|
||||
@ -67,7 +67,7 @@ class LoginViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
fun passwordCheck(password: String){
|
||||
fun inputPassword(password: String){
|
||||
this.password = password
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user