Class: BrowseEverything::Driver::GoogleDrive

Inherits:
Base
  • Object
show all
Defined in:
lib/browse_everything/driver/google_drive.rb

Class Attribute Summary collapse

Instance Attribute Summary collapse

Attributes inherited from Base

#code, #token

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#config, default_sorter, inherited, #key, #name

Constructor Details

#initialize(config_values) ⇒ GoogleDrive

Constructor

Parameters:

  • config_values (Hash)

    configuration for the driver



23
24
25
26
# File 'lib/browse_everything/driver/google_drive.rb', line 23

def initialize(config_values)
  self.class.authentication_klass ||= self.class.default_authentication_klass
  super(config_values)
end

Class Attribute Details

.authentication_klassObject

Returns the value of attribute authentication_klass.



12
13
14
# File 'lib/browse_everything/driver/google_drive.rb', line 12

def authentication_klass
  @authentication_klass
end

Instance Attribute Details

#credentialsObject (readonly)

Returns the value of attribute credentials.



19
20
21
# File 'lib/browse_everything/driver/google_drive.rb', line 19

def credentials
  @credentials
end

Class Method Details

.default_authentication_klassObject



14
15
16
# File 'lib/browse_everything/driver/google_drive.rb', line 14

def default_authentication_klass
  Google::Auth::UserAuthorizer
end

Instance Method Details

Provides a URL for authorizing against Google Drive

Returns:

  • (String)

    the URL



124
125
126
# File 'lib/browse_everything/driver/google_drive.rb', line 124

def auth_link(*_args)
  Addressable::URI.parse(authorizer.get_authorization_url)
end

#authorize!String

Request to authorize the provider This is the method which, passing an HTTP request, redeems an authorization code for an access token

Returns:

  • (String)

    a new access token



168
169
170
171
172
173
# File 'lib/browse_everything/driver/google_drive.rb', line 168

def authorize!
  @credentials = authorizer.get_credentials_from_code(user_id: user_id, code: code)
  @token = @credentials.access_token
  @code = nil # The authorization code can only be redeemed for an access token once
  @token
end

#authorized?true, false

Whether or not the current provider is authorized

Returns:

  • (true, false)


130
131
132
# File 'lib/browse_everything/driver/google_drive.rb', line 130

def authorized?
  @token.present?
end

#authorizerGoogle::Auth::UserAuthorizer

Authorization Object for Google API

Returns:

  • (Google::Auth::UserAuthorizer)


161
162
163
# File 'lib/browse_everything/driver/google_drive.rb', line 161

def authorizer
  @authorizer ||= authenticate
end

#client_idGoogle::Auth::ClientId

Client ID for authorizing against the Google API’s

Returns:

  • (Google::Auth::ClientId)


136
137
138
# File 'lib/browse_everything/driver/google_drive.rb', line 136

def client_id
  @client_id ||= Google::Auth::ClientId.from_hash(client_secrets)
end

#connect(params, _data, _url_options) ⇒ String

This is the method accessed by the BrowseEverythingController for authorizing using an authorization code

Parameters:

  • params (Hash)

    HTTP response passed to the OAuth callback

  • _data (Object, nil)

    an unused parameter

Returns:

  • (String)

    a new access token



179
180
181
182
# File 'lib/browse_everything/driver/google_drive.rb', line 179

def connect(params, _data, _url_options)
  @code = params[:code]
  authorize!
end

#contents(path = '') ⇒ Array<BrowseEverything::FileEntry>

Retrieve the files for any given resource on Google Drive

Parameters:

  • path (String) (defaults to: '')

    the root or Folder path for which to list contents

Returns:



96
97
98
99
100
101
102
103
104
105
# File 'lib/browse_everything/driver/google_drive.rb', line 96

def contents(path = '')
  @entries = []
  drive_service.batch do |drive|
    request_params = Auth::Google::RequestParameters.new
    request_params.q += " and '#{path}' in parents " if path.present?
    list_files(drive, request_params, path: path)
  end

  @sorter.call(@entries)
end

#details(file, _path = '') ⇒ BrowseEverything::FileEntry

Retrieve the file details

Parameters:

  • file (Google::Apis::DriveV3::File)

    the Google Drive File

  • path (String)

    path for the resource details (unused)

