Class: GData::Auth::AuthSub

Inherits:
Object
  • Object
show all
Defined in:
lib/gdata/auth/authsub.rb

Overview

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

Constant Summary collapse

REQUEST_HANDLER =

The URL of AuthSubRequest.

'https://www.google.com/accounts/AuthSubRequest'
SESSION_HANDLER =

The URL of AuthSubSessionToken.

'https://www.google.com/accounts/AuthSubSessionToken'
REVOKE_HANDLER =

The URL of AuthSubRevokeToken.

'https://www.google.com/accounts/AuthSubRevokeToken'
INFO_HANDLER =

The URL of AuthSubInfo.

'https://www.google.com/accounts/AuthSubTokenInfo'
BIG_INT_MAX =

2 ** 64, the largest 64 bit unsigned integer

18446744073709551616

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(token, options = {}) ⇒ AuthSub

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



45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/gdata/auth/authsub.rb', line 45

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

Instance Attribute Details

#private_keyObject

Private RSA key used to sign secure requests.



41
42
43
# File 'lib/gdata/auth/authsub.rb', line 41

def private_key
  @private_key
end

#tokenObject

AuthSub access token.



39
40
41
# File 'lib/gdata/auth/authsub.rb', line 39

def token
  @token
end

Class Method Details

.get_url(next_url, scope, secure = false, session = true, domain = nil) ⇒ Object

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.



146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/gdata/auth/authsub.rb', line 146

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

Instance Method Details

#infoObject

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



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/gdata/auth/authsub.rb', line 114

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

#revokeObject

Revoke the token.



132
133
134
135
136
137
138
139
140
141
# File 'lib/gdata/auth/authsub.rb', line 132

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) ⇒ Object

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



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/gdata/auth/authsub.rb', line 80

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

#upgradeObject

Upgrade the current token into a session token.



98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/gdata/auth/authsub.rb', line 98

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