omniauth-desk 0.1.7 → 0.2.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 +4 -4
- data/Gemfile +2 -1
- data/Rakefile +2 -1
- data/lib/omniauth-desk.rb +2 -1
- data/lib/omniauth-desk/version.rb +1 -1
- data/lib/omniauth/desk/signed_request.rb +56 -0
- data/lib/omniauth/strategies/desk.rb +38 -5
- data/omniauth-desk.gemspec +0 -1
- data/spec/omniauth/desk/signed_request_spec.rb +37 -0
- data/spec/omniauth/strategies/desk_spec.rb +38 -9
- data/spec/spec_helper.rb +2 -0
- metadata +5 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 613f20bbbfc3140cd48a42ff218cb7c3cdf50e26
|
4
|
+
data.tar.gz: 7c420f92b70dd824d03e17d9c787a62e692f3f5b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 20a44bfddbb942944e4c1bc4a60523a4ab1ac09d74663f053eef626864f05f2878a1a9d3d58f126be99203c5cf1574a96224de0a3b7b75129a214a34ad9265a6
|
7
|
+
data.tar.gz: e212d3b6c938b031f9c9da1d681cea0c30008b55728a03e59c1056fa6a2eeb6c7d039dd2a4c43f673a9cb14d9fad5cb02dc60cb7d511a72ca4161d498b42b9df
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
data/lib/omniauth-desk.rb
CHANGED
@@ -0,0 +1,56 @@
|
|
1
|
+
module OmniAuth
|
2
|
+
module Desk
|
3
|
+
module SignedRequest
|
4
|
+
ALGORITHM = 'HMACSHA256'.freeze
|
5
|
+
class Error < ArgumentError; end
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def decode(str, options = {})
|
9
|
+
shared_secret = options[:shared_secret] || ENV['DESK_SHARED_SECRET']
|
10
|
+
signature, envelope = str.split('.', 2)
|
11
|
+
hash = JSON.parse(base64_decode(envelope))
|
12
|
+
|
13
|
+
if hash['algorithm'] != ALGORITHM
|
14
|
+
raise Error.new("Invalid algorithm, use `#{ALGORITHM}`.")
|
15
|
+
end
|
16
|
+
|
17
|
+
if compare_time(hash['expiresAt'])
|
18
|
+
raise Error.new("Expired request.")
|
19
|
+
end
|
20
|
+
|
21
|
+
if base64_decode(signature) != hex(shared_secret, envelope).split.pack('H*')
|
22
|
+
raise Error.new("Invalid signature.")
|
23
|
+
end
|
24
|
+
|
25
|
+
hash
|
26
|
+
end
|
27
|
+
|
28
|
+
def encode(hash, options = {})
|
29
|
+
shared_secret = options[:shared_secret] || ENV['DESK_SHARED_SECRET']
|
30
|
+
envelope = base64_encode(JSON.generate(hash))
|
31
|
+
signature = base64_encode(hex(shared_secret, envelope).split.pack('H*'))
|
32
|
+
signature + '.' + envelope
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def compare_time(str)
|
38
|
+
Time.parse(str).to_i < Time.now.to_i
|
39
|
+
end
|
40
|
+
|
41
|
+
def hex(secret, data)
|
42
|
+
OpenSSL::HMAC.hexdigest('sha256', secret, data)
|
43
|
+
end
|
44
|
+
|
45
|
+
def base64_decode(str)
|
46
|
+
str += '=' * (4 - str.length.modulo(4))
|
47
|
+
Base64.decode64(str.tr('-_', '+/'))
|
48
|
+
end
|
49
|
+
|
50
|
+
def base64_encode(str)
|
51
|
+
Base64.strict_encode64(str).tr('+/', '-_').tr('=', '')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'omniauth-oauth'
|
2
|
-
require 'multi_json'
|
3
2
|
require 'uri'
|
4
3
|
|
5
4
|
module OmniAuth
|
@@ -8,7 +7,8 @@ module OmniAuth
|
|
8
7
|
class Desk < OmniAuth::Strategies::OAuth
|
9
8
|
option :name, 'desk'
|
10
9
|
option :site, nil
|
11
|
-
option :site_param, '
|
10
|
+
option :site_param, 'site'
|
11
|
+
option :shared_secret, nil
|
12
12
|
option :client_options, {
|
13
13
|
:authorize_path => '/oauth/authorize',
|
14
14
|
:request_token_path => '/oauth/request_token',
|
@@ -38,7 +38,11 @@ module OmniAuth
|
|
38
38
|
|
39
39
|
# Return info gathered from the verify_credentials API call
|
40
40
|
def raw_info
|
41
|
-
|
41
|
+
if access_token
|
42
|
+
@raw_info ||= JSON.parse(access_token.get('/api/v2/users/me').body)
|
43
|
+
elsif signed_request
|
44
|
+
@raw_info ||= decode(signed_request)
|
45
|
+
end
|
42
46
|
rescue ::Errno::ETIMEDOUT
|
43
47
|
raise ::Timeout::Error
|
44
48
|
end
|
@@ -48,6 +52,25 @@ module OmniAuth
|
|
48
52
|
@user_info ||= raw_info.nil? ? {} : raw_info
|
49
53
|
end
|
50
54
|
|
55
|
+
def decode(signed_request)
|
56
|
+
hash = OmniAuth::Desk::SignedRequest.decode(
|
57
|
+
signed_request, shared_secret: options.shared_secret
|
58
|
+
)['context']['user']
|
59
|
+
|
60
|
+
{
|
61
|
+
'id' => hash['userId'],
|
62
|
+
'name' => hash['fullName'],
|
63
|
+
'public_name' => hash['fullName'],
|
64
|
+
'email' => hash['email'],
|
65
|
+
'avatar' => hash['profileThumbnailUrl'],
|
66
|
+
'level' => hash['userType']
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
def signed_request
|
71
|
+
@signed_request ||= request.params['signed_request']
|
72
|
+
end
|
73
|
+
|
51
74
|
def identifier
|
52
75
|
session[:site] = options.client_options.site = options.site || validate_site(request.params[options.site_param.to_s])
|
53
76
|
session[:site] = options.client_options.site = nil if options.client_options.site == ''
|
@@ -80,8 +103,18 @@ module OmniAuth
|
|
80
103
|
end
|
81
104
|
|
82
105
|
def callback_phase
|
83
|
-
|
84
|
-
|
106
|
+
if signed_request.nil?
|
107
|
+
options.client_options.site = session[:site] if session[:site]
|
108
|
+
super
|
109
|
+
else
|
110
|
+
env['omniauth.auth'] = AuthHash.new({
|
111
|
+
provider: name,
|
112
|
+
uid: uid,
|
113
|
+
info: info,
|
114
|
+
extra: extra
|
115
|
+
})
|
116
|
+
call_app!
|
117
|
+
end
|
85
118
|
end
|
86
119
|
end
|
87
120
|
end
|
data/omniauth-desk.gemspec
CHANGED
@@ -20,7 +20,6 @@ Gem::Specification.new do |s|
|
|
20
20
|
|
21
21
|
s.add_runtime_dependency 'omniauth', '>= 1.0'
|
22
22
|
s.add_runtime_dependency 'omniauth-oauth', '>= 1.0'
|
23
|
-
s.add_runtime_dependency 'multi_json', '>= 1.3.6'
|
24
23
|
|
25
24
|
s.add_development_dependency 'rspec', '~> 3.5'
|
26
25
|
s.add_development_dependency 'rack-test'
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'omniauth/desk/signed_request'
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
describe OmniAuth::Desk::SignedRequest do
|
6
|
+
let(:shared_secret) { SecureRandom.uuid.gsub('-', '') }
|
7
|
+
let(:working) { { "expiresAt" => (Time.now + 10*60).iso8601, "algorithm" => "HMACSHA256" } }
|
8
|
+
let(:unsupported) { working.merge({ "algorithm" => "HMACSHA512" }) }
|
9
|
+
let(:too_old) { working.merge({ "expiresAt" => (Time.now - 1).iso8601 }) }
|
10
|
+
|
11
|
+
it 'encodes a valid request' do
|
12
|
+
encoded = OmniAuth::Desk::SignedRequest.encode(working, shared_secret: shared_secret)
|
13
|
+
decoded = OmniAuth::Desk::SignedRequest.decode(encoded, shared_secret: shared_secret)
|
14
|
+
expect(decoded).to eq(working)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'throws an unsupported algorithm error' do
|
18
|
+
expect do
|
19
|
+
encoded = OmniAuth::Desk::SignedRequest.encode(unsupported, shared_secret: shared_secret)
|
20
|
+
OmniAuth::Desk::SignedRequest.decode(encoded, shared_secret: shared_secret)
|
21
|
+
end.to raise_error(OmniAuth::Desk::SignedRequest::Error)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'throws a too old error' do
|
25
|
+
expect do
|
26
|
+
encoded = OmniAuth::Desk::SignedRequest.encode(too_old, shared_secret: shared_secret)
|
27
|
+
OmniAuth::Desk::SignedRequest.decode(encoded, shared_secret: shared_secret)
|
28
|
+
end.to raise_error(OmniAuth::Desk::SignedRequest::Error)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'throws an invalid signature error' do
|
32
|
+
expect do
|
33
|
+
encoded = OmniAuth::Desk::SignedRequest.encode(working, shared_secret: shared_secret)
|
34
|
+
OmniAuth::Desk::SignedRequest.decode(encoded, shared_secret: SecureRandom.uuid.gsub('-', ''))
|
35
|
+
end.to raise_error(OmniAuth::Desk::SignedRequest::Error)
|
36
|
+
end
|
37
|
+
end
|
@@ -2,10 +2,9 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe OmniAuth::Strategies::Desk, :type => :strategy do
|
4
4
|
def app
|
5
|
-
|
6
|
-
|
7
|
-
use
|
8
|
-
use strat
|
5
|
+
@app ||= Rack::Builder.new {
|
6
|
+
use Rack::Session::Cookie, secret: "MY_SECRET"
|
7
|
+
use OmniAuth::Strategies::Desk, shared_secret: SecureRandom.uuid.gsub('-', '')
|
9
8
|
run lambda {|env| [404, {'Content-Type' => 'text/plain'}, [nil || env.key?('omniauth.auth').to_s]] }
|
10
9
|
}.to_app
|
11
10
|
end
|
@@ -24,7 +23,7 @@ describe OmniAuth::Strategies::Desk, :type => :strategy do
|
|
24
23
|
end
|
25
24
|
|
26
25
|
it 'should render an identifier URL input' do
|
27
|
-
expect(last_response.body).to match(/<input[^>]*
|
26
|
+
expect(last_response.body).to match(/<input[^>]*site/)
|
28
27
|
end
|
29
28
|
end
|
30
29
|
|
@@ -32,7 +31,7 @@ describe OmniAuth::Strategies::Desk, :type => :strategy do
|
|
32
31
|
before do
|
33
32
|
@stub_devel = stub_request(:post, "https://devel.desk.com/oauth/request_token")
|
34
33
|
.to_return(status: 200, body: 'oauth_token=&oauth_token_secret=')
|
35
|
-
post '/auth/desk',
|
34
|
+
post '/auth/desk', site: 'devel'
|
36
35
|
end
|
37
36
|
|
38
37
|
it 'should have been requested' do
|
@@ -44,7 +43,7 @@ describe OmniAuth::Strategies::Desk, :type => :strategy do
|
|
44
43
|
before do
|
45
44
|
@stub_devel = stub_request(:post, "https://devel.desk.com/oauth/request_token")
|
46
45
|
.to_return(status: 200, body: 'oauth_token=&oauth_token_secret=')
|
47
|
-
post '/auth/desk',
|
46
|
+
post '/auth/desk', site: 'https://devel.desk.com'
|
48
47
|
end
|
49
48
|
|
50
49
|
it 'should have been requested' do
|
@@ -58,7 +57,7 @@ describe OmniAuth::Strategies::Desk, :type => :strategy do
|
|
58
57
|
stub_request(:post, "https://devel.desk.com/oauth/request_token")
|
59
58
|
.to_return(status: 200, body: 'oauth_token=&oauth_token_secret=')
|
60
59
|
|
61
|
-
post '/auth/desk',
|
60
|
+
post '/auth/desk', site: 'https://devel.desk.com'
|
62
61
|
|
63
62
|
@access_token = stub_request(:post, "https://devel.desk.com/oauth/access_token")
|
64
63
|
.to_return(status: 200, body: "oauth_token=6253282-eWudHldSbIaelX7swmsiHImEL4KinwaGloHANdrY&oauth_token_secret=2EEfA6BG3ly3sR3RjE0IBSnlQu4ZrUzPiYKmrkVU&user_id=6253282&screen_name=twitterapi")
|
@@ -78,6 +77,36 @@ describe OmniAuth::Strategies::Desk, :type => :strategy do
|
|
78
77
|
end
|
79
78
|
end
|
80
79
|
|
80
|
+
context 'signed request' do
|
81
|
+
before do
|
82
|
+
signed_request = OmniAuth::Desk::SignedRequest.encode({
|
83
|
+
"currentTime": Time.now.iso8601,
|
84
|
+
"expiresAt": (Time.now+3600).iso8601,
|
85
|
+
"algorithm": "HMACSHA256",
|
86
|
+
"userId": "1",
|
87
|
+
"context": {
|
88
|
+
"user": {
|
89
|
+
"userId": "1",
|
90
|
+
"userName": "agent@desk.com",
|
91
|
+
"email": "agent@desk.com",
|
92
|
+
"fullName": "Joe Agent",
|
93
|
+
"locale": "en_us",
|
94
|
+
"language": "en_us",
|
95
|
+
"timeZone": "Pacific Time (US & Canada)",
|
96
|
+
"roleId": 60,
|
97
|
+
"userType": "agent",
|
98
|
+
"profileThumbnailUrl": "http://www.gravatar.com/avatar/8a4e3154a0f99458dd1f382e72174198?default=mm&rating=PG&size=50"
|
99
|
+
}
|
100
|
+
}
|
101
|
+
}, shared_secret: app.instance_variable_get(:@app).options.shared_secret)
|
102
|
+
post '/auth/desk/callback', signed_request: signed_request
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should set omniauth.auth' do
|
106
|
+
expect(last_request.env['omniauth.auth']).not_to be_nil
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
81
110
|
context 'unsuccessful' do
|
82
111
|
before do
|
83
112
|
get '/auth/desk/callback'
|
@@ -94,7 +123,7 @@ describe OmniAuth::Strategies::Desk, :type => :strategy do
|
|
94
123
|
before do
|
95
124
|
stub_request(:post, "https://thisdoesnotexist.desk.com/oauth/request_token")
|
96
125
|
.to_return(status: 403, body: 'oauth_token=&oauth_token_secret=')
|
97
|
-
post '/auth/desk',
|
126
|
+
post '/auth/desk', site: 'https://thisdoesnotexist.desk.com'
|
98
127
|
end
|
99
128
|
|
100
129
|
it 'should be redirected to failure' do
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: omniauth-desk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Stachl
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: omniauth
|
@@ -38,20 +38,6 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: multi_json
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 1.3.6
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: 1.3.6
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: rspec
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -124,8 +110,10 @@ files:
|
|
124
110
|
- Rakefile
|
125
111
|
- lib/omniauth-desk.rb
|
126
112
|
- lib/omniauth-desk/version.rb
|
113
|
+
- lib/omniauth/desk/signed_request.rb
|
127
114
|
- lib/omniauth/strategies/desk.rb
|
128
115
|
- omniauth-desk.gemspec
|
116
|
+
- spec/omniauth/desk/signed_request_spec.rb
|
129
117
|
- spec/omniauth/strategies/desk_spec.rb
|
130
118
|
- spec/spec_helper.rb
|
131
119
|
homepage: https://github.com/tstachl/omniauth-desk
|
@@ -152,5 +140,6 @@ signing_key:
|
|
152
140
|
specification_version: 4
|
153
141
|
summary: OmniAuth strategy for Desk.com
|
154
142
|
test_files:
|
143
|
+
- spec/omniauth/desk/signed_request_spec.rb
|
155
144
|
- spec/omniauth/strategies/desk_spec.rb
|
156
145
|
- spec/spec_helper.rb
|