Returns:



54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/browse_everything/driver/google_drive.rb', line 54

def details(file, _path = '')
  mime_folder = file.mime_type == 'application/vnd.google-apps.folder'
  BrowseEverything::FileEntry.new(
    file.id,
    "#{key}:#{file.id}",
    file.name,
    file.size.to_i,
    file.modified_time || Time.new,
    mime_folder,
    mime_folder ? 'directory' : file.mime_type
  )
end

#drive_serviceGoogle::Apis::DriveV3::DriveService

Construct a new object for interfacing with the Google Drive API

Returns:

  • (Google::Apis::DriveV3::DriveService)


186
187
188
189
190
# File 'lib/browse_everything/driver/google_drive.rb', line 186

def drive_service
  Google::Apis::DriveV3::DriveService.new.tap do |s|
    s.authorization = credentials
  end
end

#iconObject



40
41
42
# File 'lib/browse_everything/driver/google_drive.rb', line 40

def icon
  'google-plus-sign'
end

Retrieve a link for a resource

Parameters:

  • id (String)

    identifier for the resource

Returns:

  • (Array<String, Hash>)

    authorized link to the resource



110
111
112
113
114
115
116
117
118
119
120
# File 'lib/browse_everything/driver/google_drive.rb', line 110

def link_for(id)
  file = drive_service.get_file(id, fields: 'id, name, size')
  auth_header = { 'Authorization' => "Bearer #{credentials.access_token}" }
  extras = {
    auth_header: auth_header,
    expires: 1.hour.from_now,
    file_name: file.name,
    file_size: file.size.to_i
  }
  [download_url(id), extras]
end

#list_files(drive, request_params, path: '') ⇒ Array<BrowseEverything::FileEntry>

Lists the files given a Google Drive context

Parameters:

  • drive (Google::Apis::DriveV3::DriveService)

    the Google Drive context

  • request_params (RequestParameters)

    the object containing the parameters for the Google Drive API request

  • path (String) (defaults to: '')

    the path (default to the root)

Returns:



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/browse_everything/driver/google_drive.rb', line 72

def list_files(drive, request_params, path: '')
  drive.list_files(**request_params.to_h) do |file_list, error|
    # Raise an exception if there was an error Google API's
    if error.present?
      # In order to properly trigger reauthentication, the token must be cleared
      # Additionally, the error is not automatically raised from the Google Client
      @token = nil
      raise error
    end

    values = file_list.files.map do |gdrive_file|
      details(gdrive_file, path)
    end
    @entries += values.compact

    request_params.page_token = file_list.next_page_token
  end

  @entries += list_files(drive, request_params, path: path) if request_params.page_token.present?
end

#sessionObject



147
148
149
150
151
152
153
154
155
# File 'lib/browse_everything/driver/google_drive.rb', line 147

def session
  AuthenticationFactory.new(
    self.class.authentication_klass,
    client_id,
    scope,
    token_store,
    callback
  )
end

#token=(value) ⇒ Object

The token here must be set using a Hash

Parameters:

  • value (String, Hash)

    the new access token



30
31
32
33
34
35
36
37
38
# File 'lib/browse_everything/driver/google_drive.rb', line 30

def token=(value)
  # This is invoked within BrowseEverythingController using a Hash
  value = value.fetch('access_token') if value.is_a? Hash

  # Restore the credentials if the access token string itself has been cached
  restore_credentials(value) if @credentials.nil?

  super(value)
end

#token_storeGoogle::Auth::Stores::FileTokenStore

Token store file used for authorizing against the Google API’s (This is fundamentally used to temporarily cache access tokens)

Returns:

  • (Google::Auth::Stores::FileTokenStore)


143
144
145
# File 'lib/browse_everything/driver/google_drive.rb', line 143

def token_store
  Google::Auth::Stores::FileTokenStore.new(file: file_token_store_path)
end

#validate_configObject

Validates the configuration for the Google Drive provider



45
46
47
48
# File 'lib/browse_everything/driver/google_drive.rb', line 45

def validate_config
  raise InitializationError, 'GoogleDrive driver requires a :client_id argument' unless config[:client_id]
  raise InitializationError, 'GoogleDrive driver requires a :client_secret argument' unless config[:client_secret]
end