main #8

Open
student-m-kuchergin wants to merge 17 commits from KHBGPU-org/NTO-2026-Android-TeamTask-Template:main into main
6 changed files with 40 additions and 22 deletions
Showing only changes of commit f5350729cc - Show all commits

View File

@ -1,8 +1,10 @@
package ru.myitschool.work.core package ru.myitschool.work.core
object Constants { object Constants {
const val HOST = "http://10.0.0.14:49183" const val HOST = "http://10.0.0.177:49183"
const val AUTH_URL = "/auth" const val AUTH_URL = "/auth"
//TODO заменить на /auth
const val INFO_URL = "/info" const val INFO_URL = "/info"
const val BOOKING_URL = "/booking" const val BOOKING_URL = "/booking"
const val BOOK_URL = "/book" const val BOOK_URL = "/book"

View File

@ -1,14 +1,19 @@
package ru.myitschool.work.data.source package ru.myitschool.work.data.source
import android.util.Log
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.call.body import io.ktor.client.call.body
import io.ktor.client.engine.cio.CIO import io.ktor.client.engine.cio.CIO
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.request.basicAuth
import io.ktor.client.request.get import io.ktor.client.request.get
import io.ktor.client.request.header
import io.ktor.client.request.post import io.ktor.client.request.post
import io.ktor.client.request.setBody import io.ktor.client.request.setBody
import io.ktor.client.statement.bodyAsText import io.ktor.client.statement.bodyAsText
import io.ktor.http.ContentType import io.ktor.http.ContentType
import io.ktor.http.HttpHeaders
import io.ktor.http.HttpHeaders.Authorization
import io.ktor.http.HttpStatusCode import io.ktor.http.HttpStatusCode
import io.ktor.http.contentType import io.ktor.http.contentType
import io.ktor.serialization.kotlinx.json.json import io.ktor.serialization.kotlinx.json.json
@ -19,6 +24,7 @@ import ru.myitschool.work.core.Constants
import ru.myitschool.work.data.dto.PlaceDto import ru.myitschool.work.data.dto.PlaceDto
import ru.myitschool.work.data.dto.BookRequestDto import ru.myitschool.work.data.dto.BookRequestDto
import ru.myitschool.work.data.dto.UserDto import ru.myitschool.work.data.dto.UserDto
import kotlin.io.encoding.Base64
object NetworkDataSource { object NetworkDataSource {
private val client by lazy { private val client by lazy {
@ -37,11 +43,24 @@ object NetworkDataSource {
} }
suspend fun checkAuth(text: String): Result<Boolean> = withContext(Dispatchers.IO) { suspend fun checkAuth(text: String): Result<Boolean> = withContext(Dispatchers.IO) {
return@withContext runCatching {
val response = client.post(
getUrl(text, Constants.AUTH_URL)) {
return@withContext runCatching {
/*
val response = client.post(
getUrl(Constants.AUTH_URL))
*/
val response = client.post(
urlString = "http://10.0.0.177:49183/api/auth" //getUrl(Constants.AUTH_URL)
) {
header(key = Authorization, value = basicAuth(text.split(Regex(":"))[0], text.split(Regex(":"))[1]))
} }
// "Basic ${Base64.encode(text.toByteArray(), )}" "Basic ${Base64.encode(text.toByteArray())}"
//val response = client.get(getUrl(Constants.AUTH_URL)) {}
Log.d("RESPONSE", response.toString())
Log.d("RESPONSE_STATUS", response.status.toString())
when (response.status) { when (response.status) {
HttpStatusCode.OK -> true HttpStatusCode.OK -> true
else -> false else -> false
@ -52,7 +71,7 @@ object NetworkDataSource {
suspend fun getInfo(code: String): Result<UserDto> = withContext(Dispatchers.IO) { suspend fun getInfo(code: String): Result<UserDto> = withContext(Dispatchers.IO) {
return@withContext runCatching { return@withContext runCatching {
println("!!!!!!!!!!!!!! getInfo $code") println("!!!!!!!!!!!!!! getInfo $code")
val response = client.get(getUrl(code, Constants.INFO_URL)) val response = client.get(getUrl(Constants.INFO_URL))
if (response.status == HttpStatusCode.OK) { if (response.status == HttpStatusCode.OK) {
println("!!!!!!!!!!!!!! getInfo OK ${response.bodyAsText()}") println("!!!!!!!!!!!!!! getInfo OK ${response.bodyAsText()}")
response.body<UserDto>() response.body<UserDto>()
@ -65,7 +84,7 @@ object NetworkDataSource {
suspend fun getBooking(code: String): Result<Map<String, List<PlaceDto>>?> = withContext(Dispatchers.IO) { suspend fun getBooking(code: String): Result<Map<String, List<PlaceDto>>?> = withContext(Dispatchers.IO) {
return@withContext runCatching { return@withContext runCatching {
val response = client.get(getUrl(code, Constants.BOOKING_URL)) val response = client.get(getUrl(Constants.BOOKING_URL))
if (response.status == HttpStatusCode.OK) { if (response.status == HttpStatusCode.OK) {
response.body<Map<String, List<PlaceDto>>>() response.body<Map<String, List<PlaceDto>>>()
} else { } else {
@ -76,7 +95,7 @@ object NetworkDataSource {
suspend fun addBook(code: String, data: BookRequestDto): Result<Boolean> = withContext(Dispatchers.IO) { suspend fun addBook(code: String, data: BookRequestDto): Result<Boolean> = withContext(Dispatchers.IO) {
return@withContext runCatching { return@withContext runCatching {
val response = client.post(getUrl(code, Constants.BOOK_URL)) { val response = client.post(getUrl(Constants.BOOK_URL)) {
contentType(ContentType.Application.Json) contentType(ContentType.Application.Json)
setBody(data) setBody(data)
} }
@ -88,5 +107,5 @@ object NetworkDataSource {
} }
} }
private fun getUrl(code: String, targetUrl: String) = "${Constants.HOST}/api/$code$targetUrl" private fun getUrl(targetUrl: String) = "${Constants.HOST}/api$targetUrl"
} }

View File

@ -9,7 +9,7 @@ class CheckAndSaveAuthDataUseCase(
textLogin: String, textLogin: String,
textPassword: String textPassword: String
): Result<Unit> { ): Result<Unit> {
return repository.checkAndSave(textLogin, textPassword).mapCatching { success -> return repository.checkAndSave("$textLogin:$textPassword").mapCatching { success ->
if (!success) { if (!success) {
error("Login or password is incorrect") error("Login or password is incorrect")

View File

@ -7,18 +7,14 @@ class CheckPasswordFormatUseCase {
operator fun invoke( operator fun invoke(
textLogin: String, textLogin: String,
textPassword: String textPassword: String
): Boolean { ):
Boolean {
val lowerCasePassword = textPassword.lowercase(getDefault()) val lowerCasePassword = textPassword.lowercase(getDefault())
val lowerCaseLogin = textLogin.lowercase(getDefault()) val lowerCaseLogin = textLogin.lowercase(getDefault())
val intersect = lowerCasePassword.toList().intersect(lowerCaseLogin.toList()); val intersect = lowerCasePassword.toList().intersect(lowerCaseLogin.toList());
return !(textPassword.length < 8 || !textPassword.all { char -> return (textPassword.length >= 8) && (textPassword.all { char ->
char.isLetterOrDigit() textPassword.count { it == char } < 3
&& ((char in 'A'..'Z')
|| (char in 'a'..'z')
|| char.isDigit())
&& textPassword.count { it == char } < 3
&& intersect.size < 3 && intersect.size < 3
}) && !("[A-Za-z0-9]+".toRegex().matches(textPassword))
})
} }
} }

View File

@ -73,7 +73,8 @@ fun AuthScreen(
} }
@Composable @Composable
private fun Content( private fun Content
(
viewModel: AuthViewModel, viewModel: AuthViewModel,
state: AuthState.Data state: AuthState.Data
) { ) {
@ -118,7 +119,7 @@ private fun Content(
if (state.error != null) { if (state.error != null) {
Text( Text(
modifier = Modifier.testTag(TestIds.Auth.ERROR), modifier = Modifier.testTag(TestIds.Auth.ERROR),
text = if (viewModel.incorrectAttemptNum > 5) { text = if (viewModel.incorrectAttemptNum >= 5) {
"Превышен лимит попыток входа" "Превышен лимит попыток входа"
} else { } else {
state.error state.error

View File

@ -59,9 +59,9 @@ class AuthViewModel : ViewModel() {
is AuthIntent.TextInput -> { is AuthIntent.TextInput -> {
updateStateIfData { oldState -> updateStateIfData { oldState ->
oldState.copy( oldState.copy(
isEnabledSend = (checkLoginFormatUseCase.invoke(intent.textLogin) && checkPasswordFormatUseCase.invoke( isEnabledSend = (checkPasswordFormatUseCase.invoke(
intent.textLogin, intent.textPassword intent.textLogin, intent.textPassword
) && incorrectAttemptNum <= 5), ) && checkLoginFormatUseCase.invoke(intent.textLogin) && incorrectAttemptNum <= 4),
error = null error = null
) )
} }