Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package ca.schwitzer.muddo.server.fsm
- import java.net.InetSocketAddress
- import akka.actor.{ActorRef, FSM, Props}
- import akka.io.Tcp
- import ca.schwitzer.muddo.db.daos.UserDAO
- import ca.schwitzer.muddo.mud.User
- import ca.schwitzer.muddo.server.connection.{ConnectionManager, Protocol, Protocols}
- import ca.schwitzer.muddo.server.fsm.LoginFSM._
- import ca.schwitzer.muddo.server.login.Authentication
- import scala.concurrent.ExecutionContext
- import scala.util.{Failure, Success}
- class LoginFSM(parent: ActorRef,
- connection: ActorRef,
- remote: InetSocketAddress)
- (implicit userDAO: UserDAO,
- authenticator: Authentication,
- ec: ExecutionContext) extends FSM[State, Data] {
- def dbError(err: Throwable): Unit = {
- log.error(s"Could not access DB. More info: ${err.getMessage}")
- val msg = {
- """Muddo could not access it's database! Sorry!! Please report this to an administrator!
- |Terminating...""".stripMargin
- }
- self ! Protocol.prepareResponse(msg)
- Thread.sleep(500)
- context.stop(connection)
- context.stop(self)
- }
- startWith(UninitializedState, UninitializedData)
- when(UninitializedState) {
- case Event(StartMachine, _) => goto(UsernameInput)
- }
- when(UsernameInput) {
- case Event(Tcp.Received(data), _) =>
- val username = Protocol.sanitizeResponse(data)
- userDAO.getByUsername(username) onComplete {
- case Success(opt) => opt match {
- case Some(user) => self ! UserFound(user)
- case None => self ! UserNotFound(username)
- }
- case Failure(err) => dbError(err)
- }
- goto(AwaitingCallback)
- }
- when(PasswordInput) {
- case Event(Tcp.Received(data), UserData(user)) =>
- val password = Protocol.sanitizeResponse(data)
- if (authenticator.authenticateUser(user, password)) {
- parent ! ConnectionManager.SetToUserMenuPipeline(user)
- stay
- }
- else {
- val msg = "Invalid password."
- self ! Protocol.prepareResponse(msg)
- goto(UsernameInput)
- }
- }
- when(AwaitingCallback) {
- case Event(UserFound(user), _) =>
- goto(PasswordInput) using UserData(user)
- case Event(UserNotFound(username), _) =>
- parent ! ConnectionManager.SetToUserCreationPipeline(username)
- stay
- }
- onTransition {
- case _ -> UsernameInput =>
- val msg = "What is your username?"
- self ! Protocol.prepareResponse(msg)
- case _ -> PasswordInput =>
- val msg = "And what is your password?"
- self ! Protocol.prepareResponse(msg)
- }
- whenUnhandled {
- case Event(Protocols.Send(data), _) =>
- connection ! Tcp.Write(data)
- stay
- case Event(Protocols.Disconnect, _) =>
- connection ! Tcp.Close
- stay
- case Event(Tcp.Closed, _) |
- Event(Tcp.PeerClosed, _) =>
- log.info(s"Client disconnected: $remote")
- context.stop(self)
- stay
- }
- }
- object LoginFSM {
- def props(parent: ActorRef, connection: ActorRef, remote: InetSocketAddress)
- (implicit auth: Authentication, ec: ExecutionContext, userDAO: UserDAO): Props = {
- Props(new LoginFSM(parent, connection, remote))
- }
- sealed trait State
- case object UninitializedState extends State
- case object UsernameInput extends State
- case object PasswordInput extends State
- case object AwaitingCallback extends State
- sealed trait Data
- case object UninitializedData extends Data
- case class UserData(user: User) extends Data
- case class UsernameData(username: String) extends Data
- sealed trait Event
- case object StartMachine extends Event
- case class UserFound(user: User) extends Event
- case class UserNotFound(username: String) extends Event
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement