main #6
58
app/src/main/java/ru/myitschool/work/data/AESEncryption.kt
Normal file
58
app/src/main/java/ru/myitschool/work/data/AESEncryption.kt
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package ru.myitschool.work.data
|
||||||
|
|
||||||
|
import android.util.Base64
|
||||||
|
import javax.crypto.Cipher
|
||||||
|
import javax.crypto.SecretKeyFactory
|
||||||
|
import javax.crypto.spec.IvParameterSpec
|
||||||
|
import javax.crypto.spec.PBEKeySpec
|
||||||
|
import javax.crypto.spec.SecretKeySpec
|
||||||
|
|
||||||
|
|
||||||
|
object AESEncyption {
|
||||||
|
|
||||||
|
const val secretKey = "tK5Ugskdkipokuodvknfdk3434weofnf="
|
||||||
|
const val salt = "QLlGNHNhYTJTQWZ2bGhpV3U="
|
||||||
|
const val iv = "bVQqNFNhRkQ1Njc4UUFaPA=="
|
||||||
|
|
||||||
|
fun encrypt(strToEncrypt: String): String? {
|
||||||
|
try {
|
||||||
|
val ivParameterSpec = IvParameterSpec(Base64.decode(iv, Base64.DEFAULT))
|
||||||
|
|
||||||
|
val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")
|
||||||
|
val spec =
|
||||||
|
PBEKeySpec(secretKey.toCharArray(), Base64.decode(salt, Base64.DEFAULT), 10000, 256)
|
||||||
|
val tmp = factory.generateSecret(spec)
|
||||||
|
val secretKey = SecretKeySpec(tmp.encoded, "AES")
|
||||||
|
|
||||||
|
val cipher = Cipher.getInstance("AES/CBC/PKCS7Padding")
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec)
|
||||||
|
return Base64.encodeToString(
|
||||||
|
cipher.doFinal(strToEncrypt.toByteArray(Charsets.UTF_8)),
|
||||||
|
Base64.DEFAULT
|
||||||
|
)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
println("Error while encrypting: $e")
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun decrypt(strToDecrypt: String?): String? {
|
||||||
|
try {
|
||||||
|
|
||||||
|
val ivParameterSpec = IvParameterSpec(Base64.decode(iv, Base64.DEFAULT))
|
||||||
|
|
||||||
|
val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")
|
||||||
|
val spec =
|
||||||
|
PBEKeySpec(secretKey.toCharArray(), Base64.decode(salt, Base64.DEFAULT), 10000, 256)
|
||||||
|
val tmp = factory.generateSecret(spec)
|
||||||
|
val secretKey = SecretKeySpec(tmp.encoded, "AES")
|
||||||
|
|
||||||
|
val cipher = Cipher.getInstance("AES/CBC/PKCS7Padding")
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec)
|
||||||
|
return String(cipher.doFinal(Base64.decode(strToDecrypt, Base64.DEFAULT)))
|
||||||
|
} catch (e: Exception) {
|
||||||
|
println("Error while decrypting: $e")
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -8,6 +8,7 @@ import androidx.datastore.preferences.core.stringPreferencesKey
|
|||||||
import androidx.datastore.preferences.preferencesDataStore
|
import androidx.datastore.preferences.preferencesDataStore
|
||||||
import kotlinx.coroutines.flow.firstOrNull
|
import kotlinx.coroutines.flow.firstOrNull
|
||||||
import ru.myitschool.work.App
|
import ru.myitschool.work.App
|
||||||
|
import ru.myitschool.work.data.AESEncyption
|
||||||
import ru.myitschool.work.data.dto.AuthRequestDto
|
import ru.myitschool.work.data.dto.AuthRequestDto
|
||||||
import ru.myitschool.work.data.dto.AuthResponseDto
|
import ru.myitschool.work.data.dto.AuthResponseDto
|
||||||
import ru.myitschool.work.data.source.NetworkDataSource
|
import ru.myitschool.work.data.source.NetworkDataSource
|
||||||
@ -21,10 +22,13 @@ object AuthRepository {
|
|||||||
suspend fun checkAndSave(login: String, password: String): Result<AuthResponseDto> {
|
suspend fun checkAndSave(login: String, password: String): Result<AuthResponseDto> {
|
||||||
val data = AuthRequestDto(login=login, password=password)
|
val data = AuthRequestDto(login=login, password=password)
|
||||||
return NetworkDataSource.checkAuth(data).onSuccess { success ->
|
return NetworkDataSource.checkAuth(data).onSuccess { success ->
|
||||||
tokenCache = success.token
|
val encryptedTokenCache = AESEncyption.encrypt(success.token)
|
||||||
App.context.userDataStore.edit { preferences ->
|
tokenCache = encryptedTokenCache
|
||||||
val prefKey = stringPreferencesKey(TOKEN_KEY)
|
if (encryptedTokenCache != null) {
|
||||||
preferences[prefKey] = success.token
|
App.context.userDataStore.edit { preferences ->
|
||||||
|
val prefKey = stringPreferencesKey(TOKEN_KEY)
|
||||||
|
preferences[prefKey] = encryptedTokenCache
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,7 +41,10 @@ object AuthRepository {
|
|||||||
preferences[stringPreferencesKey(TOKEN_KEY)]
|
preferences[stringPreferencesKey(TOKEN_KEY)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tokenCache
|
if (tokenCache != null) {
|
||||||
|
return AESEncyption.decrypt(tokenCache)
|
||||||
|
}
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun logout() {
|
suspend fun logout() {
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import ru.myitschool.work.data.dto.AuthResponseDto
|
|||||||
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 ru.myitschool.work.data.repo.AuthRepository
|
||||||
|
|
||||||
object NetworkDataSource {
|
object NetworkDataSource {
|
||||||
private val client by lazy {
|
private val client by lazy {
|
||||||
@ -41,7 +42,7 @@ object NetworkDataSource {
|
|||||||
|
|
||||||
suspend fun checkAuth(data: AuthRequestDto): Result<AuthResponseDto> = withContext(Dispatchers.IO) {
|
suspend fun checkAuth(data: AuthRequestDto): Result<AuthResponseDto> = withContext(Dispatchers.IO) {
|
||||||
return@withContext runCatching {
|
return@withContext runCatching {
|
||||||
val response = client.post(getUrl(Constants.BOOK_URL)) {
|
val response = client.post(getUrl(Constants.AUTH_URL)) {
|
||||||
contentType(ContentType.Application.Json)
|
contentType(ContentType.Application.Json)
|
||||||
setBody(data)
|
setBody(data)
|
||||||
}
|
}
|
||||||
@ -64,6 +65,9 @@ object NetworkDataSource {
|
|||||||
println("!!!!!!!!!!!!!! getInfo OK ${response.bodyAsText()}")
|
println("!!!!!!!!!!!!!! getInfo OK ${response.bodyAsText()}")
|
||||||
response.body<UserDto>()
|
response.body<UserDto>()
|
||||||
} else {
|
} else {
|
||||||
|
if (response.status == HttpStatusCode.Unauthorized) {
|
||||||
|
AuthRepository.logout()
|
||||||
|
}
|
||||||
println("!!!!!!!!!!!!!! getInfo ERROR ${response.bodyAsText()}")
|
println("!!!!!!!!!!!!!! getInfo ERROR ${response.bodyAsText()}")
|
||||||
error(response.bodyAsText())
|
error(response.bodyAsText())
|
||||||
}
|
}
|
||||||
@ -80,6 +84,9 @@ object NetworkDataSource {
|
|||||||
if (response.status == HttpStatusCode.OK) {
|
if (response.status == HttpStatusCode.OK) {
|
||||||
response.body<Map<String, List<PlaceDto>>>()
|
response.body<Map<String, List<PlaceDto>>>()
|
||||||
} else {
|
} else {
|
||||||
|
if (response.status == HttpStatusCode.Unauthorized) {
|
||||||
|
AuthRepository.logout()
|
||||||
|
}
|
||||||
error(response.bodyAsText())
|
error(response.bodyAsText())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,7 +104,12 @@ object NetworkDataSource {
|
|||||||
when (response.status) {
|
when (response.status) {
|
||||||
HttpStatusCode.Created -> true
|
HttpStatusCode.Created -> true
|
||||||
HttpStatusCode.Conflict -> false
|
HttpStatusCode.Conflict -> false
|
||||||
else -> error(response.bodyAsText())
|
else -> {
|
||||||
|
if (response.status == HttpStatusCode.Unauthorized) {
|
||||||
|
AuthRepository.logout()
|
||||||
|
}
|
||||||
|
error(response.bodyAsText())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user