From 35948e1b87271a15772071263a6d44c44618b836 Mon Sep 17 00:00:00 2001 From: 1billy17 Date: Mon, 20 Jan 2025 08:00:10 +0300 Subject: [PATCH] add Services --- .idea/vcs.xml | 6 + src/main/kotlin/Main.kt | 214 +++++++++---------- src/main/kotlin/model/AdminUser.kt | 42 +--- src/main/kotlin/model/IAdminUser.kt | 8 - src/main/kotlin/service/AdminServiceImpl.kt | 28 +++ src/main/kotlin/service/AuthorizeService.kt | 30 +++ src/main/kotlin/service/IAdminService.kt | 10 + src/main/kotlin/service/IAuthorizeService.kt | 8 + src/main/kotlin/service/IPasswordService.kt | 6 + src/main/kotlin/service/PasswordService.kt | 24 +++ 10 files changed, 210 insertions(+), 166 deletions(-) create mode 100644 .idea/vcs.xml delete mode 100644 src/main/kotlin/model/IAdminUser.kt create mode 100644 src/main/kotlin/service/AdminServiceImpl.kt create mode 100644 src/main/kotlin/service/AuthorizeService.kt create mode 100644 src/main/kotlin/service/IAdminService.kt create mode 100644 src/main/kotlin/service/IAuthorizeService.kt create mode 100644 src/main/kotlin/service/IPasswordService.kt create mode 100644 src/main/kotlin/service/PasswordService.kt diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/main/kotlin/Main.kt b/src/main/kotlin/Main.kt index aad1277..6e95d7b 100644 --- a/src/main/kotlin/Main.kt +++ b/src/main/kotlin/Main.kt @@ -1,147 +1,108 @@ import model.AdminUser -import model.ManagerUser import model.DefaultUser +import model.ManagerUser import model.User +import service.AdminServiceImpl +import service.AuthorizeService +import service.PasswordService import java.time.LocalDate -import javax.crypto.SecretKeyFactory -import javax.crypto.spec.PBEKeySpec -import java.util.Base64 - val authorizationList = mutableListOf() - -private const val HASH_LENGTH = 256 -private const val ITERATIONS = 65536 -val salt = "sosalt" - - fun main() { + val passwordService = PasswordService() + val adminService = AdminServiceImpl(authorizationList, passwordService) + val authorizeService = AuthorizeService(authorizationList, passwordService) + while (true) { - println("1) Регаться тут") - println("2) Авторизироваться тут") - var choice = readln() - if (choice == "1") { - authorizationList.add(registration()) - authorizationList.forEach{ - println(it.userId) - println(it.login) - println(it.password) - println(it.email) - println(it.lastAuthorizeDate) + println("1) Регистрация") + println("2) Авторизация") + val choice = readln() + when (choice) { + "1" -> { + val user = createUser(passwordService) + val registered = authorizeService.registration(user) + if (registered) { + println("Регистрация успешна") + } else { + println("Пользователь с таким email или логином уже существует") + } } - } - else { - println(authorization()) + "2" -> { + try { + println("Введите email:") + val email = readln() + println("Введите пароль:") + val password = readln() + val user = authorizeService.authorize(email, password) + println("Пользователь найден: ${user.login}, тип: ${user::class.simpleName}") + + if (user is AdminUser) { + var adminFlg = true + while (adminFlg) { + adminFlg = adminFunctional(adminService) + } + } + } catch (e: IllegalArgumentException) { + println(e.message) + } + } + else -> println("Неверный выбор") } } } +fun createUser(passwordService: PasswordService): User { + println("Введите email:") + val email = readln() + require(email.contains("@")) { "Email должен содержать '@'" } -fun hashPassword(password: String, salt: String): String { - val saltBytes = Base64.getDecoder().decode(salt) - val spec = PBEKeySpec(password.toCharArray(), saltBytes, ITERATIONS, HASH_LENGTH) - val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256") - val hash = factory.generateSecret(spec).encoded - return Base64.getEncoder().encodeToString(hash) -} - - -fun registration(): User{ - println("Почту пиши") - val user_Email = readlnOrNull() - checkNotNull(user_Email) - require(user_Email.contains("@")) { - "Добавь @" + println("Введите пароль:") + val password = readln() + require(password.length >= 8 && password.any { it.isDigit() } && password.any { it.isLetter() }) { + "Пароль должен быть не менее 8 символов и содержать буквы и цифры" } - println("Пароль пиши") - val user_Password = readlnOrNull() - checkNotNull(user_Password) - require(user_Password.length >= 8 && - user_Password.any { it.isDigit() } && - user_Password.any { it.isLetter() && it in 'a'..'z' || it in 'A'..'Z' } - ) { - "Длинее делай или цифру/букву добавляй" - } + println("Повторите пароль:") + val confirmPassword = readln() + require(password == confirmPassword) { "Пароли не совпадают" } - println("Заново пароль пиши") - val user_Password1 = readlnOrNull() - checkNotNull(user_Password1) - require(user_Password1 == user_Password) { - "Ну ты и тупорылый" - } + println("Введите логин:") + val login = readln() + require(login.length >= 4) { "Логин должен быть не менее 4 символов" } - println("Логин пиши") - val user_Login = readlnOrNull() - checkNotNull(user_Login) - require(user_Login.length >= 4) { - "Длинее делай" - } + println("Выберите роль: 1) Обычный пользователь 2) Администратор 3) Менеджер") + val role = readln() + val hashedPassword = passwordService.hashPassword(password) - println("ТЫ КТО? 1) лох 2) админо 3) манагер") - val role = readlnOrNull() - checkNotNull(role) - - return when(role) { - "1" -> return DefaultUser( + return when (role) { + "1" -> DefaultUser( userId = authorizationList.size + 1, - login = user_Login, - password = hashPassword(user_Password, salt), - email = user_Email, + login = login, + password = hashedPassword, + email = email, lastAuthorizeDate = LocalDate.now() ) - - "2" -> return AdminUser( + "2" -> AdminUser( userId = authorizationList.size + 1, - login = user_Login, - password = hashPassword(user_Password, salt), - email = user_Email, + login = login, + password = hashedPassword, + email = email, lastAuthorizeDate = LocalDate.now() ) - - "3" -> return ManagerUser( + "3" -> ManagerUser( userId = authorizationList.size + 1, - login = user_Login, - password = hashPassword(user_Password, salt), - email = user_Email, + login = login, + password = hashedPassword, + email = email, lastAuthorizeDate = LocalDate.now() ) - - else -> { throw IllegalArgumentException("error") } + else -> throw IllegalArgumentException("Некорректный выбор роли") } } - -fun authorization(): String{ - var adminFlg = true - println("Почту пиши") - val user_Email = readlnOrNull() - checkNotNull(user_Email) - val user = authorizationList.find { it.email == user_Email } - require(user != null) { - "нет такого" - } - - println("Пароль пиши") - val user_Password = readlnOrNull() - checkNotNull(user_Password) - require(user.password == hashPassword(user_Password, salt)) { - "не то" - } - - if (user is AdminUser) { - while (adminFlg == true) { - adminFlg = adminFunctional(user) - } - } - - return "такой есть" -} - - -fun adminFunctional(user: AdminUser): Boolean { +fun adminFunctional(adminService: AdminServiceImpl): Boolean { println("1) Показать всех") println("2) Показать всех сорт") println("3) Поменять пароль") @@ -150,13 +111,32 @@ fun adminFunctional(user: AdminUser): Boolean { var flg = readln() when(flg) { - "1" -> user.allUsers(authorizationList) - "2" -> user.allUsersSort(authorizationList) - "3" -> user.updateUserPassword(authorizationList) - "4" -> user.removeUser(authorizationList) + "1" -> { + adminService.getAllUsers().forEach { + println("${it.userId}: ${it.login} (${it.email})") + } + } + "2" -> { + adminService.getAllUsersSort().forEach { + println("${it.userId}: ${it.login} (${it.lastAuthorizeDate})") + } + } + "3" -> { + println("Введите email пользователя для обновления пароля") + val email = readln() + println("Введите новый пароль") + val newPassword = readln() + val updated = adminService.updateUserPassword(email, newPassword) + if (updated) println("Пароль обновлен") else println("Пользователь не найден") + } + "4" -> { + println("Введите ID пользователя для удаления") + val userId = readln().toInt() + val removed = adminService.removeUserById(userId) + if (removed) println("Пользователь удален") else println("Пользователь не найден") + } "5" -> return false } return true -} - +} \ No newline at end of file diff --git a/src/main/kotlin/model/AdminUser.kt b/src/main/kotlin/model/AdminUser.kt index 9f57a3a..81c72d3 100644 --- a/src/main/kotlin/model/AdminUser.kt +++ b/src/main/kotlin/model/AdminUser.kt @@ -1,7 +1,5 @@ package model -import hashPassword -import salt import java.time.LocalDate class AdminUser( @@ -10,42 +8,4 @@ class AdminUser( password: String, email: String, lastAuthorizeDate: LocalDate, -): User(userId, login, password, email, lastAuthorizeDate), IAdminUser { - - override fun allUsers(authorizationList: MutableList) { - for (user in authorizationList) { - println(user.login) - } - } - - override fun allUsersSort(authorizationList: MutableList) { - authorizationList.sortByDescending { it.lastAuthorizeDate } - for (user in authorizationList) { - println(user.login + " зашел в " + user.lastAuthorizeDate) - } - } - - override fun updateUserPassword(authorizationList: MutableList) { - println("Почту пиши для апдейта") - val email = readln() - println("Пароль пиши для апдейта") - val password = readln() - - val user = authorizationList.find { it.email == email } - require(user != null) { - "нет такого" - } - - user.password = hashPassword(password, salt) - } - - override fun removeUser(authorizationList: MutableList) { - println("Почту пиши для апдейта") - val email = readln() - - val removed = authorizationList.removeIf { it.email == email } - if (removed) { - println("удалили") - } else { println("не удалили") } - } -} \ No newline at end of file +): User(userId, login, password, email, lastAuthorizeDate) \ No newline at end of file diff --git a/src/main/kotlin/model/IAdminUser.kt b/src/main/kotlin/model/IAdminUser.kt deleted file mode 100644 index 57856f8..0000000 --- a/src/main/kotlin/model/IAdminUser.kt +++ /dev/null @@ -1,8 +0,0 @@ -package model - -interface IAdminUser { - fun allUsers(authorizationList: MutableList) - fun allUsersSort(authorizationList: MutableList) - fun updateUserPassword(authorizationList: MutableList) - fun removeUser(authorizationList: MutableList) -} \ No newline at end of file diff --git a/src/main/kotlin/service/AdminServiceImpl.kt b/src/main/kotlin/service/AdminServiceImpl.kt new file mode 100644 index 0000000..0a03bf4 --- /dev/null +++ b/src/main/kotlin/service/AdminServiceImpl.kt @@ -0,0 +1,28 @@ +package service + +import model.User + +class AdminServiceImpl(private val authorizationList: MutableList, private val passwordService: IPasswordService) : IAdminService { + + override fun getAllUsers(): List { + return authorizationList.toList() + } + + override fun getAllUsersSort(): List { + return authorizationList.sortedByDescending { it.lastAuthorizeDate } + } + + override fun updateUserPassword(email: String, newPassword: String): Boolean { + val user = authorizationList.find { it.email == email } + require(user != null) { + return false + } + + user.password = passwordService.hashPassword(newPassword) + return true + } + + override fun removeUserById(userId: Int): Boolean { + return authorizationList.removeIf { it.userId == userId } + } +} \ No newline at end of file diff --git a/src/main/kotlin/service/AuthorizeService.kt b/src/main/kotlin/service/AuthorizeService.kt new file mode 100644 index 0000000..4d2d53f --- /dev/null +++ b/src/main/kotlin/service/AuthorizeService.kt @@ -0,0 +1,30 @@ +package service + +import model.User +import java.time.LocalDate + +class AuthorizeService( + private val authorizationList: MutableList, + private val passwordService: IPasswordService +) : IAuthorizeService { + + override fun registration(user: User): Boolean { + if (authorizationList.any { it.email == user.email || it.login == user.login }) { + return false // Пользователь с таким email или логином уже существует + } + authorizationList.add(user) + return true + } + + override fun authorize(email: String, password: String): User { + val user = authorizationList.find { it.email == email } + ?: throw IllegalArgumentException("Пользователь с таким email не найден") + + if (!passwordService.matches(password, user.password)) { + throw IllegalArgumentException("Неверный пароль") + } + + user.lastAuthorizeDate = LocalDate.now() + return user + } +} \ No newline at end of file diff --git a/src/main/kotlin/service/IAdminService.kt b/src/main/kotlin/service/IAdminService.kt new file mode 100644 index 0000000..ef4e6b5 --- /dev/null +++ b/src/main/kotlin/service/IAdminService.kt @@ -0,0 +1,10 @@ +package service + +import model.User + +interface IAdminService { + fun getAllUsers(): List + fun getAllUsersSort(): List + fun updateUserPassword(email: String, newPassword: String): Boolean + fun removeUserById(userId: Int): Boolean +} \ No newline at end of file diff --git a/src/main/kotlin/service/IAuthorizeService.kt b/src/main/kotlin/service/IAuthorizeService.kt new file mode 100644 index 0000000..39a5901 --- /dev/null +++ b/src/main/kotlin/service/IAuthorizeService.kt @@ -0,0 +1,8 @@ +package service + +import model.User + +interface IAuthorizeService { + fun registration(user: User): Boolean + fun authorize(email: String, password: String): User +} \ No newline at end of file diff --git a/src/main/kotlin/service/IPasswordService.kt b/src/main/kotlin/service/IPasswordService.kt new file mode 100644 index 0000000..0474cb2 --- /dev/null +++ b/src/main/kotlin/service/IPasswordService.kt @@ -0,0 +1,6 @@ +package service + +interface IPasswordService { + fun hashPassword(password: String): String + fun matches(password: String, hashedPassword: String): Boolean +} \ No newline at end of file diff --git a/src/main/kotlin/service/PasswordService.kt b/src/main/kotlin/service/PasswordService.kt new file mode 100644 index 0000000..45a0d45 --- /dev/null +++ b/src/main/kotlin/service/PasswordService.kt @@ -0,0 +1,24 @@ +package service + +import java.util.* +import javax.crypto.SecretKeyFactory +import javax.crypto.spec.PBEKeySpec + +class PasswordService : IPasswordService{ + private val HASH_LENGTH = 256 + private val ITERATIONS = 65536 + private val salt = "sosalt" + + override fun hashPassword(password: String): String { + val saltBytes = Base64.getDecoder().decode(salt) + val spec = PBEKeySpec(password.toCharArray(), saltBytes, ITERATIONS, HASH_LENGTH) + val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256") + val hash = factory.generateSecret(spec).encoded + return Base64.getEncoder().encodeToString(hash) + } + + override fun matches(password: String, hashedPassword: String): Boolean { + val hash = hashPassword(password) + return hash == hashedPassword + } +} \ No newline at end of file