We’ve had a custom OAuth2 based authentication which looks like:
require 'auth/oauth2_authenticator'
require 'omniauth-oauth2'
class OmniAuth::Strategies::RoOauth < OmniAuth::Strategies::OAuth2
SITE_URL = '******'
# Give your strategy a name.
option :name, "ro_oauth"
# This is where you pass the options you would pass when
# initializing your consumer from the OAuth gem.
option :client_options, site: SITE_URL
# These are called after authentication has succeeded. If
# possible, you should try to set the UID without making
# additional calls (if the user id is returned with the token
# or as a URI parameter). This may not be possible with all
# providers.
uid{ raw_info['id'] }
info do
{
:name => raw_info['name'],
:email => raw_info['email'],
:groups => raw_info['groups']
}
end
extra do
{
'raw_info' => raw_info
}
end
def raw_info
@raw_info ||= access_token.get('*****').parsed
end
end
class RoAuthenticator < ::Auth::OAuth2Authenticator
CLIENT_ID = '****'
CLIENT_SECRET = '****'
def register_middleware(omniauth)
omniauth.provider :ro_oauth,
CLIENT_ID,
CLIENT_SECRET
end
def after_create_account(user, auth)
super(user, auth)
data = auth[:extra_data]
update_user_groups(user, data[:groups])
end
def update_user_groups(user, groups)
grouplist = groups.select { |item| item.starts_with?("beta-") }.map { |item| item[5, item.length - 5] }
Rails.logger.info "After create account " + grouplist.join(",")
Group.joins(:users).where(users: { id: user.id } ).each do |c|
gname = c.name
if gname.start_with?("beta_")
gname = gname[5, gname.length - 5]
if grouplist.include?(gname)
grouplist.delete(gname) # remove it from the list
else
c.group_users.where(user_id: user.id).destroy_all
# Rails.logger.info "Would remove group " + c.name
end
end
end
grouplist.each do |c|
grp = Group.where(name: "beta_" + c).first
if not grp.nil?
grp.group_users.create(user_id: user.id, group_id: grp.id)
# Rails.logger.info "adding user to " + grp.name
end
end
end
def after_authenticate(auth_token)
result = Auth::Result.new
oauth2_provider = auth_token[:provider]
oauth2_uid = auth_token[:uid]
data = auth_token[:info]
result.email = email = data[:email]
result.name = name = data[:name]
oauth2_user_info = Oauth2UserInfo.find_by(uid: oauth2_uid, provider: oauth2_provider)
if !oauth2_user_info && @opts[:trusted] && user = User.find_by_email(email)
oauth2_user_info = Oauth2UserInfo.create(uid: oauth2_uid,
provider: oauth2_provider,
name: name,
email: email,
user: user)
end
result.user = oauth2_user_info.try(:user)
result.email_valid = @opts[:trusted]
result.extra_data = {
uid: oauth2_uid,
provider: oauth2_provider,
groups: data[:groups]
}
#result
# result = super(auth_token)
if not result.user.nil?
update_user_groups(result.user, result.extra_data[:groups])
end
result
end
end
auth_provider :title => 'Click here to sign in.',
:message => 'Log in via the main site (Make sure pop up blockers are not enabled).',
:frame_width => 920,
:frame_height => 1000,
:authenticator => RoAuthenticator.new('ro_oauth', trusted: true)
register_css <<CSS
.btn-login.ro_oauth {
background: #0E76BD;
color: rgb(255, 255, 255);
text-shadow: 0px 1px 0px rgba(0, 0, 0, 0.2);
box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.1) inset;
}
CSS
But it suddenly started failing with:
NoMethodError (undefined method []' for nil:NilClass) /var/www/discourse/plugins/roauth/plugin.rb:23:in
block in class:RoOauth’
Did anything change for this, and if yes, what can I do to fix this error?
This would have been a recent fix; since i update almost daily and we only just noticed.