Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Internal Server Error of /oauth/authorized_applications #21885

Open
tateisu opened this issue Nov 30, 2022 · 24 comments
Open

Internal Server Error of /oauth/authorized_applications #21885

tateisu opened this issue Nov 30, 2022 · 24 comments
Labels
bug Something isn't working

Comments

@tateisu
Copy link
Contributor

tateisu commented Nov 30, 2022

Steps to reproduce the problem

  1. open user wettings from WebUI
  2. choose account, choose apps
  3. WebUI shows error page.

but it's account dependent. please see detailed description

Expected behaviour

WebUI shows app list.

Actual behaviour

WebUI shows error page.

Detailed description

https://{server}/oauth/authorized_applications
method=GET path=/oauth/authorized_applications format=html controller=Oauth::AuthorizedApplicationsController action=index status=500 error='ActionView::Template::Error: Failed to match sequence ((NAMESPACE COLON)? (ACCESS COLON TERM / ACCESS / TERM)) at line 1 char 1.' duration=88.39 view=0.00 db=47.05
ActionView::Template::Error (Failed to match sequence ((NAMESPACE COLON)? (ACCESS COLON TERM / ACCESS / TERM)) at line 1 char 1.):
    33:
    34:       .announcements-list__item__permissions
    35:         %ul.permissions-list
    36:           - grouped_scopes(application.scopes).each do |scope|
    37:             %li.permissions-list__item
    38:               .permissions-list__item__icon
    39:                 = fa_icon('check')
