require 'active_support/concern' require 'oauth2' module ShopliftClient extend ActiveSupport::Concern included do attr_reader :authentication attr_reader :api_key attr_reader :current_user attr_reader :current_company end class_methods do end def session_cookie session["authlift_session_id"] end def session_cookie=(new_value) session["authlift_session_id"] = new_value end def redirect_unauthorized session.clear session[:previous_url] = request.fullpath redirect_to client.auth_code.authorize_url( redirect_uri: Rails.configuration.settings['authlift_redirect_uri'], scope: scope) end def scope [Rails.configuration.settings['authlift_default_scope'], 'public'].compact.join ' ' end def find_company_by_code(code) begin @current_company ||= Company.find_or_create_by! code: code rescue ActiveRecord::StatementInvalid if $!.cause.is_a? PG::UndefinedTable fail <<-ERROR.strip_heredoc You have not defined a company, and that is compulsory even if you are not planning to add any additional fields. You do not need to seed it, so following is enough forever: rails g model company code:string; rake db:migrate ERROR end end end def authenticate_user! if session_cookie.present? @token = OAuth2::AccessToken.new client, session_cookie, scope: scope begin x = srv.get '/api/users/profile' @current_user = JSON.parse x.response.body find_company_by_code current_user['company']['code'] rescue OAuth2::Error redirect_unauthorized end else redirect_unauthorized end end def authenticate_company! @api_key = if params['key'].present? params['key'].match(/[0-9a-f]+/).to_s elsif request.headers['AUTHORIZATION'].present? request.headers['AUTHORIZATION'].gsub(/^Bearer ?/, '') else Rails.configuration.settings['authlift_default_app_key'] end fail ActionController::RoutingError, 'Authentication token missing' if @api_key.blank? response = srv.post 'auth/api_key', body: { api_key: api_key, requested_action: "#{self.controller_name}##{self.action_name}" } fail ActionController::RoutingError, 'Request not authorized' if response.blank? @authentication = JSON.parse response.body find_company_by_code authentication['company'] end def current_user return @current_user if @current_user.present? @current_user end def current_company end def user_signed_in? !current_user.nil? end # To create/update a model, params must be of form { model_name: { attr1: value1, attr2: value2 } } # and attr1, attr2 must be in the list of allowed params the Rails way. def post(url, params) puts 'co_cli: post' puts "url: #{url}" puts "params: #{params}" response = srv.request(:post, url, body: params) JSON.parse(response.body) rescue OAuth2::Error raise "Server fault, could not perform post to #{srv.client.site}#{url}" rescue raise "Unknown error, could not perform post to #{srv.client.site}#{url}" end def get(url, params = {}) puts 'co_cli: get' puts "url: #{url}" puts "params: #{params}" response = srv.request(:get, url, body: params) JSON.parse(response.body) rescue OAuth2::Error raise "Server fault, could not perform post to #{srv.client.site}#{url}" rescue raise "Unknown error, could not perform post to #{srv.client.site}#{url}" end def srv @token ||= client.client_credentials.get_token scope: scope end def client @oauth ||= OAuth2::Client.new Rails.configuration.settings['authlift_app_id'], Rails.configuration.settings['authlift_app_secret'], site: Rails.configuration.settings['authlift_url'] end end