jomz-google-api-client 0.7.1
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.
- data/CHANGELOG.md +144 -0
- data/CONTRIBUTING.md +32 -0
- data/Gemfile +41 -0
- data/LICENSE +202 -0
- data/README.md +192 -0
- data/Rakefile +46 -0
- data/lib/cacerts.pem +2183 -0
- data/lib/compat/multi_json.rb +16 -0
- data/lib/google/api_client.rb +672 -0
- data/lib/google/api_client/auth/compute_service_account.rb +28 -0
- data/lib/google/api_client/auth/file_storage.rb +87 -0
- data/lib/google/api_client/auth/installed_app.rb +122 -0
- data/lib/google/api_client/auth/jwt_asserter.rb +126 -0
- data/lib/google/api_client/auth/key_utils.rb +93 -0
- data/lib/google/api_client/auth/pkcs12.rb +41 -0
- data/lib/google/api_client/batch.rb +323 -0
- data/lib/google/api_client/client_secrets.rb +176 -0
- data/lib/google/api_client/discovery.rb +19 -0
- data/lib/google/api_client/discovery/api.rb +300 -0
- data/lib/google/api_client/discovery/media.rb +77 -0
- data/lib/google/api_client/discovery/method.rb +363 -0
- data/lib/google/api_client/discovery/resource.rb +156 -0
- data/lib/google/api_client/discovery/schema.rb +121 -0
- data/lib/google/api_client/environment.rb +42 -0
- data/lib/google/api_client/errors.rb +60 -0
- data/lib/google/api_client/gzip.rb +28 -0
- data/lib/google/api_client/logging.rb +32 -0
- data/lib/google/api_client/media.rb +259 -0
- data/lib/google/api_client/railtie.rb +16 -0
- data/lib/google/api_client/reference.rb +27 -0
- data/lib/google/api_client/request.rb +351 -0
- data/lib/google/api_client/result.rb +253 -0
- data/lib/google/api_client/service.rb +233 -0
- data/lib/google/api_client/service/batch.rb +103 -0
- data/lib/google/api_client/service/request.rb +144 -0
- data/lib/google/api_client/service/resource.rb +40 -0
- data/lib/google/api_client/service/result.rb +162 -0
- data/lib/google/api_client/service/simple_file_store.rb +151 -0
- data/lib/google/api_client/service/stub_generator.rb +59 -0
- data/lib/google/api_client/service_account.rb +18 -0
- data/lib/google/api_client/version.rb +31 -0
- data/lib/google/inflection.rb +28 -0
- data/spec/fixtures/files/privatekey.p12 +0 -0
- data/spec/fixtures/files/sample.txt +33 -0
- data/spec/fixtures/files/secret.pem +19 -0
- data/spec/google/api_client/batch_spec.rb +249 -0
- data/spec/google/api_client/discovery_spec.rb +652 -0
- data/spec/google/api_client/gzip_spec.rb +86 -0
- data/spec/google/api_client/media_spec.rb +179 -0
- data/spec/google/api_client/request_spec.rb +30 -0
- data/spec/google/api_client/result_spec.rb +203 -0
- data/spec/google/api_client/service_account_spec.rb +164 -0
- data/spec/google/api_client/service_spec.rb +586 -0
- data/spec/google/api_client/simple_file_store_spec.rb +137 -0
- data/spec/google/api_client_spec.rb +253 -0
- data/spec/spec_helper.rb +56 -0
- data/tasks/gem.rake +97 -0
- data/tasks/git.rake +45 -0
- data/tasks/metrics.rake +22 -0
- data/tasks/spec.rake +57 -0
- data/tasks/wiki.rake +82 -0
- data/tasks/yard.rake +29 -0
- metadata +309 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
# Copyright 2013 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 'faraday'
|
16
|
+
require 'signet/oauth_2/client'
|
17
|
+
|
18
|
+
module Google
|
19
|
+
class APIClient
|
20
|
+
class ComputeServiceAccount < Signet::OAuth2::Client
|
21
|
+
def fetch_access_token(options={})
|
22
|
+
connection = options[:connection] || Faraday.default_connection
|
23
|
+
response = connection.get 'http://metadata/computeMetadata/v1beta1/instance/service-accounts/default/token'
|
24
|
+
Signet::OAuth2.parse_json_credentials(response.body)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# Copyright 2013 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 'json'
|
16
|
+
require 'signet/oauth_2/client'
|
17
|
+
|
18
|
+
module Google
|
19
|
+
class APIClient
|
20
|
+
##
|
21
|
+
# Represents cached OAuth 2 tokens stored on local disk in a
|
22
|
+
# JSON serialized file. Meant to resemble the serialized format
|
23
|
+
# http://google-api-python-client.googlecode.com/hg/docs/epy/oauth2client.file.Storage-class.html
|
24
|
+
#
|
25
|
+
class FileStorage
|
26
|
+
# @return [String] Path to the credentials file.
|
27
|
+
attr_accessor :path
|
28
|
+
|
29
|
+
# @return [Signet::OAuth2::Client] Path to the credentials file.
|
30
|
+
attr_reader :authorization
|
31
|
+
|
32
|
+
##
|
33
|
+
# Initializes the FileStorage object.
|
34
|
+
#
|
35
|
+
# @param [String] path
|
36
|
+
# Path to the credentials file.
|
37
|
+
def initialize(path)
|
38
|
+
@path = path
|
39
|
+
self.load_credentials
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# Attempt to read in credentials from the specified file.
|
44
|
+
def load_credentials
|
45
|
+
if File.exist? self.path
|
46
|
+
File.open(self.path, 'r') do |file|
|
47
|
+
cached_credentials = JSON.load(file)
|
48
|
+
@authorization = Signet::OAuth2::Client.new(cached_credentials)
|
49
|
+
@authorization.issued_at = Time.at(cached_credentials['issued_at'])
|
50
|
+
if @authorization.expired?
|
51
|
+
@authorization.fetch_access_token!
|
52
|
+
self.write_credentials
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# Write the credentials to the specified file.
|
60
|
+
#
|
61
|
+
# @param [Signet::OAuth2::Client] authorization
|
62
|
+
# Optional authorization instance. If not provided, the authorization
|
63
|
+
# already associated with this instance will be written.
|
64
|
+
def write_credentials(authorization=nil)
|
65
|
+
@authorization = authorization unless authorization.nil?
|
66
|
+
|
67
|
+
unless @authorization.refresh_token.nil?
|
68
|
+
hash = {}
|
69
|
+
%w'access_token
|
70
|
+
authorization_uri
|
71
|
+
client_id
|
72
|
+
client_secret
|
73
|
+
expires_in
|
74
|
+
refresh_token
|
75
|
+
token_credential_uri'.each do |var|
|
76
|
+
hash[var] = @authorization.instance_variable_get("@#{var}")
|
77
|
+
end
|
78
|
+
hash['issued_at'] = @authorization.issued_at.to_i
|
79
|
+
|
80
|
+
File.open(self.path, 'w', 0600) do |file|
|
81
|
+
file.write(hash.to_json)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
# Copyright 2010 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 'webrick'
|
16
|
+
require 'launchy'
|
17
|
+
|
18
|
+
module Google
|
19
|
+
class APIClient
|
20
|
+
|
21
|
+
# Small helper for the sample apps for performing OAuth 2.0 flows from the command
|
22
|
+
# line or in any other installed app environment.
|
23
|
+
#
|
24
|
+
# @example
|
25
|
+
#
|
26
|
+
# client = Google::APIClient.new
|
27
|
+
# flow = Google::APIClient::InstalledAppFlow.new(
|
28
|
+
# :client_id => '691380668085.apps.googleusercontent.com',
|
29
|
+
# :client_secret => '...,
|
30
|
+
# :scope => 'https://www.googleapis.com/auth/drive'
|
31
|
+
# )
|
32
|
+
# client.authorization = flow.authorize
|
33
|
+
#
|
34
|
+
class InstalledAppFlow
|
35
|
+
|
36
|
+
RESPONSE_BODY = <<-HTML
|
37
|
+
<html>
|
38
|
+
<head>
|
39
|
+
<script>
|
40
|
+
function closeWindow() {
|
41
|
+
window.open('', '_self', '');
|
42
|
+
window.close();
|
43
|
+
}
|
44
|
+
setTimeout(closeWindow, 10);
|
45
|
+
</script>
|
46
|
+
</head>
|
47
|
+
<body>You may close this window.</body>
|
48
|
+
</html>
|
49
|
+
HTML
|
50
|
+
|
51
|
+
##
|
52
|
+
# Configure the flow
|
53
|
+
#
|
54
|
+
# @param [Hash] options The configuration parameters for the client.
|
55
|
+
# @option options [Fixnum] :port
|
56
|
+
# Port to run the embedded server on. Defaults to 9292
|
57
|
+
# @option options [String] :client_id
|
58
|
+
# A unique identifier issued to the client to identify itself to the
|
59
|
+
# authorization server.
|
60
|
+
# @option options [String] :client_secret
|
61
|
+
# A shared symmetric secret issued by the authorization server,
|
62
|
+
# which is used to authenticate the client.
|
63
|
+
# @option options [String] :scope
|
64
|
+
# The scope of the access request, expressed either as an Array
|
65
|
+
# or as a space-delimited String.
|
66
|
+
#
|
67
|
+
# @see Signet::OAuth2::Client
|
68
|
+
def initialize(options)
|
69
|
+
@port = options[:port] || 9292
|
70
|
+
@authorization = Signet::OAuth2::Client.new({
|
71
|
+
:authorization_uri => 'https://accounts.google.com/o/oauth2/auth',
|
72
|
+
:token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
|
73
|
+
:redirect_uri => "http://localhost:#{@port}/"}.update(options)
|
74
|
+
)
|
75
|
+
end
|
76
|
+
|
77
|
+
##
|
78
|
+
# Request authorization. Opens a browser and waits for response.
|
79
|
+
#
|
80
|
+
# @param [Google::APIClient::FileStorage] storage
|
81
|
+
# Optional object that responds to :write_credentials, used to serialize
|
82
|
+
# the OAuth 2 credentials after completing the flow.
|
83
|
+
#
|
84
|
+
# @return [Signet::OAuth2::Client]
|
85
|
+
# Authorization instance, nil if user cancelled.
|
86
|
+
def authorize(storage=nil)
|
87
|
+
auth = @authorization
|
88
|
+
|
89
|
+
server = WEBrick::HTTPServer.new(
|
90
|
+
:Port => @port,
|
91
|
+
:BindAddress =>"localhost",
|
92
|
+
:Logger => WEBrick::Log.new(STDOUT, 0),
|
93
|
+
:AccessLog => []
|
94
|
+
)
|
95
|
+
trap("INT") { server.shutdown }
|
96
|
+
|
97
|
+
server.mount_proc '/' do |req, res|
|
98
|
+
auth.code = req.query['code']
|
99
|
+
if auth.code
|
100
|
+
auth.fetch_access_token!
|
101
|
+
end
|
102
|
+
res.status = WEBrick::HTTPStatus::RC_ACCEPTED
|
103
|
+
res.body = RESPONSE_BODY
|
104
|
+
server.stop
|
105
|
+
end
|
106
|
+
|
107
|
+
Launchy.open(auth.authorization_uri.to_s)
|
108
|
+
server.start
|
109
|
+
if @authorization.access_token
|
110
|
+
if storage.respond_to?(:write_credentials)
|
111
|
+
storage.write_credentials(@authorization)
|
112
|
+
end
|
113
|
+
return @authorization
|
114
|
+
else
|
115
|
+
return nil
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# Copyright 2010 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 'jwt'
|
16
|
+
require 'signet/oauth_2/client'
|
17
|
+
require 'delegate'
|
18
|
+
|
19
|
+
module Google
|
20
|
+
class APIClient
|
21
|
+
##
|
22
|
+
# Generates access tokens using the JWT assertion profile. Requires a
|
23
|
+
# service account & access to the private key.
|
24
|
+
#
|
25
|
+
# @example Using Signet
|
26
|
+
#
|
27
|
+
# key = Google::APIClient::KeyUtils.load_from_pkcs12('client.p12', 'notasecret')
|
28
|
+
# client.authorization = Signet::OAuth2::Client.new(
|
29
|
+
# :token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
|
30
|
+
# :audience => 'https://accounts.google.com/o/oauth2/token',
|
31
|
+
# :scope => 'https://www.googleapis.com/auth/prediction',
|
32
|
+
# :issuer => '123456-abcdef@developer.gserviceaccount.com',
|
33
|
+
# :signing_key => key)
|
34
|
+
# client.authorization.fetch_access_token!
|
35
|
+
# client.execute(...)
|
36
|
+
#
|
37
|
+
# @deprecated
|
38
|
+
# Service accounts are now supported directly in Signet
|
39
|
+
# @see https://developers.google.com/accounts/docs/OAuth2ServiceAccount
|
40
|
+
class JWTAsserter
|
41
|
+
# @return [String] ID/email of the issuing party
|
42
|
+
attr_accessor :issuer
|
43
|
+
# @return [Fixnum] How long, in seconds, the assertion is valid for
|
44
|
+
attr_accessor :expiry
|
45
|
+
# @return [Fixnum] Seconds to expand the issued at/expiry window to account for clock skew
|
46
|
+
attr_accessor :skew
|
47
|
+
# @return [String] Scopes to authorize
|
48
|
+
attr_reader :scope
|
49
|
+
# @return [String,OpenSSL::PKey] key for signing assertions
|
50
|
+
attr_writer :key
|
51
|
+
# @return [String] Algorithm used for signing
|
52
|
+
attr_accessor :algorithm
|
53
|
+
|
54
|
+
##
|
55
|
+
# Initializes the asserter for a service account.
|
56
|
+
#
|
57
|
+
# @param [String] issuer
|
58
|
+
# Name/ID of the client issuing the assertion
|
59
|
+
# @param [String, Array] scope
|
60
|
+
# Scopes to authorize. May be a space delimited string or array of strings
|
61
|
+
# @param [String,OpenSSL::PKey] key
|
62
|
+
# Key for signing assertions
|
63
|
+
# @param [String] algorithm
|
64
|
+
# Algorithm to use, either 'RS256' for RSA with SHA-256
|
65
|
+
# or 'HS256' for HMAC with SHA-256
|
66
|
+
def initialize(issuer, scope, key, algorithm = "RS256")
|
67
|
+
self.issuer = issuer
|
68
|
+
self.scope = scope
|
69
|
+
self.expiry = 60 # 1 min default
|
70
|
+
self.skew = 60
|
71
|
+
self.key = key
|
72
|
+
self.algorithm = algorithm
|
73
|
+
end
|
74
|
+
|
75
|
+
##
|
76
|
+
# Set the scopes to authorize
|
77
|
+
#
|
78
|
+
# @param [String, Array] new_scope
|
79
|
+
# Scopes to authorize. May be a space delimited string or array of strings
|
80
|
+
def scope=(new_scope)
|
81
|
+
case new_scope
|
82
|
+
when Array
|
83
|
+
@scope = new_scope.join(' ')
|
84
|
+
when String
|
85
|
+
@scope = new_scope
|
86
|
+
when nil
|
87
|
+
@scope = ''
|
88
|
+
else
|
89
|
+
raise TypeError, "Expected Array or String, got #{new_scope.class}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
##
|
94
|
+
# Request a new access token.
|
95
|
+
#
|
96
|
+
# @param [String] person
|
97
|
+
# Email address of a user, if requesting a token to act on their behalf
|
98
|
+
# @param [Hash] options
|
99
|
+
# Pass through to Signet::OAuth2::Client.fetch_access_token
|
100
|
+
# @return [Signet::OAuth2::Client] Access token
|
101
|
+
#
|
102
|
+
# @see Signet::OAuth2::Client.fetch_access_token!
|
103
|
+
def authorize(person = nil, options={})
|
104
|
+
authorization = self.to_authorization(person)
|
105
|
+
authorization.fetch_access_token!(options)
|
106
|
+
return authorization
|
107
|
+
end
|
108
|
+
|
109
|
+
##
|
110
|
+
# Builds a Signet OAuth2 client
|
111
|
+
#
|
112
|
+
# @return [Signet::OAuth2::Client] Access token
|
113
|
+
def to_authorization(person = nil)
|
114
|
+
return Signet::OAuth2::Client.new(
|
115
|
+
:token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
|
116
|
+
:audience => 'https://accounts.google.com/o/oauth2/token',
|
117
|
+
:scope => self.scope,
|
118
|
+
:issuer => @issuer,
|
119
|
+
:signing_key => @key,
|
120
|
+
:signing_algorithm => @algorithm,
|
121
|
+
:person => person
|
122
|
+
)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# Copyright 2010 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
|
+
module Google
|
16
|
+
class APIClient
|
17
|
+
##
|
18
|
+
# Helper for loading keys from the PKCS12 files downloaded when
|
19
|
+
# setting up service accounts at the APIs Console.
|
20
|
+
#
|
21
|
+
module KeyUtils
|
22
|
+
##
|
23
|
+
# Loads a key from PKCS12 file, assuming a single private key
|
24
|
+
# is present.
|
25
|
+
#
|
26
|
+
# @param [String] keyfile
|
27
|
+
# Path of the PKCS12 file to load. If not a path to an actual file,
|
28
|
+
# assumes the string is the content of the file itself.
|
29
|
+
# @param [String] passphrase
|
30
|
+
# Passphrase for unlocking the private key
|
31
|
+
#
|
32
|
+
# @return [OpenSSL::PKey] The private key for signing assertions.
|
33
|
+
def self.load_from_pkcs12(keyfile, passphrase)
|
34
|
+
load_key(keyfile, passphrase) do |content, passphrase|
|
35
|
+
OpenSSL::PKCS12.new(content, passphrase).key
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
##
|
41
|
+
# Loads a key from a PEM file.
|
42
|
+
#
|
43
|
+
# @param [String] keyfile
|
44
|
+
# Path of the PEM file to load. If not a path to an actual file,
|
45
|
+
# assumes the string is the content of the file itself.
|
46
|
+
# @param [String] passphrase
|
47
|
+
# Passphrase for unlocking the private key
|
48
|
+
#
|
49
|
+
# @return [OpenSSL::PKey] The private key for signing assertions.
|
50
|
+
#
|
51
|
+
def self.load_from_pem(keyfile, passphrase)
|
52
|
+
load_key(keyfile, passphrase) do | content, passphrase|
|
53
|
+
OpenSSL::PKey::RSA.new(content, passphrase)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
##
|
60
|
+
# Helper for loading keys from file or memory. Accepts a block
|
61
|
+
# to handle the specific file format.
|
62
|
+
#
|
63
|
+
# @param [String] keyfile
|
64
|
+
# Path of thefile to load. If not a path to an actual file,
|
65
|
+
# assumes the string is the content of the file itself.
|
66
|
+
# @param [String] passphrase
|
67
|
+
# Passphrase for unlocking the private key
|
68
|
+
#
|
69
|
+
# @yield [String, String]
|
70
|
+
# Key file & passphrase to extract key from
|
71
|
+
# @yieldparam [String] keyfile
|
72
|
+
# Contents of the file
|
73
|
+
# @yieldparam [String] passphrase
|
74
|
+
# Passphrase to unlock key
|
75
|
+
# @yieldreturn [OpenSSL::PKey]
|
76
|
+
# Private key
|
77
|
+
#
|
78
|
+
# @return [OpenSSL::PKey] The private key for signing assertions.
|
79
|
+
def self.load_key(keyfile, passphrase, &block)
|
80
|
+
begin
|
81
|
+
begin
|
82
|
+
content = File.open(keyfile, 'rb') { |io| io.read }
|
83
|
+
rescue
|
84
|
+
content = keyfile
|
85
|
+
end
|
86
|
+
block.call(content, passphrase)
|
87
|
+
rescue OpenSSL::OpenSSLError
|
88
|
+
raise ArgumentError.new("Invalid keyfile or passphrase")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|