module CurrentUser def self.has_auth_cookie?(env) request = Rack::Request.new(env) cookie = request.cookies["_t"] !cookie.nil? && cookie.length == 32 end def self.lookup_from_env(env) request = Rack::Request.new(env) lookup_from_auth_token(request.cookies["_t"]) end def self.lookup_from_auth_token(auth_token) if auth_token && auth_token.length == 32 User.where(auth_token: auth_token).first end end # can be used to pretend current user does no exist, for CSRF attacks def clear_current_user @current_user = nil @not_logged_in = true end def log_on_user(user) session[:current_user_id] = user.id unless user.auth_token && user.auth_token.length == 32 user.auth_token = SecureRandom.hex(16) user.save! end set_permanent_cookie!(user) end def set_permanent_cookie!(user) cookies.permanent["_t"] = { value: user.auth_token, httponly: true } end def is_api? # ensure current user has been called # otherwise current_user @is_api end def current_user return @current_user if @current_user || @not_logged_in if session[:current_user_id].blank? # maybe we have a cookie? @current_user = CurrentUser.lookup_from_auth_token(cookies["_t"]) session[:current_user_id] = @current_user.id if @current_user else @current_user ||= User.where(id: session[:current_user_id]).first # I have flip flopped on this (sam), if our permanent cookie # conflicts with our current session assume session is bust # kill it if @current_user && cookies["_t"] != @current_user.auth_token @current_user = nil end end if @current_user && @current_user.is_banned? @current_user = nil end @not_logged_in = session[:current_user_id].blank? if @current_user @current_user.update_last_seen! @current_user.update_ip_address!(request.remote_ip) end # possible we have an api call, impersonate unless @current_user if api_key = request["api_key"] if api_username = request["api_username"] if SiteSetting.api_key_valid?(api_key) @is_api = true @current_user = User.where(username_lower: api_username.downcase).first end end end end @current_user end end