diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb index f915c45..deeb1cc 100644 --- a/app/controllers/profiles_controller.rb +++ b/app/controllers/profiles_controller.rb @@ -2,6 +2,7 @@ class ProfilesController < ApplicationController def show @user = Current.session.user @active_sessions = @user.sessions.active.order(last_activity_at: :desc) + @connected_applications = @user.oidc_user_consents.includes(:application).order(granted_at: :desc) end def update @@ -33,6 +34,34 @@ class ProfilesController < ApplicationController end end + def revoke_consent + @user = Current.session.user + application = Application.find(params[:application_id]) + + # Check if user has consent for this application + consent = @user.oidc_user_consents.find_by(application: application) + unless consent + redirect_to profile_path, alert: "No consent found for this application." + return + end + + # Revoke the consent + consent.destroy + redirect_to profile_path, notice: "Successfully revoked access to #{application.name}." + end + + def revoke_all_consents + @user = Current.session.user + count = @user.oidc_user_consents.count + + if count > 0 + @user.oidc_user_consents.destroy_all + redirect_to profile_path, notice: "Successfully revoked access to #{count} applications." + else + redirect_to profile_path, alert: "No applications to revoke." + end + end + private def email_params diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index d5b9973..26da98a 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -1,7 +1,7 @@ class SessionsController < ApplicationController allow_unauthenticated_access only: %i[ new create verify_totp ] - rate_limit to: 10, within: 3.minutes, only: :create, with: -> { redirect_to signin_path, alert: "Too many attempts. Try again later." } - rate_limit to: 5, within: 3.minutes, only: :verify_totp, with: -> { redirect_to totp_verification_path, alert: "Too many attempts. Try again later." } + rate_limit to: 20, within: 3.minutes, only: :create, with: -> { redirect_to signin_path, alert: "Too many attempts. Try again later." } + rate_limit to: 10, within: 3.minutes, only: :verify_totp, with: -> { redirect_to totp_verification_path, alert: "Too many attempts. Try again later." } def new # Redirect to signup if this is first run diff --git a/app/models/oidc_user_consent.rb b/app/models/oidc_user_consent.rb index c1c47c8..07ced38 100644 --- a/app/models/oidc_user_consent.rb +++ b/app/models/oidc_user_consent.rb @@ -26,6 +26,24 @@ class OidcUserConsent < ApplicationRecord (requested - granted).empty? end + # Get a human-readable list of scopes + def formatted_scopes + scopes.map do |scope| + case scope + when 'openid' + 'Basic authentication' + when 'profile' + 'Profile information' + when 'email' + 'Email address' + when 'groups' + 'Group membership' + else + scope.humanize + end + end.join(', ') + end + private def set_granted_at diff --git a/app/models/user.rb b/app/models/user.rb index 2417d26..30842e5 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -80,6 +80,15 @@ class User < ApplicationRecord .find { |consent| consent.covers_scopes?(requested_scopes) } end + def revoke_consent!(application) + consent = oidc_user_consents.find_by(application: application) + consent&.destroy + end + + def revoke_all_consents! + oidc_user_consents.destroy_all + end + private def generate_backup_codes diff --git a/app/views/profiles/show.html.erb b/app/views/profiles/show.html.erb index 406b488..58a283d 100644 --- a/app/views/profiles/show.html.erb +++ b/app/views/profiles/show.html.erb @@ -1,7 +1,7 @@
Manage your account settings and security preferences.
+Manage your account settings, active sessions, and connected applications.
These applications have access to your account. You can revoke access at any time.
++ <%= consent.application.name %> +
++ Access to: <%= consent.formatted_scopes %> +
++ Authorized <%= time_ago_in_words(consent.granted_at) %> ago +
+No connected applications.
+ <% end %> +Use these actions to quickly secure your account. Be careful - these actions cannot be undone.
+