omniauth-mastodon/lib/omniauth/strategies/mastodon.rb

106 lines
2.9 KiB
Ruby

require 'omniauth-oauth2'
module OmniAuth
module Strategies
class Mastodon < OmniAuth::Strategies::OAuth2
DEFAULT_SCOPE = 'read'.freeze
option :name, 'mastodon'
option :credentials
option :identifier
option :authorize_options, [:scope]
option :domain
option :client_options, {
authorize_url: '/oauth/authorize',
token_url: '/oauth/token'
}
uid { raw_info['id'] }
info do
{
name: raw_info['username'],
nickname: raw_info['username'],
image: raw_info['avatar'],
urls: { 'Profile' => raw_info['url'] }
}
end
extra do
{ raw_info: raw_info }
end
# Before we can redirect the user to authorize access, we must know where the user is from
# If the identifier param is not already present, a form will be shown for entering it
def request_phase
identifier ? start_oauth : get_identifier
end
def callback_phase
set_options_from_identifier
super
end
def raw_info
@raw_info ||= access_token.get('api/v1/accounts/verify_credentials').parsed
end
def callback_url
full_host + script_name + callback_path
end
def authorize_params
super.tap do |params|
params[:scope] ||= DEFAULT_SCOPE
end
end
private
def get_identifier
I18n.with_locale(locale) do
form = OmniAuth::Form.new(title: translate('.omniauth.mastodon.title'))
form.text_field translate('.omniauth.mastodon.text'), 'identifier'
form.button translate('.omniauth.mastodon.button')
form.to_response
end
end
def translate(t)
I18n.exists?(t) ? I18n.t(t) : I18n.t(t, locale: :en)
end
def locale
loc = request.params['locale'] || session[:omniauth_login_locale] || I18n.default_locale
loc = :en unless I18n.locale_available?(loc)
loc
end
def start_oauth
set_options_from_identifier
redirect client.auth_code.authorize_url({:redirect_uri => callback_url}.merge(authorize_params))
end
def identifier
i = options.identifier || request.params['identifier'] || (env['omniauth.params'].is_a?(Hash) ? env['omniauth.params']['identifier'] : nil) || session[:identifier]
i = i.downcase.strip unless i.nil?
i = nil if i == ''
session[:identifier] = i unless i.nil?
i
end
def set_options_from_identifier
username, domain = identifier.split('@')
client_id, client_secret = options.credentials.call(domain, callback_url)
options.identifier = identifier
options.client_options[:site] = "https://#{domain}"
options.client_id = client_id
options.client_secret = client_secret
end
end
end
end