Low commit activity in last 3 years
There's a lot of open issues
A long-lived project that still receives updates
A Rails engine to simplify building BookingSync Applications
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies
 Project Readme

Code Climate Build Status

BookingsyncApplication

A Rails engine to simplify building BookingSync Applications.

Requirements

For version <= 4.1 Rails >= 5.0 and Ruby >= 2.3 For version >= 4.2 Rails >= 6.0 and Ruby >= 3.0

Documentation

API documentation is available at rdoc.info.

Installation

gem 'bookingsync_application'

Then bundle install:

bundle install

Usage

BookingSync Application relies heavily on BookingSync-Engine. Have a look at the project for more options.

Add authorization routes

Then mount BookingSync Authorization routes inside routes.rb:

mount BookingSync::Engine => '/'

This will add the following routes:

  • /auth/bookingsync/callback
  • /auth/failure
  • /signout

Add a model to link with BookingSync accounts

BookingSync Application uses the Account model to authenticate each BookingSync Account, if you do not have an Account model yet, create one:

rails g model Account

Then, generate a migration to add OAuth fields for the Account class:

rails g migration AddOAuthFieldsToAccounts provider:string synced_id:integer:index \
  name:string oauth_access_token:string oauth_refresh_token:string \
  oauth_expires_at:string

and migrate:

rake db:migrate

Also include BookingSync::Engine::Models::Account in your Account model:

class Account < ActiveRecord::Base
  include BookingSync::Engine::Models::Account
end

Secure controllers to require a BookingSync authorized account

We now want to provide secured controllers, this controllers will be accessible only to BookingSync identified accounts.

You have 2 options pre built for this:

  1. Create base API controller (it will be json based):
class Api::BaseController < BookingsyncApplication::Api::BaseController
end
  1. Optionally if you want to have html based controller:
class Admin::BaseHTMLController < ApplicationController
  respond_to :html

  include BookingsyncApplication::Controllers::CommonBase
end

Note: When saving new token, this gem uses a separate thread with new db connection to ensure token save (in case of a rollback in the main transaction). To make room for the new connections, it is recommended to increase db pool size by 2-3.

BookingSync Universe API

You can expose the application API by taking advantage of BookingSync Universe API concept. BookingSync Universe API is about making all the APIs accessible by the same token that is acquired in standard OAuth flow as outlined in the docs. The authentication is handled on BookingSync Core API, but the authorization is up to the application to handle.

To enable BookingSync Universe API for the controller, include BookingsyncApplication::Controllers::BookingsyncUniverseApiAccess module:

class Api::ControllerForBookingsyncUniverseApi < BookingsyncApplication::Api::BaseController
  include BookingsyncApplication::Controllers::BookingsyncUniverseApiAccess

  def index
    head 200
  end
end

If the request includes Authorization header (you can read more about the expected format in the docs), it will be proxied to BookingSync Core API to check if the token is valid or not. If the token is not valid, 401 error will be returned with the corresponding error in the body. If it's valid, the account that is the owner of the token will be authenticated. By default there is no any extra authorization layer and as long as BookingSync Universe API is enabled all the endpoints will be accessible. To handle authorization you can use bookingsync_universe_authorize_request! method:

class Api::ControllerForBookingsyncUniverseApi < BookingsyncApplication::Api::BaseController
  include BookingsyncApplication::Controllers::BookingsyncUniverseApiAccess

  before_action -> { bookingsync_universe_authorize_request! :clients_read, :clients_write },
    only: :index

  def index
    head 200
  end
end

bookingsync_universe_authorize_request! expects the list of scopes that are required to access this endpoint. If at least one of them is present on the token, the request will be authorized. Otherwise 403 error will be returned with the corresponding error message in the body.

Configuration

The engine is configured by the following ENV variables:

  • BOOKINGSYNC_URL - the url of the website, should be
  • BOOKINGSYNC_APP_ID - BookingSync Application's Client ID
  • BOOKINGSYNC_APP_SECRET - BookingSync Application's Client Secret
  • BOOKINGSYNC_VERIFY_SSL - Verify SSL (available only in development or test). Default to false
  • BOOKINGSYNC_SCOPE - Space separated list of required scopes. Defaults to nil, which means the public scope.

You might want to use dotenv-rails to make ENV variables management easy.

Testing

RSpec

We do provide some helper for RSpec users, you can include them in your spec/rails_helper.rb (before spec/support inclusion):

require 'bookingsync_application/spec_helper'

VCR

We recommend a VCR setup inspired from the following configuration. It will mask authorization tokens from your fixtures:

require 'vcr'

VCR.configure do |config|
  config.cassette_library_dir = 'spec/fixtures/cassettes'
  config.hook_into :webmock
  config.configure_rspec_metadata!
  config.filter_sensitive_data('BOOKINGSYNC_OAUTH_ACCESS_TOKEN') do
    ENV['BOOKINGSYNC_OAUTH_ACCESS_TOKEN']
  end
  # Uncomment if using codeclimate
  # config.ignore_hosts 'codeclimate.com'
end