rodauth-oauth 0.7.1 → 0.7.2
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/CHANGELOG.md +22 -0
- data/lib/rodauth/features/oauth.rb +38 -9
- data/lib/rodauth/oauth/version.rb +1 -1
- data/locales/en.yml +2 -1
- data/templates/authorize.str +17 -7
- data/templates/oauth_tokens.str +7 -5
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d000e6a25796dbdc8c58d378e93819343810f6089c33d02732443342ce721ec3
|
4
|
+
data.tar.gz: e61c19bd7e74c3f2b68541bf7aa78c143c669d5a745bf4efc389e786598fbcd8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9d727127c9e5a6d3a935b6194fbd0bd81358f3ea9876387d1639c3cf419b15246a0b89d57688d8ef15e830bd7b86f482463332c0fa843cb494ee56afe23c3e2e
|
7
|
+
data.tar.gz: 1d565e48e99b4897ca47a64c5b937405a5a10a9696893059d59670e58ae0dc1677daf17194ddfefcdd0d9fc33960ab5fd3a1fd3716cbe0e7fae961537ad46058
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,28 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
### 0.7.2 (14/12/2021)
|
6
|
+
|
7
|
+
#### Features
|
8
|
+
|
9
|
+
* Revoking tokens from the OAuth Application management interface (@muellerj)
|
10
|
+
|
11
|
+
Token revocation was only possible when using the client ID and Secret, to aid "logout" functionality from client applications. Although the admin interface (available via `r.oauth_applications`) displayed a "Revoke" button alongside tokens in the list page, this was not working. The RFC does allow for the use case of application administrators being able to manually revoke tokens (as a result of client support, for example), so this functionality was enabled (only for the oauth application owner, for now).
|
12
|
+
|
13
|
+
#### Bugfixes
|
14
|
+
|
15
|
+
Default scope usage related bugfixes:
|
16
|
+
|
17
|
+
* Improved default scope conversion to avoid nested arrays (@muellerj);
|
18
|
+
* Authorize form shows a disabled checkbox and POST's no scope when default scope is to be used (@muellerj);
|
19
|
+
* example default scope fixed for example authorization server (should be string) (@muellerj);
|
20
|
+
* several param fixes in view templates (@muellerj);
|
21
|
+
|
22
|
+
OAuth Applications Management fixes:
|
23
|
+
|
24
|
+
* Access to OAuth Application page is now restricted to app owner;
|
25
|
+
* OAuth Applications page now lists the **only** the applications owned by the logged in user;
|
26
|
+
|
5
27
|
### 0.7.1 (05/12/2021)
|
6
28
|
|
7
29
|
#### Improvements
|
@@ -66,6 +66,7 @@ module Rodauth
|
|
66
66
|
notice_flash "Your oauth application has been registered", "create_oauth_application"
|
67
67
|
|
68
68
|
notice_flash "The oauth token has been revoked", "revoke_oauth_token"
|
69
|
+
error_flash "You are not authorized to revoke this token", "revoke_unauthorized_account"
|
69
70
|
|
70
71
|
view "authorize", "Authorize", "authorize"
|
71
72
|
view "oauth_applications", "Oauth Applications", "oauth_applications"
|
@@ -279,7 +280,13 @@ module Rodauth
|
|
279
280
|
next unless is_authorization_server?
|
280
281
|
|
281
282
|
before_revoke_route
|
282
|
-
|
283
|
+
|
284
|
+
if logged_in?
|
285
|
+
require_account
|
286
|
+
require_oauth_application_from_account
|
287
|
+
else
|
288
|
+
require_oauth_application
|
289
|
+
end
|
283
290
|
|
284
291
|
r.post do
|
285
292
|
catch_error do
|
@@ -386,7 +393,10 @@ module Rodauth
|
|
386
393
|
end
|
387
394
|
|
388
395
|
request.on(oauth_applications_id_pattern) do |id|
|
389
|
-
oauth_application = db[oauth_applications_table]
|
396
|
+
oauth_application = db[oauth_applications_table]
|
397
|
+
.where(oauth_applications_id_column => id)
|
398
|
+
.where(oauth_applications_account_id_column => account_id)
|
399
|
+
.first
|
390
400
|
next unless oauth_application
|
391
401
|
|
392
402
|
scope.instance_variable_set(:@oauth_application, oauth_application)
|
@@ -407,7 +417,8 @@ module Rodauth
|
|
407
417
|
end
|
408
418
|
|
409
419
|
request.get do
|
410
|
-
scope.instance_variable_set(:@oauth_applications, db[oauth_applications_table]
|
420
|
+
scope.instance_variable_set(:@oauth_applications, db[oauth_applications_table]
|
421
|
+
.where(oauth_applications_account_id_column => account_id))
|
411
422
|
oauth_applications_view
|
412
423
|
end
|
413
424
|
|
@@ -474,7 +485,7 @@ module Rodauth
|
|
474
485
|
when String
|
475
486
|
scope.split(" ")
|
476
487
|
when nil
|
477
|
-
|
488
|
+
Array(oauth_application_default_scope)
|
478
489
|
end
|
479
490
|
end
|
480
491
|
|
@@ -684,6 +695,20 @@ module Rodauth
|
|
684
695
|
authorization_required unless @oauth_application && secret_matches?(@oauth_application, client_secret)
|
685
696
|
end
|
686
697
|
|
698
|
+
def require_oauth_application_from_account
|
699
|
+
ds = db[oauth_applications_table]
|
700
|
+
.join(oauth_tokens_table, Sequel[oauth_tokens_table][oauth_tokens_oauth_application_id_column] =>
|
701
|
+
Sequel[oauth_applications_table][oauth_applications_id_column])
|
702
|
+
.where(oauth_token_by_token_ds(param("token")).opts.fetch(:where, true))
|
703
|
+
.where(Sequel[oauth_applications_table][oauth_applications_account_id_column] => account_id)
|
704
|
+
|
705
|
+
@oauth_application = ds.qualify.first
|
706
|
+
return if @oauth_application
|
707
|
+
|
708
|
+
set_redirect_error_flash revoke_unauthorized_account_error_flash
|
709
|
+
redirect request.referer || "/"
|
710
|
+
end
|
711
|
+
|
687
712
|
def secret_matches?(oauth_application, secret)
|
688
713
|
BCrypt::Password.new(oauth_application[oauth_applications_client_secret_column]) == secret
|
689
714
|
end
|
@@ -774,17 +799,21 @@ module Rodauth
|
|
774
799
|
end
|
775
800
|
end
|
776
801
|
|
777
|
-
def
|
802
|
+
def oauth_token_by_token_ds(token)
|
778
803
|
ds = db[oauth_tokens_table]
|
779
804
|
|
780
805
|
ds = if oauth_tokens_token_hash_column
|
781
|
-
ds.where(oauth_tokens_token_hash_column => generate_token_hash(token))
|
806
|
+
ds.where(Sequel[oauth_tokens_table][oauth_tokens_token_hash_column] => generate_token_hash(token))
|
782
807
|
else
|
783
|
-
ds.where(oauth_tokens_token_column => token)
|
808
|
+
ds.where(Sequel[oauth_tokens_table][oauth_tokens_token_column] => token)
|
784
809
|
end
|
785
810
|
|
786
|
-
ds.where(Sequel[oauth_tokens_expires_in_column] >= Sequel::CURRENT_TIMESTAMP)
|
787
|
-
.where(oauth_tokens_revoked_at_column => nil)
|
811
|
+
ds.where(Sequel[oauth_tokens_table][oauth_tokens_expires_in_column] >= Sequel::CURRENT_TIMESTAMP)
|
812
|
+
.where(Sequel[oauth_tokens_table][oauth_tokens_revoked_at_column] => nil)
|
813
|
+
end
|
814
|
+
|
815
|
+
def oauth_token_by_token(token)
|
816
|
+
oauth_token_by_token_ds(token).first
|
788
817
|
end
|
789
818
|
|
790
819
|
def oauth_token_by_refresh_token(token, revoked: false)
|
data/locales/en.yml
CHANGED
@@ -3,6 +3,7 @@ en:
|
|
3
3
|
require_authorization_error_flash: "Please authorize to continue"
|
4
4
|
create_oauth_application_error_flash: "There was an error registering your oauth application"
|
5
5
|
create_oauth_application_notice_flash: "Your oauth application has been registered"
|
6
|
+
revoke_unauthorized_account_error_flash: "You are not authorized to revoke this token"
|
6
7
|
revoke_oauth_token_notice_flash: "The oauth token has been revoked"
|
7
8
|
oauth_authorize_title: "Authorize"
|
8
9
|
oauth_oauth_applications_page_title: "Oauth Applications"
|
@@ -31,4 +32,4 @@ en:
|
|
31
32
|
unsupported_transform_algorithm_message: "transform algorithm not supported"
|
32
33
|
request_uri_not_supported_message: "request uri is unsupported"
|
33
34
|
invalid_request_object_message: "request object is invalid"
|
34
|
-
invalid_scope_message: "The Access Token expired"
|
35
|
+
invalid_scope_message: "The Access Token expired"
|
data/templates/authorize.str
CHANGED
@@ -7,12 +7,22 @@
|
|
7
7
|
|
8
8
|
#{
|
9
9
|
rodauth.scopes.map do |scope|
|
10
|
-
|
11
|
-
|
12
|
-
<
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
if scope == rodauth.oauth_application_default_scope
|
11
|
+
<<-HTML
|
12
|
+
<div class="form-check">
|
13
|
+
<input id="#{scope}" class="form-check-input" type="checkbox" name="scope[]" value="#{scope}" checked disabled>
|
14
|
+
<label class="form-check-label" for="#{scope}">#{scope}</label>
|
15
|
+
<input type="hidden" name="scope[]" value="#{scope}">
|
16
|
+
</div>
|
17
|
+
HTML
|
18
|
+
else
|
19
|
+
<<-HTML
|
20
|
+
<div class="form-check">
|
21
|
+
<input id="#{scope}" class="form-check-input" type="checkbox" name="scope[]" value="#{scope}">
|
22
|
+
<label class="form-check-label" for="#{scope}">#{scope}</label>
|
23
|
+
</div>
|
24
|
+
HTML
|
25
|
+
end
|
16
26
|
end.join
|
17
27
|
}
|
18
28
|
|
@@ -31,4 +41,4 @@
|
|
31
41
|
<input type="submit" class="btn btn-outline-primary" value="#{h(rodauth.oauth_authorize_button)}"/>
|
32
42
|
<a href="#{rodauth.redirect_uri}?error=access_denied&error_description=The+resource+owner+or+authorization+server+denied+the+request#{ "&state=#{rodauth.param("state")}" if rodauth.param_or_nil("state")}" class="btn btn-outline-danger">Cancel</a>
|
33
43
|
</p>
|
34
|
-
</form>
|
44
|
+
</form>
|
data/templates/oauth_tokens.str
CHANGED
@@ -10,7 +10,8 @@
|
|
10
10
|
<th scope="col">Token</th>
|
11
11
|
<th scope="col">Refresh Token</th>
|
12
12
|
<th scope="col">Expires in</th>
|
13
|
-
<th scope="col">
|
13
|
+
<th scope="col">Revoked at</th>
|
14
|
+
<th scope="col">Scopes</th>
|
14
15
|
<th scope="col"><span class="badge badge-pill badge-dark">#{@oauth_tokens.count}</span>
|
15
16
|
</tr>
|
16
17
|
</thead>
|
@@ -19,13 +20,14 @@
|
|
19
20
|
@oauth_tokens.map do |oauth_token|
|
20
21
|
<<-HTML
|
21
22
|
<tr>
|
22
|
-
<td>#{oauth_token[rodauth.oauth_tokens_token_column]}</td>
|
23
|
-
<td>#{oauth_token[rodauth.oauth_tokens_refresh_token_column]}</td>
|
23
|
+
<td><code class="token">#{oauth_token[rodauth.oauth_tokens_token_column]}</code></td>
|
24
|
+
<td><code class="token">#{oauth_token[rodauth.oauth_tokens_refresh_token_column]}</code></td>
|
24
25
|
<td>#{oauth_token[rodauth.oauth_tokens_expires_in_column]}</td>
|
25
26
|
<td>#{oauth_token[rodauth.oauth_tokens_revoked_at_column]}</td>
|
27
|
+
<td>#{oauth_token[rodauth.oauth_tokens_scopes_column]}</td>
|
26
28
|
<td>
|
27
29
|
#{
|
28
|
-
if !oauth_token[rodauth.
|
30
|
+
if !oauth_token[rodauth.oauth_tokens_revoked_at_column] && !oauth_token[rodauth.oauth_tokens_token_hash_column]
|
29
31
|
<<-HTML
|
30
32
|
<form method="post" action="#{rodauth.revoke_path}" class="form-horizontal" role="form" id="revoke-form">
|
31
33
|
#{csrf_tag(rodauth.revoke_path) if respond_to?(:csrf_tag)}
|
@@ -46,4 +48,4 @@
|
|
46
48
|
HTML
|
47
49
|
end
|
48
50
|
}
|
49
|
-
</div>
|
51
|
+
</div>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rodauth-oauth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tiago Cardoso
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-12-
|
11
|
+
date: 2021-12-14 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Implementation of the OAuth 2.0 protocol on top of rodauth.
|
14
14
|
email:
|
@@ -52,7 +52,8 @@ files:
|
|
52
52
|
- templates/redirect_uri_field.str
|
53
53
|
- templates/scope_field.str
|
54
54
|
homepage: https://gitlab.com/honeyryderchuck/rodauth-oauth
|
55
|
-
licenses:
|
55
|
+
licenses:
|
56
|
+
- Apache 2.0
|
56
57
|
metadata:
|
57
58
|
homepage_uri: https://gitlab.com/honeyryderchuck/rodauth-oauth
|
58
59
|
source_code_uri: https://gitlab.com/honeyryderchuck/rodauth-oauth
|
@@ -72,7 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
73
|
- !ruby/object:Gem::Version
|
73
74
|
version: '0'
|
74
75
|
requirements: []
|
75
|
-
rubygems_version: 3.
|
76
|
+
rubygems_version: 3.2.22
|
76
77
|
signing_key:
|
77
78
|
specification_version: 4
|
78
79
|
summary: Implementation of the OAuth 2.0 protocol on top of rodauth.
|