diff options
Diffstat (limited to 'src/main/scala/byspel/Service.scala')
-rw-r--r-- | src/main/scala/byspel/Service.scala | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/main/scala/byspel/Service.scala b/src/main/scala/byspel/Service.scala new file mode 100644 index 0000000..1d1e841 --- /dev/null +++ b/src/main/scala/byspel/Service.scala @@ -0,0 +1,69 @@ +package byspel + +import app.DatabaseApi +import java.sql.Timestamp +import java.time.Instant +import java.util.UUID +import scala.concurrent.{ExecutionContext, Future} +import scala.concurrent.duration._ + +trait Service { self: DatabaseApi => + import profile.api._ + + implicit def executionContext: ExecutionContext + + def login(id: String, + password: String): Future[Option[(UsersRow, SessionsRow)]] = { + val query = for { + user <- Users + if user.primaryEmail === id || user.id === id + shadow <- Shadow + if shadow.userId === user.id + } yield { + user -> shadow.hash + } + val userResult = database.run(query.result.headOption).map { + case Some((user, hash)) if PasswordHash.verify(password, hash) => + Some(user) + case _ => + // dummy password hash to avoid timing attacks + PasswordHash.verify( + password, + "$argon2i$v=19$m=65536,t=10,p=1$gFZ4l8R2rpuhfqXDFuugNg$fOvTwLSaOMahD/5AfWlbRsSMj4E6k34VpGyl5xe24yA") + None + } + + userResult.flatMap { + case Some(u) => + val newSession = SessionsRow( + UUID.randomUUID().toString, + u.id, + Timestamp.from(Instant.now.plusSeconds(60 * 60 * 24)) + ) + database + .run( + Sessions += newSession + ) + .map(_ => Some(u -> newSession)) + case None => Future.successful(None) + } + } + + def checkSession(sessionId: String): Future[Option[UsersRow]] = database.run { + val query = for { + session <- Sessions + if session.sessionId === sessionId + if session.expires > Timestamp.from(Instant.now()) + user <- Users + if user.id === session.userId + } yield { + user + } + query.result.headOption + } + + def endSession(sessionId: String) = database.run { + Sessions.filter(_.sessionId === sessionId).delete + } + +} |