forked from googleapis/google-api-ruby-client
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.rb
118 lines (105 loc) · 4.24 KB
/
app.rb
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# Copyright 2015 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 'sinatra'
require 'googleauth'
require 'googleauth/stores/redis_token_store'
require 'google/apis/drive_v3'
require 'google/apis/calendar_v3'
require 'dotenv'
LOGIN_URL = '/'
configure do
Dotenv.load
Google::Apis::ClientOptions.default.application_name = 'Ruby client samples'
Google::Apis::ClientOptions.default.application_version = '0.9'
Google::Apis::RequestOptions.default.retries = 3
enable :sessions
set :show_exceptions, false
set :client_id, Google::Auth::ClientId.new(ENV['GOOGLE_CLIENT_ID'],
ENV['GOOGLE_CLIENT_SECRET'])
set :token_store, Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)
end
helpers do
# Returns credentials authorized for the requested scopes. If no credentials are available,
# redirects the user to authorize access.
def credentials_for(scope)
authorizer = Google::Auth::WebUserAuthorizer.new(settings.client_id, scope, settings.token_store, '/oauth2callback')
session[:code_verifier] ||= Google::Auth::WebUserAuthorizer.generate_code_verifier
authorizer.code_verifier = session[:code_verifier]
user_id = session[:user_id]
redirect LOGIN_URL if user_id.nil?
credentials = authorizer.get_credentials(user_id, request)
if credentials.nil?
redirect authorizer.get_authorization_url(login_hint: user_id, request: request)
end
credentials
end
def resize(url, width)
url.sub(/s220/, sprintf('s%d', width))
end
end
# Home page
get('/') do
@client_id = settings.client_id.id
erb :home
end
# Log in the user by validating the identity token generated by the Google Sign-In button.
# This checks that the token is signed by Google, current, and is intended for this application.
#
post('/signin') do
audience = settings.client_id.id
claim = Google::Auth::IDTokens.verify_oidc(params['credential'], aud: audience, azp: audience)
if claim
session[:user_id] = claim['sub']
session[:user_email] = claim['email']
redirect back
else
logger.info('No valid identity token present')
401
end
end
# Retrieve the 10 most recently modified files in Google Drive
get('/drive') do
drive = Google::Apis::DriveV3::DriveService.new
drive.authorization = credentials_for(Google::Apis::DriveV3::AUTH_DRIVE)
@result = drive.list_files(page_size: 10,
fields: 'files(name,modified_time,web_view_link),next_page_token')
erb :drive
end
# Retrieve the next 10 upcoming events from Google Calendar
get('/calendar') do
calendar = Google::Apis::CalendarV3::CalendarService.new
calendar.authorization = credentials_for(Google::Apis::CalendarV3::AUTH_CALENDAR)
calendar_id = 'primary'
@result = calendar.list_events(calendar_id,
max_results: 10,
single_events: true,
order_by: 'startTime',
time_min: Time.now.iso8601)
erb :calendar
end
# Callback for authorization requests. This saves the authorization code and
# redirects back to the URL that originally requested authorization. The code is
# redeemed on the next request.
#
# Important: While the deferred approach is generally easier, it doesn't play well
# with developer mode and sinatra's default cookie-based session implementation. Changes to the
# session state are lost if the page doesn't render due to error, which can lead to further
# errors indicating the code has already been redeemed.
#
# Disabling show_exceptions or using a different session provider (E.g. Rack::Session::Memcache)
# avoids the issue.
get('/oauth2callback') do
target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
redirect target_url
end