indieauth_discovery 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.editorconfig +3 -0
- data/.github/FUNDING.yml +1 -0
- data/.github/workflows/verify.yml +2 -2
- data/CHANGELOG.md +7 -0
- data/Gemfile +5 -3
- data/Gemfile.lock +16 -8
- data/README.md +3 -1
- data/lib/indieauth_discovery/url.rb +20 -12
- data/lib/indieauth_discovery/version.rb +1 -1
- metadata +3 -3
- data/lib/indieauth_discovery/client.rb +0 -65
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 85ce1354360eb82468c0b95b5b0bb2b890fe730903495f2a524f8a3139fc88ca
|
|
4
|
+
data.tar.gz: 1d62542282b3a37e9eac460e2f34ea5d1d39f513cfa106130f949812f3579938
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b931adb9b684d36571b3019da778d15d4a89a9f0831744a4dfd5286f53a8db7aa012f0d64222ea20a60f4857d86b013d4aa46968dc8c19b36d11a03c6c9ca8af
|
|
7
|
+
data.tar.gz: 3f54b19e8808d4cfc0e8b0cd64ea2d304cef5cf062b72575ff631429030d85f2a0b9810464f506ce62464ee238617ee6da1240561f144dd3587837d4b1cd482e
|
data/.editorconfig
CHANGED
data/.github/FUNDING.yml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ko_fi: craftyphotons
|
|
@@ -18,7 +18,7 @@ jobs:
|
|
|
18
18
|
ruby-version: ${{ matrix.ruby }}
|
|
19
19
|
|
|
20
20
|
- name: Ruby gem cache
|
|
21
|
-
uses: actions/cache@v2.1.
|
|
21
|
+
uses: actions/cache@v2.1.1
|
|
22
22
|
with:
|
|
23
23
|
path: vendor/bundle
|
|
24
24
|
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
|
|
@@ -54,7 +54,7 @@ jobs:
|
|
|
54
54
|
ruby-version: ${{ matrix.ruby }}
|
|
55
55
|
|
|
56
56
|
- name: Ruby gem cache
|
|
57
|
-
uses: actions/cache@v2.1.
|
|
57
|
+
uses: actions/cache@v2.1.1
|
|
58
58
|
with:
|
|
59
59
|
path: vendor/bundle
|
|
60
60
|
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [0.1.1]
|
|
9
|
+
|
|
10
|
+
### Fixes
|
|
11
|
+
|
|
12
|
+
* Use the last permanent redirect before any temporary redirects when canonicalizing URLs [#3](https://github.com/craftyphotons/indieauth_discovery/issues/3).
|
|
13
|
+
|
|
8
14
|
## [0.1.0]
|
|
9
15
|
|
|
10
16
|
Initial release! :tada:
|
|
@@ -15,4 +21,5 @@ Initial release! :tada:
|
|
|
15
21
|
* Authorization, token, and MicroPub endpoint discovery from user profiles
|
|
16
22
|
|
|
17
23
|
[Unreleased]: https://github.com/craftyphotons/indieauth_discovery/compare/v0.1.0...HEAD
|
|
24
|
+
[0.1.1]: https://github.com/craftyphotons/indieauth_discovery/releases/tag/v0.1.1
|
|
18
25
|
[0.1.0]: https://github.com/craftyphotons/indieauth_discovery/releases/tag/v0.1.0
|
data/Gemfile
CHANGED
|
@@ -5,11 +5,13 @@ source 'https://rubygems.org'
|
|
|
5
5
|
gemspec
|
|
6
6
|
|
|
7
7
|
gem 'bundler-audit', '~> 0.7'
|
|
8
|
+
gem 'byebug', '~> 11.1'
|
|
8
9
|
gem 'coveralls', '~> 0.8'
|
|
10
|
+
gem 'pry', '~> 0.13'
|
|
9
11
|
gem 'rake', '~> 13.0'
|
|
10
12
|
gem 'rspec', '~> 3.9'
|
|
11
|
-
gem 'rubocop', '~> 0.
|
|
12
|
-
gem 'rubocop-performance', '~> 1.
|
|
13
|
-
gem 'rubocop-rspec', '~> 1.
|
|
13
|
+
gem 'rubocop', '~> 0.90'
|
|
14
|
+
gem 'rubocop-performance', '~> 1.8'
|
|
15
|
+
gem 'rubocop-rspec', '~> 1.43'
|
|
14
16
|
gem 'webmock', '~> 3.8'
|
|
15
17
|
gem 'yard', '~> 0.9'
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
indieauth_discovery (0.1.
|
|
4
|
+
indieauth_discovery (0.1.1)
|
|
5
5
|
faraday (~> 1.0)
|
|
6
6
|
faraday_middleware (~> 1.0)
|
|
7
7
|
link-header-parser (~> 2.0)
|
|
@@ -18,6 +18,8 @@ GEM
|
|
|
18
18
|
bundler-audit (0.7.0.1)
|
|
19
19
|
bundler (>= 1.2.0, < 3)
|
|
20
20
|
thor (>= 0.18, < 2)
|
|
21
|
+
byebug (11.1.3)
|
|
22
|
+
coderay (1.1.3)
|
|
21
23
|
coveralls (0.8.23)
|
|
22
24
|
json (>= 1.8, < 3)
|
|
23
25
|
simplecov (~> 0.16.1)
|
|
@@ -36,6 +38,7 @@ GEM
|
|
|
36
38
|
json (2.3.1)
|
|
37
39
|
link-header-parser (2.0.0)
|
|
38
40
|
absolutely (~> 4.0)
|
|
41
|
+
method_source (1.0.0)
|
|
39
42
|
mini_portile2 (2.4.0)
|
|
40
43
|
multipart-post (2.1.1)
|
|
41
44
|
nokogiri (1.10.10)
|
|
@@ -43,6 +46,9 @@ GEM
|
|
|
43
46
|
parallel (1.19.2)
|
|
44
47
|
parser (2.7.1.4)
|
|
45
48
|
ast (~> 2.4.1)
|
|
49
|
+
pry (0.13.1)
|
|
50
|
+
coderay (~> 1.1)
|
|
51
|
+
method_source (~> 1.0)
|
|
46
52
|
public_suffix (4.0.5)
|
|
47
53
|
rainbow (3.0.0)
|
|
48
54
|
rake (13.0.1)
|
|
@@ -61,7 +67,7 @@ GEM
|
|
|
61
67
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
62
68
|
rspec-support (~> 3.9.0)
|
|
63
69
|
rspec-support (3.9.3)
|
|
64
|
-
rubocop (0.
|
|
70
|
+
rubocop (0.90.0)
|
|
65
71
|
parallel (~> 1.10)
|
|
66
72
|
parser (>= 2.7.1.1)
|
|
67
73
|
rainbow (>= 2.2.2, < 4.0)
|
|
@@ -72,10 +78,10 @@ GEM
|
|
|
72
78
|
unicode-display_width (>= 1.4.0, < 2.0)
|
|
73
79
|
rubocop-ast (0.3.0)
|
|
74
80
|
parser (>= 2.7.1.4)
|
|
75
|
-
rubocop-performance (1.
|
|
76
|
-
rubocop (>= 0.82.0)
|
|
77
|
-
rubocop-rspec (1.42.0)
|
|
81
|
+
rubocop-performance (1.8.0)
|
|
78
82
|
rubocop (>= 0.87.0)
|
|
83
|
+
rubocop-rspec (1.43.2)
|
|
84
|
+
rubocop (~> 0.87)
|
|
79
85
|
ruby-progressbar (1.10.1)
|
|
80
86
|
safe_yaml (1.0.5)
|
|
81
87
|
simplecov (0.16.1)
|
|
@@ -101,13 +107,15 @@ PLATFORMS
|
|
|
101
107
|
|
|
102
108
|
DEPENDENCIES
|
|
103
109
|
bundler-audit (~> 0.7)
|
|
110
|
+
byebug (~> 11.1)
|
|
104
111
|
coveralls (~> 0.8)
|
|
105
112
|
indieauth_discovery!
|
|
113
|
+
pry (~> 0.13)
|
|
106
114
|
rake (~> 13.0)
|
|
107
115
|
rspec (~> 3.9)
|
|
108
|
-
rubocop (~> 0.
|
|
109
|
-
rubocop-performance (~> 1.
|
|
110
|
-
rubocop-rspec (~> 1.
|
|
116
|
+
rubocop (~> 0.90)
|
|
117
|
+
rubocop-performance (~> 1.8)
|
|
118
|
+
rubocop-rspec (~> 1.43)
|
|
111
119
|
webmock (~> 3.8)
|
|
112
120
|
yard (~> 0.9)
|
|
113
121
|
|
data/README.md
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
[](https://codeclimate.com/github/craftyphotons/indieauth_discovery)
|
|
6
6
|
|
|
7
7
|
[](https://coveralls.io/github/craftyphotons/indieauth_discovery)
|
|
8
|
+
|
|
9
|
+
[](https://rubygems.org/gems/indieauth_discovery)
|
|
8
10
|
|
|
9
11
|
Profile and client discovery for [Ruby](https://www.ruby-lang.org/en)-based [IndieAuth](https://indieauth.spec.indieweb.org) clients and providers.
|
|
10
12
|
|
|
@@ -101,4 +103,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
|
101
103
|
|
|
102
104
|
## Code of Conduct
|
|
103
105
|
|
|
104
|
-
Everyone interacting in the IndieauthDiscovery project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/
|
|
106
|
+
Everyone interacting in the IndieauthDiscovery project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/craftyphotons/indieauth_discovery/blob/main/CODE_OF_CONDUCT.md).
|
|
@@ -9,11 +9,12 @@ require_relative './errors'
|
|
|
9
9
|
module IndieAuthDiscovery
|
|
10
10
|
# Canonicalization for IndieAuth client and user profile URLs.
|
|
11
11
|
class URL
|
|
12
|
-
attr_reader :original_url, :canonical_url
|
|
12
|
+
attr_reader :original_url, :canonical_url, :redirects
|
|
13
13
|
|
|
14
14
|
def initialize(original_url)
|
|
15
15
|
@original_url = original_url.to_s
|
|
16
16
|
@canonical_url = original_url.to_s
|
|
17
|
+
@redirects = []
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
def self.canonicalize(original_url)
|
|
@@ -51,6 +52,8 @@ module IndieAuthDiscovery
|
|
|
51
52
|
|
|
52
53
|
FARADAY_ERRORS = [Faraday::ConnectionFailed, Faraday::TimeoutError].freeze
|
|
53
54
|
|
|
55
|
+
PERMANENT_REDIRECTS = [301, 308].freeze
|
|
56
|
+
|
|
54
57
|
def normalize_url(url)
|
|
55
58
|
URI.parse(url).normalize
|
|
56
59
|
end
|
|
@@ -93,26 +96,31 @@ module IndieAuthDiscovery
|
|
|
93
96
|
|
|
94
97
|
# @see https://indieauth.spec.indieweb.org/#redirect-examples
|
|
95
98
|
def follow_redirects(uri, response)
|
|
96
|
-
return uri unless [301, 302].include?(response.status)
|
|
99
|
+
return uri unless [300, 301, 302, 303, 304, 307, 308].include?(response.status)
|
|
100
|
+
|
|
101
|
+
redirector(uri).head
|
|
102
|
+
redirects.each do |redirect|
|
|
103
|
+
status = redirect[:status]
|
|
104
|
+
break unless PERMANENT_REDIRECTS.include?(status)
|
|
97
105
|
|
|
98
|
-
|
|
99
|
-
|
|
106
|
+
uri = redirect[:url] if PERMANENT_REDIRECTS.include?(status)
|
|
107
|
+
end
|
|
100
108
|
|
|
101
|
-
uri = redirects.last if redirects.any? && redirects.last != uri
|
|
102
109
|
uri
|
|
103
110
|
end
|
|
104
111
|
|
|
105
|
-
def redirector(uri
|
|
112
|
+
def redirector(uri)
|
|
106
113
|
@redirector ||=
|
|
107
|
-
|
|
108
|
-
callback
|
|
109
|
-
Faraday.
|
|
110
|
-
faraday.use(FaradayMiddleware::FollowRedirects, callback: callback)
|
|
111
|
-
faraday.adapter(Faraday.default_adapter)
|
|
112
|
-
end
|
|
114
|
+
Faraday.new(url: uri) do |faraday|
|
|
115
|
+
faraday.use(FaradayMiddleware::FollowRedirects, callback: method(:redirect_callback))
|
|
116
|
+
faraday.adapter(Faraday.default_adapter)
|
|
113
117
|
end
|
|
114
118
|
end
|
|
115
119
|
|
|
120
|
+
def redirect_callback(old_env, new_env)
|
|
121
|
+
redirects << { url: new_env.url.to_s, status: old_env.status }
|
|
122
|
+
end
|
|
123
|
+
|
|
116
124
|
def raise_invalid_url_error(url)
|
|
117
125
|
raise InvalidURLError.new(:invalid_url, 'URL must begin with http:// or https://', url)
|
|
118
126
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: indieauth_discovery
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tony Burns
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-
|
|
11
|
+
date: 2020-09-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
@@ -74,6 +74,7 @@ extensions: []
|
|
|
74
74
|
extra_rdoc_files: []
|
|
75
75
|
files:
|
|
76
76
|
- ".editorconfig"
|
|
77
|
+
- ".github/FUNDING.yml"
|
|
77
78
|
- ".github/ISSUE_TEMPLATE/bug_report.md"
|
|
78
79
|
- ".github/ISSUE_TEMPLATE/feature_request.md"
|
|
79
80
|
- ".github/PULL_REQUEST_TEMPLATE.md"
|
|
@@ -94,7 +95,6 @@ files:
|
|
|
94
95
|
- bin/setup
|
|
95
96
|
- indieauth_discovery.gemspec
|
|
96
97
|
- lib/indieauth_discovery.rb
|
|
97
|
-
- lib/indieauth_discovery/client.rb
|
|
98
98
|
- lib/indieauth_discovery/errors.rb
|
|
99
99
|
- lib/indieauth_discovery/profile.rb
|
|
100
100
|
- lib/indieauth_discovery/url.rb
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'faraday'
|
|
4
|
-
require 'faraday_middleware/response/follow_redirects'
|
|
5
|
-
require 'link-header-parser'
|
|
6
|
-
require 'nokogiri'
|
|
7
|
-
|
|
8
|
-
require_relative './errors'
|
|
9
|
-
require_relative './url'
|
|
10
|
-
|
|
11
|
-
module IndieAuthDiscovery
|
|
12
|
-
# Client information discovery according to the IndieAuth spec.
|
|
13
|
-
#
|
|
14
|
-
# @see https://indieauth.spec.indieweb.org/#client-information-discovery
|
|
15
|
-
class Profile
|
|
16
|
-
attr_reader :profile_url, :authorization_endpoint, :token_endpoint, :response
|
|
17
|
-
|
|
18
|
-
def initialize(default_scheme: :https)
|
|
19
|
-
@default_scheme = default_scheme
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def call(url)
|
|
23
|
-
@profile_url = URL.canonicalize(url)
|
|
24
|
-
retrieve
|
|
25
|
-
discover
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
private
|
|
29
|
-
|
|
30
|
-
def retrieve
|
|
31
|
-
@response ||= get_follow_redirects(profile_url)
|
|
32
|
-
@link_headers = parse_link_headers(response)
|
|
33
|
-
@profile_document = parse_html_document(response)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def discover
|
|
37
|
-
@authorization_endpoint = first_link('authorization_endpoint')
|
|
38
|
-
@token_endpoint = first_link('token_endpoint')
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def parse_link_headers(response)
|
|
42
|
-
return {} unless response.headers['link']
|
|
43
|
-
|
|
44
|
-
LinkHeaderParser.parse(response.headers['link'], base: profile_url).group_by_relation_type
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def parse_html_document(response)
|
|
48
|
-
return Nokogiri::HTML('') unless response.headers['content-type'].start_with?('text/html')
|
|
49
|
-
|
|
50
|
-
Nokogiri::HTML(response.body)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def first_link(rel)
|
|
54
|
-
@link_headers[rel.to_sym]&.first&.target_uri ||
|
|
55
|
-
@profile_document.at_xpath("//link[@rel='#{rel}']")&.attribute('href')&.to_s
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def get_follow_redirects(url)
|
|
59
|
-
Faraday.new(url: url) do |faraday|
|
|
60
|
-
faraday.use(FaradayMiddleware::FollowRedirects)
|
|
61
|
-
faraday.adapter(Faraday.default_adapter)
|
|
62
|
-
end.get
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
end
|