2013-10-09 00:10:37 -04:00
|
|
|
require_dependency "auth/current_user_provider"
|
|
|
|
|
|
|
|
class Auth::DefaultCurrentUserProvider
|
|
|
|
|
2014-05-22 18:13:25 -04:00
|
|
|
CURRENT_USER_KEY ||= "_DISCOURSE_CURRENT_USER".freeze
|
|
|
|
API_KEY ||= "api_key".freeze
|
|
|
|
API_KEY_ENV ||= "_DISCOURSE_API".freeze
|
|
|
|
TOKEN_COOKIE ||= "_t".freeze
|
|
|
|
PATH_INFO ||= "PATH_INFO".freeze
|
2013-10-09 00:10:37 -04:00
|
|
|
|
|
|
|
# do all current user initialization here
|
|
|
|
def initialize(env)
|
|
|
|
@env = env
|
|
|
|
@request = Rack::Request.new(env)
|
|
|
|
end
|
|
|
|
|
|
|
|
# our current user, return nil if none is found
|
|
|
|
def current_user
|
|
|
|
return @env[CURRENT_USER_KEY] if @env.key?(CURRENT_USER_KEY)
|
|
|
|
|
2014-10-23 22:38:00 -04:00
|
|
|
# bypass if we have the shared session header
|
|
|
|
if shared_key = @env['HTTP_X_SHARED_SESSION_KEY']
|
|
|
|
uid = $redis.get("shared_session_key_#{shared_key}")
|
|
|
|
user = nil
|
|
|
|
if uid
|
|
|
|
user = User.find_by(id: uid.to_i)
|
|
|
|
end
|
|
|
|
@env[CURRENT_USER_KEY] = user
|
|
|
|
return user
|
|
|
|
end
|
|
|
|
|
2014-05-22 18:13:25 -04:00
|
|
|
request = @request
|
2013-10-09 00:10:37 -04:00
|
|
|
|
|
|
|
auth_token = request.cookies[TOKEN_COOKIE]
|
|
|
|
|
|
|
|
current_user = nil
|
|
|
|
|
|
|
|
if auth_token && auth_token.length == 32
|
2014-05-06 09:41:59 -04:00
|
|
|
current_user = User.find_by(auth_token: auth_token)
|
2013-10-09 00:10:37 -04:00
|
|
|
end
|
|
|
|
|
2014-04-28 13:46:28 -04:00
|
|
|
if current_user && (current_user.suspended? || !current_user.active)
|
2013-10-09 00:10:37 -04:00
|
|
|
current_user = nil
|
|
|
|
end
|
|
|
|
|
2014-05-22 18:13:25 -04:00
|
|
|
if current_user && should_update_last_seen?
|
2014-03-16 20:59:34 -04:00
|
|
|
u = current_user
|
2014-07-17 16:22:46 -04:00
|
|
|
Scheduler::Defer.later "Updating Last Seen" do
|
2014-03-16 20:59:34 -04:00
|
|
|
u.update_last_seen!
|
|
|
|
u.update_ip_address!(request.ip)
|
|
|
|
end
|
2013-10-09 00:10:37 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
# possible we have an api call, impersonate
|
2014-05-22 18:13:25 -04:00
|
|
|
if api_key = request[API_KEY]
|
|
|
|
current_user = lookup_api_user(api_key, request)
|
|
|
|
raise Discourse::InvalidAccess unless current_user
|
|
|
|
@env[API_KEY_ENV] = true
|
2013-10-09 00:10:37 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
@env[CURRENT_USER_KEY] = current_user
|
|
|
|
end
|
|
|
|
|
|
|
|
def log_on_user(user, session, cookies)
|
|
|
|
unless user.auth_token && user.auth_token.length == 32
|
|
|
|
user.auth_token = SecureRandom.hex(16)
|
|
|
|
user.save!
|
|
|
|
end
|
2016-05-17 00:12:09 -04:00
|
|
|
if SiteSetting.permanent_session_cookie
|
|
|
|
cookies.permanent[TOKEN_COOKIE] = { value: user.auth_token, httponly: true }
|
|
|
|
else
|
|
|
|
cookies[TOKEN_COOKIE] = { value: user.auth_token, httponly: true }
|
|
|
|
end
|
2013-11-01 19:25:43 -04:00
|
|
|
make_developer_admin(user)
|
2016-04-26 13:08:19 -04:00
|
|
|
enable_bootstrap_mode(user)
|
2013-10-09 00:10:37 -04:00
|
|
|
@env[CURRENT_USER_KEY] = user
|
|
|
|
end
|
|
|
|
|
2013-11-01 19:25:43 -04:00
|
|
|
def make_developer_admin(user)
|
|
|
|
if user.active? &&
|
|
|
|
!user.admin &&
|
|
|
|
Rails.configuration.respond_to?(:developer_emails) &&
|
|
|
|
Rails.configuration.developer_emails.include?(user.email)
|
2014-03-24 03:03:39 -04:00
|
|
|
user.admin = true
|
|
|
|
user.save
|
2013-11-01 19:25:43 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-04-26 13:08:19 -04:00
|
|
|
def enable_bootstrap_mode(user)
|
|
|
|
Jobs.enqueue(:enable_bootstrap_mode, user_id: user.id) if user.admin && user.last_seen_at.nil? && !SiteSetting.bootstrap_mode_enabled && user.is_singular_admin?
|
|
|
|
end
|
|
|
|
|
2013-10-09 00:10:37 -04:00
|
|
|
def log_off_user(session, cookies)
|
2015-01-27 20:56:25 -05:00
|
|
|
if SiteSetting.log_out_strict && (user = current_user)
|
|
|
|
user.auth_token = nil
|
|
|
|
user.save!
|
2016-05-18 03:27:54 -04:00
|
|
|
|
|
|
|
if user.admin && defined?(Rack::MiniProfiler)
|
|
|
|
# clear the profiling cookie to keep stuff tidy
|
|
|
|
cookies["__profilin"] = nil
|
|
|
|
end
|
|
|
|
|
2015-05-03 22:21:00 -04:00
|
|
|
MessageBus.publish "/logout", user.id, user_ids: [user.id]
|
2015-01-27 20:56:25 -05:00
|
|
|
end
|
2013-10-09 00:10:37 -04:00
|
|
|
cookies[TOKEN_COOKIE] = nil
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
# api has special rights return true if api was detected
|
|
|
|
def is_api?
|
|
|
|
current_user
|
2014-05-22 18:42:58 -04:00
|
|
|
@env[API_KEY_ENV]
|
2013-10-09 00:10:37 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def has_auth_cookie?
|
2014-05-22 18:13:25 -04:00
|
|
|
cookie = @request.cookies[TOKEN_COOKIE]
|
2013-10-09 00:10:37 -04:00
|
|
|
!cookie.nil? && cookie.length == 32
|
|
|
|
end
|
2014-05-22 18:13:25 -04:00
|
|
|
|
|
|
|
def should_update_last_seen?
|
|
|
|
!(@request.path =~ /^\/message-bus\//)
|
|
|
|
end
|
|
|
|
|
|
|
|
protected
|
|
|
|
|
|
|
|
def lookup_api_user(api_key_value, request)
|
2016-06-01 15:48:06 -04:00
|
|
|
if api_key = ApiKey.where(key: api_key_value).includes(:user).first
|
2014-05-22 18:13:25 -04:00
|
|
|
api_username = request["api_username"]
|
2014-11-19 23:21:49 -05:00
|
|
|
|
2016-06-01 15:48:06 -04:00
|
|
|
if api_key.allowed_ips.present? && !api_key.allowed_ips.any? { |ip| ip.include?(request.ip) }
|
|
|
|
Rails.logger.warn("[Unauthorized API Access] username: #{api_username}, IP address: #{request.ip}")
|
2014-11-19 23:21:49 -05:00
|
|
|
return nil
|
|
|
|
end
|
|
|
|
|
2014-05-22 18:13:25 -04:00
|
|
|
if api_key.user
|
|
|
|
api_key.user if !api_username || (api_key.user.username_lower == api_username.downcase)
|
|
|
|
elsif api_username
|
|
|
|
User.find_by(username_lower: api_username.downcase)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-10-09 00:10:37 -04:00
|
|
|
end
|