|
| 1 | +class OrcidController < ApplicationController |
| 2 | + before_action :authenticate_user! |
| 3 | + before_action :set_oauth_client, only: [:authenticate, :callback] |
| 4 | + |
| 5 | + # Faraday::ParsingError occurs in rack-oauth2 if the response does not contain JSON |
| 6 | + rescue_from(Rack::OAuth2::Client::Error, Faraday::ParsingError) do |
| 7 | + handle_error(:unprocessable_entity, t('orcid.error')) |
| 8 | + end |
| 9 | + |
| 10 | + def authenticate |
| 11 | + redirect_to @oauth2_client.authorization_uri(scope: '/authenticate'), allow_other_host: true |
| 12 | + end |
| 13 | + |
| 14 | + def callback |
| 15 | + @oauth2_client.authorization_code = params[:code] |
| 16 | + token = Rack::OAuth2::AccessToken::Bearer.new(access_token: @oauth2_client.access_token!) |
| 17 | + orcid = token.access_token&.raw_attributes['orcid'] |
| 18 | + respond_to do |format| |
| 19 | + profile = current_user.profile |
| 20 | + if orcid.present? |
| 21 | + if profile.authenticate_orcid(orcid) |
| 22 | + flash[:notice] = t('orcid.authentication_success') |
| 23 | + else |
| 24 | + flash[:error] = profile.errors.full_messages.join(', ') |
| 25 | + end |
| 26 | + else |
| 27 | + flash[:error] = t('orcid.authentication_failure') |
| 28 | + end |
| 29 | + format.html { redirect_to current_user } |
| 30 | + end |
| 31 | + end |
| 32 | + |
| 33 | + private |
| 34 | + |
| 35 | + def set_oauth_client |
| 36 | + config = Rails.application.config.secrets.orcid |
| 37 | + @oauth2_client ||= Rack::OAuth2::Client.new( |
| 38 | + identifier: config[:client_id], |
| 39 | + secret: config[:secret], |
| 40 | + redirect_uri: config[:redirect_uri].presence || orcid_callback_url, |
| 41 | + authorization_endpoint: '/oauth/authorize', |
| 42 | + token_endpoint: '/oauth/token', |
| 43 | + host: config[:host].presence || (Rails.env.production? ? 'orcid.org' : 'sandbox.orcid.org') |
| 44 | + ) |
| 45 | + end |
| 46 | +end |
0 commit comments