mirror of
				https://github.com/arcan1s/ffxivbis.git
				synced 2025-10-30 21:23:41 +00:00 
			
		
		
		
	improve api
This commit is contained in:
		| @ -11,6 +11,7 @@ package me.arcanis.ffxivbis.http | |||||||
| import akka.actor.ActorRef | import akka.actor.ActorRef | ||||||
| import akka.pattern.ask | import akka.pattern.ask | ||||||
| import akka.util.Timeout | import akka.util.Timeout | ||||||
|  | import me.arcanis.ffxivbis.http.api.v1.json.ApiAction | ||||||
| import me.arcanis.ffxivbis.models.{Piece, Player, PlayerId} | import me.arcanis.ffxivbis.models.{Piece, Player, PlayerId} | ||||||
| import me.arcanis.ffxivbis.service.impl.DatabaseBiSHandler | import me.arcanis.ffxivbis.service.impl.DatabaseBiSHandler | ||||||
|  |  | ||||||
| @ -26,6 +27,13 @@ class BiSHelper(storage: ActorRef, ariyala: ActorRef) extends AriyalaHelper(ariy | |||||||
|          (implicit executionContext: ExecutionContext, timeout: Timeout): Future[Seq[Player]] = |          (implicit executionContext: ExecutionContext, timeout: Timeout): Future[Seq[Player]] = | ||||||
|     (storage ? DatabaseBiSHandler.GetBiS(partyId, playerId)).mapTo[Seq[Player]] |     (storage ? DatabaseBiSHandler.GetBiS(partyId, playerId)).mapTo[Seq[Player]] | ||||||
|  |  | ||||||
|  |   def doModifyBiS(action: ApiAction.Value, playerId: PlayerId, piece: Piece) | ||||||
|  |                  (implicit executionContext: ExecutionContext, timeout: Timeout): Future[Int] = | ||||||
|  |     action match { | ||||||
|  |       case ApiAction.add => addPieceBiS(playerId, piece) | ||||||
|  |       case ApiAction.remove => removePieceBiS(playerId, piece) | ||||||
|  |     } | ||||||
|  |  | ||||||
|   def putBiS(playerId: PlayerId, link: String) |   def putBiS(playerId: PlayerId, link: String) | ||||||
|             (implicit executionContext: ExecutionContext, timeout: Timeout): Future[Unit] = |             (implicit executionContext: ExecutionContext, timeout: Timeout): Future[Unit] = | ||||||
|     downloadBiS(link, playerId.job).flatMap { bis => |     downloadBiS(link, playerId.job).flatMap { bis => | ||||||
|  | |||||||
| @ -11,6 +11,7 @@ package me.arcanis.ffxivbis.http | |||||||
| import akka.actor.ActorRef | import akka.actor.ActorRef | ||||||
| import akka.pattern.ask | import akka.pattern.ask | ||||||
| import akka.util.Timeout | import akka.util.Timeout | ||||||
|  | import me.arcanis.ffxivbis.http.api.v1.json.ApiAction | ||||||
| import me.arcanis.ffxivbis.models.{Piece, Player, PlayerId, PlayerIdWithCounters} | import me.arcanis.ffxivbis.models.{Piece, Player, PlayerId, PlayerIdWithCounters} | ||||||
| import me.arcanis.ffxivbis.service.LootSelector.LootSelectorResult | import me.arcanis.ffxivbis.service.LootSelector.LootSelectorResult | ||||||
| import me.arcanis.ffxivbis.service.impl.DatabaseLootHandler | import me.arcanis.ffxivbis.service.impl.DatabaseLootHandler | ||||||
| @ -23,6 +24,13 @@ class LootHelper(storage: ActorRef) { | |||||||
|                   (implicit executionContext: ExecutionContext, timeout: Timeout): Future[Int] = |                   (implicit executionContext: ExecutionContext, timeout: Timeout): Future[Int] = | ||||||
|     (storage ? DatabaseLootHandler.AddPieceTo(playerId, piece)).mapTo[Int] |     (storage ? DatabaseLootHandler.AddPieceTo(playerId, piece)).mapTo[Int] | ||||||
|  |  | ||||||
|  |   def doModifyLoot(action: ApiAction.Value, playerId: PlayerId, piece: Piece) | ||||||
|  |                   (implicit executionContext: ExecutionContext, timeout: Timeout): Future[Int] = | ||||||
|  |     action match { | ||||||
|  |       case ApiAction.add => addPieceLoot(playerId, piece) | ||||||
|  |       case ApiAction.remove => removePieceLoot(playerId, piece) | ||||||
|  |     } | ||||||
|  |  | ||||||
|   def loot(partyId: String, playerId: Option[PlayerId]) |   def loot(partyId: String, playerId: Option[PlayerId]) | ||||||
|           (implicit executionContext: ExecutionContext, timeout: Timeout): Future[Seq[Player]] = |           (implicit executionContext: ExecutionContext, timeout: Timeout): Future[Seq[Player]] = | ||||||
|     (storage ? DatabaseLootHandler.GetLoot(partyId, playerId)).mapTo[Seq[Player]] |     (storage ? DatabaseLootHandler.GetLoot(partyId, playerId)).mapTo[Seq[Player]] | ||||||
|  | |||||||
| @ -11,11 +11,11 @@ package me.arcanis.ffxivbis.http | |||||||
| import akka.actor.ActorRef | import akka.actor.ActorRef | ||||||
| import akka.pattern.ask | import akka.pattern.ask | ||||||
| import akka.util.Timeout | import akka.util.Timeout | ||||||
|  | import me.arcanis.ffxivbis.http.api.v1.json.ApiAction | ||||||
| import me.arcanis.ffxivbis.models.{Party, Player, PlayerId} | import me.arcanis.ffxivbis.models.{Party, Player, PlayerId} | ||||||
| import me.arcanis.ffxivbis.service.impl.{DatabaseBiSHandler, DatabasePartyHandler} | import me.arcanis.ffxivbis.service.impl.{DatabaseBiSHandler, DatabasePartyHandler} | ||||||
|  |  | ||||||
| import scala.concurrent.{ExecutionContext, Future} | import scala.concurrent.{ExecutionContext, Future} | ||||||
| import scala.util.{Failure, Success} |  | ||||||
|  |  | ||||||
| class PlayerHelper(storage: ActorRef, ariyala: ActorRef) extends AriyalaHelper(ariyala) { | class PlayerHelper(storage: ActorRef, ariyala: ActorRef) extends AriyalaHelper(ariyala) { | ||||||
|  |  | ||||||
| @ -31,6 +31,13 @@ class PlayerHelper(storage: ActorRef, ariyala: ActorRef) extends AriyalaHelper(a | |||||||
|       } |       } | ||||||
|     }.flatten |     }.flatten | ||||||
|  |  | ||||||
|  |   def doModifyPlayer(action: ApiAction.Value, player: Player) | ||||||
|  |                     (implicit executionContext: ExecutionContext, timeout: Timeout): Future[Int] = | ||||||
|  |     action match { | ||||||
|  |       case ApiAction.add => addPlayer(player) | ||||||
|  |       case ApiAction.remove => removePlayer(player.playerId) | ||||||
|  |     } | ||||||
|  |  | ||||||
|   def getPlayers(partyId: String, maybePlayerId: Option[PlayerId]) |   def getPlayers(partyId: String, maybePlayerId: Option[PlayerId]) | ||||||
|                 (implicit executionContext: ExecutionContext, timeout: Timeout): Future[Seq[Player]] = |                 (implicit executionContext: ExecutionContext, timeout: Timeout): Future[Seq[Player]] = | ||||||
|     maybePlayerId match { |     maybePlayerId match { | ||||||
|  | |||||||
| @ -13,6 +13,7 @@ import akka.http.scaladsl.model.{HttpEntity, StatusCodes} | |||||||
| import akka.http.scaladsl.server.Directives._ | import akka.http.scaladsl.server.Directives._ | ||||||
| import akka.http.scaladsl.server._ | import akka.http.scaladsl.server._ | ||||||
| import akka.util.Timeout | import akka.util.Timeout | ||||||
|  | import com.typesafe.scalalogging.StrictLogging | ||||||
| import io.swagger.v3.oas.annotations.enums.ParameterIn | import io.swagger.v3.oas.annotations.enums.ParameterIn | ||||||
| import io.swagger.v3.oas.annotations.media.{ArraySchema, Content, Schema} | import io.swagger.v3.oas.annotations.media.{ArraySchema, Content, Schema} | ||||||
| import io.swagger.v3.oas.annotations.responses.ApiResponse | import io.swagger.v3.oas.annotations.responses.ApiResponse | ||||||
| @ -24,9 +25,11 @@ import me.arcanis.ffxivbis.http.{Authorization, BiSHelper} | |||||||
| import me.arcanis.ffxivbis.http.api.v1.json._ | import me.arcanis.ffxivbis.http.api.v1.json._ | ||||||
| import me.arcanis.ffxivbis.models.PlayerId | import me.arcanis.ffxivbis.models.PlayerId | ||||||
|  |  | ||||||
|  | import scala.util.{Failure, Success} | ||||||
|  |  | ||||||
| @Path("api/v1") | @Path("api/v1") | ||||||
| class BiSEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit timeout: Timeout) | class BiSEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit timeout: Timeout) | ||||||
|   extends BiSHelper(storage, ariyala) with Authorization with JsonSupport { |   extends BiSHelper(storage, ariyala) with Authorization with JsonSupport with HttpExceptionsHandler { | ||||||
|  |  | ||||||
|   def route: Route = createBiS ~ getBiS ~ modifyBiS |   def route: Route = createBiS ~ getBiS ~ modifyBiS | ||||||
|  |  | ||||||
| @ -51,12 +54,17 @@ class BiSEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit ti | |||||||
|   ) |   ) | ||||||
|   def createBiS: Route = |   def createBiS: Route = | ||||||
|     path("party" / Segment / "bis") { partyId => |     path("party" / Segment / "bis") { partyId => | ||||||
|  |       handleExceptions(exceptionHandler) { | ||||||
|         extractExecutionContext { implicit executionContext => |         extractExecutionContext { implicit executionContext => | ||||||
|           authenticateBasicBCrypt(s"party $partyId", authPost(partyId)) { _ => |           authenticateBasicBCrypt(s"party $partyId", authPost(partyId)) { _ => | ||||||
|             put { |             put { | ||||||
|               entity(as[PlayerBiSLinkResponse]) { bisLink => |               entity(as[PlayerBiSLinkResponse]) { bisLink => | ||||||
|                 val playerId = bisLink.playerId.withPartyId(partyId) |                 val playerId = bisLink.playerId.withPartyId(partyId) | ||||||
|               complete(putBiS(playerId, bisLink.link).map(_ => (StatusCodes.Created, HttpEntity.Empty))) |                 onComplete(putBiS(playerId, bisLink.link)) { | ||||||
|  |                   case Success(_) => complete(StatusCodes.Created, HttpEntity.Empty) | ||||||
|  |                   case Failure(exception) => throw exception | ||||||
|  |                 } | ||||||
|  |               } | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
| @ -86,12 +94,17 @@ class BiSEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit ti | |||||||
|   ) |   ) | ||||||
|   def getBiS: Route = |   def getBiS: Route = | ||||||
|     path("party" / Segment / "bis") { partyId => |     path("party" / Segment / "bis") { partyId => | ||||||
|  |       handleExceptions(exceptionHandler) { | ||||||
|         extractExecutionContext { implicit executionContext => |         extractExecutionContext { implicit executionContext => | ||||||
|           authenticateBasicBCrypt(s"party $partyId", authGet(partyId)) { _ => |           authenticateBasicBCrypt(s"party $partyId", authGet(partyId)) { _ => | ||||||
|             get { |             get { | ||||||
|               parameters("nick".as[String].?, "job".as[String].?) { (maybeNick, maybeJob) => |               parameters("nick".as[String].?, "job".as[String].?) { (maybeNick, maybeJob) => | ||||||
|                 val playerId = PlayerId(partyId, maybeNick, maybeJob) |                 val playerId = PlayerId(partyId, maybeNick, maybeJob) | ||||||
|               complete(bis(partyId, playerId).map(_.map(PlayerResponse.fromPlayer))) |                 onComplete(bis(partyId, playerId)) { | ||||||
|  |                   case Success(response) => complete(response.map(PlayerResponse.fromPlayer)) | ||||||
|  |                   case Failure(exception) => throw exception | ||||||
|  |                 } | ||||||
|  |               } | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
| @ -119,17 +132,16 @@ class BiSEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit ti | |||||||
|   ) |   ) | ||||||
|   def modifyBiS: Route = |   def modifyBiS: Route = | ||||||
|     path("party" / Segment / "bis") { partyId => |     path("party" / Segment / "bis") { partyId => | ||||||
|  |       handleExceptions(exceptionHandler) { | ||||||
|         extractExecutionContext { implicit executionContext => |         extractExecutionContext { implicit executionContext => | ||||||
|           authenticateBasicBCrypt(s"party $partyId", authPost(partyId)) { _ => |           authenticateBasicBCrypt(s"party $partyId", authPost(partyId)) { _ => | ||||||
|             post { |             post { | ||||||
|               entity(as[PieceActionResponse]) { action => |               entity(as[PieceActionResponse]) { action => | ||||||
|                 val playerId = action.playerIdResponse.withPartyId(partyId) |                 val playerId = action.playerIdResponse.withPartyId(partyId) | ||||||
|               complete { |                 onComplete(doModifyBiS(action.action, playerId, action.piece.toPiece)) { | ||||||
|                 val result = action.action match { |                   case Success(_) => complete(StatusCodes.Accepted, HttpEntity.Empty) | ||||||
|                   case ApiAction.add => addPieceBiS(playerId, action.piece.toPiece) |                   case Failure(exception) => throw exception | ||||||
|                   case ApiAction.remove => removePieceBiS(playerId, action.piece.toPiece) |  | ||||||
|                 } |                 } | ||||||
|                 result.map(_ => (StatusCodes.Accepted, HttpEntity.Empty)) |  | ||||||
|               } |               } | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
|  | |||||||
| @ -0,0 +1,16 @@ | |||||||
|  | package me.arcanis.ffxivbis.http.api.v1 | ||||||
|  |  | ||||||
|  | import akka.http.scaladsl.model.StatusCodes | ||||||
|  | import akka.http.scaladsl.server.Directives._ | ||||||
|  | import akka.http.scaladsl.server._ | ||||||
|  | import com.typesafe.scalalogging.StrictLogging | ||||||
|  | import me.arcanis.ffxivbis.http.api.v1.json._ | ||||||
|  |  | ||||||
|  | trait HttpExceptionsHandler extends StrictLogging { this: JsonSupport => | ||||||
|  |  | ||||||
|  |   def exceptionHandler: ExceptionHandler = ExceptionHandler { | ||||||
|  |     case other: Exception => | ||||||
|  |       logger.error("exception during request completion", other) | ||||||
|  |       complete(StatusCodes.InternalServerError, ErrorResponse("unknown server error")) | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -24,9 +24,11 @@ import me.arcanis.ffxivbis.http.{Authorization, LootHelper} | |||||||
| import me.arcanis.ffxivbis.http.api.v1.json._ | import me.arcanis.ffxivbis.http.api.v1.json._ | ||||||
| import me.arcanis.ffxivbis.models.PlayerId | import me.arcanis.ffxivbis.models.PlayerId | ||||||
|  |  | ||||||
|  | import scala.util.{Failure, Success} | ||||||
|  |  | ||||||
| @Path("api/v1") | @Path("api/v1") | ||||||
| class LootEndpoint(override val storage: ActorRef)(implicit timeout: Timeout) | class LootEndpoint(override val storage: ActorRef)(implicit timeout: Timeout) | ||||||
|   extends LootHelper(storage) with Authorization with JsonSupport { |   extends LootHelper(storage) with Authorization with JsonSupport with HttpExceptionsHandler { | ||||||
|  |  | ||||||
|   def route: Route = getLoot ~ modifyLoot |   def route: Route = getLoot ~ modifyLoot | ||||||
|  |  | ||||||
| @ -53,12 +55,17 @@ class LootEndpoint(override val storage: ActorRef)(implicit timeout: Timeout) | |||||||
|   ) |   ) | ||||||
|   def getLoot: Route = |   def getLoot: Route = | ||||||
|     path("party" / Segment / "loot") { partyId => |     path("party" / Segment / "loot") { partyId => | ||||||
|  |       handleExceptions(exceptionHandler) { | ||||||
|         extractExecutionContext { implicit executionContext => |         extractExecutionContext { implicit executionContext => | ||||||
|           authenticateBasicBCrypt(s"party $partyId", authGet(partyId)) { _ => |           authenticateBasicBCrypt(s"party $partyId", authGet(partyId)) { _ => | ||||||
|             get { |             get { | ||||||
|               parameters("nick".as[String].?, "job".as[String].?) { (maybeNick, maybeJob) => |               parameters("nick".as[String].?, "job".as[String].?) { (maybeNick, maybeJob) => | ||||||
|                 val playerId = PlayerId(partyId, maybeNick, maybeJob) |                 val playerId = PlayerId(partyId, maybeNick, maybeJob) | ||||||
|               complete(loot(partyId, playerId).map(_.map(PlayerResponse.fromPlayer))) |                 onComplete(loot(partyId, playerId)) { | ||||||
|  |                   case Success(response) => complete(response.map(PlayerResponse.fromPlayer)) | ||||||
|  |                   case Failure(exception) => throw exception | ||||||
|  |                 } | ||||||
|  |               } | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
| @ -86,17 +93,16 @@ class LootEndpoint(override val storage: ActorRef)(implicit timeout: Timeout) | |||||||
|   ) |   ) | ||||||
|   def modifyLoot: Route = |   def modifyLoot: Route = | ||||||
|     path("party" / Segment / "loot") { partyId => |     path("party" / Segment / "loot") { partyId => | ||||||
|  |       handleExceptions(exceptionHandler) { | ||||||
|         extractExecutionContext { implicit executionContext => |         extractExecutionContext { implicit executionContext => | ||||||
|           authenticateBasicBCrypt(s"party $partyId", authPost(partyId)) { _ => |           authenticateBasicBCrypt(s"party $partyId", authPost(partyId)) { _ => | ||||||
|             post { |             post { | ||||||
|               entity(as[PieceActionResponse]) { action => |               entity(as[PieceActionResponse]) { action => | ||||||
|                 val playerId = action.playerIdResponse.withPartyId(partyId) |                 val playerId = action.playerIdResponse.withPartyId(partyId) | ||||||
|               complete { |                 onComplete(doModifyLoot(action.action, playerId, action.piece.toPiece)) { | ||||||
|                 val result = action.action match { |                   case Success(_) => complete(StatusCodes.Accepted, HttpEntity.Empty) | ||||||
|                   case ApiAction.add => addPieceLoot(playerId, action.piece.toPiece) |                   case Failure(exception) => throw exception | ||||||
|                   case ApiAction.remove => removePieceLoot(playerId, action.piece.toPiece) |  | ||||||
|                 } |                 } | ||||||
|                 result.map(_ => (StatusCodes.Accepted, HttpEntity.Empty)) |  | ||||||
|               } |               } | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
| @ -129,13 +135,14 @@ class LootEndpoint(override val storage: ActorRef)(implicit timeout: Timeout) | |||||||
|   ) |   ) | ||||||
|   def suggestLoot: Route = |   def suggestLoot: Route = | ||||||
|     path("party" / Segment / "loot") { partyId => |     path("party" / Segment / "loot") { partyId => | ||||||
|  |       handleExceptions(exceptionHandler) { | ||||||
|         extractExecutionContext { implicit executionContext => |         extractExecutionContext { implicit executionContext => | ||||||
|           authenticateBasicBCrypt(s"party $partyId", authGet(partyId)) { _ => |           authenticateBasicBCrypt(s"party $partyId", authGet(partyId)) { _ => | ||||||
|             put { |             put { | ||||||
|               entity(as[PieceResponse]) { piece => |               entity(as[PieceResponse]) { piece => | ||||||
|               complete { |                 onComplete(suggestPiece(partyId, piece.toPiece)) { | ||||||
|                 suggestPiece(partyId, piece.toPiece).map { players => |                   case Success(response) => complete(response.map(PlayerIdWithCountersResponse.fromPlayerId)) | ||||||
|                   players.map(PlayerIdWithCountersResponse.fromPlayerId) |                   case Failure(exception) => throw exception | ||||||
|                 } |                 } | ||||||
|               } |               } | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -24,9 +24,11 @@ import me.arcanis.ffxivbis.http.{Authorization, PlayerHelper} | |||||||
| import me.arcanis.ffxivbis.http.api.v1.json._ | import me.arcanis.ffxivbis.http.api.v1.json._ | ||||||
| import me.arcanis.ffxivbis.models.PlayerId | import me.arcanis.ffxivbis.models.PlayerId | ||||||
|  |  | ||||||
|  | import scala.util.{Failure, Success} | ||||||
|  |  | ||||||
| @Path("api/v1") | @Path("api/v1") | ||||||
| class PlayerEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit timeout: Timeout) | class PlayerEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit timeout: Timeout) | ||||||
|   extends PlayerHelper(storage, ariyala) with Authorization with JsonSupport { |   extends PlayerHelper(storage, ariyala) with Authorization with JsonSupport with HttpExceptionsHandler { | ||||||
|  |  | ||||||
|   def route: Route = getParty ~ modifyParty |   def route: Route = getParty ~ modifyParty | ||||||
|  |  | ||||||
| @ -53,12 +55,17 @@ class PlayerEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit | |||||||
|   ) |   ) | ||||||
|   def getParty: Route = |   def getParty: Route = | ||||||
|     path("party" / Segment) { partyId => |     path("party" / Segment) { partyId => | ||||||
|  |       handleExceptions(exceptionHandler) { | ||||||
|         extractExecutionContext { implicit executionContext => |         extractExecutionContext { implicit executionContext => | ||||||
|           authenticateBasicBCrypt(s"party $partyId", authGet(partyId)) { _ => |           authenticateBasicBCrypt(s"party $partyId", authGet(partyId)) { _ => | ||||||
|             get { |             get { | ||||||
|               parameters("nick".as[String].?, "job".as[String].?) { (maybeNick, maybeJob) => |               parameters("nick".as[String].?, "job".as[String].?) { (maybeNick, maybeJob) => | ||||||
|                 val playerId = PlayerId(partyId, maybeNick, maybeJob) |                 val playerId = PlayerId(partyId, maybeNick, maybeJob) | ||||||
|               complete(getPlayers(partyId, playerId).map(_.map(PlayerResponse.fromPlayer))) |                 onComplete(getPlayers(partyId, playerId)) { | ||||||
|  |                   case Success(response) => complete(response.map(PlayerResponse.fromPlayer)) | ||||||
|  |                   case Failure(exception) => throw exception | ||||||
|  |                 } | ||||||
|  |               } | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
| @ -86,16 +93,15 @@ class PlayerEndpoint(override val storage: ActorRef, ariyala: ActorRef)(implicit | |||||||
|   ) |   ) | ||||||
|   def modifyParty: Route = |   def modifyParty: Route = | ||||||
|     path("party" / Segment) { partyId => |     path("party" / Segment) { partyId => | ||||||
|  |       handleExceptions(exceptionHandler) { | ||||||
|         extractExecutionContext { implicit executionContext => |         extractExecutionContext { implicit executionContext => | ||||||
|           authenticateBasicBCrypt(s"party $partyId", authPost(partyId)) { _ => |           authenticateBasicBCrypt(s"party $partyId", authPost(partyId)) { _ => | ||||||
|             entity(as[PlayerActionResponse]) { action => |             entity(as[PlayerActionResponse]) { action => | ||||||
|               val player = action.playerIdResponse.toPlayer.copy(partyId = partyId) |               val player = action.playerIdResponse.toPlayer.copy(partyId = partyId) | ||||||
|             complete { |               onComplete(doModifyPlayer(action.action, player)) { | ||||||
|               val result = action.action match { |                 case Success(_) => complete(StatusCodes.Accepted, HttpEntity.Empty) | ||||||
|                 case ApiAction.add => addPlayer(player) |                 case Failure(exception) => throw exception | ||||||
|                 case ApiAction.remove => removePlayer(player.playerId) |  | ||||||
|               } |               } | ||||||
|               result.map(_ => (StatusCodes.Accepted, HttpEntity.Empty)) |  | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -24,9 +24,11 @@ import me.arcanis.ffxivbis.http.{Authorization, UserHelper} | |||||||
| import me.arcanis.ffxivbis.http.api.v1.json._ | import me.arcanis.ffxivbis.http.api.v1.json._ | ||||||
| import me.arcanis.ffxivbis.models.Permission | import me.arcanis.ffxivbis.models.Permission | ||||||
|  |  | ||||||
|  | import scala.util.{Failure, Success} | ||||||
|  |  | ||||||
| @Path("api/v1") | @Path("api/v1") | ||||||
| class UserEndpoint(override val storage: ActorRef)(implicit timeout: Timeout) | class UserEndpoint(override val storage: ActorRef)(implicit timeout: Timeout) | ||||||
|   extends UserHelper(storage) with Authorization with JsonSupport { |   extends UserHelper(storage) with Authorization with JsonSupport with HttpExceptionsHandler { | ||||||
|  |  | ||||||
|   def route: Route = createParty ~ createUser ~ deleteUser ~ getUsers |   def route: Route = createParty ~ createUser ~ deleteUser ~ getUsers | ||||||
|  |  | ||||||
| @ -49,12 +51,15 @@ class UserEndpoint(override val storage: ActorRef)(implicit timeout: Timeout) | |||||||
|   ) |   ) | ||||||
|   def createParty: Route = |   def createParty: Route = | ||||||
|     path("party" / Segment / "create") { partyId => |     path("party" / Segment / "create") { partyId => | ||||||
|  |       handleExceptions(exceptionHandler) { | ||||||
|         extractExecutionContext { implicit executionContext => |         extractExecutionContext { implicit executionContext => | ||||||
|           put { |           put { | ||||||
|             entity(as[UserResponse]) { user => |             entity(as[UserResponse]) { user => | ||||||
|               val admin = user.toUser.copy(partyId = partyId, permission = Permission.admin) |               val admin = user.toUser.copy(partyId = partyId, permission = Permission.admin) | ||||||
|             complete { |               onComplete(addUser(admin, isHashedPassword = false)) { | ||||||
|               addUser(admin, isHashedPassword = false).map(_ => (StatusCodes.Created, HttpEntity.Empty)) |                 case Success(_) => complete(StatusCodes.Created, HttpEntity.Empty) | ||||||
|  |                 case Failure(exception) => throw exception | ||||||
|  |               } | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
| @ -82,13 +87,16 @@ class UserEndpoint(override val storage: ActorRef)(implicit timeout: Timeout) | |||||||
|   ) |   ) | ||||||
|   def createUser: Route = |   def createUser: Route = | ||||||
|     path("party" / Segment / "users") { partyId => |     path("party" / Segment / "users") { partyId => | ||||||
|  |       handleExceptions(exceptionHandler) { | ||||||
|         extractExecutionContext { implicit executionContext => |         extractExecutionContext { implicit executionContext => | ||||||
|           authenticateBasicBCrypt(s"party $partyId", authAdmin(partyId)) { _ => |           authenticateBasicBCrypt(s"party $partyId", authAdmin(partyId)) { _ => | ||||||
|             post { |             post { | ||||||
|               entity(as[UserResponse]) { user => |               entity(as[UserResponse]) { user => | ||||||
|                 val withPartyId = user.toUser.copy(partyId = partyId) |                 val withPartyId = user.toUser.copy(partyId = partyId) | ||||||
|               complete { |                 onComplete(addUser(withPartyId, isHashedPassword = false)) { | ||||||
|                 addUser(withPartyId, isHashedPassword = false).map(_ => (StatusCodes.Accepted, HttpEntity.Empty)) |                   case Success(_) => complete(StatusCodes.Accepted, HttpEntity.Empty) | ||||||
|  |                   case Failure(exception) => throw exception | ||||||
|  |                 } | ||||||
|               } |               } | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
| @ -114,11 +122,14 @@ class UserEndpoint(override val storage: ActorRef)(implicit timeout: Timeout) | |||||||
|   ) |   ) | ||||||
|   def deleteUser: Route = |   def deleteUser: Route = | ||||||
|     path("party" / Segment / "users" / Segment) { (partyId, username) => |     path("party" / Segment / "users" / Segment) { (partyId, username) => | ||||||
|  |       handleExceptions(exceptionHandler) { | ||||||
|         extractExecutionContext { implicit executionContext => |         extractExecutionContext { implicit executionContext => | ||||||
|           authenticateBasicBCrypt(s"party $partyId", authAdmin(partyId)) { _ => |           authenticateBasicBCrypt(s"party $partyId", authAdmin(partyId)) { _ => | ||||||
|             delete { |             delete { | ||||||
|             complete { |               onComplete(removeUser(partyId, username)) { | ||||||
|               removeUser(partyId, username).map(_ => (StatusCodes.Accepted, HttpEntity.Empty)) |                 case Success(_) => complete(StatusCodes.Accepted, HttpEntity.Empty) | ||||||
|  |                 case Failure(exception) => throw exception | ||||||
|  |               } | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
| @ -146,11 +157,14 @@ class UserEndpoint(override val storage: ActorRef)(implicit timeout: Timeout) | |||||||
|   ) |   ) | ||||||
|   def getUsers: Route = |   def getUsers: Route = | ||||||
|     path("party" / Segment / "users") { partyId => |     path("party" / Segment / "users") { partyId => | ||||||
|  |       handleExceptions(exceptionHandler) { | ||||||
|         extractExecutionContext { implicit executionContext => |         extractExecutionContext { implicit executionContext => | ||||||
|           authenticateBasicBCrypt(s"party $partyId", authAdmin(partyId)) { _ => |           authenticateBasicBCrypt(s"party $partyId", authAdmin(partyId)) { _ => | ||||||
|             get { |             get { | ||||||
|             complete { |               onComplete(users(partyId)) { | ||||||
|               users(partyId).map(_.map(UserResponse.fromUser)) |                 case Success(response) => complete(response.map(UserResponse.fromUser)) | ||||||
|  |                 case Failure(exception) => throw exception | ||||||
|  |               } | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -0,0 +1,6 @@ | |||||||
|  | package me.arcanis.ffxivbis.http.api.v1.json | ||||||
|  |  | ||||||
|  | import io.swagger.v3.oas.annotations.media.Schema | ||||||
|  |  | ||||||
|  | case class ErrorResponse( | ||||||
|  |   @Schema(description = "error message", required = true) message: String) | ||||||
| @ -27,6 +27,7 @@ trait JsonSupport extends SprayJsonSupport with DefaultJsonProtocol { | |||||||
|   implicit val actionFormat: RootJsonFormat[ApiAction.Value] = enumFormat(ApiAction) |   implicit val actionFormat: RootJsonFormat[ApiAction.Value] = enumFormat(ApiAction) | ||||||
|   implicit val permissionFormat: RootJsonFormat[Permission.Value] = enumFormat(Permission) |   implicit val permissionFormat: RootJsonFormat[Permission.Value] = enumFormat(Permission) | ||||||
|  |  | ||||||
|  |   implicit val errorFormat: RootJsonFormat[ErrorResponse] = jsonFormat1(ErrorResponse.apply) | ||||||
|   implicit val pieceFormat: RootJsonFormat[PieceResponse] = jsonFormat3(PieceResponse.apply) |   implicit val pieceFormat: RootJsonFormat[PieceResponse] = jsonFormat3(PieceResponse.apply) | ||||||
|   implicit val playerFormat: RootJsonFormat[PlayerResponse] = jsonFormat7(PlayerResponse.apply) |   implicit val playerFormat: RootJsonFormat[PlayerResponse] = jsonFormat7(PlayerResponse.apply) | ||||||
|   implicit val playerActionFormat: RootJsonFormat[PlayerActionResponse] = jsonFormat2(PlayerActionResponse.apply) |   implicit val playerActionFormat: RootJsonFormat[PlayerActionResponse] = jsonFormat2(PlayerActionResponse.apply) | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user