app/helpers/application_helper.rb:234:in `block in grouped_scopes'
app/helpers/application_helper.rb:233:in `each_with_object'
app/helpers/application_helper.rb:233:in `grouped_scopes'
app/views/oauth/authorized_applications/index.html.haml:36
app/views/oauth/authorized_applications/index.html.haml:9
app/controllers/concerns/localized.rb:11:in `set_locale'
lib/mastodon/rack_middleware.rb:9:in `call'

Specifications

Mastodon v4.0.2
using included Dockerfile

@tateisu tateisu added the bug Something isn't working label Nov 30, 2022
@tateisu
Copy link
Contributor Author

tateisu commented Nov 30, 2022

The account used when this phenomenon occurred was created in April 2017.
Since I am an app creator, this account has information of many linked apps.
It may contain information from old schemas.

@ClearlyClaire
Copy link
Contributor

Thanks for the report!

Could you run the following in a Rails console (RAILS_ENV=production bundle exec rails c)?

Account.find_local!('yourusername').user.applications.map { |app| app.scopes }.filter do |scopes|
  scopes.map { |scope| ScopeParser.new.parse(scope) }
  false
rescue
  true
end

@tateisu
Copy link
Contributor Author

tateisu commented Nov 30, 2022

$ docker-compose run --rm web  bundle exec rails c
irb(main):007:1* Account.find_local!('SubwayTooter').user.applications.map { |app| app.scopes }.filter do |scopes|
irb(main):008:1*   scopes.map { |scope| ScopeParser.new.parse(scope) }
irb(main):009:1*   false
irb(main):010:1* rescue
irb(main):011:1*   true
irb(main):012:0> end
=> []

@ClearlyClaire
Copy link
Contributor

Hm, strange, what about:

Account.find_local!('SubwayTooter').user.applications.map { |app| app.scopes }.filter do |scopes|
  scopes.map { |scope| ScopeTransformer.new.apply(ScopeParser.new.parse(scope)) }
  false
rescue
  true
end

@ClearlyClaire
Copy link
Contributor

ClearlyClaire commented Nov 30, 2022

Doorkeeper.config.application_model.authorized_for(Account.find_local!('SubwayTooter').user).map { |app| app.scopes }.filter do |scopes|
  scopes.map { |scope| ScopeTransformer.new.apply(ScopeParser.new.parse(scope)) }
  false
rescue
  true
end

@tateisu
Copy link
Contributor Author

tateisu commented Nov 30, 2022

irb(main):047:1* Doorkeeper.config.application_model.authorized_for(Account.find_local!('SubwayTooter').user).map { |app| app.scopes }.filter do |scopes|
irb(main):048:1*   scopes.map { |scope| ScopeTransformer.new.apply(ScopeParser.new.parse(scope)) }
irb(main):049:1*   false
irb(main):050:1* rescue
irb(main):051:1*     true
irb(main):052:0> end
=> [#<Doorkeeper::OAuth::Scopes:0x00007fa1722d8640 @scopes=["{:scopes=>\"read", "write", "follow\"}"]>]

@ClearlyClaire
Copy link
Contributor

Doorkeeper.config.application_model.authorized_for(Account.find_local!('SubwayTooter').user).filter do |app|
  app.scopes.map { |scope| ScopeTransformer.new.apply(ScopeParser.new.parse(scope)) }
  false
rescue
  true
end

(scrub the secrets if needed)

@tateisu
Copy link
Contributor Author

tateisu commented Nov 30, 2022

irb(main):053:1* Doorkeeper.config.application_model.authorized_for(Account.find_local!('SubwayTooter').user).filter do |app|
irb(main):054:1*   app.scopes.map { |scope| ScopeTransformer.new.apply(ScopeParser.new.parse(scope)) }
irb(main):055:1*     false
irb(main):056:1* rescue
irb(main):057:1*   true
irb(main):058:0> end
=>
[#<Doorkeeper::Application:0x00007fa16e7e0bf0
  id: 391,
  name: "My Ruby App",
  uid: "**",
  secret: "**",
  redirect_uri: "http://mywebsite.com/callback",
  scopes: "{:scopes=>\"read write follow\"}",
  created_at: Sat, 22 Apr 2017 03:41:58.068929000 UTC +00:00,
  updated_at: Sat, 22 Apr 2017 03:41:58.068929000 UTC +00:00,
  superapp: false,
  website: nil,
  owner_id: nil,
  owner_type: nil,
  confidential: true>]

@tateisu
Copy link
Contributor Author

tateisu commented Nov 30, 2022

Oh, it looks like I specified it wrong when I tried oauth.

@ClearlyClaire
Copy link
Contributor

ok this appears to be a very old app record with broken scopes, we would need to make sure it's not currently possible to register such apps, and to handle any existing one gracefully I guess

@offbyone
Copy link
Contributor

offbyone commented Jul 4, 2023

FWIW I also have this issue; I'll look back upthread and see if I can fix my app too.

@offbyone
Copy link
Contributor

offbyone commented Jul 4, 2023

Mine is not an old app; I ran the script you provided and got a much newer app:

irb(main):014:1* Doorkeeper.config.application_model.authorized_for(Account.find_local!('offby1').user).filter do |app|
irb(main):015:1*   app.scopes.map { |scope| ScopeTransformer.new.apply(ScopeParser.new.parse(scope)) }
irb(main):016:1*   false
irb(main):017:1* rescue
irb(main):018:1*   true
irb(main):019:0> end
=>
[#<Doorkeeper::Application:0x00007efd9d26b6e0
  name: "autoadmin",
  uid: "*** scrubbed ***",
  secret: "*** scrubbed ****",
  redirect_uri: "urn:ietf:wg:oauth:2.0:oob",
  scopes:
   "read write follow admin:read admin:read:accounts admin:read:canonical_email_blocks admin:read:domain_allows admin:read:domain_blocks admin:read:email_domain_blocks admin:read:ip_blocks admin:read:reports admin:write admin:write:accounts admin:write:canonical_email_blocks admin:write:domain_allows admin:write:domain_blocks admin:write:email_domain_blocks admin:write:ip_blocks admin:write:reports",
  created_at: Mon, 24 Apr 2023 20:27:45.107234000 UTC +00:00,
  updated_at: Mon, 24 Apr 2023 20:27:45.107234000 UTC +00:00,
  superapp: false,
  website: "",
  owner_type: "User",
  id: 8999,
  owner_id: 1151,
  confidential: true>]

I'm gonna delete it -- it was an experiment I was running to see if I could set up an automated admin tool -- but I figured I'd record the scopes here for posterity.

@ClearlyClaire
Copy link
Contributor

What error did you get?

@offbyone
Copy link
Contributor

offbyone commented Jul 4, 2023

app_1        | [a06aee6e-460a-4908-9619-c68b53e86049] method=GET path=/oauth/authorized_applications format=html controller=Oauth::AuthorizedApplicationsController action=index status=500 error='ActionView::Template::Error: Failed to match sequence ((NAMESPACE COLON)? (ACCESS COLON TERM / ACCESS / TERM)) at line 1 char 7.' duration=1516.07 view=0.00 db=1124.56
app_1        | [a06aee6e-460a-4908-9619-c68b53e86049]
app_1        | [a06aee6e-460a-4908-9619-c68b53e86049] ActionView::Template::Error (Failed to match sequence ((NAMESPACE COLON)? (ACCESS COLON TERM / ACCESS / TERM)) at line 1 char 7.):
app_1        | [a06aee6e-460a-4908-9619-c68b53e86049]     33:
app_1        | [a06aee6e-460a-4908-9619-c68b53e86049]     34:       .announcements-list__item__permissions
app_1        | [a06aee6e-460a-4908-9619-c68b53e86049]     35:         %ul.permissions-list
app_1        | [a06aee6e-460a-4908-9619-c68b53e86049]     36:           - grouped_scopes(application.scopes).each do |scope|
app_1        | [a06aee6e-460a-4908-9619-c68b53e86049]     37:             %li.permissions-list__item
app_1        | [a06aee6e-460a-4908-9619-c68b53e86049]     38:               .permissions-list__item__icon
app_1        | [a06aee6e-460a-4908-9619-c68b53e86049]     39:                 = fa_icon('check')
app_1        | [a06aee6e-460a-4908-9619-c68b53e86049]
app_1        | [a06aee6e-460a-4908-9619-c68b53e86049] app/helpers/application_helper.rb:234:in `block in grouped_scopes'
app_1        | [a06aee6e-460a-4908-9619-c68b53e86049] app/helpers/application_helper.rb:233:in `each_with_object'
app_1        | [a06aee6e-460a-4908-9619-c68b53e86049] app/helpers/application_helper.rb:233:in `grouped_scopes'
app_1        | [a06aee6e-460a-4908-9619-c68b53e86049] app/views/oauth/authorized_applications/index.html.haml:36
app_1        | [a06aee6e-460a-4908-9619-c68b53e86049] app/views/oauth/authorized_applications/index.html.haml:9
app_1        | [a06aee6e-460a-4908-9619-c68b53e86049] app/controllers/concerns/localized.rb:11:in `set_locale'
app_1        | [a06aee6e-460a-4908-9619-c68b53e86049] lib/mastodon/rack_middleware.rb:9:in `call'
app_1        | [a06aee6e-460a-4908-9619-c68b53e86049] lib/public_file_server_middleware.rb:18:in `call'

@ClearlyClaire
Copy link
Contributor

Thanks! 4.1.0 introduced scopes with underscores, but our parser does not handle that. Going to fix the issue!

@edsu
Copy link

edsu commented Dec 4, 2023

I have a user who registered in 2017 who is unable to visit this page /oauth/authorized_applications and I noticed the same error as above. While the account is old, the application was added very recently: 2023-11-18. The app has scopes of read write follow.

I believe the user actually wants to delete the application, should it be ok to manually delete it so that they can visit the page again?

@ClearlyClaire
Copy link
Contributor

I can't reproduce the issue, are you sure this is caused by an app with read write follow scopes? What is the exact backtrace? Are there apps with other scopes?

@edsu
Copy link

edsu commented Dec 7, 2023

Thanks for taking a look @ClearlyClaire. Here's the stack trace:

I, [2023-12-04T20:40:58.000098 #25]  INFO -- : [83574e2d-7fe3-4a4b-86be-e7006e484d39] method=GET path=/oauth/authorized_applications format=html controller=Oauth::AuthorizedApplicationsController action=index status=500 allocations=13828 duration=20.59 view=0.00 db=3.78
F, [2023-12-04T20:40:58.001265 #25] FATAL -- : [83574e2d-7fe3-4a4b-86be-e7006e484d39]
[83574e2d-7fe3-4a4b-86be-e7006e484d39] ActionView::Template::Error (Failed to match sequence ((NAMESPACE COLON)? (ACCESS COLON TERM / ACCESS / TERM)) at line 1 char 1.):
[83574e2d-7fe3-4a4b-86be-e7006e484d39]     33:
[83574e2d-7fe3-4a4b-86be-e7006e484d39]     34:       .announcements-list__item__permissions
[83574e2d-7fe3-4a4b-86be-e7006e484d39]     35:         %ul.permissions-list
[83574e2d-7fe3-4a4b-86be-e7006e484d39]     36:           - grouped_scopes(application.scopes).each do |scope|
[83574e2d-7fe3-4a4b-86be-e7006e484d39]     37:             %li.permissions-list__item
[83574e2d-7fe3-4a4b-86be-e7006e484d39]     38:               .permissions-list__item__icon
[83574e2d-7fe3-4a4b-86be-e7006e484d39]     39:                 = fa_icon('check')
[83574e2d-7fe3-4a4b-86be-e7006e484d39]
[83574e2d-7fe3-4a4b-86be-e7006e484d39] app/helpers/application_helper.rb:221:in `block in grouped_scopes'
[83574e2d-7fe3-4a4b-86be-e7006e484d39] app/helpers/application_helper.rb:220:in `each_with_object'
[83574e2d-7fe3-4a4b-86be-e7006e484d39] app/helpers/application_helper.rb:220:in `grouped_scopes'
[83574e2d-7fe3-4a4b-86be-e7006e484d39] app/views/oauth/authorized_applications/index.html.haml:36
[83574e2d-7fe3-4a4b-86be-e7006e484d39] app/views/oauth/authorized_applications/index.html.haml:9
[83574e2d-7fe3-4a4b-86be-e7006e484d39] app/controllers/concerns/localized.rb:11:in `set_locale'
[83574e2d-7fe3-4a4b-86be-e7006e484d39] lib/mastodon/rack_middleware.rb:9:in `call'
[83574e2d-7fe3-4a4b-86be-e7006e484d39] lib/public_file_server_middleware.rb:18:in `call'

There is only one row in oauth_applications where the owner_id was set to the users.id for this user:

select * from oauth_applications where owner_id = 435;
-[ RECORD 1 ]+--------------------------------------------
name         | search
uid          | REMOVED
secret       | REMOVED
redirect_uri | urn:ietf:wg:oauth:2.0:oob
scopes       | read write follow
created_at   | 2023-11-18 04:47:22.800815
updated_at   | 2023-11-18 04:47:22.800815
superapp     | f
website      |
owner_type   | User
id           | 68672
owner_id     | 435
confidential | t

The user described that they have signed up to use several third party applications with the Mastodon instance, but every time they need to login they need to reconfirm their decision to trust the application, as if Mastodon had forgotten it (which is suggested by the presence of only a single row). Could it be some issue with the user settings?

select * from users where id = 435;
-[ RECORD 1 ]+--------------------------------------------
email                     | REMOVED
created_at                | 2017-08-30 05:20:28.045987
updated_at                | 2023-12-07 07:38:00.248132
encrypted_password        | REMOVED
reset_password_token      |
reset_password_sent_at    |
sign_in_count             | 7959
current_sign_in_at        | 2023-12-07 07:38:00.247798
last_sign_in_at           | 2023-12-07 06:16:18.549014
admin                     | f
confirmation_token        | REMOVED
confirmed_at              | 2017-08-30 05:20:28.08023
confirmation_sent_at      | 2017-08-30 05:20:28.046629
unconfirmed_email         |
locale                    | en
encrypted_otp_secret      |
encrypted_otp_secret_iv   |
encrypted_otp_secret_salt |
consumed_timestep         |
otp_required_for_login    | f
last_emailed_at           |
otp_backup_codes          |
account_id                | 15851
id                        | 435
disabled                  | f
moderator                 | f
invite_id                 |
chosen_languages          |
created_by_application_id |
approved                  | t
sign_in_token             |
sign_in_token_sent_at     |
webauthn_id               |
sign_up_ip                |
skip_sign_in_token        |
role_id                   |
settings                  | {"default_privacy":"public","web.default_sensitive":false,"default_language":"","noindex":false,"theme":"default","web.trends":true,"web.unfollow_modal":false,"web.reblog_modal":false,"web.delete_modal":true,"web.auto_play":false,"web.display_media":"show_all","web.expand_content_warnings":false,"web.reduce_motion":false,"web.disable_swiping":false,"web.use_system_font":false,"web.advanced_layout":false,"web.use_blurhash":false,"web.use_pending_items":false,"web.crop_images":true,"show_application":true}
time_zone                 |

@ClearlyClaire
Copy link
Contributor

There is only one row in oauth_applications where the owner_id was set to the users.id for this user

Ah! You're not looking into the right thing! Those are the applications created by the user, not those used by the user (that would thus appear on the page with an error).

You'd want something like:

SELECT "oauth_applications".id, "oauth_applications".scopes FROM "oauth_applications" WHERE "oauth_applications"."id" IN (SELECT DISTINCT "oauth_access_tokens"."application_id" FROM "oauth_access_tokens" WHERE "oauth_access_tokens"."resource_owner_id" = 435 AND "oauth_access_tokens"."revoked_at" IS NULL)

@edsu
Copy link

edsu commented Dec 8, 2023

Thank you! I wonder if it's the comma separated one? read,follow,write

  id   |         scopes
-------+------------------------
 68716 | write read follow push
 68714 | read write follow push
 68719 | read write follow push
 68325 | read
  2407 | read:accounts
 68672 | read write follow
  5782 | read write follow push
  2643 | read write follow
   314 | read,follow,write
   651 | read write follow
   649 | read write follow
   647 | read write follow
  5063 | follow read write
 68712 | read write follow push
 68706 | read write follow push
  5959 | read
 68606 | read:accounts
   421 | read write follow
   168 | read write follow
   471 | read write follow
 68715 | read write follow push
  3770 | read write follow push
   211 | read follow
   683 | read write follow
 68749 | read write follow push
 68725 | write read follow push
(26 rows)

@ClearlyClaire
Copy link
Contributor

Thank you! I wonder if it's the comma separated one? read,follow,write

Yes, most likely. It shouldn't be possible to create such app records anymore, but this existing record is most definitely what's causing the issue.

@edsu
Copy link

edsu commented Dec 8, 2023

Updating that row fixed the problem. Thanks!

I guess this issue can be closed?

@ClearlyClaire
Copy link
Contributor

It should not be possible to create new apps with invalid scopes, so the issue should be mostly addressed, but old records can still be around and we probably need to either automatically clean them or at least prevent them from making the app list view crash.

@ThisIsMissEm
Copy link
Contributor

@ClearlyClaire The creation side is solved by using enforce_configured_scopes on Doorkeeper's configuration, which we now do, this was done in #16042

We probably want a migration to repair or delete old applications that aren't correct, though this could be complex to implement correctly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants