Skip to content

madcato/API-LiShop

Repository files navigation

Build Status codecov.io codebeat badge

LiShop server specification

Synchronization API

Design

  • For the main resource (Article) use a RESTful API
  • Many users or devices can access the same LIST_ID with its own API_KEY.
  • The owner could remove any API_KEY that has access to its LIST_ID.
  • The owner could request a new API_KEY and share it with other user to let them access to his list.
  • Each API_KEY should be used by only one user. But the same API_KEY can be set in several devices.
  • LIST_ID numbers never will leave ther server.

Model

  • List
    • list_id
    • paymentIdentifier
    • receipt
    • creationDate
    • modificationDate

$ rails g scaffold List

  • ApiKey:
    • list_id
    • api_key
    • email
    • owner
    • creationDate
    • modificationDate

$ rails g scaffold ApiKey list_id:integer api_key:string email:string owner:boolean

  • Article
    • list_id
    • name
    • qty
    • category
    • type
    • shop
    • prize
    • checked

$ rails g scaffold Article list_id:integer name:string qty:string category:string type:string shop:string prize:string checked:string

Entry points

  • Article RESTful CRUD. RESTful API
    To access this resource with any of its URL, the client must specify its API_KEY in the http header: "api_key" = "<API_KEY>"
    if api_key doesn't exits or it's not present in the query, the response will be -> http_status: 401, responseBody: "Unauthorized"
    Sample URL:

- recoverApiKey To recover forgotten accounts.
The user will receive and email with his API_KEY
* Request parameters:
- email
* Responses:
- On OK -> http_status: 200, responseBody: <empty/>
- If email parameter not indicated -> http_status: 400, responseBody: "email parameter required" - If email not found -> http_status: 404, responseBody: "email not found"

  • requestNewApiKey To invite a new user to access owner list.
    The user will receive a new API_KEY that must send to the invited user. Doing this way is the owner how send the email in its own name.
    Only the list owner can invite others users.

    • http header
      • api_key
    • Request parameters:
      • email
    • Responses:
      • On OK -> http_status: 200, responseBody: { "api_key" : "<API_KEY>"}
      • If email not indicated -> http_status: 400, responseBody: "email parameter required"
      • If api_key not indicated or not found -> http_status: 401, responseBody: "Unauthorized"
      • if api_key is not the owner -> http_status: 403, responseBody: "Forbidden"
  • removeApiKey To close access to other user.

    • http header
      • api_key
    • Request parameters:
      • sharedApiKey
    • Responses:
      • On OK -> http_status: 200, responseBody:[ "api_key": { "api_key" : "<API_KEY1>", "email" : "<email1>"}, "api_key": { "api_key" : "<API_KEY2>", "email" : "<email2>"}]
      • If sharedApiKey not indicated -> http_status: 400, responseBody: "sharedApiKey parameter required"
      • If sharedApiKey not found -> http_status: 404, responseBody: "sharedApiKeynot found"
      • If api_key not indicated or not found -> http_status: 401, responseBody: "Unauthorized"
      • if api_key is not the owner -> http_status: 403, responseBody: "Forbidden"
  • registerAccount To create or recover an account.
    The user must specify the receipt to demostrate the new account payment. If it's the first time accesing, a new list will be created. If the account was previously created, only it's API_KEY is returned. But each time is called this method, a new API_KEY must be generated for security.

    • Request parameters:
      • paymentIdentifier
      • receipt
    • Responses:
      • On OK -> http_status: 200, responseBody: { "api_key" : "<API_KEY>"}
      • If any parameter is not indicated -> http_status: 400, responseBody: "<param> parameter required"
      • If paymentIdentifier not found -> http_status: 404, responseBody: "receipt not found"
  • sharedApiKey Return the shared keys and its emails. The owner user API_KEY is not returned.

    • http header
      • api_key
    • Request parameters:
    • Responses:
      • On OK -> http_status: 200, responseBody: [ "api_key": { "api_key" : "<API_KEY1>", "email" : "<email1>"}, "api_key": { "api_key" : "<API_KEY2>", "email" : "<email2>"}]
      • If api_key not indicated or not found -> http_status: 401, responseBody: "Unauthorized"
      • if api_key is not the owner -> http_status: 403, responseBody: "Forbidden"

