Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.erezbiox1
- import java.nio.charset.StandardCharsets
- import java.security.MessageDigest
- import java.sql.DriverManager
- import java.sql.ResultSet
- import java.util.*
- import kotlin.reflect.KProperty
- @Suppress("NullableBooleanElvis", "unused", "MemberVisibilityCanPrivate")
- /**
- * Created by Erezbiox1 on 30/11/2017.
- * (C) 2017 Erez Rotem All Rights Reserved.
- */
- abstract class AbstractUser(val id: Int) {
- var username: String by SQL()
- var email: String by SQL()
- var password: String
- get() = error("Cannot access hashed password")
- set(pass) = sql("UPDATE users SET password = ?", hash(password))
- companion object {
- fun sql(query: String, vararg objects: Any, function: ((ResultSet?) -> Unit)? = null) {
- Class.forName("com.mysql.jdbc.Driver")
- val db = DriverManager.getConnection("jdbc:mysql://localhost:3306/main", "erez", "Pizza123")
- val statement = db.prepareStatement(query)
- objects.withIndex().forEach {
- when(it.value){
- is Int -> statement.setInt(it.index + 1, it.value as Int)
- is Boolean -> statement.setBoolean(it.index + 1, it.value as Boolean)
- else -> statement.setString(it.index + 1, it.value.toString())
- }
- }
- val result =
- if(statement.execute() && statement.resultSet.next())
- statement.resultSet
- else null
- function?.invoke(result)
- result?.close()
- statement.close()
- db.close()
- }
- inline fun <reified T> ResultSet?.get(column: Int = 1) : T? {
- if(this == null)
- return null
- return when(T::class){
- java.lang.Integer::class -> this.getInt(column) as T
- java.lang.Integer::class.java -> this.getInt(column) as T
- java.lang.Boolean::class -> this.getBoolean(column) as T
- java.lang.Boolean::class.java -> this.getBoolean(column) as T
- else -> this.getString(column) as T
- }
- }
- private fun createHash(password: String) : String {
- val random = UUID.randomUUID().toString()
- return random + ":" + hash(random + password)
- }
- private fun matchHash(password: String, hash: String) : Boolean {
- val split = hash.split(":")
- val salt = split[0]
- val hashed = split[1]
- return hash(salt + password) == hashed
- }
- private fun hash(password: String): String {
- return Base64.getEncoder().encodeToString(MessageDigest.getInstance("SHA-256").digest(password.toByteArray(StandardCharsets.UTF_8)))
- }
- @JvmStatic
- protected fun registerUser(username: String, email: String, password: String) : Int {
- var userId = -1
- sql("SELECT id, password FROM users WHERE username = ?", username.toLowerCase()){
- val pass = it?.get<String>(2)
- if(pass != null){
- userId =
- if(hash(password.toLowerCase()) == pass)
- it.get(1)!!
- else -2
- }
- }
- if(userId == -1){
- sql("INSERT INTO users (username, email, password) VALUES (?, ?, ?)",
- username.toLowerCase(),
- email.toLowerCase(),
- createHash(password.toLowerCase()))
- sql("SELECT id FROM users WHERE username = ?", username.toLowerCase()){
- userId = it?.get() ?: -1 // Cannot really be -1, but what the heck.
- }
- }
- return userId
- }
- @JvmStatic
- protected fun loginUser(username: String, password: String) : Int {
- var userId = -1
- sql("SELECT id, password FROM users WHERE username = ?", username.toLowerCase()){
- val pass = it?.get<String>(2)
- if(pass != null)
- userId = if(matchHash(password.toLowerCase(), pass))
- it.get(1) ?: -1
- else -2
- }
- return userId
- }
- }
- inner class SQL(val name: String? = null) {
- inline operator fun <reified T> getValue(ref: Any?, property: KProperty<*>) : T {
- var value: T? = null
- sql("SELECT ${name ?: property.name} FROM users where id = ?", id){
- value = it.get()
- }
- return value ?: error("Database Connection Error. value is null.")
- }
- operator fun <T> setValue(ref: Any?, property: KProperty<*>, value: T) {
- sql("UPDATE users SET ${name ?: property.name} = ? WHERE id = ?", value!!, id)
- }
- }
- }
Add Comment
Please, Sign In to add comment