clientlogin.rb
3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# Copyright (C) 2008 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
require 'cgi'
module GData
module Auth
# This class implements ClientLogin signatures for Data API requests.
# It can be used with a GData::Client::GData object.
class ClientLogin
# The ClientLogin authentication handler
attr_accessor :auth_url
# One of 'HOSTED_OR_GOOGLE', 'GOOGLE', or 'HOSTED'.
# See documentation here:
# http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html
attr_accessor :account_type
# The access token
attr_accessor :token
# The service name for the API you are working with
attr_accessor :service
# Initialize the class with the service name of an API that you wish
# to request a token for.
def initialize(service, options = {})
if service.nil?
raise ArgumentError, "Service name cannot be nil"
end
@service = service
options.each do |key, value|
self.send("#{key}=", value)
end
@auth_url ||= 'https://www.google.com/accounts/ClientLogin'
@account_type ||= 'HOSTED_OR_GOOGLE'
end
# Retrieves a token for the given username and password.
# source identifies your application.
# login_token and login_captcha are used only if you are responding
# to a previously issued CAPTCHA challenge.
def get_token(username, password, source, login_token = nil,
login_captcha = nil)
body = Hash.new
body['accountType'] = @account_type
body['Email'] = username
body['Passwd'] = password
body['service'] = @service
body['source'] = source
if login_token and login_captcha
body['logintoken'] = login_token
body['logincaptcha'] = login_captcha
end
request = GData::HTTP::Request.new(@auth_url, :body => body,
:method => :post)
service = GData::HTTP::DefaultService.new
response = service.make_request(request)
if response.status_code != 200
url = response.body[/Url=(.*)/,1]
error = response.body[/Error=(.*)/,1]
if error == "CaptchaRequired"
captcha_token = response.body[/CaptchaToken=(.*)/,1]
captcha_url = response.body[/CaptchaUrl=(.*)/,1]
raise GData::Client::CaptchaError.new(captcha_token, captcha_url),
"#{error} : #{url}"
end
raise GData::Client::AuthorizationError.new(response)
end
@token = response.body[/Auth=(.*)/,1]
return @token
end
# Creates an appropriate Authorization header on a GData::HTTP::Request
# object.
def sign_request!(request)
if @token == nil
raise GData::Client::Error, "Cannot sign request without credentials"
end
request.headers['Authorization'] = "GoogleLogin auth=#{@token}"
end
end
end
end