basic auth - mne horosho...

This commit is contained in:
shipovnikaaa 2025-02-20 10:52:44 +03:00
parent eae3035683
commit 5129a8b3f2
9 changed files with 167 additions and 38 deletions

View File

@ -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

View File

@ -2,4 +2,4 @@ package ru.myitschool.work.ui.admin
import kotlinx.serialization.Serializable
@Serializable
data class AdminDestination(val username: String)
data class AdminDestination(val username: String, val password: String)

View File

@ -35,26 +35,30 @@ class AdminFragment : Fragment(R.layout.fragment_admin) {
val username =
findNavController().currentBackStackEntry?.toRoute<AdminDestination>()?.username
username?.let { user ->
val password =
findNavController().currentBackStackEntry?.toRoute<AdminDestination>()?.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<AdminDestination>(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<AdminDestination>(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)

View File

@ -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) {

View File

@ -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())
}

View File

@ -35,7 +35,7 @@ class LoginFragment : Fragment(R.layout.fragment_login) {
viewModel.tryLogin(username, password) {
findNavController().apply {
popBackStack<LoginDestination>(true)
navigate(MainDestination(username))
navigate(MainDestination(username, password))
}
}
}

View File

@ -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()

View File

@ -32,7 +32,7 @@ class MainFragment: Fragment(R.layout.fragment_main) {
val password = findNavController().currentBackStackEntry?.toRoute<MainDestination>()?.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))
}
}
}

View File

@ -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 {