Skip to content

Commit 46d2dc2

Browse files
committed
pass in user id for just in time user impersonation override
1 parent ab34ca8 commit 46d2dc2

File tree

5 files changed

+51
-1
lines changed

5 files changed

+51
-1
lines changed

.ruby-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.1.7
1+
3.4.7

Gemfile.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ PATH
22
remote: .
33
specs:
44
zendesk_api (3.1.1)
5+
base64
56
faraday (> 2.0.0)
67
faraday-multipart
78
hashie (>= 3.5.2)

lib/zendesk_api/client.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
require 'zendesk_api/middleware/request/raise_rate_limited'
1010
require 'zendesk_api/middleware/request/upload'
1111
require 'zendesk_api/middleware/request/encode_json'
12+
require 'zendesk_api/middleware/request/api_token_impersonate'
1213
require 'zendesk_api/middleware/request/url_based_access_token'
1314
require 'zendesk_api/middleware/response/callback'
1415
require 'zendesk_api/middleware/response/deflate'
@@ -104,6 +105,24 @@ def initialize
104105
add_warning_callback
105106
end
106107

108+
# token impersonation for the scope of the block
109+
# @param [String] username The username (email) of the user to impersonate
110+
# @yield The block to run while impersonating the user
111+
# @example
112+
# client.api_token_impersonate("[email protected]") do
113+
# client.tickets.create(:subject => "Help!")
114+
# end
115+
#
116+
# # creates a ticket on behalf of otheruser
117+
# @return
118+
# yielded value
119+
def api_token_impersonate(username)
120+
Thread.current[:local_username] = username
121+
yield
122+
ensure
123+
Thread.current[:local_username] = nil
124+
end
125+
107126
# Creates a connection if there is none, otherwise returns the existing connection.
108127
#
109128
# @return [Faraday::Connection] Faraday connection for the client
@@ -180,6 +199,7 @@ def build_connection
180199
end
181200

182201
builder.adapter(*adapter, &config.adapter_proc)
202+
builder.use ZendeskAPI::Middleware::Request::ApiTokenImpersonate
183203
end
184204
end
185205

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
require 'base64'
2+
module ZendeskAPI
3+
# @private
4+
module Middleware
5+
# @private
6+
module Request
7+
# ApiTokenImpersonate
8+
# If Thread.current[:local_username] is set, it will modify the Authorization header
9+
# to impersonate that user using the API token from the current Authorization header.
10+
class ApiTokenImpersonate < Faraday::Middleware
11+
def call(env)
12+
if Thread.current[:local_username] && env[:request_headers][:authorization] =~ /^Basic /
13+
current_u_p_encoded = env[:request_headers][:authorization].split(/\s+/)[1]
14+
current_u_p = Base64.urlsafe_decode64(current_u_p_encoded)
15+
unless current_u_p.include?("/token:")
16+
raise ZendeskAPI::Error, "You must use an API token to impersonate a user."
17+
end
18+
19+
parts = current_u_p.split(":")
20+
next_u_p = "#{Thread.current[:local_username]}/token:#{parts[1]}"
21+
env[:request_headers][:authorization] = "Basic #{Base64.urlsafe_encode64(next_u_p)}"
22+
end
23+
@app.call(env)
24+
end
25+
end
26+
end
27+
end
28+
end

zendesk_api.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,5 @@ Gem::Specification.new do |s|
3333
s.add_dependency "inflection"
3434
s.add_dependency "multipart-post", "~> 2.0"
3535
s.add_dependency "mini_mime"
36+
s.add_dependency "base64"
3637
end

0 commit comments

Comments
 (0)