Extract the auth library into its own project
- adds no new functionality beyond the initial attempt at providing Usable Auth constructors. - adds enough packaging metadata to be able to export this library as a gem. - next steps: complete usable auth implemntation of Application Default Credentials.
This commit is contained in:
1 parent
1688c65e80
commit
3e60a713c5
12 files changed
+759
No files matched your search
@@ -0,0 +1,69 @@
|
||||
# Copyright 2015, Google Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
require 'faraday'
|
||||
require 'googleauth/signet'
|
||||
|
||||
module Google
|
||||
# Module Auth provides classes that provide Google-specific authorization
|
||||
# used to access Google APIs.
|
||||
module Auth
|
||||
# Extends Signet::OAuth2::Client so that the auth token is obtained from
|
||||
# the GCE metadata server.
|
||||
class GCECredentials < Signet::OAuth2::Client
|
||||
# The IP Address is used in the URIs to speed up failures on non-GCE
|
||||
# systems.
|
||||
COMPUTE_AUTH_TOKEN_URI = 'http://169.254.169.254/computeMetadata/v1/'\
|
||||
'instance/service-accounts/default/token'
|
||||
COMPUTE_CHECK_URI = 'http://169.254.169.254'
|
||||
|
||||
# Detect if this appear to be a GCE instance, by checking if metadata
|
||||
# is available
|
||||
def self.on_gce?(options = {})
|
||||
c = options[:connection] || Faraday.default_connection
|
||||
resp = c.get(COMPUTE_CHECK_URI)
|
||||
return false unless resp.status == 200
|
||||
return false unless resp.headers.key?('Metadata-Flavor')
|
||||
return resp.headers['Metadata-Flavor'] == 'Google'
|
||||
rescue Faraday::ConnectionFailed
|
||||
return false
|
||||
end
|
||||
|
||||
# Overrides the super class method to change how access tokens are
|
||||
# fetched.
|
||||
def fetch_access_token(options = {})
|
||||
c = options[:connection] || Faraday.default_connection
|
||||
c.headers = { 'Metadata-Flavor' => 'Google' }
|
||||
resp = c.get(COMPUTE_AUTH_TOKEN_URI)
|
||||
Signet::OAuth2.parse_credentials(resp.body,
|
||||
resp.headers['content-type'])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,71 @@
|
||||
# Copyright 2015, Google Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
require 'googleauth/signet'
|
||||
require 'multi_json'
|
||||
require 'openssl'
|
||||
|
||||
# Reads the private key and client email fields from service account JSON key.
|
||||
def read_json_key(json_key_io)
|
||||
json_key = MultiJson.load(json_key_io.read)
|
||||
fail 'missing client_email' unless json_key.key?('client_email')
|
||||
fail 'missing private_key' unless json_key.key?('private_key')
|
||||
[json_key['private_key'], json_key['client_email']]
|
||||
end
|
||||
|
||||
module Google
|
||||
# Module Auth provides classes that provide Google-specific authorization
|
||||
# used to access Google APIs.
|
||||
module Auth
|
||||
# Authenticates requests using Google's Service Account credentials.
|
||||
#
|
||||
# This class provides a simpler surface to the behavior in
|
||||
# Signet::OAuth2::Client. It allows authorizing requests directly using
|
||||
# credentials from a json key file downloaded from the developer console
|
||||
# (via 'Generate new Json Key').
|
||||
#
|
||||
# cf [Application Default Credentials](http://goo.gl/mkAHpZ)
|
||||
class ServiceAccountCredentials < Signet::OAuth2::Client
|
||||
TOKEN_CRED_URI = 'https://www.googleapis.com/oauth2/v3/token'
|
||||
|
||||
# Initializes a ServiceAccountCredentials.
|
||||
#
|
||||
# @param scope [string|array] the scope(s) to access
|
||||
# @param json_key_io [IO] an IO from which the JSON key can be read
|
||||
def initialize(scope, json_key_io)
|
||||
private_key, client_email = read_json_key(json_key_io)
|
||||
super(token_credential_uri: TOKEN_CRED_URI,
|
||||
audience: TOKEN_CRED_URI, # TODO: confirm this
|
||||
scope: scope,
|
||||
issuer: client_email,
|
||||
signing_key: OpenSSL::PKey::RSA.new(private_key))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,63 @@
|
||||
# Copyright 2015, Google Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
require 'signet/oauth_2/client'
|
||||
|
||||
module Signet
|
||||
# OAuth2 supports OAuth2 authentication.
|
||||
module OAuth2
|
||||
AUTH_METADATA_KEY = :Authorization
|
||||
# Signet::OAuth2::Client creates an OAuth2 client
|
||||
#
|
||||
# This reopens Client to add #apply and #apply! methods which update a
|
||||
# hash with the fetched authentication token.
|
||||
class Client
|
||||
# Updates a_hash updated with the authentication token
|
||||
def apply!(a_hash, opts = {})
|
||||
# fetch the access token there is currently not one, or if the client
|
||||
# has expired
|
||||
fetch_access_token!(opts) if access_token.nil? || expired?
|
||||
a_hash[AUTH_METADATA_KEY] = "Bearer #{access_token}"
|
||||
end
|
||||
|
||||
# Returns a clone of a_hash updated with the authentication token
|
||||
def apply(a_hash, opts = {})
|
||||
a_copy = a_hash.clone
|
||||
apply!(a_copy, opts)
|
||||
a_copy
|
||||
end
|
||||
|
||||
# Returns a reference to the #apply method, suitable for passing as
|
||||
# a closure
|
||||
def updater_proc
|
||||
lambda(&method(:apply))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,36 @@
|
||||
# Copyright 2014, Google Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
module Google
|
||||
# Module Auth provides classes that provide Google-specific authorization
|
||||
# used to access Google APIs.
|
||||
module Auth
|
||||
VERSION = '0.1.0'
|
||||
end
|
||||
end
|
||||
Reference in new issue
Block a user