feat: Create authorization

This commit is contained in:
2026-01-18 22:16:51 +01:00
parent 9d72cda5ff
commit af88f5c559
15 changed files with 794 additions and 12 deletions

View File

@@ -0,0 +1,161 @@
package logic.user.impl
import com.typesafe.config.Config
import jakarta.inject.Inject
import jakarta.persistence.EntityManager
import logic.user.UserManager
import model.users.{User, UserEntity}
import services.OpenIDUserInfo
import util.UserHash
import javax.inject.Singleton
import scala.jdk.CollectionConverters.*
@Singleton
class HibernateUserManager @Inject()(em: EntityManager, config: Config) extends UserManager {
override def addUser(name: String, password: String): Boolean = {
try {
// Check if user already exists
val existing = em.createQuery("SELECT u FROM UserEntity u WHERE u.username = :username", classOf[UserEntity])
.setParameter("username", name)
.getResultList
if (!existing.isEmpty) {
return false
}
// Create new user
val userEntity = UserEntity.fromUser(User(
internalId = 0L, // Will be set by database
id = java.util.UUID.randomUUID(),
name = name,
passwordHash = UserHash.hashPW(password)
))
em.persist(userEntity)
em.flush()
true
} catch {
case _: Exception => false
}
}
override def addOpenIDUser(name: String, userInfo: OpenIDUserInfo): Boolean = {
try {
// Check if user already exists
val existing = em.createQuery("SELECT u FROM UserEntity u WHERE u.username = :username", classOf[UserEntity])
.setParameter("username", name)
.getResultList
if (!existing.isEmpty) {
return false
}
// Check if OpenID user already exists
val existingOpenID = em.createQuery(
"SELECT u FROM UserEntity u WHERE u.openidProvider = :provider AND u.openidProviderId = :providerId",
classOf[UserEntity]
)
.setParameter("provider", userInfo.provider)
.setParameter("providerId", userInfo.id)
.getResultList
if (!existingOpenID.isEmpty) {
return false
}
// Create new OpenID user
val userEntity = UserEntity.fromOpenIDUser(name, userInfo)
em.persist(userEntity)
em.flush()
true
} catch {
case _: Exception => false
}
}
override def authenticate(name: String, password: String): Option[User] = {
try {
val users = em.createQuery("SELECT u FROM UserEntity u WHERE u.username = :username", classOf[UserEntity])
.setParameter("username", name)
.getResultList
if (users.isEmpty) {
return None
}
val userEntity = users.get(0)
if (UserHash.verifyUser(password, userEntity.toUser)) {
Some(userEntity.toUser)
} else {
None
}
} catch {
case _: Exception => None
}
}
override def authenticateOpenID(provider: String, providerId: String): Option[User] = {
try {
val users = em.createQuery(
"SELECT u FROM UserEntity u WHERE u.openidProvider = :provider AND u.openidProviderId = :providerId",
classOf[UserEntity]
)
.setParameter("provider", provider)
.setParameter("providerId", providerId)
.getResultList
if (users.isEmpty) {
None
} else {
Some(users.get(0).toUser)
}
} catch {
case _: Exception => None
}
}
override def userExists(name: String): Option[User] = {
try {
val users = em.createQuery("SELECT u FROM UserEntity u WHERE u.username = :username", classOf[UserEntity])
.setParameter("username", name)
.getResultList
if (users.isEmpty) {
None
} else {
Some(users.get(0).toUser)
}
} catch {
case _: Exception => None
}
}
override def userExistsById(id: Long): Option[User] = {
try {
Option(em.find(classOf[UserEntity], id)).map(_.toUser)
} catch {
case _: Exception => None
}
}
override def removeUser(name: String): Boolean = {
try {
val users = em.createQuery("SELECT u FROM UserEntity u WHERE u.username = :username", classOf[UserEntity])
.setParameter("username", name)
.getResultList
if (users.isEmpty) {
false
} else {
em.remove(users.get(0))
em.flush()
true
}
} catch {
case _: Exception => false
}
}
}

View File

@@ -3,26 +3,22 @@ package logic.user.impl
import com.typesafe.config.Config
import logic.user.UserManager
import model.users.User
import services.OpenIDUserInfo
import util.UserHash
import javax.inject.{Inject, Singleton}
import scala.collection.mutable
@Singleton
class StubUserManager @Inject()(val config: Config) extends UserManager {
class StubUserManager @Inject()(config: Config) extends UserManager {
private val user: Map[String, User] = Map(
private val user: mutable.Map[String, User] = mutable.Map(
"Janis" -> User(
internalId = 1L,
id = java.util.UUID.fromString("123e4567-e89b-12d3-a456-426614174000"),
name = "Janis",
passwordHash = UserHash.hashPW("password123")
),
"Leon" -> User(
internalId = 2L,
id = java.util.UUID.fromString("223e4567-e89b-12d3-a456-426614174000"),
name = "Leon",
passwordHash = UserHash.hashPW("password123")
),
"Jakob" -> User(
internalId = 2L,
id = java.util.UUID.fromString("323e4567-e89b-12d3-a456-426614174000"),
@@ -35,6 +31,18 @@ class StubUserManager @Inject()(val config: Config) extends UserManager {
throw new NotImplementedError("StubUserManager.addUser is not implemented")
}
override def addOpenIDUser(name: String, userInfo: OpenIDUserInfo): Boolean = {
// For stub implementation, just add a user without password
val newUser = User(
internalId = user.size.toLong + 1,
id = java.util.UUID.randomUUID(),
name = name,
passwordHash = "" // No password for OpenID users
)
user(name) = newUser
true
}
override def authenticate(name: String, password: String): Option[User] = {
user.get(name) match {
case Some(u) if UserHash.verifyUser(password, u) => Some(u)
@@ -42,6 +50,13 @@ class StubUserManager @Inject()(val config: Config) extends UserManager {
}
}
override def authenticateOpenID(provider: String, providerId: String): Option[User] = {
user.values.find { u =>
// In a real implementation, this would check stored OpenID provider info
u.name.startsWith(s"${provider}_") && u.name.contains(providerId)
}
}
override def userExists(name: String): Option[User] = {
user.get(name)
}
@@ -51,7 +66,6 @@ class StubUserManager @Inject()(val config: Config) extends UserManager {
}
override def removeUser(name: String): Boolean = {
throw new NotImplementedError("StubUserManager.removeUser is not implemented")
user.remove(name).isDefined
}
}