Websites/app/logical/requests/discord_oauth.rb
2024-05-02 22:04:43 -05:00

102 lines
3.4 KiB
Ruby

# frozen_string_literal: true
module Requests
class DiscordOauth
include HTTParty
base_uri "https://discord.com/api/oauth2"
Authorization = Struct.new(:access_token, :token_type, :expires_in, :refresh_token, :scope, :webhook) do
def get_authorization # rubocop:disable Naming/AccessorMethodName
r = DiscordOauth.get("/@me", {
headers: {
"Authorization" => "#{token_type} #{access_token}",
},
})
if r.code != 200
Rails.logger.error("Failed to get user info: #{r.code} #{r.body}")
return nil
end
JSON.parse(r.body)
end
def get_guilds # rubocop:disable Naming/AccessorMethodName
r = HTTParty.get("https://discord.com/api/users/@me/guilds", {
headers: {
"Authorization" => "#{token_type} #{access_token}",
},
})
if r.code != 200
Rails.logger.error("Failed to get user guilds: #{r.code} #{r.body}")
return nil
end
JSON.parse(r.body)
end
def user_id
get_authorization.try(:[], "user").try(:[], "id")
end
end
Webhook = Struct.new(:application_id, :name, :url, :channel_id, :token, :type, :avatar, :guild_id, :id)
Error = Struct.new(:error, :error_description)
attr_reader :client_id, :client_secret
def initialize(client_id:, client_secret:)
@client_id = client_id
@client_secret = client_secret
end
def authorize(redirect_uri:, code:)
data = self.class.post("/token", {
body: URI.encode_www_form({
grant_type: "authorization_code",
code: code,
redirect_uri: redirect_uri,
}),
basic_auth: {
username: client_id,
password: client_secret,
},
headers: {
"Content-Type" => "application/x-www-form-urlencoded",
},
})
unless data.success?
Rails.logger.info(client_id)
Rails.logger.error("Failed to authorize: #{data.code} #{data.body}")
end
return Error.new(data["error"], data["error_description"]) if data["error"]
hook = nil
hook = Webhook.new(data["webhook"]["application_id"], data["webhook"]["name"], data["webhook"]["url"], data["webhook"]["channel_id"], data["webhook"]["token"], data["webhook"]["type"], data["webhook"]["avatar"], data["webhook"]["guild_id"], data["webhook"]["id"]) if data["webhook"]
Authorization.new(data["access_token"], data["token_type"], data["expires_in"], data["refresh_token"], data["scope"], hook)
end
def client_grant(scopes:)
data = self.class.post("/token", {
body: URI.encode_www_form({
grant_type: "client_credentials",
scope: scopes.join(" "),
}),
basic_auth: {
username: client_id,
password: client_secret,
},
headers: {
"Content-Type" => "application/x-www-form-urlencoded",
},
})
return Error.new(data["error"], data["error_description"]) if data["error"]
Authorization.new(data["access_token"], data["token_type"], data["expires_in"], data["refresh_token"], data["scope"], nil)
end
def self.yiffy_client_credentials(scopes:)
new(
client_id: Websites.config.yiffyapi_discord_id,
client_secret: Websites.config.yiffyapi_discord_secret,
).client_grant(scopes: scopes)
end
end
end