Last active
August 24, 2023 13:36
-
-
Save amkisko/75974437677b9bbdc37d0b04dc28fe04 to your computer and use it in GitHub Desktop.
Slack oauth2 omniauth devise implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "omniauth/slack_oauth2" | |
config.omniauth( | |
:slack_oauth2, | |
ENV.fetch("SLACK_CLIENT_ID"), | |
ENV.fetch("SLACK_CLIENT_SECRET"), | |
{ | |
scope: "openid,email,profile", | |
redirect_uri: Rails.env.development? ? "https://localhost:3000/user/auth/slack_oauth2/callback" : nil, | |
provider_ignores_state: Rails.env.development? | |
} | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class User::OmniauthCallbacksController < Devise::OmniauthCallbacksController | |
skip_before_action :verify_authenticity_token | |
# NOTE: slack redirect_url is https://host:port/user/auth/slack_oauth2/callback | |
def slack_oauth2 | |
if !auth[:extra][:data].email_verified || | |
auth[:extra][:data].team_domain != ENV.fetch("SLACK_TEAM_DOMAIN") | |
redirect_to root_path, alert: "You are not authorized to use this app." | |
return | |
end | |
user_session = | |
UserSession.find_by(provider: auth["provider"], uid: auth["uid"]) | |
@user = user_session&.user || User.find_or_create_with_omniauth(auth) | |
user_session ||= | |
@user.user_sessions.find_or_create_by(provider: auth["provider"]) | |
user_session.assign_attributes( | |
name: auth["info"]["name"], | |
avatar_url: auth["info"]["image"] | |
) | |
user_session.data = { | |
"access_token" => auth.credentials.token, | |
"user_id" => auth[:extra][:data].user_id, | |
"team_id" => auth[:extra][:data].team_id, | |
"name" => auth[:extra][:data].name, | |
"team_name" => auth[:extra][:data].team_name, | |
"team_domain" => auth[:extra][:data].team_domain, | |
"picture" => auth[:extra][:data].picture | |
} | |
user_session.save! | |
flash[:notice] = I18n.t("devise.omniauth_callbacks.success", kind: "Slack") | |
sign_in @user | |
redirect_to root_path | |
end | |
def auth | |
request.env["omniauth.auth"] | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
devise_for( | |
:user, | |
controllers: { | |
sessions: "user/sessions", | |
omniauth_callbacks: "user/omniauth_callbacks" | |
} | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<%- if devise_mapping.omniauthable? %> | |
<%- resource_class.omniauth_providers.each do |provider| %> | |
<% case provider %> | |
<% when :google_oauth2 %> | |
<%= render partial: "google_button", locals: { provider: provider, resource_name: resource_name } %> | |
<% when :slack_oauth2 %> | |
<%= render partial: "slack_button", locals: { provider: provider, resource_name: resource_name } %> | |
<% end %> | |
<% end %> | |
<% end %> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "omniauth/strategies/oauth2" | |
module OmniAuth | |
module Strategies | |
class SlackOauth2 < OmniAuth::Strategies::OAuth2 | |
AUTH_OPTIONS = %i[scope user_scope team team_domain] | |
INFO_DATA = | |
Data.define( | |
:user_id, | |
:team_id, | |
:email, | |
:email_verified, | |
:name, | |
:picture, | |
:given_name, | |
:family_name, | |
:locale, | |
:team_name, | |
:team_domain | |
) | |
option :name, "slack_oauth2" | |
option :client_options, | |
{ | |
site: "https://slack.com", | |
authorize_url: "/openid/connect/authorize", | |
token_url: "/api/openid.connect.token" | |
} | |
option :redirect_uri | |
uid { | |
"#{raw_info.dig("https://slack.com/team_id")}-#{raw_info.dig("https://slack.com/user_id")}" | |
} | |
info { { | |
name: raw_info.dig("name"), | |
email: raw_info.dig("email"), | |
image: raw_info.dig("picture") | |
} } | |
extra do | |
{ | |
data: | |
INFO_DATA.new( | |
user_id: raw_info.dig("https://slack.com/user_id"), | |
team_id: raw_info.dig("https://slack.com/team_id"), | |
email: raw_info.dig("email"), | |
email_verified: raw_info.dig("email_verified"), | |
name: raw_info.dig("name"), | |
picture: raw_info.dig("picture"), | |
given_name: raw_info.dig("given_name"), | |
family_name: raw_info.dig("family_name"), | |
locale: raw_info.dig("locale"), | |
team_name: raw_info.dig("https://slack.com/team_name"), | |
team_domain: raw_info.dig("https://slack.com/team_domain") | |
), | |
raw_info: raw_info | |
} | |
end | |
def callback_url | |
options.redirect_uri || full_host + script_name + callback_path | |
end | |
def raw_info | |
@raw_info ||= access_token.get("/api/openid.connect.userInfo").parsed | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
devise( | |
:database_authenticatable, | |
:trackable, | |
:omniauthable, | |
omniauth_providers: %i[google_oauth2 slack_oauth2] | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment