121 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Ruby
		
	
	
	
		
		
			
		
	
	
			121 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Ruby
		
	
	
	
|  | # 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 'google-id-token' | ||
|  | 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) | ||
|  |     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 | ||
|  |   # Important: The google-id-token gem is not production ready. If using, consider fetching and | ||
|  |   # supplying the valid keys separately rather than using the built-in certificate fetcher. | ||
|  |   validator = GoogleIDToken::Validator.new | ||
|  |   claim = validator.check(params['id_token'], audience, audience) | ||
|  |   if claim | ||
|  |     session[:user_id] = claim['sub'] | ||
|  |     session[:user_email] = claim['email'] | ||
|  |     200
 | ||
|  |   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 autorization 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 |