Total Complexity | 50 |
Total Lines | 233 |
Duplicated Lines | 0 % |
Complex classes like Client often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | require 'base64' |
||
7 | module RingCentralSdk::REST |
||
8 | class Client |
||
9 | ACCESS_TOKEN_TTL = 600 # 10 minutes |
||
10 | REFRESH_TOKEN_TTL = 36000 # 10 hours |
||
11 | REFRESH_TOKEN_TTL_REMEMBER = 604800 # 1 week |
||
12 | ACCOUNT_PREFIX = '/account/' |
||
13 | ACCOUNT_ID = '~' |
||
14 | AUTHZ_ENDPOINT = '/restapi/oauth/authorize' |
||
15 | TOKEN_ENDPOINT = '/restapi/oauth/token' |
||
16 | REVOKE_ENDPOINT = '/restapi/oauth/revoke' |
||
17 | API_VERSION = 'v1.0' |
||
18 | URL_PREFIX = '/restapi' |
||
19 | DEFAULT_LANGUAGE = 'en-us' |
||
20 | |||
21 | attr_reader :app_config |
||
22 | attr_reader :http |
||
23 | attr_reader :oauth2client |
||
24 | attr_reader :token |
||
25 | attr_reader :user_agent |
||
26 | attr_reader :messages |
||
27 | |||
28 | attr_reader :instance_headers |
||
29 | |||
30 | def initialize(app_key='', app_secret='', server_url=RingCentralSdk::RC_SERVER_SANDBOX, opts={}) |
||
31 | init_attributes() |
||
32 | self.app_config = RingCentralSdk::REST::ConfigApp.new( |
||
33 | app_key, app_secret, server_url, opts) |
||
34 | |||
35 | if opts.key?(:username) && opts.key?(:password) |
||
36 | extension = opts.key?(:extension) ? opts[:extension] : '' |
||
37 | authorize_password(opts[:username], extension, opts[:password]) |
||
38 | end |
||
39 | |||
40 | @instance_headers = opts[:headers] || {} |
||
41 | |||
42 | @messages = RingCentralSdk::REST::Messages.new self |
||
43 | end |
||
44 | |||
45 | def app_config=(new_app_config) |
||
46 | @app_config = new_app_config |
||
47 | @oauth2client = new_oauth2_client() |
||
48 | end |
||
49 | |||
50 | def init_attributes() |
||
51 | @token = nil |
||
52 | @http = nil |
||
53 | @user_agent = get_user_agent() |
||
54 | end |
||
55 | |||
56 | def api_version_url() |
||
57 | return @app_config.server_url + URL_PREFIX + '/' + API_VERSION |
||
58 | end |
||
59 | |||
60 | def create_url(url, add_server=false, add_method=nil, add_token=false) |
||
61 | built_url = '' |
||
62 | has_http = !url.index('http://').nil? && !url.index('https://').nil? |
||
63 | |||
64 | if add_server && ! has_http |
||
65 | built_url += @app_config.server_url |
||
66 | end |
||
67 | |||
68 | if url.index(URL_PREFIX).nil? && ! has_http |
||
69 | built_url += URL_PREFIX + '/' + API_VERSION + '/' |
||
70 | end |
||
71 | |||
72 | if url.index('/') == 0 |
||
73 | if built_url =~ /\/$/ |
||
74 | built_url += url.gsub(/^\//, '') |
||
75 | else |
||
76 | built_url += url |
||
77 | end |
||
78 | else # no / |
||
79 | if built_url =~ /\/$/ |
||
80 | built_url += url |
||
81 | else |
||
82 | built_url += '/' + url |
||
83 | end |
||
84 | end |
||
85 | |||
86 | return built_url |
||
87 | end |
||
88 | |||
89 | def create_urls(urls, add_server=false, add_method=nil, add_token=false) |
||
90 | unless urls.is_a?(Array) |
||
91 | raise "URLs is not an array" |
||
92 | end |
||
93 | built_urls = [] |
||
94 | urls.each do |url| |
||
95 | built_urls.push(create_url(url, add_server, add_method, add_token)) |
||
96 | end |
||
97 | return built_urls |
||
98 | end |
||
99 | |||
100 | def authorize_url(opts = {}) |
||
101 | @oauth2client.auth_code.authorize_url(_add_redirect_uri(opts)) |
||
102 | end |
||
103 | |||
104 | def authorize_code(code, opts = {}) |
||
105 | token = @oauth2client.auth_code.get_token(code, _add_redirect_uri(opts)) |
||
106 | set_token(token) |
||
107 | return token |
||
108 | end |
||
109 | |||
110 | def _add_redirect_uri(opts = {}) |
||
111 | if !opts.key?(:redirect_uri) && @app_config.redirect_url.to_s.length > 0 |
||
112 | opts[:redirect_uri] = @app_config.redirect_url.to_s |
||
113 | end |
||
114 | return opts |
||
115 | end |
||
116 | |||
117 | def authorize_password(username, extension = '', password = '', remember = false) |
||
118 | token = @oauth2client.password.get_token(username, password, { |
||
119 | extension: extension, |
||
120 | headers: {'Authorization' => 'Basic ' + get_api_key()}}) |
||
121 | set_token(token) |
||
122 | return token |
||
123 | end |
||
124 | |||
125 | def authorize_user(user, remember = false) |
||
126 | authorize_password(user.username, user.extension, user.password) |
||
127 | end |
||
128 | |||
129 | def set_token(token) |
||
130 | if token.is_a? Hash |
||
131 | token = OAuth2::AccessToken::from_hash(@oauth2client, token) |
||
132 | end |
||
133 | |||
134 | unless token.is_a? OAuth2::AccessToken |
||
135 | raise "Token is not a OAuth2::AccessToken" |
||
136 | end |
||
137 | |||
138 | @token = token |
||
139 | |||
140 | @http = Faraday.new(url: api_version_url()) do |conn| |
||
141 | conn.request :oauth2_refresh, @token |
||
142 | conn.request :json |
||
143 | conn.request :url_encoded |
||
144 | conn.headers['User-Agent'] = @user_agent |
||
145 | if @instance_headers.is_a? Hash |
||
146 | @instance_headers.each do |k,v| |
||
147 | conn.headers[k] = v |
||
148 | end |
||
149 | end |
||
150 | conn.headers['RC-User-Agent'] = @user_agent |
||
151 | conn.headers['SDK-User-Agent'] = @user_agent |
||
152 | conn.response :json, content_type: /\bjson$/ |
||
153 | conn.adapter Faraday.default_adapter |
||
154 | end |
||
155 | end |
||
156 | |||
157 | def new_oauth2_client() |
||
158 | return OAuth2::Client.new(@app_config.key, @app_config.secret, |
||
159 | site: @app_config.server_url, |
||
160 | authorize_url: AUTHZ_ENDPOINT, |
||
161 | token_url: TOKEN_ENDPOINT) |
||
162 | end |
||
163 | |||
164 | def set_oauth2_client(client=nil) |
||
165 | if client.nil? |
||
166 | @oauth2client = new_oauth2_client() |
||
167 | elsif client.is_a? OAuth2::Client |
||
168 | @oauth2client = client |
||
169 | else |
||
170 | fail "client is not an OAuth2::Client" |
||
171 | end |
||
172 | end |
||
173 | |||
174 | def get_api_key() |
||
175 | api_key = (@app_config.key.is_a?(String) && @app_config.secret.is_a?(String)) \ |
||
176 | ? Base64.encode64("#{@app_config.key}:#{@app_config.secret}").gsub(/[\s\t\r\n]/,'') : '' |
||
177 | return api_key |
||
178 | end |
||
179 | |||
180 | def send_request(request_sdk = {}) |
||
181 | if request_sdk.is_a? Hash |
||
182 | request_sdk = RingCentralSdk::REST::Request::Simple.new(request_sdk) |
||
183 | elsif !request_sdk.is_a? RingCentralSdk::REST::Request::Base |
||
184 | fail 'Request is not a RingCentralSdk::REST::Request::Base' |
||
185 | end |
||
186 | |||
187 | method = request_sdk.method.to_s.downcase |
||
188 | method = 'get' if method.empty? |
||
189 | |||
190 | res = nil |
||
191 | |||
192 | case method |
||
193 | when 'delete' |
||
194 | res = @http.delete { |req| req = inflate_request(req, request_sdk) } |
||
195 | when 'get' |
||
196 | res = @http.get { |req| req = inflate_request(req, request_sdk) } |
||
197 | when 'post' |
||
198 | res = @http.post { |req| req = inflate_request(req, request_sdk) } |
||
199 | when 'put' |
||
200 | res = @http.put { |req| req = inflate_request(req, request_sdk) } |
||
201 | else |
||
202 | fail "method [#{method}] not supported" |
||
203 | end |
||
204 | return res |
||
205 | end |
||
206 | |||
207 | def inflate_request(req_faraday, req_sdk) |
||
208 | req_faraday.url req_sdk.url |
||
209 | req_faraday.body = req_sdk.body if req_sdk.body |
||
210 | if req_sdk.params.is_a? Hash |
||
211 | req_sdk.params.each { |k,v| req_faraday.params[k] = v } |
||
212 | end |
||
213 | if req_sdk.headers.is_a? Hash |
||
214 | req_sdk.headers.each { |k,v| req_faraday.headers[k] = v } |
||
215 | end |
||
216 | |||
217 | ct = req_sdk.content_type |
||
218 | if !ct.nil? && ct.to_s.length > 0 |
||
219 | req_faraday.headers['Content-Type'] = ct.to_s |
||
220 | end |
||
221 | return req_faraday |
||
222 | end |
||
223 | |||
224 | def get_user_agent() |
||
225 | ua = "ringcentral-sdk-ruby/#{RingCentralSdk::VERSION} %s/%s %s" % [ |
||
226 | (RUBY_ENGINE rescue nil or "ruby"), |
||
227 | RUBY_VERSION, |
||
228 | RUBY_PLATFORM |
||
229 | ] |
||
230 | return ua.strip |
||
231 | end |
||
232 | |||
233 | def create_subscription() |
||
234 | return RingCentralSdk::REST::Subscription.new(self) |
||
235 | end |
||
236 | |||
237 | alias_method :authorize, :authorize_password |
||
238 | alias_method :login, :authorize_password |
||
239 | private :api_version_url |
||
240 | end |
||
242 |