20862: Merge branch 'main' into 20862-google-api-client
[arvados.git] / sdk / ruby-google-api-client / spec / google / api_client / service_account_spec.rb
1 # Copyright 2012 Google Inc.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 require 'spec_helper'
16
17 require 'google/api_client'
18
19 fixtures_path = File.expand_path('../../../fixtures', __FILE__)
20
21 RSpec.describe Google::APIClient::KeyUtils do
22   it 'should read PKCS12 files from the filesystem' do
23     if RUBY_PLATFORM == 'java' && RUBY_VERSION.start_with?('1.8')
24       pending "Reading from PKCS12 not supported on jruby 1.8.x"
25     end
26     path =  File.expand_path('files/privatekey.p12', fixtures_path)
27     key = Google::APIClient::KeyUtils.load_from_pkcs12(path, 'notasecret')
28     expect(key).not_to eq(nil)
29   end
30
31   it 'should read PKCS12 files from loaded files' do
32     if RUBY_PLATFORM == 'java' && RUBY_VERSION.start_with?('1.8')
33       pending "Reading from PKCS12 not supported on jruby 1.8.x"
34     end
35     path =  File.expand_path('files/privatekey.p12', fixtures_path)
36     content = File.read(path)
37     key = Google::APIClient::KeyUtils.load_from_pkcs12(content, 'notasecret')
38     expect(key).not_to eq(nil)
39   end
40
41   it 'should read PEM files from the filesystem' do
42     path =  File.expand_path('files/secret.pem', fixtures_path)
43     key = Google::APIClient::KeyUtils.load_from_pem(path, 'notasecret')
44     expect(key).not_to eq(nil)
45   end
46
47   it 'should read PEM files from loaded files' do
48     path =  File.expand_path('files/secret.pem', fixtures_path)
49     content = File.read(path)
50     key = Google::APIClient::KeyUtils.load_from_pem(content, 'notasecret')
51     expect(key).not_to eq(nil)
52   end
53
54 end
55
56 RSpec.describe Google::APIClient::JWTAsserter do
57   include ConnectionHelpers
58
59   before do
60     @key = OpenSSL::PKey::RSA.new 2048
61   end
62
63   it 'should generate valid JWTs' do
64     asserter = Google::APIClient::JWTAsserter.new('client1', 'scope1 scope2', @key)
65     jwt = asserter.to_authorization.to_jwt
66     expect(jwt).not_to eq(nil)
67
68     claim = JWT.decode(jwt, @key.public_key, true)
69     claim = claim[0] if claim[0]
70     expect(claim["iss"]).to eq('client1')
71     expect(claim["scope"]).to eq('scope1 scope2')
72   end
73
74   it 'should allow impersonation' do
75     conn = stub_connection do |stub|
76       stub.post('/o/oauth2/token') do |env|
77         params = Addressable::URI.form_unencode(env[:body])
78         JWT.decode(params.assoc("assertion").last, @key.public_key)
79         expect(params.assoc("grant_type")).to eq(['grant_type','urn:ietf:params:oauth:grant-type:jwt-bearer'])
80         [200, {'content-type' => 'application/json'}, '{
81           "access_token" : "1/abcdef1234567890",
82           "token_type" : "Bearer",
83           "expires_in" : 3600
84         }']
85       end
86     end
87     asserter = Google::APIClient::JWTAsserter.new('client1', 'scope1 scope2', @key)
88     auth = asserter.authorize('user1@email.com', { :connection => conn })
89     expect(auth).not_to eq(nil?)
90     expect(auth.person).to eq('user1@email.com')
91     conn.verify
92   end
93
94   it 'should send valid access token request' do
95     conn = stub_connection do |stub|
96       stub.post('/o/oauth2/token') do |env|
97         params = Addressable::URI.form_unencode(env[:body])
98         JWT.decode(params.assoc("assertion").last, @key.public_key)
99         expect(params.assoc("grant_type")).to eq(['grant_type','urn:ietf:params:oauth:grant-type:jwt-bearer'])
100         [200, {'content-type' => 'application/json'}, '{
101           "access_token" : "1/abcdef1234567890",
102           "token_type" : "Bearer",
103           "expires_in" : 3600
104         }']
105       end
106     end
107     asserter = Google::APIClient::JWTAsserter.new('client1', 'scope1 scope2', @key)
108     auth = asserter.authorize(nil, { :connection => conn })
109     expect(auth).not_to eq(nil?)
110     expect(auth.access_token).to eq("1/abcdef1234567890")
111     conn.verify
112   end
113
114   it 'should be refreshable' do
115     conn = stub_connection do |stub|
116       stub.post('/o/oauth2/token') do |env|
117         params = Addressable::URI.form_unencode(env[:body])
118         JWT.decode(params.assoc("assertion").last, @key.public_key)
119         expect(params.assoc("grant_type")).to eq(['grant_type','urn:ietf:params:oauth:grant-type:jwt-bearer'])
120         [200, {'content-type' => 'application/json'}, '{
121           "access_token" : "1/abcdef1234567890",
122           "token_type" : "Bearer",
123           "expires_in" : 3600
124         }']
125       end
126       stub.post('/o/oauth2/token') do |env|
127         params = Addressable::URI.form_unencode(env[:body])
128         JWT.decode(params.assoc("assertion").last, @key.public_key)
129         expect(params.assoc("grant_type")).to eq(['grant_type','urn:ietf:params:oauth:grant-type:jwt-bearer'])
130         [200, {'content-type' => 'application/json'}, '{
131           "access_token" : "1/0987654321fedcba",
132           "token_type" : "Bearer",
133           "expires_in" : 3600
134         }']
135       end
136     end
137     asserter = Google::APIClient::JWTAsserter.new('client1', 'scope1 scope2', @key)
138     auth = asserter.authorize(nil, { :connection => conn })
139     expect(auth).not_to eq(nil?)
140     expect(auth.access_token).to eq("1/abcdef1234567890")
141
142     auth.fetch_access_token!(:connection => conn)
143     expect(auth.access_token).to eq("1/0987654321fedcba")
144
145     conn.verify
146   end
147 end
148
149 RSpec.describe Google::APIClient::ComputeServiceAccount do
150   include ConnectionHelpers
151
152   it 'should query metadata server' do
153     conn = stub_connection do |stub|
154       stub.get('/computeMetadata/v1beta1/instance/service-accounts/default/token') do |env|
155         expect(env.url.host).to eq('metadata')
156         [200, {'content-type' => 'application/json'}, '{
157           "access_token" : "1/abcdef1234567890",
158           "token_type" : "Bearer",
159           "expires_in" : 3600
160         }']
161       end
162     end
163     service_account = Google::APIClient::ComputeServiceAccount.new
164     auth = service_account.fetch_access_token!({ :connection => conn })
165     expect(auth).not_to eq(nil?)
166     expect(auth["access_token"]).to eq("1/abcdef1234567890")
167     conn.verify
168   end
169 end