Allow adjusting issued-at time to minimize clock skew issues
[arvados.git] / lib / google / api_client / service_account.rb
index 7d8caad787163a3357bf74100a2a0c228183dcab..2b0e390081a557a9a993f32ac7bf4706649a5497 100644 (file)
@@ -20,6 +20,8 @@ module Google
     ##
     # Helper for loading keys from the PKCS12 files downloaded when
     # setting up service accounts at the APIs Console.
+    #
+
     module PKCS12
       
       ##
@@ -51,8 +53,19 @@ module Google
     ##
     # Generates access tokens using the JWT assertion profile. Requires a
     # service account & access to the private key.
+    #
+    # @example
+    #
+    #    client = Google::APIClient.new
+    #    key = Google::APIClient::PKCS12.load_key('client.p12', 'notasecret')
+    #    service_account = Google::APIClient::JWTAsserter(
+    #        '123456-abcdef@developer.gserviceaccount.com',
+    #        'https://www.googleapis.com/auth/prediction',
+    #        key)
+    #    client.authorization = service_account.authorize
+    #    client.execute(...)
     class JWTAsserter
-      attr_accessor :issuer, :expiry
+      attr_accessor :issuer, :expiry, :skew
       attr_reader :scope
       attr_writer :key
 
@@ -63,19 +76,20 @@ module Google
       #    Name/ID of the client issuing the assertion
       # @param [String or Array] scope
       #   Scopes to authorize. May be a space delimited string or array of strings
-      # @param [OpenSSL::PKey]
+      # @param [OpenSSL::PKey] key
       #   RSA private key for signing assertions
       def initialize(issuer, scope, key)
         self.issuer = issuer
         self.scope = scope
-        self.expiry = 60 # 1 min default        
+        self.expiry = 60 # 1 min default 
+        self.skew = 60      
         self.key = key
       end
 
       ##
       # Set the scopes to authorize
       #
-      # @param [String or Array] scope
+      # @param [String, Array] new_scope
       #   Scopes to authorize. May be a space delimited string or array of strings
       def scope=(new_scope)
         case new_scope
@@ -103,7 +117,7 @@ module Google
           "scope" => self.scope,
           "aud" => "https://accounts.google.com/o/oauth2/token",
           "exp" => (now + expiry).to_i,
-          "iat" => now.to_i
+          "iat" => (now - skew).to_i
         }
         assertion['prn'] = person unless person.nil?
         return JWT.encode(assertion, @key, "RS256")