yandex_client 0.1.2 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +30 -0
- data/.gitignore +2 -0
- data/.pryrc +6 -0
- data/.rubocop.yml +10 -1
- data/Gemfile +2 -0
- data/README.md +34 -83
- data/dip.yml +8 -11
- data/docker/Dockerfile.dip +8 -0
- data/docker/docker-compose.yml +16 -8
- data/docker/prepare_env.sh +11 -0
- data/lib/yandex_client/auth.rb +62 -0
- data/lib/yandex_client/configurable.rb +26 -0
- data/lib/yandex_client/dav/prop_find_response.rb +70 -0
- data/lib/yandex_client/dav.rb +104 -0
- data/lib/yandex_client/disk.rb +84 -0
- data/lib/yandex_client/error_handler.rb +20 -0
- data/lib/yandex_client/passport.rb +45 -0
- data/lib/yandex_client/version.rb +1 -1
- data/lib/yandex_client.rb +38 -19
- data/yandex_client.gemspec +2 -1
- metadata +29 -14
- data/.travis.yml +0 -12
- data/docker/Dockerfile.2.6 +0 -13
- data/docker/docker-compose.development.yml +0 -18
- data/lib/yandex_client/api_request_error.rb +0 -15
- data/lib/yandex_client/auth/client.rb +0 -57
- data/lib/yandex_client/client.rb +0 -97
- data/lib/yandex_client/dav/client.rb +0 -117
- data/lib/yandex_client/dav/propfind_parser.rb +0 -51
- data/lib/yandex_client/not_found_error.rb +0 -6
- data/lib/yandex_client/passport/client.rb +0 -36
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module YandexClient
|
4
|
+
module ErrorHandler
|
5
|
+
private
|
6
|
+
|
7
|
+
def error_for_response(response)
|
8
|
+
msg = response.body.empty? ? response.status.to_s : response.body.to_s.force_encoding('UTF-8')
|
9
|
+
err =
|
10
|
+
case response.code
|
11
|
+
when 404
|
12
|
+
NotFoundError.new(msg, http_code: 404)
|
13
|
+
else
|
14
|
+
ApiRequestError.new(msg, http_code: response.code)
|
15
|
+
end
|
16
|
+
|
17
|
+
raise err
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module YandexClient
|
4
|
+
# https://tech.yandex.ru/passport/doc/dg/reference/request-docpage/
|
5
|
+
#
|
6
|
+
# Example:
|
7
|
+
# YandexClient::Passport::Client[Token.first.access_token].info
|
8
|
+
class Passport
|
9
|
+
include Configurable
|
10
|
+
include ErrorHandler
|
11
|
+
|
12
|
+
ACTION_URL = 'https://login.yandex.ru/info'
|
13
|
+
|
14
|
+
attr_reader :token
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def with_token(token)
|
18
|
+
new(token)
|
19
|
+
end
|
20
|
+
|
21
|
+
alias [] with_token
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(token)
|
25
|
+
@token = token
|
26
|
+
end
|
27
|
+
|
28
|
+
def info
|
29
|
+
process_response \
|
30
|
+
with_config.get(ACTION_URL, headers: auth_headers)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def auth_headers
|
36
|
+
{Authorization: "Bearer #{@token}"}
|
37
|
+
end
|
38
|
+
|
39
|
+
def process_response(response)
|
40
|
+
return JSON.parse(response.body, symbolize_names: true) if response.status.success?
|
41
|
+
|
42
|
+
error_for_response(response)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/yandex_client.rb
CHANGED
@@ -2,31 +2,50 @@
|
|
2
2
|
|
3
3
|
require 'yandex_client/version'
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
require 'yandex_client/error_handler'
|
6
|
+
require 'yandex_client/configurable'
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
require 'yandex_client/dav'
|
9
|
+
require 'yandex_client/disk'
|
10
|
+
require 'yandex_client/auth'
|
11
|
+
require 'yandex_client/passport'
|
11
12
|
|
12
|
-
|
13
|
-
|
13
|
+
module YandexClient
|
14
|
+
Config = Struct.new \
|
15
|
+
:api_key,
|
16
|
+
:api_secret,
|
17
|
+
:logger,
|
18
|
+
:read_timeout,
|
19
|
+
:write_timeout,
|
20
|
+
:connect_timeout
|
21
|
+
|
22
|
+
class ApiRequestError < StandardError
|
23
|
+
attr_reader :http_code
|
24
|
+
|
25
|
+
def initialize(msg = nil, http_code: nil)
|
26
|
+
if http_code
|
27
|
+
super "#{msg}, (http code #{http_code})"
|
28
|
+
else
|
29
|
+
super msg
|
30
|
+
end
|
31
|
+
|
32
|
+
@http_code = http_code
|
33
|
+
end
|
14
34
|
end
|
15
35
|
|
16
|
-
|
17
|
-
autoload :ApiRequestError, 'yandex_client/api_request_error'
|
18
|
-
autoload :NotFoundError, 'yandex_client/not_found_error'
|
36
|
+
NotFoundError = Class.new(ApiRequestError)
|
19
37
|
|
20
|
-
|
21
|
-
|
22
|
-
|
38
|
+
class << self
|
39
|
+
def config
|
40
|
+
@config ||= Config.new(nil, nil, nil, 120, 600, 5)
|
41
|
+
end
|
23
42
|
|
24
|
-
|
25
|
-
|
26
|
-
|
43
|
+
def configure
|
44
|
+
yield config
|
45
|
+
end
|
27
46
|
|
28
|
-
|
29
|
-
|
30
|
-
|
47
|
+
def auth
|
48
|
+
@auth ||= Auth.new
|
49
|
+
end
|
31
50
|
end
|
32
51
|
end
|
data/yandex_client.gemspec
CHANGED
@@ -23,12 +23,13 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
24
|
spec.require_paths = ['lib']
|
25
25
|
|
26
|
-
spec.add_runtime_dependency '
|
26
|
+
spec.add_runtime_dependency 'http'
|
27
27
|
spec.add_runtime_dependency 'ox'
|
28
28
|
|
29
29
|
spec.add_development_dependency 'bundler'
|
30
30
|
spec.add_development_dependency 'rake', '>= 10'
|
31
31
|
spec.add_development_dependency 'rspec', '>= 3.0'
|
32
|
+
spec.add_development_dependency 'simplecov', '>= 0.9'
|
32
33
|
spec.add_development_dependency 'vcr'
|
33
34
|
spec.add_development_dependency 'webmock'
|
34
35
|
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yandex_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maxim Tretyakov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-12-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: http
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '3.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.9'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.9'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: vcr
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -115,10 +129,11 @@ executables: []
|
|
115
129
|
extensions: []
|
116
130
|
extra_rdoc_files: []
|
117
131
|
files:
|
132
|
+
- ".github/workflows/main.yml"
|
118
133
|
- ".gitignore"
|
134
|
+
- ".pryrc"
|
119
135
|
- ".rspec"
|
120
136
|
- ".rubocop.yml"
|
121
|
-
- ".travis.yml"
|
122
137
|
- Gemfile
|
123
138
|
- LICENSE.txt
|
124
139
|
- README.md
|
@@ -126,17 +141,17 @@ files:
|
|
126
141
|
- bin/console
|
127
142
|
- bin/setup
|
128
143
|
- dip.yml
|
129
|
-
- docker/Dockerfile.
|
130
|
-
- docker/docker-compose.development.yml
|
144
|
+
- docker/Dockerfile.dip
|
131
145
|
- docker/docker-compose.yml
|
146
|
+
- docker/prepare_env.sh
|
132
147
|
- lib/yandex_client.rb
|
133
|
-
- lib/yandex_client/
|
134
|
-
- lib/yandex_client/
|
135
|
-
- lib/yandex_client/
|
136
|
-
- lib/yandex_client/dav/
|
137
|
-
- lib/yandex_client/
|
138
|
-
- lib/yandex_client/
|
139
|
-
- lib/yandex_client/passport
|
148
|
+
- lib/yandex_client/auth.rb
|
149
|
+
- lib/yandex_client/configurable.rb
|
150
|
+
- lib/yandex_client/dav.rb
|
151
|
+
- lib/yandex_client/dav/prop_find_response.rb
|
152
|
+
- lib/yandex_client/disk.rb
|
153
|
+
- lib/yandex_client/error_handler.rb
|
154
|
+
- lib/yandex_client/passport.rb
|
140
155
|
- lib/yandex_client/version.rb
|
141
156
|
- yandex_client.gemspec
|
142
157
|
homepage: https://github.com/yamax2/yandex_client
|
@@ -158,7 +173,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
158
173
|
- !ruby/object:Gem::Version
|
159
174
|
version: '0'
|
160
175
|
requirements: []
|
161
|
-
rubygems_version: 3.
|
176
|
+
rubygems_version: 3.2.5
|
162
177
|
signing_key:
|
163
178
|
specification_version: 4
|
164
179
|
summary: Yandex Client
|
data/.travis.yml
DELETED
data/docker/Dockerfile.2.6
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
FROM ruby:2.6.5-alpine
|
2
|
-
|
3
|
-
RUN apk add --update --no-cache tzdata openssh-client less git build-base
|
4
|
-
RUN cp /usr/share/zoneinfo/Asia/Yekaterinburg /etc/localtime && echo 'Asia/Yekaterinburg' > /etc/timezone
|
5
|
-
|
6
|
-
RUN ssh-keyscan -H github.com >> /etc/ssh/ssh_known_hosts
|
7
|
-
|
8
|
-
ENV BUNDLE_APP_CONFIG /app/.bundle
|
9
|
-
|
10
|
-
RUN echo 'gem: --no-rdoc --no-ri --no-document' > /root/.gemrc
|
11
|
-
RUN gem install 'bundler:2.0.2' rubocop
|
12
|
-
|
13
|
-
WORKDIR /app
|
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module YandexClient
|
4
|
-
class ApiRequestError < StandardError
|
5
|
-
attr_reader :error, :error_description, :code
|
6
|
-
|
7
|
-
def initialize(error:, error_description:, code:)
|
8
|
-
@error = error
|
9
|
-
@error_description = error_description
|
10
|
-
@code = code
|
11
|
-
|
12
|
-
super [error, error_description, "http code #{@code}"].compact.join(', ')
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'uri'
|
4
|
-
|
5
|
-
module YandexClient
|
6
|
-
module Auth
|
7
|
-
# https://tech.yandex.ru/oauth/doc/dg/reference/refresh-client-docpage/
|
8
|
-
# https://tech.yandex.ru/oauth/doc/dg/reference/auto-code-client-docpage/#auto-code-client__get-token
|
9
|
-
#
|
10
|
-
# https://oauth.yandex.ru/authorize?response_type=code&client_id=99bcbd17ad7f411694710592d978a4a2&force_confirm=false
|
11
|
-
#
|
12
|
-
# Example:
|
13
|
-
# token = Token.first
|
14
|
-
#
|
15
|
-
# client = YandexClient::Auth::Client.new
|
16
|
-
# client.create_token(code: '9388894')
|
17
|
-
# client.refresh_token(refresh_token: token.refresh_token)
|
18
|
-
class Client < ::YandexClient::Client
|
19
|
-
AUTH_ACTION_URL = 'https://oauth.yandex.ru/token'
|
20
|
-
|
21
|
-
ACTIONS = {
|
22
|
-
create_token: 'authorization_code',
|
23
|
-
refresh_token: 'refresh_token'
|
24
|
-
}.freeze
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def http(_request_uri)
|
29
|
-
@http ||= super
|
30
|
-
end
|
31
|
-
|
32
|
-
def http_method_for_action
|
33
|
-
METHOD_POST
|
34
|
-
end
|
35
|
-
|
36
|
-
def request_body(params)
|
37
|
-
body_hash = {
|
38
|
-
grant_type: ACTIONS.fetch(@action),
|
39
|
-
client_id: ::YandexClient.config.api_key,
|
40
|
-
client_secret: ::YandexClient.config.api_secret
|
41
|
-
}.merge!(params)
|
42
|
-
|
43
|
-
URI.encode_www_form(body_hash)
|
44
|
-
end
|
45
|
-
|
46
|
-
def request_headers(_params)
|
47
|
-
{
|
48
|
-
'Content-type' => 'application/x-www-form-urlencoded'
|
49
|
-
}
|
50
|
-
end
|
51
|
-
|
52
|
-
def request_uri(_params)
|
53
|
-
@request_uri ||= URI.parse(AUTH_ACTION_URL)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
data/lib/yandex_client/client.rb
DELETED
@@ -1,97 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'oj'
|
4
|
-
require 'net/http'
|
5
|
-
|
6
|
-
module YandexClient
|
7
|
-
# Base api client
|
8
|
-
class Client
|
9
|
-
METHOD_GET = 'Get'
|
10
|
-
METHOD_POST = 'Post'
|
11
|
-
|
12
|
-
ERRORS_BY_CODES = {
|
13
|
-
404 => NotFoundError
|
14
|
-
}.freeze
|
15
|
-
|
16
|
-
def method_missing(method_name, *args, &_)
|
17
|
-
return super unless self.class::ACTIONS.include?(method_name)
|
18
|
-
|
19
|
-
@action = method_name
|
20
|
-
result = nil
|
21
|
-
response = make_request(args.last.is_a?(Hash) ? args.last : {})
|
22
|
-
|
23
|
-
result = parse_response_body(response) unless response.body.nil? || response.body.empty?
|
24
|
-
process_errors(response, result) unless response.is_a?(Net::HTTPSuccess)
|
25
|
-
|
26
|
-
result
|
27
|
-
end
|
28
|
-
|
29
|
-
def respond_to_missing?(method_name, include_private = false)
|
30
|
-
self.class::ACTIONS.include?(method_name) || super
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
def http(request_uri)
|
36
|
-
Net::HTTP.new(request_uri.host, request_uri.port).tap do |http|
|
37
|
-
http.use_ssl = true
|
38
|
-
http.read_timeout = YandexClient.config.read_timeout
|
39
|
-
http.continue_timeout = YandexClient.config.read_timeout
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def http_method_for_action
|
44
|
-
METHOD_GET
|
45
|
-
end
|
46
|
-
|
47
|
-
def log_api_request(request_uri, request, response)
|
48
|
-
return if (logger = YandexClient.config.logger).nil?
|
49
|
-
|
50
|
-
logger.info "#{request.method} #{request_uri} #{response.code} #{response.message}"
|
51
|
-
logger.info "request headers: #{Oj.dump(request.to_hash)}"
|
52
|
-
logger.info "response headers: #{Oj.dump(response.to_hash)}"
|
53
|
-
end
|
54
|
-
|
55
|
-
def make_request(params)
|
56
|
-
request_uri = request_uri(params)
|
57
|
-
@body = request_body(params)
|
58
|
-
|
59
|
-
request = Object.const_get("Net::HTTP::#{http_method_for_action}").new(
|
60
|
-
request_uri.request_uri,
|
61
|
-
request_headers(params)
|
62
|
-
)
|
63
|
-
|
64
|
-
request.body = @body
|
65
|
-
response = http(request_uri).start { |http| http.request(request) }
|
66
|
-
|
67
|
-
log_api_request(request_uri, request, response)
|
68
|
-
|
69
|
-
response
|
70
|
-
end
|
71
|
-
|
72
|
-
def parse_response_body(response)
|
73
|
-
Oj.load(response.body, symbol_keys: true)
|
74
|
-
end
|
75
|
-
|
76
|
-
def process_errors(response, result)
|
77
|
-
klass = ERRORS_BY_CODES.fetch(response.code.to_i, ApiRequestError)
|
78
|
-
|
79
|
-
raise klass.new(
|
80
|
-
error: result.is_a?(Hash) ? result&.fetch(:error) : result,
|
81
|
-
error_description: result.is_a?(Hash) ? result&.fetch(:error_description) : nil,
|
82
|
-
code: response.code.to_i
|
83
|
-
)
|
84
|
-
end
|
85
|
-
|
86
|
-
def request_body(_params)
|
87
|
-
end
|
88
|
-
|
89
|
-
def request_headers(_params)
|
90
|
-
{}
|
91
|
-
end
|
92
|
-
|
93
|
-
def request_uri(_params)
|
94
|
-
raise 'not implemented'
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
@@ -1,117 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'digest'
|
4
|
-
|
5
|
-
module YandexClient
|
6
|
-
module Dav
|
7
|
-
# https://tech.yandex.ru/disk/doc/dg/reference/put-docpage/
|
8
|
-
#
|
9
|
-
# cli = YandexClient::Dav::Client.new(access_token: access_token)
|
10
|
-
#
|
11
|
-
# cli.put(file: '1.txt', name: '/a/b/c/1.txt')
|
12
|
-
# cli.delete(name: '/a/b/c/1.txt')
|
13
|
-
# cli.mkcol(name: '/a/b/c')
|
14
|
-
#
|
15
|
-
# cli.propfind(name: '/a/dip.yml', depth: 0)
|
16
|
-
# cli.propfind(name: '/a', depth: 1)
|
17
|
-
# cli.propfind(name: '/', quota: true)
|
18
|
-
class Client < ::YandexClient::Client
|
19
|
-
ACTION_URL = 'https://webdav.yandex.ru'
|
20
|
-
PROPFIND_QUERY = '<?xml version="1.0" encoding="utf-8"?><propfind xmlns="DAV:"></propfind>'
|
21
|
-
PROPFIND_QUOTA_QUERY = <<~XML
|
22
|
-
<D:propfind xmlns:D="DAV:">
|
23
|
-
<D:prop>
|
24
|
-
<D:quota-available-bytes/>
|
25
|
-
<D:quota-used-bytes/>
|
26
|
-
</D:prop>
|
27
|
-
</D:propfind>
|
28
|
-
XML
|
29
|
-
|
30
|
-
# actions with header processors
|
31
|
-
ACTIONS = {
|
32
|
-
mkcol: nil,
|
33
|
-
delete: nil,
|
34
|
-
|
35
|
-
put: lambda do |params|
|
36
|
-
filename = params.fetch(:file)
|
37
|
-
|
38
|
-
etag = params[:etag] || Digest::MD5.file(filename)
|
39
|
-
sha256 = params[:sha256] || Digest::SHA256.file(filename)
|
40
|
-
size = params[:size] || File.size(filename)
|
41
|
-
|
42
|
-
{
|
43
|
-
Etag: etag.to_s,
|
44
|
-
Sha256: sha256.to_s,
|
45
|
-
Expect: '100-continue',
|
46
|
-
'Content-Length' => size.to_s
|
47
|
-
}
|
48
|
-
end,
|
49
|
-
|
50
|
-
propfind: lambda do |params|
|
51
|
-
depth = 0
|
52
|
-
depth = params.fetch(:depth, 0) unless params.key?(:quota)
|
53
|
-
|
54
|
-
headers = {
|
55
|
-
Depth: depth.to_s,
|
56
|
-
'Content-Type' => 'application/x-www-form-urlencoded'
|
57
|
-
}
|
58
|
-
|
59
|
-
headers['Content-Length'] = @body.length unless @body.nil? || @body.empty?
|
60
|
-
headers
|
61
|
-
end
|
62
|
-
}.freeze
|
63
|
-
|
64
|
-
BODY_PROCESSORS = {
|
65
|
-
put: ->(params) { File.read(params.fetch(:file)) },
|
66
|
-
propfind: lambda do |params|
|
67
|
-
if params.fetch(:quota, false)
|
68
|
-
PROPFIND_QUOTA_QUERY
|
69
|
-
elsif params.fetch(:depth, 0).zero?
|
70
|
-
PROPFIND_QUERY
|
71
|
-
end
|
72
|
-
end
|
73
|
-
}.freeze
|
74
|
-
|
75
|
-
RESPONSE_PARSERS = {
|
76
|
-
propfind: PropfindParser
|
77
|
-
}.freeze
|
78
|
-
|
79
|
-
def initialize(access_token:)
|
80
|
-
@access_token = access_token
|
81
|
-
end
|
82
|
-
|
83
|
-
private
|
84
|
-
|
85
|
-
def http_method_for_action
|
86
|
-
@action.to_s.capitalize
|
87
|
-
end
|
88
|
-
|
89
|
-
def parse_response_body(response)
|
90
|
-
if response.is_a?(Net::HTTPSuccess) && !(parser = RESPONSE_PARSERS[@action]).nil?
|
91
|
-
parser.call(response.body)
|
92
|
-
else
|
93
|
-
response.body
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
def request_body(params)
|
98
|
-
return if (proc = BODY_PROCESSORS[@action]).nil?
|
99
|
-
|
100
|
-
proc.call(params)
|
101
|
-
end
|
102
|
-
|
103
|
-
def request_headers(params)
|
104
|
-
proc = ACTIONS.fetch(@action)
|
105
|
-
|
106
|
-
headers = {Authorization: "OAuth #{@access_token}"}
|
107
|
-
headers.merge!(proc.call(params)) unless proc.nil?
|
108
|
-
|
109
|
-
headers
|
110
|
-
end
|
111
|
-
|
112
|
-
def request_uri(params)
|
113
|
-
URI.parse("#{ACTION_URL}#{params.fetch(:name)}")
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'ox'
|
4
|
-
require 'cgi'
|
5
|
-
|
6
|
-
module YandexClient
|
7
|
-
module Dav
|
8
|
-
class PropfindParser
|
9
|
-
SUCCESS_STATUS = 'HTTP/1.1 200 OK'
|
10
|
-
|
11
|
-
PROCESSORS = {
|
12
|
-
getcontentlength: ->(value) { value.to_i },
|
13
|
-
resourcetype: ->(value) { value.is_a?(Hash) ? :folder : :file }
|
14
|
-
}.freeze
|
15
|
-
|
16
|
-
class ParseError < StandardError
|
17
|
-
end
|
18
|
-
|
19
|
-
def initialize(xml)
|
20
|
-
# FIXME: dup?
|
21
|
-
@document = Ox.load(xml.dup.force_encoding('UTF-8'), mode: :hash)
|
22
|
-
end
|
23
|
-
|
24
|
-
def call
|
25
|
-
@document[:'d:multistatus'].each_with_object({}) do |node, memo|
|
26
|
-
next if (response = node[:'d:response']).nil?
|
27
|
-
|
28
|
-
name = CGI.unescape(response.fetch(:'d:href'))
|
29
|
-
memo[name] = parse_node_props(response.fetch(:'d:propstat'))
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.call(xml)
|
34
|
-
new(xml).call
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def parse_node_props(node)
|
40
|
-
raise ParseError unless node.fetch(:'d:status') == SUCCESS_STATUS
|
41
|
-
|
42
|
-
node.fetch(:'d:prop').each_with_object({}) do |(key, value), memo|
|
43
|
-
prop_key = key.to_s.gsub(/^d:/, '').to_sym
|
44
|
-
processor = PROCESSORS[prop_key]
|
45
|
-
|
46
|
-
memo[prop_key] = processor.nil? ? value : processor.call(value)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module YandexClient
|
4
|
-
module Passport
|
5
|
-
# https://tech.yandex.ru/passport/doc/dg/reference/request-docpage/
|
6
|
-
#
|
7
|
-
# Example:
|
8
|
-
# client = YandexClient::Passport::Client.new(access_token: Token.first.access_token)
|
9
|
-
# client.info
|
10
|
-
class Client < ::YandexClient::Client
|
11
|
-
ACTION_URL = 'https://login.yandex.ru/info'
|
12
|
-
ACTIONS = %i[info].freeze
|
13
|
-
|
14
|
-
# action - info
|
15
|
-
def initialize(access_token:)
|
16
|
-
@access_token = access_token
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def http(_request_uri)
|
22
|
-
@http ||= super
|
23
|
-
end
|
24
|
-
|
25
|
-
def request_uri(_params)
|
26
|
-
@request_uri ||= URI.parse(ACTION_URL)
|
27
|
-
end
|
28
|
-
|
29
|
-
def request_headers(_params)
|
30
|
-
{
|
31
|
-
Authorization: "Bearer #{@access_token}"
|
32
|
-
}
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|