From 51b5909246f74e2af1846c91e12e55518926b98c Mon Sep 17 00:00:00 2001 From: SiloSas Date: Thu, 25 Feb 2016 04:24:56 +0100 Subject: [PATCH 1/4] uploadUsersInfo -- rib ok IDCard methodsOK --- server/app/application/Application.scala | 1 + .../CredentialsAuthController.scala | 1 + server/app/application/SignUpController.scala | 1 + .../application/SocialAuthController.scala | 1 + server/app/application/UserController.scala | 53 -------- .../app/artistsDomain/ArtistController.scala | 3 +- .../app/database/MyDBTableDefinitions.scala | 30 ++++- server/app/eventsDomain/EventController.scala | 3 +- server/app/fillDatabase/InitController.scala | 2 +- server/app/issues/IssueController.scala | 3 +- server/app/json/JsonHelper.scala | 4 + .../OrganizerController.scala | 2 +- server/app/others/MailController.scala | 2 +- server/app/placesDomain/PlaceController.scala | 4 +- .../playlistsDomain/PlaylistController.scala | 3 +- server/app/services/UserService.scala | 2 +- .../services/UserServiceImplementation.scala | 3 +- server/app/silhouette/SilhouetteModule.scala | 2 +- server/app/silhouette/UserDAO.scala | 3 +- server/app/silhouette/UserDAOImpl.scala | 2 +- .../app/tariffsDomain/TariffController.scala | 2 +- .../app/ticketsDomain/TicketController.scala | 2 +- server/app/trackingDomain/Tracking.scala | 3 +- .../trackingDomain/TrackingController.scala | 4 +- server/app/tracksDomain/TrackController.scala | 3 +- .../{application => userDomain}/User.scala | 45 ++++++- server/app/userDomain/UserController.scala | 115 +++++++++++++++++ server/conf/evolutions/default/1.sql | 19 +++ server/conf/evolutions/tests/1.sql | 17 +++ server/conf/routes | 12 +- .../test/PlaylistModelIntegrationTest.scala | 3 +- server/test/TestUserController.scala | 116 +++++++++++++++++- server/test/UserModelIntegrationTest.scala | 80 +++++++++++- server/test/testsHelper/Context.scala | 3 +- server/test/testsHelper/Injectors.scala | 2 +- 35 files changed, 453 insertions(+), 98 deletions(-) delete mode 100755 server/app/application/UserController.scala rename server/app/{application => userDomain}/User.scala (54%) create mode 100755 server/app/userDomain/UserController.scala diff --git a/server/app/application/Application.scala b/server/app/application/Application.scala index 9c7ac4e1..1acc67e4 100755 --- a/server/app/application/Application.scala +++ b/server/app/application/Application.scala @@ -9,6 +9,7 @@ import play.api.Logger import play.api.i18n.MessagesApi import play.api.libs.ws._ import play.api.mvc.Action +import userDomain.{UserMethods, Administrator, GuestUser, User} import scala.concurrent.Future import scala.concurrent.ExecutionContext.Implicits.global diff --git a/server/app/application/CredentialsAuthController.scala b/server/app/application/CredentialsAuthController.scala index 72a2de1a..3b06d069 100755 --- a/server/app/application/CredentialsAuthController.scala +++ b/server/app/application/CredentialsAuthController.scala @@ -12,6 +12,7 @@ import com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator import com.mohiva.play.silhouette.impl.providers._ import play.api.Configuration import play.api.i18n.MessagesApi +import userDomain.User import scala.language.postfixOps diff --git a/server/app/application/SignUpController.scala b/server/app/application/SignUpController.scala index 705497a2..99a6536b 100755 --- a/server/app/application/SignUpController.scala +++ b/server/app/application/SignUpController.scala @@ -16,6 +16,7 @@ import com.mohiva.play.silhouette.impl.providers._ import play.api.i18n.MessagesApi import play.api.libs.concurrent.Execution.Implicits._ import play.api.mvc.Action +import userDomain.User import scala.concurrent.Future diff --git a/server/app/application/SocialAuthController.scala b/server/app/application/SocialAuthController.scala index d878a3b2..a26c603a 100644 --- a/server/app/application/SocialAuthController.scala +++ b/server/app/application/SocialAuthController.scala @@ -11,6 +11,7 @@ import com.mohiva.play.silhouette.impl.providers._ import play.api.i18n.{Messages, MessagesApi} import play.api.libs.concurrent.Execution.Implicits._ import play.api.mvc.Action +import userDomain.User import scala.concurrent.Future import scala.util.Try diff --git a/server/app/application/UserController.scala b/server/app/application/UserController.scala deleted file mode 100755 index 9d84b806..00000000 --- a/server/app/application/UserController.scala +++ /dev/null @@ -1,53 +0,0 @@ -package application - -import javax.inject.Inject - -import com.mohiva.play.silhouette.api.{Environment, Silhouette} -import com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator -import play.api.Logger -import play.api.Play.current -import play.api.i18n.MessagesApi -import play.api.libs.concurrent.Execution.Implicits._ -import play.api.libs.json.Json -import play.api.libs.ws.{WS, WSClient} -import play.api.mvc._ - - -class UserController @Inject() (ws: WSClient, - val messagesApi: MessagesApi, - val env: Environment[User, CookieAuthenticator], - val userMethods: UserMethods) - extends Silhouette[User, CookieAuthenticator] { - - def getTracksRemoved = SecuredAction.async { implicit request => - userMethods.findUUIDOfTracksRemoved(request.identity.uuid) map { response => - Ok(Json.toJson(response)) - } recover { - case e => - Logger.error("UserController.getTracksRemoved: ", e) - InternalServerError - } - } - - def isConnected = SecuredAction { implicit request => - Ok(Json.toJson(true)) - } - - case class Token(token: String) - def findFacebookAccessToken = SecuredAction { implicit request => - val token = Json.parse("""{"token": 1}""") - Ok(Json.toJson(token)) - } - - def getUserGeographicPoint = Action.async { implicit request => - WS.url("http://ip-api.com/json/" + request.remoteAddress) - .get() - .map { response => - Ok(Json.toJson(response.json)) - } recover { - case e => - Logger.error("UserController.getUserGeographicPoint: ", e) - InternalServerError - } - } -} diff --git a/server/app/artistsDomain/ArtistController.scala b/server/app/artistsDomain/ArtistController.scala index f22f5a29..9716c93b 100755 --- a/server/app/artistsDomain/ArtistController.scala +++ b/server/app/artistsDomain/ArtistController.scala @@ -2,7 +2,7 @@ package artistsDomain import javax.inject.Inject -import application.{Administrator, ThereIsNoArtistForThisFacebookIdException, User} +import application.ThereIsNoArtistForThisFacebookIdException import com.mohiva.play.silhouette.api.{Environment, Silhouette} import com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator import com.mohiva.play.silhouette.impl.providers.SocialProviderRegistry @@ -19,6 +19,7 @@ import play.api.mvc._ import services.{LoggerHelper, Utilities} import trackingDomain.UserSession import tracksDomain.TrackMethods +import userDomain.{Administrator, User} import scala.concurrent.Future import scala.language.postfixOps diff --git a/server/app/database/MyDBTableDefinitions.scala b/server/app/database/MyDBTableDefinitions.scala index ce3083a3..c7a10434 100755 --- a/server/app/database/MyDBTableDefinitions.scala +++ b/server/app/database/MyDBTableDefinitions.scala @@ -4,7 +4,6 @@ import java.sql.{JDBCType, Timestamp} import java.util.UUID import addresses.Address -import application.GuestUser import artistsDomain.Artist import attendees.{FacebookAttendee, FacebookAttendeeEventRelation} import com.vividsolutions.jts.geom.Geometry @@ -25,6 +24,7 @@ import tracksDomain.{Track, TrackRating} import tariffsDomain.Tariff import ticketsDomain._ import tracksDomain.{TrackRating, Track} +import userDomain.{IdCard, Rib, GuestUser} case class UserArtistRelation(userId: UUID, artistId: Long) @@ -510,6 +510,34 @@ trait MyDBTableDefinitions extends DBTableDefinitions { } lazy val userActions = TableQuery[UserActions] + class Ribs(tag: Tag) extends Table[Rib](tag, "ribs") { + def id = column[Long]("id", O.PrimaryKey, O.AutoInc) + def bankCode = column[String]("bankcode") + def deskCode = column[String]("deskcode") + def accountNumber = column[String]("accountnumber") + def ribKey = column[String]("ribkey") + def userId = column[UUID]("userid") + def creationTime = column[Timestamp]("creationtime") + + def * = (id.?, bankCode, deskCode, accountNumber, ribKey, userId) <> + ((Rib.apply _).tupled, Rib.unapply) + + def aFK = foreignKey("userid", userId, slickUsers)(_.id) + } + lazy val ribs = TableQuery[Ribs] + + + class IdCards(tag: Tag) extends Table[IdCard](tag, "idcards") { + def uuid = column[UUID]("uuid", O.PrimaryKey) + def userId = column[UUID]("userid") + def creationTime = column[Timestamp]("creationtime") + + def * = (uuid, userId) <> ((IdCard.apply _).tupled, IdCard.unapply) + + def aFK = foreignKey("userid", userId, slickUsers)(_.id) + } + lazy val idCards = TableQuery[IdCards] + lazy val artistsFollowed = TableQuery[ArtistsFollowed] lazy val genres = TableQuery[Genres] diff --git a/server/app/eventsDomain/EventController.scala b/server/app/eventsDomain/EventController.scala index cb2484aa..db505984 100755 --- a/server/app/eventsDomain/EventController.scala +++ b/server/app/eventsDomain/EventController.scala @@ -3,12 +3,10 @@ package eventsDomain import javax.inject.Inject import addresses.SearchGeographicPoint -import application.{Administrator, User} import com.mohiva.play.silhouette.api.{Environment, Silhouette} import com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator import com.mohiva.play.silhouette.impl.providers.SocialProviderRegistry import database.UserEventRelation -import json.JsonHelper import json.JsonHelper._ import org.postgresql.util.PSQLException import play.api.Logger @@ -17,6 +15,7 @@ import play.api.libs.json.{JsError, JsSuccess, Json} import play.api.libs.ws.WSClient import play.api.mvc._ import services.LoggerHelper +import userDomain.{Administrator, User} import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.Future diff --git a/server/app/fillDatabase/InitController.scala b/server/app/fillDatabase/InitController.scala index 33914e97..fac3ecba 100755 --- a/server/app/fillDatabase/InitController.scala +++ b/server/app/fillDatabase/InitController.scala @@ -3,7 +3,6 @@ package fillDatabase import javax.inject.Inject import addresses.SearchGeographicPoint -import application.User import artistsDomain.ArtistMethods import com.mohiva.play.silhouette.api.{Environment, Silhouette} import com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator @@ -15,6 +14,7 @@ import play.api.Logger import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfigProvider} import play.api.i18n.MessagesApi import play.api.mvc.Action +import userDomain.User import scala.concurrent.ExecutionContext.Implicits.global import scala.io.Source diff --git a/server/app/issues/IssueController.scala b/server/app/issues/IssueController.scala index de62edf1..959409c4 100755 --- a/server/app/issues/IssueController.scala +++ b/server/app/issues/IssueController.scala @@ -1,8 +1,6 @@ package issues import javax.inject.Inject - -import application.User import com.mohiva.play.silhouette.api.{Environment, Silhouette} import com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator import com.mohiva.play.silhouette.impl.providers.SocialProviderRegistry @@ -12,6 +10,7 @@ import play.api.i18n.MessagesApi import play.api.libs.json.Json import play.api.libs.ws.WSClient import play.api.mvc._ +import userDomain.User import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.Future diff --git a/server/app/json/JsonHelper.scala b/server/app/json/JsonHelper.scala index c96bc44b..13777b18 100755 --- a/server/app/json/JsonHelper.scala +++ b/server/app/json/JsonHelper.scala @@ -17,6 +17,7 @@ import tariffsDomain.Tariff import ticketsDomain._ import trackingDomain.{UserAction, UserSession} import tracksDomain.{Track, TrackWithGenres} +import userDomain.{Rib, FromClientRib} object JsonHelper { @@ -69,6 +70,8 @@ object JsonHelper { // implicit val account4686Format: Format[Account4686] = Json.format[Account4686] implicit val genreFormat = Json.format[Genre] + implicit val fromClientRibFormat = Json.format[FromClientRib] + implicit val ribFormat = Json.format[Rib] implicit val trackFormat: Format[Track] = Json.format[Track] implicit val trackWithGenresFormat: Format[TrackWithGenres] = Json.format[TrackWithGenres] implicit val trackWithPlaylistRankFormat = Json.format[TrackWithPlaylistRank] @@ -109,4 +112,5 @@ object JsonHelper { val readTicketBillReads: Reads[Seq[TicketBill]] = Reads.seq(__.read[TicketBill]) val readMaybeSalableEventReads: Reads[Seq[MaybeSalableEvent]] = Reads.seq(__.read[MaybeSalableEvent]) val readTariffReads: Reads[Seq[Tariff]] = Reads.seq(__.read[Tariff]) + val readRibReads: Reads[Seq[Rib]] = Reads.seq(__.read[Rib]) } diff --git a/server/app/organizersDomain/OrganizerController.scala b/server/app/organizersDomain/OrganizerController.scala index 5240c52a..5e36efa9 100755 --- a/server/app/organizersDomain/OrganizerController.scala +++ b/server/app/organizersDomain/OrganizerController.scala @@ -3,7 +3,6 @@ package organizersDomain import javax.inject.Inject import addresses.SearchGeographicPoint -import application.{Administrator, User} import com.mohiva.play.silhouette.api.{Environment, Silhouette} import com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator import com.mohiva.play.silhouette.impl.providers.SocialProviderRegistry @@ -16,6 +15,7 @@ import play.api.libs.json.Json import play.api.libs.ws.WSClient import play.api.mvc._ import services.Utilities +import userDomain.{Administrator, User} import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.Future diff --git a/server/app/others/MailController.scala b/server/app/others/MailController.scala index 2ee293f0..6a05dabb 100755 --- a/server/app/others/MailController.scala +++ b/server/app/others/MailController.scala @@ -1,6 +1,5 @@ package others -import application.User import play.api.Logger import play.api.data.Form import play.api.data.Forms._ @@ -15,6 +14,7 @@ import com.mohiva.play.silhouette.api.{ Environment, LogoutEvent, Silhouette } import com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator import com.mohiva.play.silhouette.impl.providers.SocialProviderRegistry import play.api.i18n.MessagesApi +import userDomain.User class MailController @Inject()(ws: WSClient, val messagesApi: MessagesApi, diff --git a/server/app/placesDomain/PlaceController.scala b/server/app/placesDomain/PlaceController.scala index d558d0e1..7e993328 100755 --- a/server/app/placesDomain/PlaceController.scala +++ b/server/app/placesDomain/PlaceController.scala @@ -2,8 +2,7 @@ package placesDomain import javax.inject.Inject -import addresses.{SearchGeographicPoint, AddressFormsTrait} -import application.{Administrator, User} +import addresses.{AddressFormsTrait, SearchGeographicPoint} import com.mohiva.play.silhouette.api.{Environment, Silhouette} import com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator import com.mohiva.play.silhouette.impl.providers.SocialProviderRegistry @@ -17,6 +16,7 @@ import play.api.libs.json.Json import play.api.libs.ws.WSClient import play.api.mvc._ import services.Utilities +import userDomain.{Administrator, User} import scala.concurrent.Future import scala.util.{Failure, Success} diff --git a/server/app/playlistsDomain/PlaylistController.scala b/server/app/playlistsDomain/PlaylistController.scala index b9fb43bc..521f6111 100755 --- a/server/app/playlistsDomain/PlaylistController.scala +++ b/server/app/playlistsDomain/PlaylistController.scala @@ -1,8 +1,6 @@ package playlistsDomain import javax.inject.Inject - -import application.User import com.mohiva.play.silhouette.api.{Environment, Silhouette} import com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator import com.mohiva.play.silhouette.impl.providers.SocialProviderRegistry @@ -11,6 +9,7 @@ import play.api.Logger import play.api.i18n.MessagesApi import play.api.libs.json.Json import play.api.libs.ws.WSClient +import userDomain.User import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.Future diff --git a/server/app/services/UserService.scala b/server/app/services/UserService.scala index ed7ecc43..2af5933f 100755 --- a/server/app/services/UserService.scala +++ b/server/app/services/UserService.scala @@ -1,8 +1,8 @@ package services -import application.User import com.mohiva.play.silhouette.api.services.IdentityService import com.mohiva.play.silhouette.impl.providers.CommonSocialProfile +import userDomain.User import scala.concurrent.Future diff --git a/server/app/services/UserServiceImplementation.scala b/server/app/services/UserServiceImplementation.scala index 1971d33f..8d6bce12 100755 --- a/server/app/services/UserServiceImplementation.scala +++ b/server/app/services/UserServiceImplementation.scala @@ -2,12 +2,11 @@ package services import java.util.UUID import javax.inject.Inject - -import application.User import com.mohiva.play.silhouette.api.LoginInfo import com.mohiva.play.silhouette.impl.providers.CommonSocialProfile import play.api.libs.concurrent.Execution.Implicits._ import silhouette.UserDAO +import userDomain.User import scala.concurrent.Future diff --git a/server/app/silhouette/SilhouetteModule.scala b/server/app/silhouette/SilhouetteModule.scala index f791078e..ad1395aa 100755 --- a/server/app/silhouette/SilhouetteModule.scala +++ b/server/app/silhouette/SilhouetteModule.scala @@ -1,7 +1,6 @@ package silhouette import _root_.services.{UserService, UserServiceImplementation} -import application.User import com.google.inject.{AbstractModule, Provides} import com.mohiva.play.silhouette.api.repositories.AuthInfoRepository import com.mohiva.play.silhouette.api.services._ @@ -27,6 +26,7 @@ import play.api.Configuration import play.api.libs.concurrent.Execution.Implicits._ import play.api.libs.openid.OpenIdClient import play.api.libs.ws.WSClient +import userDomain.User /** * The Guice module which wires all Silhouette dependencies. diff --git a/server/app/silhouette/UserDAO.scala b/server/app/silhouette/UserDAO.scala index 5e35afe7..6ae3b011 100755 --- a/server/app/silhouette/UserDAO.scala +++ b/server/app/silhouette/UserDAO.scala @@ -1,9 +1,8 @@ package silhouette import java.util.UUID - -import application.User import com.mohiva.play.silhouette.api.LoginInfo +import userDomain.User import scala.concurrent.Future diff --git a/server/app/silhouette/UserDAOImpl.scala b/server/app/silhouette/UserDAOImpl.scala index 2daa959a..17c7caf2 100755 --- a/server/app/silhouette/UserDAOImpl.scala +++ b/server/app/silhouette/UserDAOImpl.scala @@ -1,13 +1,13 @@ package silhouette import java.util.UUID -import application.User import com.mohiva.play.silhouette.api.LoginInfo import database.MyPostgresDriver import play.api.libs.concurrent.Execution.Implicits.defaultContext import slick.dbio.DBIOAction import javax.inject.Inject import play.api.db.slick.DatabaseConfigProvider +import userDomain.User import scala.concurrent.Future import MyPostgresDriver.api._ diff --git a/server/app/tariffsDomain/TariffController.scala b/server/app/tariffsDomain/TariffController.scala index d03032e3..77745c8e 100644 --- a/server/app/tariffsDomain/TariffController.scala +++ b/server/app/tariffsDomain/TariffController.scala @@ -2,7 +2,6 @@ package tariffsDomain import javax.inject.Inject -import application.{Administrator, User} import com.mohiva.play.silhouette.api.{Environment, Silhouette} import com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator import json.JsonHelper._ @@ -11,6 +10,7 @@ import play.api.Logger import play.api.i18n.MessagesApi import play.api.libs.json.Json import play.api.mvc._ +import userDomain.{Administrator, User} import scala.concurrent.ExecutionContext.Implicits.global import scala.language.postfixOps diff --git a/server/app/ticketsDomain/TicketController.scala b/server/app/ticketsDomain/TicketController.scala index 3a6e0aca..76b9f0e3 100755 --- a/server/app/ticketsDomain/TicketController.scala +++ b/server/app/ticketsDomain/TicketController.scala @@ -3,7 +3,6 @@ package ticketsDomain import javax.inject.Inject import addresses.SearchGeographicPoint -import application.{Administrator, User} import com.mohiva.play.silhouette.api.{Environment, Silhouette} import com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator import com.vividsolutions.jts.geom.Geometry @@ -13,6 +12,7 @@ import play.api.Logger import play.api.i18n.MessagesApi import play.api.libs.json.Json import play.api.mvc._ +import userDomain.{Administrator, User} import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.Future diff --git a/server/app/trackingDomain/Tracking.scala b/server/app/trackingDomain/Tracking.scala index 94de527f..058f7ffc 100644 --- a/server/app/trackingDomain/Tracking.scala +++ b/server/app/trackingDomain/Tracking.scala @@ -3,12 +3,11 @@ package trackingDomain import java.sql.Timestamp import java.util.UUID import javax.inject.Inject - -import application.GuestUser import database.MyPostgresDriver.api._ import database.{MyDBTableDefinitions, MyPostgresDriver} import org.joda.time.DateTime import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfigProvider} +import userDomain.GuestUser import scala.concurrent.Future import scala.concurrent.ExecutionContext.Implicits.global diff --git a/server/app/trackingDomain/TrackingController.scala b/server/app/trackingDomain/TrackingController.scala index 5f4b2adf..2024c736 100644 --- a/server/app/trackingDomain/TrackingController.scala +++ b/server/app/trackingDomain/TrackingController.scala @@ -3,15 +3,15 @@ package trackingDomain import java.util.UUID import javax.inject.Inject -import application.{Administrator, User} import com.mohiva.play.silhouette.api.{Environment, Silhouette} import com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator import json.JsonHelper._ -import play.api.Logger import play.api.i18n.MessagesApi import play.api.libs.json._ import play.api.mvc._ import services.LoggerHelper +import userDomain.{Administrator, User} + import scala.concurrent.ExecutionContext.Implicits.global import scala.language.postfixOps import scala.util.control.NonFatal diff --git a/server/app/tracksDomain/TrackController.scala b/server/app/tracksDomain/TrackController.scala index eac8f991..74e09354 100755 --- a/server/app/tracksDomain/TrackController.scala +++ b/server/app/tracksDomain/TrackController.scala @@ -2,8 +2,6 @@ package tracksDomain import java.util.UUID import javax.inject.Inject - -import application.User import com.mohiva.play.silhouette.api.{Environment, Silhouette} import com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator import com.mohiva.play.silhouette.impl.providers.SocialProviderRegistry @@ -16,6 +14,7 @@ import play.api.libs.json.Json import play.api.libs.ws.WSClient import play.api.mvc._ import services.Utilities +import userDomain.User import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.Future diff --git a/server/app/application/User.scala b/server/app/userDomain/User.scala similarity index 54% rename from server/app/application/User.scala rename to server/app/userDomain/User.scala index efd93ac4..740feb72 100755 --- a/server/app/application/User.scala +++ b/server/app/userDomain/User.scala @@ -1,15 +1,15 @@ -package application +package userDomain import java.util.UUID import javax.inject.Inject import com.mohiva.play.silhouette.api.{Authorization, Identity, LoginInfo} import com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator -import database.{MyPostgresDriver, MyDBTableDefinitions} +import database.{MyDBTableDefinitions, MyPostgresDriver} import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfigProvider} -import play.api.i18n.{Messages, Lang} +import play.api.i18n.Messages import play.api.libs.json.Json -import play.api.mvc.{Request, RequestHeader} +import play.api.mvc.Request import slick.driver.PostgresDriver.api._ import scala.concurrent.Future @@ -26,6 +26,21 @@ case class User(uuid: UUID, case class GuestUser(ip: String, userUuid: Option[UUID]) +case class Rib(id: Option[Long], + bankCode: String, + deskCode: String, + accountNumber: String, + ribKey: String, + userId: UUID) + +case class FromClientRib(id: Option[Long], + bankCode: String, + deskCode: String, + accountNumber: String, + ribKey: String) + +case class IdCard(uuid: UUID, userId: UUID) + case class Administrator() extends Authorization[User, CookieAuthenticator] { def isAuthorized[B](user: User, authenticator: CookieAuthenticator)( implicit request: Request[B], messages: Messages) = { @@ -38,6 +53,17 @@ class UserMethods @Inject()(protected val dbConfigProvider: DatabaseConfigProvid extends HasDatabaseConfigProvider[MyPostgresDriver] with MyDBTableDefinitions { implicit val userWrites = Json.writes[User] + + def fromClientRibToRib(fromClientRib: FromClientRib, userUUID: UUID): Rib = { + Rib( + id = fromClientRib.id, + bankCode = fromClientRib.bankCode, + deskCode = fromClientRib.deskCode, + accountNumber = fromClientRib.accountNumber, + ribKey = fromClientRib.ribKey, + userId = userUUID + ) + } def findGuestUserByIp(ip: String): Future[Option[GuestUser]] = db.run(guestUsers.filter(_.ip === ip).result.headOption) @@ -46,4 +72,15 @@ class UserMethods @Inject()(protected val dbConfigProvider: DatabaseConfigProvid def findUUIDOfTracksRemoved(userUUID: UUID): Future[Seq[UUID]] = db.run((for { trackRating <- trackRatings if trackRating.userId === userUUID && trackRating.reason.nonEmpty } yield trackRating.trackId).result) + + def createRib(rib: Rib): Future[Int] = db.run(ribs += rib) + + def updateRib(rib: Rib): Future[Int] = + db.run(ribs.filter(foundRib => foundRib.id === rib.id && foundRib.userId === rib.userId).update(rib)) + + def findRibsByUserId(userId: UUID): Future[Seq[Rib]] = db.run(ribs.filter(_.userId === userId).result) + + def createIdCard(idCard: IdCard): Future[Int] = db.run(idCards += idCard) + + def findIdCardsByUserId(userId: UUID): Future[Seq[IdCard]] = db.run(idCards.filter(_.userId === userId).result) } diff --git a/server/app/userDomain/UserController.scala b/server/app/userDomain/UserController.scala new file mode 100755 index 00000000..7130f1af --- /dev/null +++ b/server/app/userDomain/UserController.scala @@ -0,0 +1,115 @@ +package userDomain + +import java.util.UUID +import javax.inject.Inject + +import com.mohiva.play.silhouette.api.{Environment, Silhouette} +import com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator +import play.api.Logger +import play.api.Play.current +import play.api.i18n.MessagesApi +import play.api.libs.concurrent.Execution.Implicits._ +import play.api.libs.json.{JsSuccess, JsError, Json} +import play.api.libs.ws.{WS, WSClient} +import play.api.mvc._ +import services.LoggerHelper +import json.JsonHelper._ + +import scala.concurrent.Future +import scala.util.control.NonFatal + + +class UserController @Inject() (ws: WSClient, + val messagesApi: MessagesApi, + val env: Environment[User, CookieAuthenticator], + val userMethods: UserMethods) + extends Silhouette[User, CookieAuthenticator] with LoggerHelper { + + def getTracksRemoved = SecuredAction.async { implicit request => + userMethods.findUUIDOfTracksRemoved(request.identity.uuid) map { response => + Ok(Json.toJson(response)) + } recover { + case e => + Logger.error("UserController.getTracksRemoved: ", e) + InternalServerError + } + } + + def isConnected = SecuredAction { implicit request => + Ok(Json.toJson(true)) + } + + case class Token(token: String) + def findFacebookAccessToken = SecuredAction { implicit request => + val token = Json.parse("""{"token": 1}""") + Ok(Json.toJson(token)) + } + + def getUserGeographicPoint = Action.async { implicit request => + WS.url("http://ip-api.com/json/" + request.remoteAddress) + .get() + .map { response => + Ok(Json.toJson(response.json)) + } recover { + case e => + Logger.error("UserController.getUserGeographicPoint: ", e) + InternalServerError + } + } + + def createRib = SecuredAction.async { implicit request => + val validatedUserRib = request.body.asJson.get.validate[FromClientRib] + + validatedUserRib match { + case error: JsError => + log(error.toString) + Future(InternalServerError(error.toString)) + case userRib: JsSuccess[FromClientRib] => + val rib = userMethods.fromClientRibToRib(userRib.get, request.identity.uuid) + userMethods.createRib(rib) map { response => + Ok(Json.toJson(response)) + } recover { case NonFatal(e) => + log(e.getMessage) + InternalServerError(e.getMessage) + } + } + } + + def updateRib = SecuredAction.async { implicit request => + val validatedUserRib = request.body.asJson.get.validate[FromClientRib] + + validatedUserRib match { + case error: JsError => + log(error.toString) + Future(InternalServerError(error.toString)) + case userRib: JsSuccess[FromClientRib] => + val rib = userMethods.fromClientRibToRib(userRib.get, request.identity.uuid) + userMethods.updateRib(rib) map { response => + Ok(Json.toJson(response)) + } recover { case NonFatal(e) => + log(e.getMessage) + InternalServerError(e.getMessage) + } + } + } + + def findRibsByUserId(userId: String) = SecuredAction(Administrator()).async { implicit request => + val uuid = UUID.fromString(userId) + userMethods.findRibsByUserId(uuid) map { ribs => + Ok(Json.toJson(ribs)) + } + } + + def findUsersRibs = SecuredAction.async { implicit request => + val uuid = request.identity.uuid + userMethods.findRibsByUserId(uuid) map { ribs => + Ok(Json.toJson(ribs)) + } + } + + def createIdCard = ??? + + def findIdCardsByUserId = ??? + + def findUsersIdCards = ??? +} diff --git a/server/conf/evolutions/default/1.sql b/server/conf/evolutions/default/1.sql index d7d08058..821c901f 100755 --- a/server/conf/evolutions/default/1.sql +++ b/server/conf/evolutions/default/1.sql @@ -302,6 +302,23 @@ CREATE TABLE userActions ( ); +CREATE TABLE ribs ( + id SERIAL PRIMARY KEY, + bankCode VARCHAR(255) NOT NULL, + deskCode VARCHAR(255) NOT NULL, + accountNumber VARCHAR(255) NOT NULL UNIQUE, + ribKey VARCHAR(255) NOT NULL, + userId UUID REFERENCES users (userId) NOT NULL, + creationTime TIMESTAMP WITH TIME ZONE DEFAULT current_timestamp NOT NULL +); + +CREATE TABLE idCards ( + uuid UUID PRIMARY KEY, + userId UUID REFERENCES users (userId) NOT NULL, + creationTime TIMESTAMP WITH TIME ZONE DEFAULT current_timestamp NOT NULL +); + + CREATE TABLE issues ( issueId SERIAL PRIMARY KEY, title VARCHAR NOT NULL, @@ -650,6 +667,8 @@ DROP TABLE IF EXISTS salableEvents; DROP TABLE IF EXISTS userActions; DROP TABLE IF EXISTS userSessions; DROP TABLE IF EXISTS guestUsers; +DROP TABLE IF EXISTS idCards; +DROP TABLE IF EXISTS ribs; DROP TABLE IF EXISTS tickets; DROP TABLE IF EXISTS tariffs; DROP TABLE IF EXISTS bank; diff --git a/server/conf/evolutions/tests/1.sql b/server/conf/evolutions/tests/1.sql index 7b008183..19d50cf5 100755 --- a/server/conf/evolutions/tests/1.sql +++ b/server/conf/evolutions/tests/1.sql @@ -301,6 +301,21 @@ CREATE TABLE userActions ( sessionId UUID REFERENCES userSessions(id) ); +CREATE TABLE ribs ( + id SERIAL PRIMARY KEY, + bankCode VARCHAR(255) NOT NULL, + deskCode VARCHAR(255) NOT NULL, + accountNumber VARCHAR(255) NOT NULL UNIQUE, + ribKey VARCHAR(255) NOT NULL, + userId UUID REFERENCES users (userId) NOT NULL, + creationTime TIMESTAMP WITH TIME ZONE DEFAULT current_timestamp NOT NULL +); + +CREATE TABLE idCards ( + uuid UUID PRIMARY KEY, + userId UUID REFERENCES users (userId) NOT NULL, + creationTime TIMESTAMP WITH TIME ZONE DEFAULT current_timestamp NOT NULL +); CREATE TABLE issues ( issueId SERIAL PRIMARY KEY, @@ -652,6 +667,8 @@ DROP TABLE IF EXISTS userActions; DROP TABLE IF EXISTS userSessions; DROP TABLE IF EXISTS tickets; DROP TABLE IF EXISTS guestUsers; +DROP TABLE IF EXISTS ribs; +DROP TABLE IF EXISTS idCards; DROP TABLE IF EXISTS tariffsBlocked; DROP TABLE IF EXISTS tariffs; DROP TABLE IF EXISTS bank; diff --git a/server/conf/routes b/server/conf/routes index 2e14e010..77b99f08 100755 --- a/server/conf/routes +++ b/server/conf/routes @@ -164,10 +164,14 @@ POST /actions @tr #GET /users/:id @controllers.UserController.user(id: Long) #GET /users/containing/:pattern @controllers.UserController.findUsersContaining(pattern: String) #GET /users/:userId/tools @controllers.UserController.findToolsByUserId(userId: Long) -GET /users/geographicPoint @application.UserController.getUserGeographicPoint -POST /users/facebookAccessToken/ @application.UserController.findFacebookAccessToken -GET /users/tracksRemoved @application.UserController.getTracksRemoved -POST /users/isConnected @application.UserController.isConnected +GET /users/geographicPoint @userDomain.UserController.getUserGeographicPoint +POST /users/facebookAccessToken/ @userDomain.UserController.findFacebookAccessToken +GET /users/tracksRemoved @userDomain.UserController.getTracksRemoved +POST /users/isConnected @userDomain.UserController.isConnected +POST /ribs @userDomain.UserController.createRib +PUT /ribs @userDomain.UserController.updateRib +GET /ribs @userDomain.UserController.findRibsByUserId(userId: String) +GET /users/ribs @userDomain.UserController.findUsersRibs ################################## Buy ticket ########################################### #GET /buyTicket @others.TicketController.buyTicket diff --git a/server/test/PlaylistModelIntegrationTest.scala b/server/test/PlaylistModelIntegrationTest.scala index beef0f36..b6ef7aa7 100755 --- a/server/test/PlaylistModelIntegrationTest.scala +++ b/server/test/PlaylistModelIntegrationTest.scala @@ -1,6 +1,4 @@ import java.util.UUID - -import application.User import com.mohiva.play.silhouette.api.LoginInfo import database.MyPostgresDriver.api._ import genresDomain.Genre @@ -10,6 +8,7 @@ import org.scalatest.time.{Seconds, Span} import playlistsDomain._ import testsHelper.GlobalApplicationForModelsIntegration import tracksDomain.{Track, TrackWithGenres} +import userDomain.User import scala.concurrent.Await import scala.concurrent.duration._ diff --git a/server/test/TestUserController.scala b/server/test/TestUserController.scala index 9eceec6f..efcb4a20 100644 --- a/server/test/TestUserController.scala +++ b/server/test/TestUserController.scala @@ -1,10 +1,13 @@ +import java.util.UUID + import com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator import com.mohiva.play.silhouette.test._ import database.MyPostgresDriver.api._ -import play.api.mvc.AnyContentAsEmpty -import play.api.test.{FakeHeaders, FakeRequest} +import play.api.libs.json.{JsResult, JsSuccess, JsError, Json} +import play.api.test.FakeRequest import testsHelper.GlobalApplicationForControllers - +import userDomain.Rib +import json.JsonHelper._ import scala.concurrent.Await import scala.concurrent.duration._ import scala.language.postfixOps @@ -15,6 +18,10 @@ class TestUserController extends GlobalApplicationForControllers { Await.result( dbConfProvider.get.db.run(sqlu""" INSERT INTO artists(artistid, name, facebookurl) VALUES('100', 'name', 'facebookUrl0'); + INSERT INTO ribs(id, bankCode, deskCode, accountNumber, ribKey, userId) + VALUES (100, 'bank', 'desk', 'account2', '20', '077f3ea6-2272-4457-a47e-9e9111108e44'); + INSERT INTO ribs(id, bankCode, deskCode, accountNumber, ribKey, userId) + VALUES (200, 'bank', 'desk', 'account3', '20', '077f3ea6-2272-4457-a47e-9e9111108e44'); INSERT INTO tracks(trackid, title, url, platform, thumbnailurl, artistfacebookurl, artistname) VALUES('13894e56-08d1-4c1f-b3e4-466c069d15ed', 'title0', 'url00', 'y', 'thumbnailUrl', 'facebookUrl0', 'artistName'); INSERT INTO tracksrating(userId, trackId, reason) @@ -42,6 +49,109 @@ class TestUserController extends GlobalApplicationForControllers { contentAsString(removedTracks) must contain("13894e56-08d1-4c1f-b3e4-466c069d15ed") } + "create a rib for a user" in { + + val jsonRib = Json.parse("""{ + "bankCode": "bank", + "deskCode": "desk", + "accountNumber": "account1", + "ribKey": "20" + }""") + val Some(response) = route(FakeRequest(userDomain.routes.UserController.createRib()) + .withJsonBody(jsonRib) + .withAuthenticator[CookieAuthenticator](identity.loginInfo)) + + status(response) mustEqual OK + } + + "find ribs for a userId" in { + val expectedRib = Rib( + id = Some(200), + bankCode = "bank", + deskCode = "desk", + accountNumber = "account3", + ribKey = "20", + userId = UUID.fromString("077f3ea6-2272-4457-a47e-9e9111108e44") + ) + + val Some(ribs) = route(FakeRequest( + userDomain.routes.UserController.findRibsByUserId("077f3ea6-2272-4457-a47e-9e9111108e44") + ) + .withAuthenticator[CookieAuthenticator](administrator.loginInfo)) + + val validatedRibs: JsResult[Seq[Rib]] = contentAsJson(ribs).validate[Seq[Rib]](readRibReads) + val readRibs = validatedRibs match { + case error: JsError => + throw new Exception("find ribs for a userId") + case success: JsSuccess[Seq[Rib]] => + success.get + } + + readRibs must contain(expectedRib) + } + + "find ribs for a conected user" in { + val expectedRib = Rib( + id = Some(200), + bankCode = "bank", + deskCode = "desk", + accountNumber = "account3", + ribKey = "20", + userId = UUID.fromString("077f3ea6-2272-4457-a47e-9e9111108e44") + ) + + val Some(ribs) = route(FakeRequest( + userDomain.routes.UserController.findUsersRibs() + ) + .withAuthenticator[CookieAuthenticator](identity.loginInfo)) + + val validatedRibs: JsResult[Seq[Rib]] = contentAsJson(ribs).validate[Seq[Rib]](readRibReads) + val readRibs = validatedRibs match { + case error: JsError => + throw new Exception("find ribs for connected user") + case success: JsSuccess[Seq[Rib]] => + success.get + } + + readRibs must contain(expectedRib) + } + + "return forbidden if a connected user try to get other users ribs" in { + + val Some(ribs) = route(FakeRequest( + userDomain.routes.UserController.findRibsByUserId("077f3ea6-2272-4457-a47e-9e9111108e44") + ) + .withAuthenticator[CookieAuthenticator](identity.loginInfo)) + + status(ribs) mustEqual FORBIDDEN + } + + "return unauthorized if an unconnected user try to get ribs" in { + + val Some(ribs) = route(FakeRequest( + userDomain.routes.UserController.findUsersRibs() + )) + + status(ribs) mustEqual UNAUTHORIZED + } + + "update a rib for a user" in { + + val jsonRib = Json.parse("""{ + "id": 100, + "bankCode": "bank", + "deskCode": "desk", + "accountNumber": "account5", + "ribKey": "20" + }""") + + val Some(response) = route(FakeRequest(userDomain.routes.UserController.updateRib()) + .withJsonBody(jsonRib) + .withAuthenticator[CookieAuthenticator](identity.loginInfo)) + + status(response) mustEqual OK + } + } } diff --git a/server/test/UserModelIntegrationTest.scala b/server/test/UserModelIntegrationTest.scala index 2f93bf3c..c5895edf 100755 --- a/server/test/UserModelIntegrationTest.scala +++ b/server/test/UserModelIntegrationTest.scala @@ -1,6 +1,5 @@ import java.util.UUID -import application.{GuestUser, User} import com.mohiva.play.silhouette.api.LoginInfo import database.MyPostgresDriver.api._ import database.UserOrganizerRelation @@ -9,6 +8,7 @@ import org.scalatest.concurrent.ScalaFutures._ import org.scalatest.time.{Seconds, Span} import organizersDomain.{Organizer, OrganizerWithAddress} import testsHelper.GlobalApplicationForModelsIntegration +import userDomain.{IdCard, GuestUser, Rib, User} import scala.concurrent.Await import scala.concurrent.duration._ @@ -17,9 +17,21 @@ import scala.language.postfixOps class UserModelIntegrationTest extends GlobalApplicationForModelsIntegration { override def beforeAll(): Unit = { generalBeforeAll() + /* val rib = Rib( + id = None, + bankCode = "bank", + deskCode = "desk", + accountNumber = "account1", + ribKey = "20", + userId = UUID.fromString("077f3ea6-2272-4457-a47e-9e9111108e44") + )*/ Await.result( dbConfProvider.get.db.run(sqlu""" INSERT INTO guestUsers(ip) VALUES ('127.0.0.0'); + INSERT INTO ribs(id, bankCode, deskCode, accountNumber, ribKey, userId) + VALUES (100, 'bank', 'desk', 'account2', '20', '077f3ea6-2272-4457-a47e-9e9111108e44'); + INSERT INTO idCards(uuid, userId) + VALUES ('077f3ea6-2272-4457-a47e-9e9111108e45', '077f3ea6-2272-4457-a47e-9e9111108e44'); INSERT INTO places(placeid, name, facebookid) VALUES(400, 'testId4BecauseThereIsTRANSBORDEUR', 'facebookIdTestFollowController'); INSERT INTO placesfollowed(placeid, userid) VALUES (400, '077f3ea6-2272-4457-a47e-9e9111108e44');"""), @@ -119,6 +131,72 @@ class UserModelIntegrationTest extends GlobalApplicationForModelsIntegration { } } + "create a rib" in { + val rib = Rib( + id = None, + bankCode = "bank", + deskCode = "desk", + accountNumber = "account1", + ribKey = "20", + userId = UUID.fromString("077f3ea6-2272-4457-a47e-9e9111108e44") + ) + + whenReady(userMethods.createRib(rib)) { resp => + resp mustBe 1 + } + } + + "found all ribs of an user" in { + val expectedRib = Rib( + id = Some(100), + bankCode = "bank", + deskCode = "desk", + accountNumber = "account2", + ribKey = "20", + userId = UUID.fromString("077f3ea6-2272-4457-a47e-9e9111108e44") + ) + + whenReady(userMethods.findRibsByUserId(expectedRib.userId)) { resp => + resp must contain(expectedRib) + } + } + + "update a rib" in { + val newRib = Rib( + id = Some(100), + bankCode = "bank", + deskCode = "desk", + accountNumber = "account5", + ribKey = "20", + userId = UUID.fromString("077f3ea6-2272-4457-a47e-9e9111108e44") + ) + + whenReady(userMethods.updateRib(newRib)) { resp => + resp mustBe 1 + } + } + + "create an idCard" in { + val idCard = IdCard( + uuid = UUID.randomUUID(), + userId = UUID.fromString("077f3ea6-2272-4457-a47e-9e9111108e44") + ) + + whenReady(userMethods.createIdCard(idCard)) { resp => + resp mustBe 1 + } + } + + "found all idCards for a user" in { + val expectedCard = IdCard( + uuid = UUID.fromString("077f3ea6-2272-4457-a47e-9e9111108e45"), + userId = UUID.fromString("077f3ea6-2272-4457-a47e-9e9111108e44") + ) + whenReady(userMethods.findIdCardsByUserId(expectedCard.userId)) { resp => + resp must contain(expectedCard) + } + } + // // "get tracks he had removed" in { // val artist = Artist(None, Option("facebookIdTestUserModel"), "artistTest", Option("imagePath"), diff --git a/server/test/testsHelper/Context.scala b/server/test/testsHelper/Context.scala index 4e551be0..6c68c1c4 100644 --- a/server/test/testsHelper/Context.scala +++ b/server/test/testsHelper/Context.scala @@ -1,8 +1,6 @@ package testsHelper import java.util.UUID - -import application.User import com.google.inject.AbstractModule import com.mohiva.play.silhouette.api.{Environment, LoginInfo} import com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator @@ -11,6 +9,7 @@ import net.codingwell.scalaguice.ScalaModule import org.specs2.specification.Scope import play.api.Configuration import play.api.inject.guice.GuiceApplicationBuilder +import userDomain.User import scala.concurrent.ExecutionContext.Implicits.global diff --git a/server/test/testsHelper/Injectors.scala b/server/test/testsHelper/Injectors.scala index 3574eabd..2f5bfcf1 100644 --- a/server/test/testsHelper/Injectors.scala +++ b/server/test/testsHelper/Injectors.scala @@ -3,7 +3,6 @@ package testsHelper import actors.DuplicateTracksActorInstance import addresses.{AddressMethods, SearchGeographicPoint} import akka.actor.ActorSystem -import application.UserMethods import artistsDomain.ArtistMethods import attendees.AttendeeMethods import eventsDomain.EventMethods @@ -23,6 +22,7 @@ import tariffsDomain.TariffMethods import ticketsDomain.TicketMethods import trackingDomain.TrackingMethods import tracksDomain.{SearchSoundCloudTracks, SearchYoutubeTracks, TrackMethods, TrackRatingMethods} +import userDomain.UserMethods trait Injectors { From c2df9c39c8f9805394b78967b9b198806b2ab07a Mon Sep 17 00:00:00 2001 From: SiloSas Date: Thu, 25 Feb 2016 05:17:52 +0100 Subject: [PATCH 2/4] idCards without tests --- server/app/json/JsonHelper.scala | 4 +- server/app/userDomain/UserController.scala | 66 ++++++++++++++++++++-- server/conf/routes | 21 ++++--- server/test/TestUserController.scala | 3 + 4 files changed, 81 insertions(+), 13 deletions(-) diff --git a/server/app/json/JsonHelper.scala b/server/app/json/JsonHelper.scala index 13777b18..4b8464e9 100755 --- a/server/app/json/JsonHelper.scala +++ b/server/app/json/JsonHelper.scala @@ -17,7 +17,7 @@ import tariffsDomain.Tariff import ticketsDomain._ import trackingDomain.{UserAction, UserSession} import tracksDomain.{Track, TrackWithGenres} -import userDomain.{Rib, FromClientRib} +import userDomain.{IdCard, Rib, FromClientRib} object JsonHelper { @@ -72,6 +72,7 @@ object JsonHelper { implicit val genreFormat = Json.format[Genre] implicit val fromClientRibFormat = Json.format[FromClientRib] implicit val ribFormat = Json.format[Rib] + implicit val idCardFormat = Json.format[IdCard] implicit val trackFormat: Format[Track] = Json.format[Track] implicit val trackWithGenresFormat: Format[TrackWithGenres] = Json.format[TrackWithGenres] implicit val trackWithPlaylistRankFormat = Json.format[TrackWithPlaylistRank] @@ -113,4 +114,5 @@ object JsonHelper { val readMaybeSalableEventReads: Reads[Seq[MaybeSalableEvent]] = Reads.seq(__.read[MaybeSalableEvent]) val readTariffReads: Reads[Seq[Tariff]] = Reads.seq(__.read[Tariff]) val readRibReads: Reads[Seq[Rib]] = Reads.seq(__.read[Rib]) + val readIdCardReads: Reads[Seq[IdCard]] = Reads.seq(__.read[IdCard]) } diff --git a/server/app/userDomain/UserController.scala b/server/app/userDomain/UserController.scala index 7130f1af..a0d502e3 100755 --- a/server/app/userDomain/UserController.scala +++ b/server/app/userDomain/UserController.scala @@ -1,11 +1,13 @@ package userDomain +import java.io.{ByteArrayOutputStream, File} import java.util.UUID +import javax.imageio.ImageIO import javax.inject.Inject import com.mohiva.play.silhouette.api.{Environment, Silhouette} import com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator -import play.api.Logger +import play.api.{Play, Logger} import play.api.Play.current import play.api.i18n.MessagesApi import play.api.libs.concurrent.Execution.Implicits._ @@ -107,9 +109,65 @@ class UserController @Inject() (ws: WSClient, } } - def createIdCard = ??? + def createIdCard = SecuredAction.async(parse.multipartFormData) { request => + val userId = request.identity.uuid + + request.body.file("picture").map { image => + image.contentType match { + case Some(fileExtension) if fileExtension == "jpg" => + val filename = UUID.randomUUID() + image.ref.moveTo(new File(Play.application.path.getPath + "/idCards/" + filename), replace = true) + userMethods.createIdCard(IdCard(filename, userId)) map { response => + Ok(Json.toJson(response)) + } + case _ => + Future(Unauthorized("Wrong content type")) + } + }.getOrElse { + Future(BadRequest) + } + } - def findIdCardsByUserId = ??? + def findIdCardImageForUser(uuid: String) = SecuredAction.async { request => + val userUuid = request.identity.uuid + userMethods.findIdCardsByUserId(userUuid) map { idCards => + idCards.find(_.uuid == uuid) match { + case Some(idCard) => + getImageForUUID(uuid) + case _ => + log("error found id card for user") + InternalServerError("userController.findIdCardImageForUser") + } + } + } - def findUsersIdCards = ??? + def findIdCardImages(uuid: String) = SecuredAction(Administrator()) { request => + getImageForUUID(uuid) + } + + def getImageForUUID(uuid: String): Result = { + val imageFile = new File(Play.application.path.getPath + "/idCards/" + uuid) + val image = ImageIO.read(imageFile) + if (imageFile.length > 0) { + val baos = new ByteArrayOutputStream() + ImageIO.write(image, "jpg", baos) + Ok(baos.toByteArray).as("image/jpg") + } else + log("error found image of id card for user") + InternalServerError("userController.findIdCardImageForUser") + } + + def findIdCardsByUserId(userId: String) = SecuredAction(Administrator()).async { request => + val userUuid = UUID.fromString(userId) + userMethods.findIdCardsByUserId(userUuid) map { idCards => + Ok(Json.toJson(idCards)) + } + } + + def findUsersIdCards = SecuredAction.async { request => + val userUuid = request.identity.uuid + userMethods.findIdCardsByUserId(userUuid) map { idCards => + Ok(Json.toJson(idCards)) + } + } } diff --git a/server/conf/routes b/server/conf/routes index 77b99f08..139fb08d 100755 --- a/server/conf/routes +++ b/server/conf/routes @@ -164,14 +164,19 @@ POST /actions @tr #GET /users/:id @controllers.UserController.user(id: Long) #GET /users/containing/:pattern @controllers.UserController.findUsersContaining(pattern: String) #GET /users/:userId/tools @controllers.UserController.findToolsByUserId(userId: Long) -GET /users/geographicPoint @userDomain.UserController.getUserGeographicPoint -POST /users/facebookAccessToken/ @userDomain.UserController.findFacebookAccessToken -GET /users/tracksRemoved @userDomain.UserController.getTracksRemoved -POST /users/isConnected @userDomain.UserController.isConnected -POST /ribs @userDomain.UserController.createRib -PUT /ribs @userDomain.UserController.updateRib -GET /ribs @userDomain.UserController.findRibsByUserId(userId: String) -GET /users/ribs @userDomain.UserController.findUsersRibs +GET /users/geographicPoint @userDomain.UserController.getUserGeographicPoint +POST /users/facebookAccessToken/ @userDomain.UserController.findFacebookAccessToken +GET /users/tracksRemoved @userDomain.UserController.getTracksRemoved +POST /users/isConnected @userDomain.UserController.isConnected +POST /ribs @userDomain.UserController.createRib +PUT /ribs @userDomain.UserController.updateRib +GET /ribs @userDomain.UserController.findRibsByUserId(userId: String) +GET /users/ribs @userDomain.UserController.findUsersRibs +POST /idCards @userDomain.UserController.createIdCard +GET /users/idCards/:uuid @userDomain.UserController.findIdCardImageForUser(uuid: String) +GET /idCards/:uuid @userDomain.UserController.findIdCardImages(uuid: String) +GET /users/:userId/idCards @userDomain.UserController.findIdCardsByUserId(userId: String) +GET /idCards @userDomain.UserController.findUsersIdCards ################################## Buy ticket ########################################### #GET /buyTicket @others.TicketController.buyTicket diff --git a/server/test/TestUserController.scala b/server/test/TestUserController.scala index efcb4a20..f8c419e2 100644 --- a/server/test/TestUserController.scala +++ b/server/test/TestUserController.scala @@ -22,6 +22,8 @@ class TestUserController extends GlobalApplicationForControllers { VALUES (100, 'bank', 'desk', 'account2', '20', '077f3ea6-2272-4457-a47e-9e9111108e44'); INSERT INTO ribs(id, bankCode, deskCode, accountNumber, ribKey, userId) VALUES (200, 'bank', 'desk', 'account3', '20', '077f3ea6-2272-4457-a47e-9e9111108e44'); + INSERT INTO idCards(uuid, userId) + VALUES ('077f3ea6-2272-4457-a47e-9e9111108e45', '077f3ea6-2272-4457-a47e-9e9111108e44'); INSERT INTO tracks(trackid, title, url, platform, thumbnailurl, artistfacebookurl, artistname) VALUES('13894e56-08d1-4c1f-b3e4-466c069d15ed', 'title0', 'url00', 'y', 'thumbnailUrl', 'facebookUrl0', 'artistName'); INSERT INTO tracksrating(userId, trackId, reason) @@ -152,6 +154,7 @@ class TestUserController extends GlobalApplicationForControllers { status(response) mustEqual OK } + } } From 7f8b207e166b815524806248883c78557371cda0 Mon Sep 17 00:00:00 2001 From: SiloSas Date: Sun, 28 Feb 2016 18:54:23 +0100 Subject: [PATCH 3/4] uploadUsersInfo --- client/src/main/scala/App.scala | 2 +- .../main/scala/idCards/idCardUploader.html | 7 + favicon.jpeg | Bin 0 -> 3582 bytes server/app/userDomain/UserController.scala | 30 ++-- server/app/views/scripts.scala.html | 1 + .../5e7b7c6c-98b3-4245-a5fb-405c9cc904f4 | Bin 0 -> 3582 bytes server/test/TestUserController.scala | 159 +++++++++++++++++- 7 files changed, 179 insertions(+), 20 deletions(-) create mode 100644 client/src/main/scala/idCards/idCardUploader.html create mode 100755 favicon.jpeg create mode 100644 server/idCards/5e7b7c6c-98b3-4245-a5fb-405c9cc904f4 diff --git a/client/src/main/scala/App.scala b/client/src/main/scala/App.scala index bbcd0f88..652f476c 100644 --- a/client/src/main/scala/App.scala +++ b/client/src/main/scala/App.scala @@ -26,7 +26,7 @@ object App extends JSApp { override def main() { val module = Angular.module("app", Seq("ngAnimate", "ngAria", "ngMaterial", "mm.foundation", "ngRoute", "ngMap", - "ngCookies", "angularTranslateApp", "ngSanitize", "themingAngularMaterial", "satellizer")) + "ngCookies", "angularTranslateApp", "ngSanitize", "themingAngularMaterial", "satellizer", "idCardUploader")) module.config(RoutingConfig) module.config(AuthConfig) diff --git a/client/src/main/scala/idCards/idCardUploader.html b/client/src/main/scala/idCards/idCardUploader.html new file mode 100644 index 00000000..257dc28c --- /dev/null +++ b/client/src/main/scala/idCards/idCardUploader.html @@ -0,0 +1,7 @@ + + + + diff --git a/favicon.jpeg b/favicon.jpeg new file mode 100755 index 0000000000000000000000000000000000000000..6f7852801b6ba5a3c42c5a12d31da55db2f22b13 GIT binary patch literal 3582 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 val userId = request.identity.uuid - request.body.file("picture").map { image => + println("image = " + image.contentType) image.contentType match { - case Some(fileExtension) if fileExtension == "jpg" => + case Some(fileExtension) if fileExtension == "image/jpeg" => val filename = UUID.randomUUID() image.ref.moveTo(new File(Play.application.path.getPath + "/idCards/" + filename), replace = true) userMethods.createIdCard(IdCard(filename, userId)) map { response => - Ok(Json.toJson(response)) + Ok(Json.toJson(filename)) } case _ => Future(Unauthorized("Wrong content type")) @@ -128,33 +128,33 @@ class UserController @Inject() (ws: WSClient, } } - def findIdCardImageForUser(uuid: String) = SecuredAction.async { request => + def findIdCardImageForUser(stringUuid: String) = SecuredAction.async { request => val userUuid = request.identity.uuid + val uuid = UUID.fromString(stringUuid) userMethods.findIdCardsByUserId(userUuid) map { idCards => idCards.find(_.uuid == uuid) match { case Some(idCard) => - getImageForUUID(uuid) + getImageForUUID(stringUuid) case _ => log("error found id card for user") - InternalServerError("userController.findIdCardImageForUser") + NotFound("userController.findIdCardImageForUser") } } } - def findIdCardImages(uuid: String) = SecuredAction(Administrator()) { request => - getImageForUUID(uuid) - } + def findIdCardImages(uuid: String) = SecuredAction(Administrator()) { request => getImageForUUID(uuid) } def getImageForUUID(uuid: String): Result = { val imageFile = new File(Play.application.path.getPath + "/idCards/" + uuid) - val image = ImageIO.read(imageFile) if (imageFile.length > 0) { - val baos = new ByteArrayOutputStream() - ImageIO.write(image, "jpg", baos) - Ok(baos.toByteArray).as("image/jpg") - } else + val image = ImageIO.read(imageFile) + val byteArrayOutputStream = new ByteArrayOutputStream() + ImageIO.write(image, "png", byteArrayOutputStream) + Ok(byteArrayOutputStream.toByteArray).as("image/png") + } else { log("error found image of id card for user") - InternalServerError("userController.findIdCardImageForUser") + InternalServerError("userController.findIdCardImageForUser") + } } def findIdCardsByUserId(userId: String) = SecuredAction(Administrator()).async { request => diff --git a/server/app/views/scripts.scala.html b/server/app/views/scripts.scala.html index 4d0f3c4a..67591916 100644 --- a/server/app/views/scripts.scala.html +++ b/server/app/views/scripts.scala.html @@ -42,6 +42,7 @@ + diff --git a/server/idCards/5e7b7c6c-98b3-4245-a5fb-405c9cc904f4 b/server/idCards/5e7b7c6c-98b3-4245-a5fb-405c9cc904f4 new file mode 100644 index 0000000000000000000000000000000000000000..6f7852801b6ba5a3c42c5a12d31da55db2f22b13 GIT binary patch literal 3582 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 + values.map { value => + val name = s""""$key"""" + s"--$boundary\r\n${HeaderNames.CONTENT_DISPOSITION}: form-data; name=$name\r\n\r\n$value\r\n" + } + }.mkString("") + Codec.utf_8.encode(dataParts) + } + + def filePartHeader(file: FilePart[TemporaryFile]) = { + val name = s""""${file.key}"""" + val filename = s""""${file.filename}"""" + val contentType = file.contentType.map { ct => + s"${HeaderNames.CONTENT_TYPE}: $ct\r\n" + }.getOrElse("") + Codec.utf_8.encode(s"--$boundary\r\n${HeaderNames.CONTENT_DISPOSITION}: form-data; name=$name; filename=$filename\r\n$contentType\r\n") + } + + val singleton = Writeable[MultipartFormData[TemporaryFile]]( + transform = { form: MultipartFormData[TemporaryFile] => + formatDataParts(form.dataParts) ++ + form.files.flatMap { file => + val fileBytes = Files.readAllBytes(Paths.get(file.ref.file.getAbsolutePath)) + filePartHeader(file) ++ fileBytes ++ Codec.utf_8.encode("\r\n") + } ++ + Codec.utf_8.encode(s"--$boundary--") + }, + contentType = Some(s"multipart/form-data; boundary=$boundary") + ) +} class TestUserController extends GlobalApplicationForControllers { override def beforeAll(): Unit = { @@ -23,7 +70,9 @@ class TestUserController extends GlobalApplicationForControllers { INSERT INTO ribs(id, bankCode, deskCode, accountNumber, ribKey, userId) VALUES (200, 'bank', 'desk', 'account3', '20', '077f3ea6-2272-4457-a47e-9e9111108e44'); INSERT INTO idCards(uuid, userId) - VALUES ('077f3ea6-2272-4457-a47e-9e9111108e45', '077f3ea6-2272-4457-a47e-9e9111108e44'); + VALUES ('5e7b7c6c-98b3-4245-a5fb-405c9cc904f4', '077f3ea6-2272-4457-a47e-9e9111108e44'); + INSERT INTO idCards(uuid, userId) + VALUES ('5e8b7c6c-98b3-4245-a5fb-405c9cc904f4', '078f3ea6-2272-4457-a47e-9e9111108e44'); INSERT INTO tracks(trackid, title, url, platform, thumbnailurl, artistfacebookurl, artistname) VALUES('13894e56-08d1-4c1f-b3e4-466c069d15ed', 'title0', 'url00', 'y', 'thumbnailUrl', 'facebookUrl0', 'artistName'); INSERT INTO tracksrating(userId, trackId, reason) @@ -92,7 +141,7 @@ class TestUserController extends GlobalApplicationForControllers { readRibs must contain(expectedRib) } - "find ribs for a conected user" in { + "find ribs for a connected user" in { val expectedRib = Rib( id = Some(200), bankCode = "bank", @@ -155,6 +204,108 @@ class TestUserController extends GlobalApplicationForControllers { } + implicit val anyContentAsMultipartFormWritable: Writeable[AnyContentAsMultipartFormData] = { + MultipartFormDataWritable.singleton.map(_.mdf) + } + + "create a new IdCard" in { + val tempFile = TemporaryFile(new java.io.File("../favicon.jpeg")) + val part = FilePart[TemporaryFile](key = "picture", filename = "the.file", contentType = Some("image/jpeg"), + ref = tempFile) + val formData = MultipartFormData(dataParts = Map(), files = Seq(part), badParts = Seq(), missingFileParts = Seq()) + val Some(result) = route(FakeRequest(userDomain.routes.UserController.createIdCard()) + .withMultipartFormDataBody(formData) + .withAuthenticator[CookieAuthenticator](identity.loginInfo)) + + status(result) mustEqual OK + } + + "return unauthorized if a unconnected user try to create a new IdCard" in { + val tempFile = TemporaryFile(new java.io.File("../favicon.jpeg")) + val part = FilePart[TemporaryFile](key = "picture", filename = "the.file", contentType = Some("image/jpeg"), + ref = tempFile) + val formData = MultipartFormData(dataParts = Map(), files = Seq(part), badParts = Seq(), missingFileParts = Seq()) + val Some(result) = route(FakeRequest(userDomain.routes.UserController.createIdCard()) + .withMultipartFormDataBody(formData)) + + status(result) mustEqual UNAUTHORIZED + } + + "find id cards for a connected user" in { + val expectedIdCard = IdCard(uuid = UUID.fromString("5e7b7c6c-98b3-4245-a5fb-405c9cc904f4"), + userId = UUID.fromString("077f3ea6-2272-4457-a47e-9e9111108e44")) + val unexpectedIdCard = IdCard(uuid = UUID.fromString("5e8b7c6c-98b3-4245-a5fb-405c9cc904f4"), + userId = UUID.fromString("078f3ea6-2272-4457-a47e-9e9111108e44")) + + val Some(result) = route(FakeRequest(userDomain.routes.UserController.findUsersIdCards()) + .withAuthenticator[CookieAuthenticator](identity.loginInfo)) + + val validatedIdCards: JsResult[Seq[IdCard]] = contentAsJson(result).validate[Seq[IdCard]](readIdCardReads) + val readIdCards = validatedIdCards match { + case error: JsError => + throw new Exception("find idCard for connected user") + case success: JsSuccess[Seq[IdCard]] => + success.get + } + + readIdCards must contain(expectedIdCard) + readIdCards must not contain unexpectedIdCard + } + + "find id cards for a user id" in { + val expectedIdCard = IdCard(uuid = UUID.fromString("5e7b7c6c-98b3-4245-a5fb-405c9cc904f4"), + userId = UUID.fromString("077f3ea6-2272-4457-a47e-9e9111108e44")) + val unexpectedIdCard = IdCard(uuid = UUID.fromString("5e8b7c6c-98b3-4245-a5fb-405c9cc904f4"), + userId = UUID.fromString("078f3ea6-2272-4457-a47e-9e9111108e44")) + + val Some(result) = route(FakeRequest( + userDomain.routes.UserController.findIdCardsByUserId("077f3ea6-2272-4457-a47e-9e9111108e44")) + .withAuthenticator[CookieAuthenticator](administrator.loginInfo)) + + val validatedIdCards: JsResult[Seq[IdCard]] = contentAsJson(result).validate[Seq[IdCard]](readIdCardReads) + val readIdCards = validatedIdCards match { + case error: JsError => + throw new Exception("find idCard for connected user") + case success: JsSuccess[Seq[IdCard]] => + success.get + } + + readIdCards must contain(expectedIdCard) + readIdCards must not contain unexpectedIdCard + } + + "return forbidden if a user try to find id cards for a user id" in { + val Some(result) = route(FakeRequest( + userDomain.routes.UserController.findIdCardsByUserId("077f3ea6-2272-4457-a47e-9e9111108e44")) + .withAuthenticator[CookieAuthenticator](identity.loginInfo)) + + status(result) mustEqual FORBIDDEN + } + + "return an image for a card uuid for a connected user" in { + val Some(result) = route(FakeRequest( + userDomain.routes.UserController.findIdCardImageForUser("5e7b7c6c-98b3-4245-a5fb-405c9cc904f4")) + .withAuthenticator[CookieAuthenticator](identity.loginInfo)) + + status(result) mustEqual OK + } + + + "return an image for a card uuid for a connected administrateur" in { + val Some(result) = route(FakeRequest( + userDomain.routes.UserController.findIdCardImages("5e7b7c6c-98b3-4245-a5fb-405c9cc904f4")) + .withAuthenticator[CookieAuthenticator](administrator.loginInfo)) + + status(result) mustEqual OK + } + + "return not found if a connected user try to get idCard of an other user" in { + val Some(result) = route(FakeRequest( + userDomain.routes.UserController.findIdCardImageForUser("5e8b7c6c-98b3-4245-a5fb-405c9cc904f4")) + .withAuthenticator[CookieAuthenticator](identity.loginInfo)) + + status(result) mustEqual NOT_FOUND + } } } From a7cb8dccba781190b55abc9bc423b857e50e1f98 Mon Sep 17 00:00:00 2001 From: SiloSas Date: Sun, 28 Feb 2016 19:34:07 +0100 Subject: [PATCH 4/4] review --- server/app/userDomain/UserController.scala | 5 +- server/test/TestUserController.scala | 85 ++++--------------- server/test/UserModelIntegrationTest.scala | 16 +--- .../MultipartFormDataWritable.scala | 50 +++++++++++ 4 files changed, 74 insertions(+), 82 deletions(-) create mode 100644 server/test/testsHelper/MultipartFormDataWritable.scala diff --git a/server/app/userDomain/UserController.scala b/server/app/userDomain/UserController.scala index 5c15541d..1350f979 100755 --- a/server/app/userDomain/UserController.scala +++ b/server/app/userDomain/UserController.scala @@ -112,14 +112,15 @@ class UserController @Inject() (ws: WSClient, def createIdCard = SecuredAction.async(parse.multipartFormData) { request => val userId = request.identity.uuid request.body.file("picture").map { image => - println("image = " + image.contentType) image.contentType match { + case Some(fileExtension) if fileExtension == "image/jpeg" => val filename = UUID.randomUUID() image.ref.moveTo(new File(Play.application.path.getPath + "/idCards/" + filename), replace = true) userMethods.createIdCard(IdCard(filename, userId)) map { response => Ok(Json.toJson(filename)) } + case _ => Future(Unauthorized("Wrong content type")) } @@ -133,8 +134,10 @@ class UserController @Inject() (ws: WSClient, val uuid = UUID.fromString(stringUuid) userMethods.findIdCardsByUserId(userUuid) map { idCards => idCards.find(_.uuid == uuid) match { + case Some(idCard) => getImageForUUID(stringUuid) + case _ => log("error found id card for user") NotFound("userController.findIdCardImageForUser") diff --git a/server/test/TestUserController.scala b/server/test/TestUserController.scala index 775f921d..266d308b 100644 --- a/server/test/TestUserController.scala +++ b/server/test/TestUserController.scala @@ -1,63 +1,21 @@ -import java.nio.file.{Files, Paths} import java.util.UUID import com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator import com.mohiva.play.silhouette.test._ import database.MyPostgresDriver.api._ -import org.specs2.runner.files +import json.JsonHelper._ import play.api.libs.Files.TemporaryFile -import play.api.libs.json.{JsResult, JsSuccess, JsError, Json} -import play.api.mvc.{AnyContentAsMultipartFormData, MultipartFormData} +import play.api.libs.json.{JsError, JsResult, JsSuccess, Json} +import play.api.mvc.MultipartFormData import play.api.mvc.MultipartFormData.FilePart -import play.api.test.{FakeHeaders, FakeRequest} +import play.api.test.FakeRequest import testsHelper.GlobalApplicationForControllers +import testsHelper.MultipartFormDataWritable._ import userDomain.{IdCard, Rib} -import json.JsonHelper._ + import scala.concurrent.Await import scala.concurrent.duration._ import scala.language.postfixOps -import scala.concurrent.ExecutionContext.Implicits.global -import java.io.File - -import play.api.http.{HeaderNames, Writeable} -import play.api.libs.Files.TemporaryFile -import play.api.mvc.MultipartFormData.FilePart -import play.api.mvc.{AnyContentAsMultipartFormData, Codec, MultipartFormData} - -object MultipartFormDataWritable { - val boundary = "--------ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" - - def formatDataParts(data: Map[String, Seq[String]]) = { - val dataParts = data.flatMap { case (key, values) => - values.map { value => - val name = s""""$key"""" - s"--$boundary\r\n${HeaderNames.CONTENT_DISPOSITION}: form-data; name=$name\r\n\r\n$value\r\n" - } - }.mkString("") - Codec.utf_8.encode(dataParts) - } - - def filePartHeader(file: FilePart[TemporaryFile]) = { - val name = s""""${file.key}"""" - val filename = s""""${file.filename}"""" - val contentType = file.contentType.map { ct => - s"${HeaderNames.CONTENT_TYPE}: $ct\r\n" - }.getOrElse("") - Codec.utf_8.encode(s"--$boundary\r\n${HeaderNames.CONTENT_DISPOSITION}: form-data; name=$name; filename=$filename\r\n$contentType\r\n") - } - - val singleton = Writeable[MultipartFormData[TemporaryFile]]( - transform = { form: MultipartFormData[TemporaryFile] => - formatDataParts(form.dataParts) ++ - form.files.flatMap { file => - val fileBytes = Files.readAllBytes(Paths.get(file.ref.file.getAbsolutePath)) - filePartHeader(file) ++ fileBytes ++ Codec.utf_8.encode("\r\n") - } ++ - Codec.utf_8.encode(s"--$boundary--") - }, - contentType = Some(s"multipart/form-data; boundary=$boundary") - ) -} class TestUserController extends GlobalApplicationForControllers { override def beforeAll(): Unit = { @@ -151,10 +109,8 @@ class TestUserController extends GlobalApplicationForControllers { userId = UUID.fromString("077f3ea6-2272-4457-a47e-9e9111108e44") ) - val Some(ribs) = route(FakeRequest( - userDomain.routes.UserController.findUsersRibs() - ) - .withAuthenticator[CookieAuthenticator](identity.loginInfo)) + val Some(ribs) = route(FakeRequest(userDomain.routes.UserController.findUsersRibs()) + .withAuthenticator[CookieAuthenticator](identity.loginInfo)) val validatedRibs: JsResult[Seq[Rib]] = contentAsJson(ribs).validate[Seq[Rib]](readRibReads) val readRibs = validatedRibs match { @@ -170,18 +126,14 @@ class TestUserController extends GlobalApplicationForControllers { "return forbidden if a connected user try to get other users ribs" in { val Some(ribs) = route(FakeRequest( - userDomain.routes.UserController.findRibsByUserId("077f3ea6-2272-4457-a47e-9e9111108e44") - ) - .withAuthenticator[CookieAuthenticator](identity.loginInfo)) + userDomain.routes.UserController.findRibsByUserId("077f3ea6-2272-4457-a47e-9e9111108e44") + ).withAuthenticator[CookieAuthenticator](identity.loginInfo)) status(ribs) mustEqual FORBIDDEN } "return unauthorized if an unconnected user try to get ribs" in { - - val Some(ribs) = route(FakeRequest( - userDomain.routes.UserController.findUsersRibs() - )) + val Some(ribs) = route(FakeRequest(userDomain.routes.UserController.findUsersRibs())) status(ribs) mustEqual UNAUTHORIZED } @@ -203,24 +155,19 @@ class TestUserController extends GlobalApplicationForControllers { status(response) mustEqual OK } - - implicit val anyContentAsMultipartFormWritable: Writeable[AnyContentAsMultipartFormData] = { - MultipartFormDataWritable.singleton.map(_.mdf) - } - "create a new IdCard" in { val tempFile = TemporaryFile(new java.io.File("../favicon.jpeg")) val part = FilePart[TemporaryFile](key = "picture", filename = "the.file", contentType = Some("image/jpeg"), ref = tempFile) val formData = MultipartFormData(dataParts = Map(), files = Seq(part), badParts = Seq(), missingFileParts = Seq()) val Some(result) = route(FakeRequest(userDomain.routes.UserController.createIdCard()) - .withMultipartFormDataBody(formData) - .withAuthenticator[CookieAuthenticator](identity.loginInfo)) + .withMultipartFormDataBody(formData) + .withAuthenticator[CookieAuthenticator](identity.loginInfo)) status(result) mustEqual OK } - "return unauthorized if a unconnected user try to create a new IdCard" in { + "return unauthorized if a not loged in user try to create a new IdCard" in { val tempFile = TemporaryFile(new java.io.File("../favicon.jpeg")) val part = FilePart[TemporaryFile](key = "picture", filename = "the.file", contentType = Some("image/jpeg"), ref = tempFile) @@ -259,8 +206,8 @@ class TestUserController extends GlobalApplicationForControllers { userId = UUID.fromString("078f3ea6-2272-4457-a47e-9e9111108e44")) val Some(result) = route(FakeRequest( - userDomain.routes.UserController.findIdCardsByUserId("077f3ea6-2272-4457-a47e-9e9111108e44")) - .withAuthenticator[CookieAuthenticator](administrator.loginInfo)) + userDomain.routes.UserController.findIdCardsByUserId("077f3ea6-2272-4457-a47e-9e9111108e44")) + .withAuthenticator[CookieAuthenticator](administrator.loginInfo)) val validatedIdCards: JsResult[Seq[IdCard]] = contentAsJson(result).validate[Seq[IdCard]](readIdCardReads) val readIdCards = validatedIdCards match { diff --git a/server/test/UserModelIntegrationTest.scala b/server/test/UserModelIntegrationTest.scala index c5895edf..0aec5d33 100755 --- a/server/test/UserModelIntegrationTest.scala +++ b/server/test/UserModelIntegrationTest.scala @@ -17,14 +17,6 @@ import scala.language.postfixOps class UserModelIntegrationTest extends GlobalApplicationForModelsIntegration { override def beforeAll(): Unit = { generalBeforeAll() - /* val rib = Rib( - id = None, - bankCode = "bank", - deskCode = "desk", - accountNumber = "account1", - ribKey = "20", - userId = UUID.fromString("077f3ea6-2272-4457-a47e-9e9111108e44") - )*/ Await.result( dbConfProvider.get.db.run(sqlu""" INSERT INTO guestUsers(ip) VALUES ('127.0.0.0'); @@ -156,8 +148,8 @@ class UserModelIntegrationTest extends GlobalApplicationForModelsIntegration { userId = UUID.fromString("077f3ea6-2272-4457-a47e-9e9111108e44") ) - whenReady(userMethods.findRibsByUserId(expectedRib.userId)) { resp => - resp must contain(expectedRib) + whenReady(userMethods.findRibsByUserId(expectedRib.userId)) { ribs => + ribs must contain(expectedRib) } } @@ -192,8 +184,8 @@ class UserModelIntegrationTest extends GlobalApplicationForModelsIntegration { uuid = UUID.fromString("077f3ea6-2272-4457-a47e-9e9111108e45"), userId = UUID.fromString("077f3ea6-2272-4457-a47e-9e9111108e44") ) - whenReady(userMethods.findIdCardsByUserId(expectedCard.userId)) { resp => - resp must contain(expectedCard) + whenReady(userMethods.findIdCardsByUserId(expectedCard.userId)) { cards => + cards must contain(expectedCard) } } diff --git a/server/test/testsHelper/MultipartFormDataWritable.scala b/server/test/testsHelper/MultipartFormDataWritable.scala new file mode 100644 index 00000000..edcdc7f7 --- /dev/null +++ b/server/test/testsHelper/MultipartFormDataWritable.scala @@ -0,0 +1,50 @@ +package testsHelper + +import java.nio.file.{Files, Paths} + +import play.api.http.{HeaderNames, Writeable} +import play.api.libs.Files.TemporaryFile +import play.api.mvc.MultipartFormData.FilePart +import play.api.mvc.{AnyContentAsMultipartFormData, Codec, MultipartFormData} + +import scala.concurrent.ExecutionContext.Implicits.global + +object MultipartFormDataWritable { + val boundary = "--------ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" + + def formatDataParts(data: Map[String, Seq[String]]) = { + val dataParts = data.flatMap { case (key, values) => + values.map { value => + val name = s""""$key"""" + s"--$boundary\r\n${HeaderNames.CONTENT_DISPOSITION}: form-data; name=$name\r\n\r\n$value\r\n" + } + }.mkString("") + Codec.utf_8.encode(dataParts) + } + + def filePartHeader(file: FilePart[TemporaryFile]) = { + val name = s""""${file.key}"""" + val filename = s""""${file.filename}"""" + val contentType = file.contentType.map { ct => + s"${HeaderNames.CONTENT_TYPE}: $ct\r\n" + }.getOrElse("") + Codec.utf_8.encode(s"--$boundary\r\n${HeaderNames.CONTENT_DISPOSITION}: form-data; name=$name; filename=$filename\r\n$contentType\r\n") + } + + val singleton = Writeable[MultipartFormData[TemporaryFile]]( + transform = { form: MultipartFormData[TemporaryFile] => + formatDataParts(form.dataParts) ++ + form.files.flatMap { file => + val fileBytes = Files.readAllBytes(Paths.get(file.ref.file.getAbsolutePath)) + filePartHeader(file) ++ fileBytes ++ Codec.utf_8.encode("\r\n") + } ++ + Codec.utf_8.encode(s"--$boundary--") + }, + contentType = Some(s"multipart/form-data; boundary=$boundary") + ) + + + implicit val anyContentAsMultipartFormWritable: Writeable[AnyContentAsMultipartFormData] = + MultipartFormDataWritable.singleton.map(_.mdf) + +}