Merge branch 'master' of github.com:google/google-api-ruby-client
[arvados.git] / lib / google / api_client / client_secrets.rb
1 # Copyright 2010 Google Inc.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15
16 require 'multi_json'
17 require 'compat/multi_json'
18
19
20 module Google
21   class APIClient
22     ##
23     # Manages the persistence of client configuration data and secrets.
24     class ClientSecrets
25       def self.load(filename=nil)
26         if filename && File.directory?(filename)
27           search_path = File.expand_path(filename)
28           filename = nil
29         end
30         while filename == nil
31           search_path ||= File.expand_path('.')
32           puts search_path
33           if File.exist?(File.join(search_path, 'client_secrets.json'))
34             filename = File.join(search_path, 'client_secrets.json')
35           elsif search_path == '/' || search_path =~ /[a-zA-Z]:[\/\\]/
36             raise ArgumentError,
37               'No client_secrets.json filename supplied ' +
38               'and/or could not be found in search path.'
39           else
40             search_path = File.expand_path(File.join(search_path, '..'))
41           end
42         end
43         data = File.open(filename, 'r') { |file| MultiJson.load(file.read) }
44         return self.new(data)
45       end
46
47       def initialize(options={})
48         # Client auth configuration
49         @flow = options[:flow] || options.keys.first.to_s || 'web'
50         fdata = options[@flow]
51         @client_id = fdata[:client_id] || fdata["client_id"]
52         @client_secret = fdata[:client_secret] || fdata["client_secret"]
53         @redirect_uris = fdata[:redirect_uris] || fdata["redirect_uris"]
54         @redirect_uris ||= [fdata[:redirect_uri]]
55         @javascript_origins = (
56           fdata[:javascript_origins] ||
57           fdata["javascript_origins"]
58         )
59         @javascript_origins ||= [fdata[:javascript_origin]]
60         @authorization_uri = fdata[:auth_uri] || fdata["auth_uri"]
61         @authorization_uri ||= fdata[:authorization_uri]
62         @token_credential_uri = fdata[:token_uri] || fdata["token_uri"]
63         @token_credential_uri ||= fdata[:token_credential_uri]
64
65         # Associated token info
66         @access_token = fdata[:access_token] || fdata["access_token"]
67         @refresh_token = fdata[:refresh_token] || fdata["refresh_token"]
68         @id_token = fdata[:id_token] || fdata["id_token"]
69         @expires_in = fdata[:expires_in] || fdata["expires_in"]
70         @expires_at = fdata[:expires_at] || fdata["expires_at"]
71         @issued_at = fdata[:issued_at] || fdata["issued_at"]
72       end
73
74       attr_reader(
75         :flow, :client_id, :client_secret, :redirect_uris, :javascript_origins,
76         :authorization_uri, :token_credential_uri, :access_token,
77         :refresh_token, :id_token, :expires_in, :expires_at, :issued_at
78       )
79
80       def to_json
81         return MultiJson.dump({
82           self.flow => ({
83             'client_id' => self.client_id,
84             'client_secret' => self.client_secret,
85             'redirect_uris' => self.redirect_uris,
86             'javascript_origins' => self.javascript_origins,
87             'auth_uri' => self.authorization_uri,
88             'token_uri' => self.token_credential_uri,
89             'access_token' => self.access_token,
90             'refresh_token' => self.refresh_token,
91             'id_token' => self.id_token,
92             'expires_in' => self.expires_in,
93             'expires_at' => self.expires_at,
94             'issued_at' => self.issued_at
95           }).inject({}) do |accu, (k, v)|
96             # Prunes empty values from JSON output.
97             unless v == nil || (v.respond_to?(:empty?) && v.empty?)
98               accu[k] = v
99             end
100             accu
101           end
102         })
103       end
104     end
105   end
106 end