Sungwon Chung

Sungwon Chung@sungpi

Showing all posts tagged "Whoshungry"

HTTPS and SSL Certificate

HTTPS vs HTTP

HTTP stands for Hypertext Transfer Protocol. Which means, it is a protocol that we can use for transferring Hypertext datas. “S" in HTTPS stands for Over Secure Socket Layer. Intuitively, it’s secured HTTP protocol. HTTP sends data without encryption; hackers can easily eavesdrop data flowing between server and client.

HTTPS and SSL

HTTPS and SSL are not same concept as Internet and Web are not same. SSL protocol is more broad concept; HTTPS works on the SSL protocol.

SSL and TLS

Netscape developed SSL, but this term was redefined by IETF to TLS. However, no one cares and it is stilled called by SSL.

SSL Digital Certificate

Communication between client and server can be guaranteed by third person, and documented to SSL certificate. Right after client approaches server, server sends this certificate to client. Client examines whether is certificate is trustable and safe, then client processes next procedures. There we can earn benefits by SSL.

  • Hide information from eavesdropper
  • Client can determine if server is trustable or not
  • Both can assure if communication was changed in the middle or not

Citation

http://opentutorials.org/course/228

Setting AWS for Who’s Hungry?

1 Load Balancer
1 Web/App Server with Passenger
1 DB server ( postgreSQL )

Description of methods

Phone

Send Verification Message to User

  • method : POST
  • version : v1
  • URL : /v1/phone/sendsms
Description

You can use this method for sending verification SMS to user, with 6 random digit code

Parameters
  • contact
Constraints
  • contact : should be “+15129994336" form
Response

Simple text, “SENT"

Verify 6 digit number from SMS

  • method : POST
  • version : v1
  • URL : /v1/phone/verify
Description

You can use this method to verify SMS from our server.

Parameters
  • contact
  • code
Constraints
  • contact should be “+15129994336" form.
Response

“OK" if right, or “Wrong" if wrong.

User

Creates User

  • method : POST
  • version : v1
  • URL : /v1/users
Description

You can register user, using parameters above. This is exactly same as “Sign Up" that you can see everywhere on the website. You’ll use user_id from response for every single actions for Who’s Hungry? server

Parameters :
  • name : name of the user from facebook
  • picture : url of the profile picture from facebook
  • contact : user’s contact number
  • email : user’s email address
  • fb_id : facebook id of the user
  • access_token : access_token from Facebook login
  • os_type : iOS / android
  • push_id : push id of the device
Constraints
  • contact
    should be unique. If you try to make user with existing contact number, server will not allow any actions. you can use put method existing below.
Response
  • id : this is user_id
  • name
  • picture
  • contact
  • email
  • fb_id
  • created_at
  • updated_at
  • devices
    • id : this is device_id
    • user_id
    • os_type
    • push_id
    • created_at
    • updated_at

Show One User

  • method : GET
  • version : v1
  • URL : v1/{token}/user/{user_id}
Description
Parameter
Constraint
Response

see apiary

Update User

  • method : PUT
  • version : v1
  • URL : v1/{token}/users
Description
Parameter
Constraint
Response
  • id : this is user_id
  • name
  • picture
  • contact
  • email
  • fb_id
  • created_at
  • updated_at
  • devices
    • id : this is device_id
    • user_id
    • os_type
    • push_id
    • created_at
    • updated_at

Auth

login to the server

  • method : POST
  • version : v1
  • URL : /v1/auth
Descriptions

If access_token from the Facebook is expired, you should update user cause Who’s Hungry? server will never allow you to login. (It will never match data from the server)
Response token will allow you every single authorization towards the server.

Parameters
  • user_id : user_id of Who’s Hungry? server
  • access_token : access_token from facebook
Constraints

none

Response
  • user_id
  • id
  • login_type
  • token
  • created_at
  • updated_at

Group

Create Group

  • method : POST
  • version : v1
  • URL : /v1/{token}/groups
Descriptions

Creates group according to invitation. We invite through contact number, and

Parameters
  • invitation
    • fb_id or contact
    • fb_id or contact
    • fb_id or contact … (at least one contact number)
Constraints
  • token
    We need token to authorize user
  • contact
    Contact number should contain country code, ex : “+15129994336".
Response
  • id : id of group
  • user_id : admin user_id
  • name : name of the group
  • created_at
  • updated_at
  • users
    • id
    • fb_id
    • name
    • picture
    • contact
    • email
    • created_at
    • updated_at
    • devices
      • id : this is device_id
      • user_id
      • os_type
      • push_id
      • created_at
      • updated_at

Show groups where you belongs

  • method: GET
  • version: v1
  • url: v1/{token}/groups
Description

Get the list of groups that you’re belonging to

Parameters

none

Constraints

none

Responses

