pyc-website

main website for pyc inc.

git clone https://9o.is/git/pyc-website.git

IdVerification.scala

(4285B)


      1 package inc.pyc
      2 package rest
      3 
      4 import model._
      5 import config._
      6 import net.liftweb._
      7 import net.liftweb.http._
      8 import net.liftweb.util._
      9 import net.liftweb.http.rest._
     10 import net.liftweb.common._
     11 import net.liftweb.http.js.JsCmds._
     12 import net.liftmodules.mongoauth.MongoAuth
     13 import inc.pyc.aws.s3._
     14 import net.liftweb.http.LiftRulesMocker.toLiftRules
     15 import net.liftweb.util.Mailer.From
     16 import net.liftweb.util.Mailer.PlainMailBodyType
     17 import net.liftweb.util.Mailer.Subject
     18 import net.liftweb.util.Mailer.To
     19 import net.liftweb.util.Mailer.sendMail
     20 
     21 /**
     22  * The identification files uploaded by a user will be stored here.
     23  * Assure to clean up when done to save memory.
     24  */
     25 object IdVerificationFiles extends SessionVar[List[FileParamHolder]](Nil)
     26 
     27 /**
     28  * The REST point is used to load identification files to memory only.
     29  * Manipulation should occur somewhere else (like snippet).
     30  */
     31 object IdVerificationUpload extends RestHelper with Logger {
     32 
     33   def init(): Unit = {
     34     LiftRules.dispatch.append(IdVerificationUpload)
     35   }
     36   
     37   /**
     38    * File can only be a maximum of 5 MB.
     39    */
     40   def imgTooLarge(file: FileParamHolder) = file.length > 5243000
     41 
     42   /**
     43    * Only allow images of types: jpeg, png, svg, pdf
     44    */
     45   def imgInvalid(file: FileParamHolder) = ! List(
     46     "image/jpeg", "image/png", "image/svg+xml", "application/pdf", 
     47     "application/x-pdf", "application/x-bzpdf", "application/x-gzpdf").exists(_ == file.mimeType)
     48     
     49   /**
     50    * The maximum amount of files allowed in memory per user.
     51    */
     52   def maxFilesInMemory = 3
     53   
     54   /**
     55    * Checks if another file can be added to memory or not.
     56    */
     57   def tooManyFiles = IdVerificationFiles.get.size >= maxFilesInMemory
     58   
     59   /**
     60    * API for uploading files to server.
     61    */
     62   serve("settings" / "verification" prefix {
     63     case "upload" :: Nil Post req =>
     64       for {
     65         user <- User.currentUser ?~ "Must be logged in" ~> 400
     66         file <- Box(req.uploadedFiles) ?~ "File not found"
     67       } yield {
     68         if(imgInvalid(file))
     69           ResponseWithReason(BadResponse(), "Can only upload jpeg, png or svg file types.")
     70         else if(imgTooLarge(file))
     71           ResponseWithReason(BadResponse(), "Image can only be 5MB or less.")
     72         else if(tooManyFiles)
     73           ResponseWithReason(BadResponse(), "Up to "+maxFilesInMemory+" files can be uploaded at once.")
     74         else {
     75           val thisreq = req
     76           IdVerificationFiles.set(IdVerificationFiles.get :+ file)
     77           OkResponse()
     78         }
     79       }
     80   })
     81 }
     82 
     83 /**
     84  * Other utility functions to help with the process of 
     85  * uploading identification files. 
     86  */
     87 object IdVerificationHelper {
     88 
     89   private val s3Obj = new S3(
     90       Props.get("idverify.access.key", "NONE"), 
     91       Props.get("idverify.secret.key", "NONE"), 
     92       Props.get("idverify.bucket", "NONE"))
     93   
     94   /**
     95    * Create an S3 object for uploading files.
     96    */
     97   def s3(path: String = "") = s3Obj.copy(path = path)
     98   
     99   /** 
    100    *  S3 folder formatting: /full_name/id/date/ 
    101    */
    102   def createS3Folder(user: User) = {
    103     val prefix = if(Props.devMode) "dev/" else ""
    104     
    105     prefix + s"%s/%s/%s/".format(
    106         user.email.get, user.id.get, new java.util.Date().toString)
    107   }
    108   
    109   
    110   /**
    111    * Uploads the pending files and returns 
    112    * if it was successful or not.
    113    */
    114   def upload(service: S3): Boolean = 
    115     if(IdVerificationFiles.isEmpty) {
    116       false
    117     } else {
    118       val statusCodes = IdVerificationFiles.get.map { fp =>
    119         service.createFile(fp.fileName, fp.file, fp.mimeType)
    120       } map {
    121         f =>
    122           import dispatch._
    123           f().getStatusCode()
    124       }
    125 
    126       IdVerificationFiles(Nil)
    127 
    128       statusCodes.forall(_ == 200)
    129     }
    130   
    131   
    132   /**
    133    * Notifies us of a new user requesting their 
    134    * identification to be verified.
    135    * @param thirdParty if the user is requesting verification with 3rd party
    136    */
    137   def notifyIdentityRequest(user: User): Unit = {
    138     import net.liftweb.util.Mailer._
    139     
    140     val msgTxt =
    141       s"""
    142         |Identity Check Request!
    143         |Id: ${user.id.get}
    144         |Status: ${user.purchaseLimit.get}
    145         |Email: ${user.email.get}
    146       """
    147         
    148     sendMail(
    149       From(MongoAuth.systemFancyEmail),
    150       Subject("PYC: Identity Check"),
    151       To(Emails.idVerification),
    152       PlainMailBodyType(msgTxt)
    153     )
    154   }
    155 }