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 }