class GData::Auth::AuthSub

This class implements AuthSub signatures for Data API requests. It can be used with a GData::Client::GData object.

Constants

BIG_INT_MAX

2 ** 64, the largest 64 bit unsigned integer

INFO_HANDLER

The URL of AuthSubInfo.

REQUEST_HANDLER

The URL of AuthSubRequest.

REVOKE_HANDLER

The URL of AuthSubRevokeToken.

SESSION_HANDLER

The URL of AuthSubSessionToken.

Attributes

private_key[R]

Private RSA key used to sign secure requests.

token[RW]

AuthSub access token.

Public Class Methods

get_url(next_url, scope, secure = false, session = true, domain = nil) click to toggle source

Return the proper URL for an AuthSub approval page with the requested scope. next_url should be a URL that points back to your code that will receive the token. domain is optionally a Google Apps domain.

# File lib/gdata/auth/authsub.rb, line 145
def self.get_url(next_url, scope, secure = false, session = true, 
    domain = nil)
  next_url = CGI.escape(next_url)
  scope = CGI.escape(scope)
  secure = secure ? 1 : 0
  session = session ? 1 : 0
  body = "next=#{next_url}&scope=#{scope}&session=#{session}" +
         "&secure=#{secure}"
  if domain
    domain = CGI.escape(domain)
    body = "#{body}&hd=#{domain}"
  end
  return "#{REQUEST_HANDLER}?#{body}"
end
new(token, options = {}) click to toggle source

Initialize the class with a new token. Optionally pass a private key or custom URLs.

# File lib/gdata/auth/authsub.rb, line 44
def initialize(token, options = {})
  if token.nil?
    raise ArgumentError, "Token cannot be nil."
  elsif token.class != String
    raise ArgumentError, "Token must be a String."
  end
  
  @token = token
  
  options.each do |key, value|
    self.send("#{key}=", value)
  end
end

Public Instance Methods

info() click to toggle source

Return some information about the current token. If the current token is a one-time use token, this operation will use it up!

# File lib/gdata/auth/authsub.rb, line 113
def info
  request = GData::HTTP::Request.new(INFO_HANDLER)
  sign_request!(request)
  service = GData::HTTP::DefaultService.new
  response = service.make_request(request)
  if response.status_code != 200
    raise GData::Client::AuthorizationError.new(response)
  end
  
  result = {}
  result[:target] = response.body[/Target=(.*)/,1]
  result[:scope] = response.body[/Scope=(.*)/,1]
  result[:secure] = response.body[/Secure=(.*)/,1]
  return result
 
end
private_key=(key) click to toggle source

Set the private key to use with this AuthSub token. The key can be an OpenSSL::PKey::RSA object, a string containing a private key in PEM format, or a string specifying a path to a PEM file that contains the private key.

# File lib/gdata/auth/authsub.rb, line 62
def private_key=(key)
  begin
    if key.nil? or key.class == OpenSSL::PKey::RSA
      @private_key = key
    elsif File.exists?(key)
      key_from_file = File.read(key)
      @private_key = OpenSSL::PKey::RSA.new(key_from_file)
    else
      @private_key = OpenSSL::PKey::RSA.new(key)
    end
  rescue
    raise ArgumentError, "Not a valid private key."
  end
end
revoke() click to toggle source

Revoke the token.

# File lib/gdata/auth/authsub.rb, line 131
def revoke
  request = GData::HTTP::Request.new(REVOKE_HANDLER)
  sign_request!(request)
  service = GData::HTTP::DefaultService.new
  response = service.make_request(request)
  if response.status_code != 200
    raise GData::Client::AuthorizationError.new(response)
  end

end
sign_request!(request) click to toggle source

Sign a GData::Http::Request object with a valid AuthSub Authorization header.

# File lib/gdata/auth/authsub.rb, line 79
def sign_request!(request)
  header = "AuthSub token=\"#{@token}\""
  
  if @private_key
    time = Time.now.to_i
    nonce = OpenSSL::BN.rand_range(BIG_INT_MAX)
    method = request.method.to_s.upcase
    data = "#{method} #{request.url} #{time} #{nonce}"
    sig = @private_key.sign(OpenSSL::Digest::SHA1.new, data)
    sig = Base64.encode64(sig).gsub(/\n/, '')
    header = "#{header} sigalg=\"rsa-sha1\" data=\"#{data}\""
    header = "#{header} sig=\"#{sig}\""
  end
  
  request.headers['Authorization'] = header
end
upgrade() click to toggle source

Upgrade the current token into a session token.

# File lib/gdata/auth/authsub.rb, line 97
def upgrade
  request = GData::HTTP::Request.new(SESSION_HANDLER)
  sign_request!(request)
  service = GData::HTTP::DefaultService.new
  response = service.make_request(request)
  if response.status_code != 200
    raise GData::Client::AuthorizationError.new(response)
  end
  
  @token = response.body[/Token=(.*)/,1]
  return @token
  
end