Class: Bible270::SessionsController
- Inherits:
-
ApplicationController
- Object
- ApplicationController
- Bible270::SessionsController
- Defined in:
- app/controllers/bible270/sessions_controller.rb
Overview
Built-in OmniAuth sign-in.
The OmniAuth middleware (registered by the host app) handles the request and callback phases; by the time #create runs, request.env is populated and we just need to turn it into a Reader and remember them.
NOTE: OmniAuth 2.0+ only permits POST to its request-phase routes, so all sign-in controls in these views are forms/buttons rather than links.
Instance Method Summary collapse
- #create ⇒ Object
- #destroy ⇒ Object
-
#email_callback ⇒ Object
GET: the reader clicked the link.
-
#email_link ⇒ Object
POST: accept an address and send a one-time link.
- #failure ⇒ Object
- #new ⇒ Object
Instance Method Details
#create ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'app/controllers/bible270/sessions_controller.rb', line 20 def create auth = request.env['omniauth.auth'] redirect_to(sign_in_path, alert: "Sign in didn't complete. Please try again.") and return unless auth if enrollment_closed? && !Reader.omniauth_reader_exists?(auth['provider'], auth['uid']) redirect_to(sign_in_path, alert: ) and return end reader = Reader.from_omniauth(auth) redirect_to(sign_in_path, alert: "We couldn't set up your reader profile.") and return unless reader&.persisted? destination = safe_origin(request.env['omniauth.origin']) || after_sign_in_path # Rotate the session id to avoid session fixation, then sign in. reset_session session[:bible270_reader_id] = reader.id @current_reader = reader redirect_to destination, notice: "Welcome #{reader.first_name}." end |
#destroy ⇒ Object
41 42 43 44 45 |
# File 'app/controllers/bible270/sessions_controller.rb', line 41 def destroy reset_session @current_reader = nil redirect_to(after_sign_out_path, notice: 'Signed out.') end |
#email_callback ⇒ Object
GET: the reader clicked the link.
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'app/controllers/bible270/sessions_controller.rb', line 93 def email_callback token = SignInToken.claim!(params[:token]) if token.nil? redirect_to(sign_in_path, alert: 'That link has expired or was already used. Please request a new one.') and return end if enrollment_closed? && !Reader.email_reader_exists?(token.email) redirect_to(sign_in_path, alert: ) and return end reader = Reader.from_email(token.email, first_name: token.first_name, last_name: token.last_name, display_name: token.display_name) redirect_to(sign_in_path, alert: "We couldn't set up your reader profile.") and return unless reader&.persisted? destination = safe_origin(params[:origin]) || after_sign_in_path reset_session session[:bible270_reader_id] = reader.id @current_reader = reader if name_needed?(reader) redirect_to(profile_path, notice: 'Welcome. Please add your name, so others know who they are reading with.') return end redirect_to destination, notice: "Welcome #{reader.first_name}." end |
#email_link ⇒ Object
POST: accept an address and send a one-time link.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'app/controllers/bible270/sessions_controller.rb', line 55 def email_link unless Bible270.config.email_sign_in? redirect_to(sign_in_path, alert: "Email sign-in isn't enabled here.") and return end origin = safe_origin(params[:origin]) address = EmailSignIn.normalize_email(params[:email]) if address.nil? redirect_to(sign_in_path(origin: origin), alert: "That doesn't look like an email address — please check and try again.") and return end # Names are optional here. Requiring them only for unknown addresses would # make the response differ, which tells a stranger whether an address # already has an account. A new reader is asked for their name after they # click the link instead (see email_callback). names = Names.normalize(params[:first_name], params[:last_name]) _record, raw = SignInToken.issue!(address, first_name: names&.dig(:first_name), last_name: names&.dig(:last_name)) if raw && enrollment_closed? && !Reader.email_reader_exists?(address) Rails.logger.info("[bible270] enrolment closed; no link sent to #{address}") elsif raw deliver_sign_in_link(address, email_sign_in_url(token: raw, origin: origin)) else # Silent to the reader by design; say so in the log or this is undebuggable. Rails.logger.warn("[bible270] no sign-in link issued for #{address} " \ '(rate limited — see config.email_sign_in_max_per_window)') end # Deliberately identical whether or not a link was actually sent, so this # reveals neither who has an account nor that a limit was hit. redirect_to sign_in_path, notice: "Check your inbox — if that address is valid we've sent a sign-in link to #{address}." end |
#failure ⇒ Object
47 48 49 50 |
# File 'app/controllers/bible270/sessions_controller.rb', line 47 def failure = params[:message].presence || 'unknown error' redirect_to sign_in_path, alert: "Sign in failed (#{.to_s.tr('_', ' ')})." end |