pyc-website

main website for pyc inc.

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

AtmRest.scala

(3480B)


      1 package inc.pyc
      2 package rest
      3 
      4 import model._
      5 import field._
      6 import net.liftweb._
      7 import common._
      8 import http._
      9 import rest._
     10 import util._
     11 import Helpers._
     12 import json._
     13 import JsonDSL._
     14 
     15 
     16 object AtmRest extends RestHelper {
     17   
     18   def init(): Unit = {
     19     LiftRules.dispatch.append(AtmRest)
     20   }
     21 
     22   /**
     23    * API for uploading files to server.
     24    */
     25   serve("api" / "atm" prefix {
     26       
     27       
     28     // /api/atm/{atm_id}/{atm_password}/user/{user_email}/{user_one-time_password}/login
     29     case id :: pw :: "user" :: email :: verifyPass :: "login" :: Nil JsonGet _ => 
     30       authenticate(id, pw, authenticateUser(email, verifyPass, sendUserInfo))
     31       
     32       
     33     // /api/atm/{atm_id}/{atm_password}/address/{bitcoin_address}/login
     34     case id :: pw :: "address" :: bitcoinAddress :: "login" :: Nil JsonGet _ => 
     35       authenticate(id, pw, User findByAddress (bitcoinAddress) map sendUserInfo openOr failure("User not found"))
     36       
     37       
     38     // /api/atm/{atm_id}/{atm_password}/phone/{phone_number}/login
     39     case id :: pw :: "phone" :: phoneNumber :: "login" :: Nil JsonGet _ => 
     40       authenticate(id, pw, User findByPhone (phoneNumber) map sendUserInfo openOr failure("User not found"))
     41       
     42       
     43       
     44     // /api/atm/{atm_id}/{atm_password}/create_user
     45     // - phone and email is required. 
     46     // - ID will be uploaded if any files are in the buffer.
     47     case id :: pw :: "create_user" :: Nil Post req =>
     48 
     49       import IdVerificationHelper._
     50       
     51       val user = User.createRecord.
     52       	email(req param "email" openOr "invalid").
     53       	phone(req param "phone" openOr "invalid").
     54       	purchaseLimit(USAPurchaseLimit.D3k).
     55       	username(Helpers.randomString(20)).
     56       	password(Helpers.randomString(20))
     57       	
     58       user.password.hashIt
     59       
     60       def uploadID: Boolean = {
     61         IdVerificationFiles(req.uploadedFiles)
     62         val service = s3(createS3Folder(user))
     63         upload(service)
     64       }          
     65             
     66       user.validate match {
     67         case Nil =>
     68           user.save() 
     69 
     70           if(uploadID) {
     71             user.purchaseLimit(USAPurchaseLimit.D10k_?)
     72             user.update
     73             notifyIdentityRequest(user)
     74             success()
     75           } else {
     76             User.sendLoginToken(user)
     77             failure("Failed to upload ID") ~ ("sentLoginToken" -> true)
     78           }         
     79           
     80         case errors =>
     81           failure("Invalid submission: "+
     82               errors.map(_.msg).mkString(", "))
     83       }
     84   })
     85 
     86   def authenticate(id: String, passwd: String, f: JValue) =
     87     for {
     88       atm <- Atm.findByStringId(id) ?~ "Invalid Credentials" ~> 401
     89       if atm.secret.isMatch(passwd)
     90     } yield f
     91     
     92   def authenticateUser(email: String, verifyPass: String, f: User => JValue) = 
     93     (for {
     94       user <- User.findByEmail(email) 
     95       if user.verifypass.get == verifyPass
     96     } yield {
     97       user.verifypass.reset.update
     98       f(user)
     99     }) openOr failure("Invalid Verification Credentials")
    100     
    101   def sendUserInfo(user: User): JValue = {
    102     success(
    103         ("fname" -> user.fname.get) ~ 
    104         ("lname" -> user.lname.get) ~
    105         ("email" -> user.email.get) ~
    106         ("purchaseLimit" -> user.userLimitAsInt))
    107   }
    108   
    109   def success(data: JValue = JNull) = response(true, data = data)
    110   def failure(reason: String) = response(false, reason = reason)
    111     
    112   def response(success: Boolean, data: JValue = JNull, reason: String = "") = 
    113     ("success" -> success) ~ ("data" -> data) ~ ("reason" -> reason)
    114 }