see apiary

Show one group

  • method: GET
  • version: v1
  • url: v1/{token}/group/{group_id}
Description
Parameters
Constraints
Responses

Vote

Create Vote

  • method : POST
  • version : v1
  • URL : /v1/{token}/{group_id}/votes
Description

Create “Vote" with information of votes, and known information with restaurants. Automatically creates “Choices" in the vote, and restaurants are automatically registered in the servers so you can use it.

Parameters
  • vote_type : vote type such as “lunch", “dinner" ...
  • name : name of the vote
  • expires_in : integer minute, which is, vote will expire in 10 minute => 10
  • expires_at : Datetime of expiring time of the vote
  • restaurants : JSON array of restaurants
    • place_id : id of restaurant(from google place API, yelp …)
    • name : name of restaurant
    • picture : url of profile pic of restaurant
    • lat : latitude
    • lng : longitude
    • rating : official rating
Constraints
Response
  • id : id of vote
  • group_id : id of group
  • vote_type
  • name
  • expires_in
  • expires_at
  • created_at
  • updated_at
  • choices
    • id
    • vote_id
    • restaurant_id
    • count
    • created_at
    • updated_at

Show one Vote

  • method: GET
  • version: v1
  • URL: v1/{token}/vote/{vote_id}
Description

show one vote

Parameters

none

Constraints

none

Response

Choices

View all the choices in the vote

  • method: GET
  • version: v1
  • URL: v1/{token}/{vote_id}/choices
Description

Look up all the choices that belongs to certain {vote_id}.

Parameters

none

Constraints

none

Response
  • choices
    • id
    • vote_id
    • restaurant_id
    • count
    • created_at
    • updated_at

Create new choice in the vote

  • method: POST
  • version: v1
  • URL: v1/{token}/{vote_id}/choices
Description

Create single choice under certain {vote_id}, which is adding a restaurant to vote.

Parameters
  • place_id
  • name
  • picture
  • lat
  • lng
  • rating
Constraints
Response
  • id
  • vote_id
  • restaurant_id
  • count
  • created_at
  • updated_at

Make a choice (make a vote)

  • method: PUT
  • version: v1
  • URL: v1/{token}/choice/{choice_id}
Description

Make a vote, with the count with given {choice_id} from other APIS.

Parameters
  • count : up vote? down vote?
Constraints
  • count
    should be {-1, 1}, one can remain in state {upvote, not voted, down vote }
Response
  • id
  • vote_id
  • restaurant_id
  • count
  • created_at
  • updated_at

Rsvp

Make a RSVP

  • method: POST
  • version: v1
  • URL: v1/{token}/{vote_id}/rsvps
Description

Make a Rsvp, and send push notification between devices so RSVP of the vote can remain updated.

Parameters
  • rsvp : integer (1: going, -1: not going, 0: default)
Constraints
Response
  • id
  • vote_id
  • user_id
  • rsvp
  • created_at
  • updated_at

Get one vote’s RSVP list

  • method: GET
  • version: v1
  • URL: v1/{token}/{vote_id}/rsvps
Description

Get all RSVPs from Vote

Parameters

none

Constraints
Response
  • rsvps : JSON array of rsvps
    • id
    • vote_id
    • user_id
    • rsvp
    • created_at
    • updated_at

Restaurant

Show one restaurant’s information

  • method: GET
  • version: v1
  • URL: v1/{token}/restaurant/{restaurant_id}
Description

Get all the information about the restaurant. {restaurant_id} either can be Who’s Hungry? server’s id or place_id

Parameter

none

Constraints
Response
  • id
  • place_id
  • name
  • picture
  • lat
  • lng
  • rating
  • created_at
  • updated_at

Location

Update user’s location

  • method: POST
  • version: v1
  • URL: v1/{token}/locations
Description

Update user’s location