- verifyReceipt See section "Receipt verification using App Store" * Request parameters:
- receipt The base64 encoded receipt data. - deviceIdentifier UUID base64 encoded. Unique identifier of the device. - debug Optional. If set to any value, use sandbox varification. * Responses:
- On OK -> http_status: 200, responseBody: <empty/> - If receipt is not indicated -> http_status: 400, responseBody: "receipt parameter required" - If deviceIdentifier is not indicated -> http_status: 400, responseBody: "deviceIdentifier parameter required"

- deleteList Remove all the data of a list. This method will be called if the user don't want to use/pay for the service. The API_KEY must be associated to the owner. * http header - api_key * Request parameters:
* Responses:
- On OK -> http_status: 200, responseBody: <empty/> - If api_key not indicated or not found -> http_status: 401, responseBody: "Unauthorized"
- if api_key is not the owner -> http_status: 403, responseBody: "Forbidden"

Security

  • Users with a valid API_KEY will access to its LIST_ID. Required.
  • Each client could create new API_KEY for sharing his list with other users.
  • To recover forgotten API_KEY, the user will have a button to request his API_KEY using his email.
  • SSL: create an owned ssl certificate signed by a personal CA and use it in local to verify. Or verify server certificate with its MD5.

API Versioning

The version of the API will be indicated in the url.

Sample:

http://api.server.com/2.0/articles.js

But first one will not have a code: http://api.server.com/articles.js

Receipt verification using App Store

Launch this verification method asynchronously.
This method is called when a client call the API method "registerAccount".
Make an http call to https://buy.itunes.apple.com/verifyReceipt or https://sandbox.itunes.apple.com/verifyReceipt for debugging.

Send the receipt data to the App Store

Create a JSON object with the following keys:

  • receipt-data The base64 encoded receipt data.
  • password Only used for receipts that contain auto-renewable subscriptions. Your app’s shared secret (a hexadecimal string).

Parse the Response

The response’s payload is a JSON object that contains the following keys and values:

  • status Either 0 if the receipt is valid, or one of the error codes listed in Error Table
  • receipt A JSON representation of the receipt that was sent for verification

Error table

  • 21000 The App Store could not read the JSON object you provided.
  • 21002 The data in the receipt-data property was malformed or missing.
  • 21003 The receipt could not be authenticated.
  • 21004 The shared secret you provided does not match the shared secret on file for your account. Only returned for iOS 6 style transaction receipts for auto-renewable subscriptions.
  • 21005 The receipt server is not currently available.
  • 21006 This receipt is valid but the subscription has expired. When this status code is returned to your server, the receipt data is also decoded and returned as part of the response. Only returned for iOS 6 style transaction receipts for auto-renewable subscriptions.
  • 21007 This receipt is from the test environment, but it was sent to the production environment for verification. Send it to the test environment instead.
  • 21008 This receipt is from the production environment, but it was sent to the test environment for verification. Send it to the production environment instead.

Steps to install and configure the server

Is obligatory to define three environment veriables to run de server in production and development:

  • LISHOP_API_SECRET any large string can be used
  • LISHOP_INVITATION_MAIL gmail account
  • LISHOP_INVITATION_PASSWORD password for sending mails

In test mode only LISHOP_API_SECRET is needed

Backup and restore methods

See document: "OpenShift management"

To prevent attacks from internet

To prevent brute force attacks, develop the following:

For services using api_key as authentication system.

To prevent brute force can do the following:

  • Save the IP of the peer.
  • Save the last date of the IP connection.
  • Save the last api_key of that IP.

If at some time you contacted different api_key. It is a brute force attack, there must cancel.

To prevent attacks of DOS

Count the numbers of connections per second. If there are many, cancel.

Server

Use OpenShift. non-scalable Rails 4 app with MySql 5.1

How to scale

See document: "OpenShift management"

Rails status

  • 400 => :bad_request
  • 401 => :unauthorized
  • 402 => :payment_required
  • 403 => :forbidden
  • 404 => :not_found

Installation

Define the API_LISHOP_SECRET to define the secret API key to create accounts

export LISHOP_API_SECRET="XXXXXXXXXXXXXXXX"

Execute bundle in production enviroment

bundle install --without postgresql mysql

Execute bundle in development enviroment

bundle install --without postgresql mysql production

About

API to allow LiShop users to share their article lists

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •