mirror of
				https://github.com/scinote-eln/scinote-web.git
				synced 2025-10-28 07:00:24 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			97 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| # frozen_string_literal: true
 | |
| 
 | |
| module Api
 | |
|   class ApiController < ActionController::API
 | |
|     attr_reader :iss
 | |
|     attr_reader :token
 | |
|     attr_reader :current_user
 | |
| 
 | |
|     before_action :authenticate_request!, except: %i(status health)
 | |
| 
 | |
|     rescue_from StandardError do |e|
 | |
|       logger.error e.message
 | |
|       logger.error e.backtrace.join("\n")
 | |
|       render json: {}, status: :bad_request
 | |
|     end
 | |
| 
 | |
|     rescue_from JWT::DecodeError,
 | |
|                 JWT::InvalidPayload,
 | |
|                 JWT::VerificationError do |e|
 | |
|       logger.error e.message
 | |
|       render json: { message: I18n.t('api.core.invalid_token') },
 | |
|              status: :unauthorized
 | |
|     end
 | |
| 
 | |
|     rescue_from JWT::ExpiredSignature do |e|
 | |
|       logger.error e.message
 | |
|       render json: { message: I18n.t('api.core.expired_token') },
 | |
|              status: :unauthorized
 | |
|     end
 | |
| 
 | |
|     def initialize
 | |
|       super
 | |
|       @iss = nil
 | |
|     end
 | |
| 
 | |
|     def health
 | |
|       User.new && Team.new && Project.new
 | |
|       User.first if params[:db]
 | |
|       if Rails.application.secrets.system_notifications_uri.present? &&
 | |
|          Rails.application.secrets.system_notifications_channel.present? &&
 | |
|          !Notifications::SyncSystemNotificationsService.available?
 | |
|         return render plain: 'SYSTEM NOTIFICATIONS SERVICE CHECK FAILED', status: :error
 | |
|       end
 | |
|       render plain: 'RUNNING'
 | |
|     end
 | |
| 
 | |
|     def status
 | |
|       response = {}
 | |
|       response[:message] = I18n.t('api.core.status_ok')
 | |
|       response[:versions] = []
 | |
|       Extends::API_VERSIONS.each do |ver|
 | |
|         response[:versions] << { version: ver, baseUrl: "/api/#{ver}/" }
 | |
|       end
 | |
|       render json: response, status: :ok
 | |
|     end
 | |
| 
 | |
|     private
 | |
| 
 | |
|     def azure_jwt_auth
 | |
|       return unless iss =~ %r{windows.net/|microsoftonline.com/}
 | |
|       token_payload, = Api::AzureJwt.decode(token)
 | |
|       @current_user = User.from_azure_jwt_token(token_payload)
 | |
|       unless current_user
 | |
|         raise JWT::InvalidPayload, I18n.t('api.core.no_azure_user_mapping')
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     def authenticate_request!
 | |
|       @token = request.headers['Authorization']&.sub('Bearer ', '')
 | |
|       unless @token
 | |
|         raise JWT::VerificationError, I18n.t('api.core.missing_token')
 | |
|       end
 | |
| 
 | |
|       @iss = CoreJwt.read_iss(token)
 | |
|       raise JWT::InvalidPayload, I18n.t('api.core.no_iss') unless @iss
 | |
| 
 | |
|       Extends::API_PLUGABLE_AUTH_METHODS.each do |auth_method|
 | |
|         method(auth_method).call
 | |
|         return true if current_user
 | |
|       end
 | |
| 
 | |
|       # Default token implementation
 | |
|       unless iss == Rails.configuration.x.core_api_token_iss
 | |
|         raise JWT::InvalidPayload, I18n.t('api.core.wrong_iss')
 | |
|       end
 | |
|       payload = CoreJwt.decode(token)
 | |
|       @current_user = User.find_by_id(payload['sub'])
 | |
|       unless current_user
 | |
|         raise JWT::InvalidPayload, I18n.t('api.core.no_user_mapping')
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     def auth_params
 | |
|       params.permit(:grant_type, :email, :password)
 | |
|     end
 | |
|   end
 | |
| end
 |