Parameters
  • lat : latitude of the user
  • lng : longitude of the user
  • pickup : {1: “I want to be picked up", 2: “I am driving", 3: “I’m inviting you to my home"}
Constraints
Response
  • id
  • user_id
  • lat
  • lng
  • pickup
  • updated_at
  • created_at

Get Vote's location

  • method: GET
  • version: v1
  • URL: v1/{token}/{vote_id}/locations
Description

Get group’s location

Parameters

none

Constraints

“ I have a question :: Do we have to filter users that who RSVPed?"

Response
  • locations
    • id
    • user_id
    • lat
    • lng
    • pickup
    • updated_at
    • created_at

Lobby

See Lobby

  • method : POST
  • version : v1
  • URL: v1/{token}/lobbies
Description

Get lobby

Parameters
  • limit : limit of lobby {should send default :: 40}
  • offset : starting point {should send default :: 0}
Constraint

please send limit and offset

Response

JSON array of votes : chk document for vote

Chat

upload your chat

  • method : POST
  • version: v1
  • URL: v1/{token}/{vote_id}/chat
Description

Upload chat from the user to the server

Parameters
  • text
Constraint
Response

See all Chats

  • method : GET
  • version: v1
  • URL: v1/{token}/{vote_id}/chat
Description

See all the chats

Parameters

none

Contraint
Response

Overlap

Show one overlap

  • method : GET
  • version : v1
  • URL: v1/{token}/{choice_id}/overlap

DB Scheme for Who’s Hungry?

There’s two strong entity, User, Restaurant.
Any other tables are weak entities.

Abstract

User table hold data of user, including it’s Facebook id, name, profile picture, contact number. Device table belongs to User table, and saves User’s device data in case user has many devices, mainly exists for push notification. Session table exists for security issue, belongs to User table. Location table exists for saving user’s location, reason this table is separated is, for encrypting issue. Group table exists to re-use the group that people made. Crew table exists holding data between User and Group, for N to N relationship. Vote table is for every single information of votes besides information of restaurant. Choice table holds data between Restaurant and Vote table, for counting issue. (to be updated)

User
Device
Restaurant
Group
Vote
Location
Auth
Subscription
Crew
Rsvp
Chat
Choice
Rating

User

  • id : PK
  • fb_id : string indexed Facebook_id*
  • name : string Name of the user
  • picture : string URL of the user’s profile picture
  • contact : string indexed Phone number of the user*
  • created_at : datetime
  • updated_at : datetime

Device

Belongs to User

  • id : PK id of device in our server
  • os_type : string {ios, android, web} default : web
  • push_id : string push_id
  • (user_id)
  • created_at
  • updated_at

Restaurant

  • id : PK id of restaurant in our server, not Google Place API
  • place_id : string indexed id of restaurant in Google Place API
  • lat : float Latitude of the restaurant location
  • lng : float Longitude of the restaurant location
  • name : string Name of the restaurant
  • rating : float Rating of the restaurant
  • created_at
  • updated_at

Group

  • id : PK
  • lead_user_id : user_id Leader of the group
  • name : string NULL
  • created_at
  • updated_at

Vote

  • id : PK
  • (group_id) :
  • type : string {lunch, dinner, cafe, bar}
  • name : string Name of the vote
  • expires_in : integer Expires in # minute
  • winner: restaurant_id FK to restaurant(id)
  • expires_at : datetime
  • created_at
  • updated_at

Location

  • id : PK
  • (user_id)
  • lat : float
  • lng : float

Auth

Belongs to User

  • user_id
  • login_type
  • token
  • created_at
  • updated_at

Subscription (User-User)

Use to look up mutual friends, invitation, etc..
Recursive relations between User

  • id : PK
  • friend_from : user_id indexed
  • friend_to : user_id

Crew (User- Group)

Belongs to User and Group

  • id
  • user_id
  • group_id

Rsvp (User-Vote)

Belongs to User and Vote

  • id
  • user_id
  • vote_id
  • rsvp : integer {1: going, -1: not going, 0: Dunno}

Chat (User-Vote)

Belongs to User and Vote

user_id
vote_id
chat : text
created_at
*updated_at

Choice (Vote-Restaurant)

Belongs to User and Restaurant

  • restaurant_id
  • user_id
  • count

Rating (User-Restaurant)

Belongs to User and Restaurant

  • restaurant_id
  • user_id
  • rating

Development Environment for Who’s Hungry?

1. Setting up Ruby

visit

http://rvm.io

and install RVM through curl.
‘’'bash

$ \curl -sSL https://get.rvm.io | bash -s stable

‘''
Then, you enable bash_profile for later install.

$ source .bash_profile

We’re currently using Ruby 2.2.0 version, therefore

$ rvm install 2.2.0

2. Setting up Rails

Install rails 4.2.0 , with command (with out documentations, and two “-“s in front of no)
‘’’bash
gem install rails —no-ri —nordoc
‘''

3. Install PostgreSQL

brew install postgresql

To have launchd start postgresql at login:

ln -sfv /usr/local/opt/postgresql/*.plist ~/Library/LaunchAgents

Then to load postgresql now:

launchctl load ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist

Or, if you don't want/need launchctl, you can just run:

postgres -D /usr/local/var/postgres

What is Load Balancer

This article is for deciding server stacks, for Who's Hungry?, and to help other startup backend developers if possible.

Cipher Block Chaining Mode

CBC

To encrypt using this mode, a uniform initialization vector (IV) of length $n$ is first chosen. Then, cipher text blocks are generated by applying the block cipher to XOR of the current plaintext block and the previous ciphertext block. That is, set $c_0$ := IV and then for i = 1 to $l$, set $c_i$ := $F_k$ ($c_{i-1} \xor m_i$). The final