omniauth-bokun 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f9a6491b34fbd258d3b37409faa99049032941b6fa430d5758decd2d32b493c8
4
+ data.tar.gz: f338b2a14fa2e2f4f84e85748c7c42695571bd70a22579c9d25492197c8ba571
5
+ SHA512:
6
+ metadata.gz: 43d44a58c0643e2d18bbd88c258e56aaf00492ec45b3841b9772a36421f747d90cbb9c669264b4a300be6a5e29262107799e459498f9aaa12db0ca7d48c97944
7
+ data.tar.gz: 350e8069d8138dffa6e172aaa16735a397c0d0f11c07ab6247d40b031f0eccbeb013882ba8b2cbcd7e250fb2642cc7ae1cf4ad35768fa81b5ac4665b4e16d575
@@ -0,0 +1,43 @@
1
+ require 'openssl'
2
+
3
+ module OmniAuth
4
+ module Bokun
5
+ class SignedRequest
6
+ attr_reader :params, :secret
7
+
8
+ def initialize(params, secret)
9
+ @params = params
10
+ @secret = secret
11
+ end
12
+
13
+ def valid_signature?
14
+ ActiveSupport::SecurityUtils.secure_compare(digest, hmac_value)
15
+ end
16
+
17
+ private
18
+
19
+ def hmac_value
20
+ hmac_value ||= CGI.unescape(params['hmac'].to_s)
21
+ end
22
+
23
+ def digest
24
+ digest ||= OpenSSL::HMAC.hexdigest(
25
+ 'sha256',
26
+ secret,
27
+ verification_string
28
+ )
29
+ end
30
+
31
+
32
+ def verification_params
33
+ @verification_params ||= params.to_h
34
+ .except('hmac', 'controller', 'action', 'format')
35
+ .sort.to_h
36
+ end
37
+
38
+ def verification_string
39
+ @verification_string ||= verification_params.map { |k, v| "#{k}=#{v}" }.join('&')
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,5 @@
1
+ module Omniauth
2
+ module Bokun
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,2 @@
1
+ require "omniauth/bokun/version"
2
+ require 'omniauth/strategies/bokun'
@@ -0,0 +1,110 @@
1
+ require 'omniauth/strategies/oauth2'
2
+ require 'omniauth/bokun/signed_request'
3
+
4
+ module OmniAuth
5
+ module Strategies
6
+ class Bokun < OmniAuth::Strategies::OAuth2
7
+ class NoAuthorizationCodeError < StandardError; end
8
+ option :name, 'bokun'
9
+ option :authorize_options, [:scope, :state, :redirect_uri]
10
+ option :client_options, {
11
+ authorize_url: '/appstore/oauth/authorize',
12
+ token_url: '/appstore/oauth/access_token'
13
+ }
14
+ option :authorize_params, {
15
+ scope: 'BOOKINGS_READ,BOOKINGS_WRITE,CUSTOMERS_READ,CUSTOMERS_WRITE',
16
+ state: SecureRandom.hex(24),
17
+ redirect_uri: "https://#{ENV['BOKUN_REDIRECT_DOMAIN']}/users/auth/bokun/callback"
18
+ }
19
+ option :token_params, {
20
+ client_id: ENV['BOKUN_ID'],
21
+ client_secret: ENV['BOKUN_SECRET']
22
+ }
23
+
24
+ uid { Base64.decode64(access_token.params['vendor_id']).split(':').last }
25
+
26
+ info do
27
+ {
28
+ first_name: access_token.params['appInstalledByUserFirstName'],
29
+ last_name: access_token.params['appInstalledByUserLastName'],
30
+ email: access_token.params['appInstalledByUserEmail'],
31
+ vendor_id: access_token.params['vendor_id'],
32
+ scope: access_token.params['scope']
33
+ }
34
+ rescue NoMethodError
35
+ Rails.logger.error "[Bokun] Failed to fetch user info from access token"
36
+ {}
37
+ end
38
+
39
+ def client
40
+ options.client_options.merge!(
41
+ site: "https://#{subdomain}.#{domain}"
42
+ )
43
+ super
44
+ end
45
+
46
+ def request_phase
47
+ unless OmniAuth::Bokun::SignedRequest.new(request.params, options.client_secret).valid_signature?
48
+ Rails.logger.warn "[Bokun] HMAC verification failed"
49
+ return fail!(:invalid_credentials)
50
+ end
51
+ super
52
+ end
53
+
54
+ def build_access_token
55
+ token_params = options.token_params.merge(
56
+ code: authorization_code,
57
+ redirect_uri: callback_url
58
+ )
59
+
60
+ response = client.request(:post, options.client_options.token_url, {
61
+ body: URI.encode_www_form(token_params),
62
+ headers: { 'Content-Type' => 'application/x-www-form-urlencoded' }
63
+ })
64
+
65
+ parsed_response = JSON.parse(response.body)
66
+
67
+ @access_token = ::OAuth2::AccessToken.from_hash(client, parsed_response)
68
+ rescue ::OAuth2::Error => e
69
+ Rails.logger.error "[Bokun] Token exchange failed: #{e.message}"
70
+ Rails.logger.error "[Bokun] Response body: #{e.response.body}" if e.respond_to?(:response)
71
+ raise e
72
+ end
73
+
74
+ def callback_url
75
+ options.authorize_params[:redirect_uri] || super
76
+ end
77
+
78
+ private
79
+
80
+ def authorization_code
81
+ @authorization_code ||= request.params['code']
82
+ end
83
+
84
+ def session
85
+ @session ||= request.session
86
+ end
87
+
88
+ def origin_host
89
+ raw_origin = request.env['omniauth.origin'] || session['omniauth.origin']
90
+ @origin_host ||= URI.parse(raw_origin.to_s).host
91
+ rescue URI::InvalidURIError, NoMethodError
92
+ nil
93
+ end
94
+
95
+ def domain
96
+ @domain ||=
97
+ if origin_host&.include?('bokuntest.com')
98
+ 'bokuntest.com'
99
+ else
100
+ 'bokun.io'
101
+ end
102
+ end
103
+
104
+ def subdomain
105
+ # Yes, Bokun did not name their subdomain param properply. We can work with it :)
106
+ @subdomain ||= request.params['domain']
107
+ end
108
+ end
109
+ end
110
+ end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: omniauth-bokun
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Dmitry Sychev
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2025-04-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: omniauth
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: omniauth-oauth2
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.8'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.8'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '5.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '5.0'
83
+ description: An unofficial OmniAuth strategy for Bokun, allowing authentication via
84
+ Bokun's OAuth2 API.
85
+ email:
86
+ - dmitry.sychev@me.com
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - lib/omniauth/bokun.rb
92
+ - lib/omniauth/bokun/signed_request.rb
93
+ - lib/omniauth/bokun/version.rb
94
+ - lib/omniauth/strategies/bokun.rb
95
+ homepage: https://github.com/DmitrySychev/omniauth-bokun
96
+ licenses:
97
+ - MIT
98
+ metadata: {}
99
+ post_install_message:
100
+ rdoc_options: []
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubygems_version: 3.0.3.1
115
+ signing_key:
116
+ specification_version: 4
117
+ summary: unofficial omniauth strategy for Bokun
118
+ test_files: []