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 +7 -0
- data/lib/omniauth/bokun/signed_request.rb +43 -0
- data/lib/omniauth/bokun/version.rb +5 -0
- data/lib/omniauth/bokun.rb +2 -0
- data/lib/omniauth/strategies/bokun.rb +110 -0
- metadata +118 -0
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,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: []
|