From 5129a8b3f21e5d33a4d6d0cf3a5a243301cb9a02 Mon Sep 17 00:00:00 2001 From: shipovnikaaa Date: Thu, 20 Feb 2025 10:52:44 +0300 Subject: [PATCH] basic auth - mne horosho... --- .kotlin/errors/errors-1740036840667.log | 82 +++++++++++++++++++ .../work/ui/admin/AdminDestination.kt | 2 +- .../myitschool/work/ui/admin/AdminFragment.kt | 32 ++++---- .../work/ui/admin/AdminViewModel.kt | 33 +++++--- .../ru/myitschool/work/ui/login/BasicAuth.kt | 23 ++++++ .../myitschool/work/ui/login/LoginFragment.kt | 2 +- .../work/ui/login/LoginViewModel.kt | 1 + .../myitschool/work/ui/main/MainFragment.kt | 4 +- .../myitschool/work/ui/main/MainViewModel.kt | 26 +++--- 9 files changed, 167 insertions(+), 38 deletions(-) create mode 100644 .kotlin/errors/errors-1740036840667.log create mode 100644 app/src/main/java/ru/myitschool/work/ui/login/BasicAuth.kt diff --git a/.kotlin/errors/errors-1740036840667.log b/.kotlin/errors/errors-1740036840667.log new file mode 100644 index 0000000..75380f9 --- /dev/null +++ b/.kotlin/errors/errors-1740036840667.log @@ -0,0 +1,82 @@ +kotlin version: 2.0.21 +error message: Daemon compilation failed: null +java.lang.Exception + at org.jetbrains.kotlin.daemon.common.CompileService$CallResult$Error.get(CompileService.kt:69) + at org.jetbrains.kotlin.daemon.common.CompileService$CallResult$Error.get(CompileService.kt:65) + at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:240) + at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159) + at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111) + at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:76) + at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63) + at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:66) + at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:62) + at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:100) + at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:62) + at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44) + at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41) + at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209) + at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204) + at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66) + at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59) + at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166) + at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59) + at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53) + at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41) + at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:59) + at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:174) + at java.base/java.util.concurrent.FutureTask.run(Unknown Source) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:195) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:128) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:170) + at org.gradle.internal.Factories$1.create(Factories.java:31) + at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:267) + at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:131) + at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:136) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:165) + at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:134) + at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) + at java.base/java.util.concurrent.FutureTask.run(Unknown Source) + at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64) + at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:48) + at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) + at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) + at java.base/java.lang.Thread.run(Unknown Source) +Caused by: java.nio.file.DirectoryNotEmptyException: C:\Users\User\AppData\Local\Temp\kotlin-backups3293833258477019099 + at java.base/sun.nio.fs.WindowsFileSystemProvider.implDelete(Unknown Source) + at java.base/sun.nio.fs.AbstractFileSystemProvider.delete(Unknown Source) + at java.base/java.nio.file.Files.delete(Unknown Source) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction$cleanupStash$2$1$1.invoke(CompilationTransaction.kt:244) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction$cleanupStash$2$1$1.invoke(CompilationTransaction.kt:244) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction.cleanupStash$lambda$11$lambda$10$lambda$9(CompilationTransaction.kt:244) + at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source) + at java.base/java.util.ArrayList.forEach(Unknown Source) + at java.base/java.util.stream.SortedOps$RefSortingSink.end(Unknown Source) + at java.base/java.util.stream.Sink$ChainedReference.end(Unknown Source) + at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source) + at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source) + at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source) + at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source) + at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source) + at java.base/java.util.stream.ReferencePipeline.forEach(Unknown Source) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction.cleanupStash(CompilationTransaction.kt:244) + at org.jetbrains.kotlin.incremental.RecoverableCompilationTransaction.close(CompilationTransaction.kt:254) + at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.tryCompileIncrementally(IncrementalCompilerRunner.kt:747) + at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compile(IncrementalCompilerRunner.kt:120) + at org.jetbrains.kotlin.daemon.CompileServiceImplBase.execIncrementalCompiler(CompileServiceImpl.kt:675) + at org.jetbrains.kotlin.daemon.CompileServiceImplBase.access$execIncrementalCompiler(CompileServiceImpl.kt:92) + at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1660) + at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source) + at java.base/java.lang.reflect.Method.invoke(Unknown Source) + at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(Unknown Source) + at java.rmi/sun.rmi.transport.Transport$1.run(Unknown Source) + at java.rmi/sun.rmi.transport.Transport$1.run(Unknown Source) + at java.base/java.security.AccessController.doPrivileged(Unknown Source) + at java.rmi/sun.rmi.transport.Transport.serviceCall(Unknown Source) + at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source) + at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source) + at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(Unknown Source) + at java.base/java.security.AccessController.doPrivileged(Unknown Source) + at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source) + ... 3 more + + diff --git a/app/src/main/java/ru/myitschool/work/ui/admin/AdminDestination.kt b/app/src/main/java/ru/myitschool/work/ui/admin/AdminDestination.kt index 3b0c8d1..0103ec7 100644 --- a/app/src/main/java/ru/myitschool/work/ui/admin/AdminDestination.kt +++ b/app/src/main/java/ru/myitschool/work/ui/admin/AdminDestination.kt @@ -2,4 +2,4 @@ package ru.myitschool.work.ui.admin import kotlinx.serialization.Serializable @Serializable -data class AdminDestination(val username: String) \ No newline at end of file +data class AdminDestination(val username: String, val password: String) \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/admin/AdminFragment.kt b/app/src/main/java/ru/myitschool/work/ui/admin/AdminFragment.kt index ced9de4..03e2427 100644 --- a/app/src/main/java/ru/myitschool/work/ui/admin/AdminFragment.kt +++ b/app/src/main/java/ru/myitschool/work/ui/admin/AdminFragment.kt @@ -35,26 +35,30 @@ class AdminFragment : Fragment(R.layout.fragment_admin) { val username = findNavController().currentBackStackEntry?.toRoute()?.username username?.let { user -> + val password = + findNavController().currentBackStackEntry?.toRoute()?.password + password?.let { password -> - binding.loginadmin.addTextChangedListener(TextChangedListener { - viewModel.onUsernameChanged(it) - }) - subscribe() - binding.adminName.text = user - binding.find.setOnClickListener { - login(binding.loginadmin.text.toString()) - } - binding.backAdmin.setOnClickListener{ - findNavController().apply { - popBackStack(true) - navigate(MainDestination(user)) + binding.loginadmin.addTextChangedListener(TextChangedListener { + viewModel.onUsernameChanged(it) + }) + subscribe() + binding.adminName.text = user + binding.find.setOnClickListener { + login(user, password, binding.loginadmin.text.toString()) + } + binding.backAdmin.setOnClickListener { + findNavController().apply { + popBackStack(true) + navigate(MainDestination(user, password = password)) + } } } } } - private fun login(username: String) { - viewModel.loadPersonInfo(username) { + private fun login(username: String, password: String, loginPerson : String) { + viewModel.loadPersonInfo(username, password, loginPerson) { viewModel.state.collectWhenStarted(this) { state -> if (state.photo.isNotEmpty()) { picasso.load(state.photo).into(binding.photoAdmin) diff --git a/app/src/main/java/ru/myitschool/work/ui/admin/AdminViewModel.kt b/app/src/main/java/ru/myitschool/work/ui/admin/AdminViewModel.kt index d6ae36d..d5e6b6e 100644 --- a/app/src/main/java/ru/myitschool/work/ui/admin/AdminViewModel.kt +++ b/app/src/main/java/ru/myitschool/work/ui/admin/AdminViewModel.kt @@ -5,6 +5,8 @@ import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.google.gson.GsonBuilder +import createAuthHeader +import createRetrofit import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.flow.MutableStateFlow @@ -14,8 +16,10 @@ import kotlinx.coroutines.launch import retrofit2.HttpException import ru.myitschool.work.data.remote.LoginApi import ru.myitschool.work.data.remote.ErrorDto +import ru.myitschool.work.data.remote.PersonInfoDto import ru.myitschool.work.di.AppModule import ru.myitschool.work.ui.admin.AdminState +import ru.myitschool.work.ui.main.MainState import java.text.SimpleDateFormat import javax.inject.Inject @@ -34,18 +38,27 @@ class AdminViewModel @Inject constructor( private val dfo = SimpleDateFormat("yyyy-MM-dd HH:mm") private val dfi= SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss") - fun loadPersonInfo(username: String, onSuccess: () -> Unit) { + private val retrofit = createRetrofit("your_username", "your_password") + private val loginApi = retrofit.create(LoginApi::class.java) + + fun loadPersonInfo(username: String, password : String, loginPerson: String, onSuccess: () -> Unit) { viewModelScope.launch { try { - val info = api.info(username) - _state.update { - AdminMainState( - fullName = info.name, - photo = info.photo, - position = info.position, - lastVisit = dfo.format(dfi.parse(info.lastVisit)!!), - error = null - ) + val authHeader = createAuthHeader(username = username, password) + val info = loginApi.info(authHeader, loginPerson) + val personInfo = info.body()?.let { responseBody -> + GsonBuilder().create().fromJson(responseBody.string(), PersonInfoDto::class.java) + } + if (personInfo != null) { + _state.update { + AdminMainState( + fullName = personInfo.name, + photo = personInfo.photo, + position = personInfo.position, + lastVisit = dfo.format(dfi.parse(personInfo.lastVisit)!!), + error = null + ) + } } onSuccess() } catch (httpException: HttpException) { diff --git a/app/src/main/java/ru/myitschool/work/ui/login/BasicAuth.kt b/app/src/main/java/ru/myitschool/work/ui/login/BasicAuth.kt new file mode 100644 index 0000000..dfa8324 --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/ui/login/BasicAuth.kt @@ -0,0 +1,23 @@ +import android.os.Build +import androidx.annotation.RequiresApi +import okhttp3.OkHttpClient +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import ru.myitschool.work.core.Constants +import java.util.Base64 + +fun createRetrofit(username: String, password: String): Retrofit { + val client = OkHttpClient.Builder() + .build() + + return Retrofit.Builder() + .baseUrl(Constants.SERVER_ADDRESS) + .client(client) + .addConverterFactory(GsonConverterFactory.create()) + .build() +} + +fun createAuthHeader(username: String, password: String): String { + val credentials = "$username:$password" + return "Basic " + Base64.getEncoder().encodeToString(credentials.toByteArray()) +} diff --git a/app/src/main/java/ru/myitschool/work/ui/login/LoginFragment.kt b/app/src/main/java/ru/myitschool/work/ui/login/LoginFragment.kt index 98a48fa..b05a521 100644 --- a/app/src/main/java/ru/myitschool/work/ui/login/LoginFragment.kt +++ b/app/src/main/java/ru/myitschool/work/ui/login/LoginFragment.kt @@ -35,7 +35,7 @@ class LoginFragment : Fragment(R.layout.fragment_login) { viewModel.tryLogin(username, password) { findNavController().apply { popBackStack(true) - navigate(MainDestination(username)) + navigate(MainDestination(username, password)) } } } diff --git a/app/src/main/java/ru/myitschool/work/ui/login/LoginViewModel.kt b/app/src/main/java/ru/myitschool/work/ui/login/LoginViewModel.kt index 09a19d6..bb8e25e 100644 --- a/app/src/main/java/ru/myitschool/work/ui/login/LoginViewModel.kt +++ b/app/src/main/java/ru/myitschool/work/ui/login/LoginViewModel.kt @@ -73,6 +73,7 @@ class LoginViewModel @Inject constructor( onSuccess() } catch (httpExc: HttpException) { Log.e("LoginViewModel", "Login failed for $username", httpExc) + _state.update { it.copy(error = "Login failed for: $username") } try { httpExc.response()?.errorBody()?.string()?.let { errorString -> val gson = GsonBuilder().create() diff --git a/app/src/main/java/ru/myitschool/work/ui/main/MainFragment.kt b/app/src/main/java/ru/myitschool/work/ui/main/MainFragment.kt index 24e58c0..3a80d74 100644 --- a/app/src/main/java/ru/myitschool/work/ui/main/MainFragment.kt +++ b/app/src/main/java/ru/myitschool/work/ui/main/MainFragment.kt @@ -32,7 +32,7 @@ class MainFragment: Fragment(R.layout.fragment_main) { val password = findNavController().currentBackStackEntry?.toRoute()?.password password?.let { password -> viewModel.loadPersonInfo(user, password) - binding.refresh.setOnClickListener { viewModel.loadPersonInfo(user) } + binding.refresh.setOnClickListener { viewModel.loadPersonInfo(user, password) } binding.logout.setOnClickListener { viewModel.logout { findNavController().apply { @@ -46,7 +46,7 @@ class MainFragment: Fragment(R.layout.fragment_main) { findNavController().navigate(QrScanDestination) } binding.admin.setOnClickListener { - findNavController().navigate(AdminDestination(user)) + findNavController().navigate(AdminDestination(user, password)) } } } diff --git a/app/src/main/java/ru/myitschool/work/ui/main/MainViewModel.kt b/app/src/main/java/ru/myitschool/work/ui/main/MainViewModel.kt index 4627999..864c33f 100644 --- a/app/src/main/java/ru/myitschool/work/ui/main/MainViewModel.kt +++ b/app/src/main/java/ru/myitschool/work/ui/main/MainViewModel.kt @@ -17,6 +17,7 @@ import kotlinx.coroutines.launch import retrofit2.HttpException import ru.myitschool.work.data.remote.LoginApi import ru.myitschool.work.data.remote.ErrorDto +import ru.myitschool.work.data.remote.PersonInfoDto import ru.myitschool.work.di.AppModule import java.text.SimpleDateFormat import javax.inject.Inject @@ -39,16 +40,21 @@ class MainViewModel @Inject constructor( fun loadPersonInfo(username: String, password : String) { viewModelScope.launch { try { - val authHeader = createAuthHeader(username = username, password) - val info = loginApi.auth(authHeader, username) - _state.update { - MainState( - fullName = info.name, - photo = info.photo, - position = info.position, - lastVisit = dfo.format(dfi.parse(info.lastVisit)!!), - error = null - ) + val authHeader = createAuthHeader(username = username, password= password) + val info = loginApi.info(authHeader, username) + val personInfo = info.body()?.let { responseBody -> + GsonBuilder().create().fromJson(responseBody.string(), PersonInfoDto::class.java) + } + if (personInfo != null) { + _state.update { + MainState( + fullName = personInfo.name, + photo = personInfo.photo, + position = personInfo.position, + lastVisit = dfo.format(dfi.parse(personInfo.lastVisit)!!), + error = null + ) + } } } catch (httpException: HttpException) { try {