remote_user.rb 3.44 KB
module OmniAuth
  module Strategies
    class RemoteUser
      include OmniAuth::Strategy

      option :remote_user_cookie, '_remote_user'
      option :last_path_cookie, '_last_path'

      def call(env)

        remote_user = env['HTTP_REMOTE_USER']

        session_user = __current_user(env)

        if remote_user
          if session_user
            if remote_user == session_user
              __return_last_path(env) || super(env)
            else
              __logout(env)
            end
          else
            __login(env, remote_user)
          end
        else
          if session_user
            __logout(env)
          else
            super(env)
          end
        end
      end

      def __current_user(env)
        request = Rack::Request.new(env)
        request.cookies.has_key?(options.remote_user_cookie) && request.cookies[options.remote_user_cookie]
      end
      
      def __last_path(env)
        request = Rack::Request.new(env)
        request.cookies.has_key?(options.last_path_cookie) && request.cookies[options.last_path_cookie]
      end

      def __set_last_path(env,response)
        request = Rack::Request.new(env)
        puts "---#{request.path_info}--#{__last_path(env)}"
        if not __last_path(env) 
          response.set_cookie(options.last_path_cookie, {value: request.path_info , path: "#{request.script_name}", httponly: true})
        end
        response 
      end

      def __return_last_path(env)
        last_path = __last_path(env)
        request = Rack::Request.new(env)
        response = Rack::Response.new
        if last_path
          response.delete_cookie(options.last_path_cookie , path: "#{request.script_name}" )
          response.redirect last_path
          response.finish
        end
      end

      def __logout(env)
        request = Rack::Request.new(env)
        request.session.clear
        response = redirect_if_not_logging_in(request, request.path )
        if response
          response.delete_cookie(options.remote_user_cookie , path: "#{request.script_name}" )
          response = __set_last_path(env,response)
          response.finish
        end
      end

      def __login(env, uid)
        request = Rack::Request.new(env)
        response = redirect_if_not_logging_in(request,_auth_path(request) )
        if response
          response.set_cookie(options.remote_user_cookie, {value: uid, path: "#{request.script_name}", httponly: true})
          response = __set_last_path(env,response)
          response.finish
        end
      end

      def redirect_if_not_logging_in(request, url)
        if ! [
            _auth_path(request),
            _callback_path(request)
          ].include?(request.path_info)
          response = Rack::Response.new
          response.redirect url
          response
        end
      end


      uid do
        request.env['HTTP_REMOTE_USER']
      end

      info do
        user_data = request.env['HTTP_REMOTE_USER_DATA']
        if user_data
          data = JSON.parse(user_data)
          data['nickname'] = uid
          data['firstname'] = data['name'].split()[0]
          data['lastname'] = data['name'].split()[1]
          data
        else
          {}
        end
      end

      def request_phase
        redirect _callback_path(request)
      end

      def _callback_path(request)
        "#{_auth_path(request)}/callback"
      end

      def _auth_path(request)
        "#{request.script_name}#{path_prefix}/RemoteUser"
      end

    end
  end
end