User.scala 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. package com.weEat.models
  2. import codes.reactive.scalatime._
  3. import org.bson.types.ObjectId
  4. import com.weEat.shared.models.UserAuthorization
  5. import java.security.SecureRandom
  6. import java.time.{Duration,Instant}
  7. import java.util.Base64
  8. import scala.language.postfixOps
  9. import scalaoauth2.provider.AccessToken
  10. import scala.language.existentials
  11. import scala.language.implicitConversions
  12. /* Basic User information */
  13. case class User (
  14. val _id: ObjectId,
  15. val fname: String,
  16. val lname: String,
  17. val email: String,
  18. val password: String,
  19. val created: Instant = Instant.now(),
  20. val isAdmin: Boolean = false
  21. ) {
  22. def toShared() = com.weEat.shared.models.User(
  23. _id,
  24. fname,
  25. lname,
  26. email
  27. )
  28. import com.github.t3hnar.bcrypt.BCryptStrOps
  29. def changePassword(pwd: String) = copy(
  30. password = pwd.boundedBcrypt
  31. )
  32. }
  33. object User extends Collectable[User] {
  34. import com.weEat.shared.models.UserRegistration
  35. import com.github.t3hnar.bcrypt.BCryptStrOps
  36. val collectionName = "users"
  37. def apply(reg: UserRegistration): User = User(
  38. new ObjectId(),
  39. reg.fname,
  40. reg.lname,
  41. reg.email,
  42. reg.password.boundedBcrypt
  43. )
  44. }
  45. class Authorization (
  46. val accessToken: Array[Byte],
  47. val refreshToken: Array[Byte],
  48. val created: Instant,
  49. val email: String,
  50. val userId: ObjectId,
  51. val hasAdminPermissions: Boolean
  52. ) {
  53. def accessExpiration() = created + Authorization.accessFreshTime
  54. def refreshExpiration() = created + Authorization.refreshFreshTime
  55. implicit def asFiniteDuration(d: java.time.Duration) =
  56. scala.concurrent.duration.Duration.fromNanos(d.toNanos)
  57. implicit def asDate(d: java.time.Instant) =
  58. new java.util.Date(d.toEpochMilli())
  59. def toToken() = new AccessToken(
  60. Authorization.encodeToken(accessToken),
  61. Some(Authorization.encodeToken(refreshToken)),
  62. Some(Set.concat(
  63. Some("user"),
  64. Option.when(hasAdminPermissions)("admin")
  65. ).mkString(" ")),
  66. Some(Duration.between(Instant.now(), accessExpiration()).getSeconds()),
  67. created
  68. )
  69. def toUserAuth() = UserAuthorization(
  70. Authorization.encodeToken(accessToken),
  71. "Bearer",
  72. Duration.between(Instant.now(), accessExpiration()),
  73. Authorization.encodeToken(refreshToken),
  74. Set.concat(
  75. Some("user"),
  76. Option.when(hasAdminPermissions)("admin")
  77. )
  78. )
  79. }
  80. object Authorization extends Collectable[Authorization] {
  81. val accessFreshTime = 1 hour
  82. val refreshFreshTime = 10 hour
  83. val collectionName = "authorizations"
  84. private val rand = new SecureRandom()
  85. private def generateSecureBytes(n: Int = 32): Array[Byte] = {
  86. val token = new Array[Byte](n);
  87. rand.nextBytes(token)
  88. token
  89. }
  90. def encodeToken(token: Array[Byte]) = Base64.getEncoder.encodeToString(token)
  91. def decodeToken(token: String) = Base64.getDecoder.decode(token)
  92. def apply(user: User) = new Authorization(
  93. generateSecureBytes(),
  94. generateSecureBytes(),
  95. Instant.now(),
  96. user.email,
  97. user._id,
  98. user.isAdmin
  99. )
  100. }