Skip to content

Commit 0cda67d

Browse files
authored
Merge pull request #10 from youzik/slack_auth
Slack auth
2 parents 1dd77ce + bb256f0 commit 0cda67d

File tree

8 files changed

+101
-12
lines changed

8 files changed

+101
-12
lines changed

lib/generators/sorcery/templates/initializer.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373

7474

7575
# -- external --
76-
# What providers are supported by this app, i.e. [:twitter, :facebook, :github, :linkedin, :xing, :google, :liveid, :salesforce] .
76+
# What providers are supported by this app, i.e. [:twitter, :facebook, :github, :linkedin, :xing, :google, :liveid, :salesforce, :slack] .
7777
# Default: `[]`
7878
#
7979
# config.external_providers =
@@ -144,6 +144,11 @@
144144
# config.vk.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=vk"
145145
# config.vk.user_info_mapping = {:login => "domain", :name => "full_name"}
146146
#
147+
#config.slack.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=slack"
148+
#config.slack.key = ''
149+
#config.slack.secret = ''
150+
#config.slack.user_info_mapping = {email: 'email'}
151+
#
147152
# To use liveid in development mode you have to replace mydomain.com with
148153
# a valid domain even in development. To use a valid domain in development
149154
# simply add your domain in your /etc/hosts file in front of 127.0.0.1

lib/sorcery/controller/submodules/external.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ def self.included(base)
2020
require 'sorcery/providers/jira'
2121
require 'sorcery/providers/salesforce'
2222
require 'sorcery/providers/paypal'
23+
require 'sorcery/providers/slack'
2324

2425
Config.module_eval do
2526
class << self

lib/sorcery/providers/slack.rb

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
module Sorcery
2+
module Providers
3+
# This class adds support for OAuth with slack.com.
4+
5+
class Slack < Base
6+
7+
include Protocols::Oauth2
8+
9+
attr_accessor :auth_path, :scope, :token_url, :user_info_path
10+
11+
def initialize
12+
super
13+
14+
@scope = 'identity.basic, identity.email'
15+
@site = 'https://slack.com/'
16+
@user_info_path = 'https://slack.com/api/users.identity'
17+
@auth_path = '/oauth/authorize'
18+
@token_url = '/api/oauth.access'
19+
end
20+
21+
def get_user_hash(access_token)
22+
response = access_token.get(user_info_path, params: { token: access_token.token })
23+
auth_hash(access_token).tap do |h|
24+
h[:user_info] = JSON.parse(response.body)
25+
h[:user_info]['email'] = h[:user_info]['user']['email']
26+
h[:uid] = h[:user_info]['user']['id']
27+
end
28+
end
29+
30+
# calculates and returns the url to which the user should be redirected,
31+
# to get authenticated at the external provider's site.
32+
def login_url(params, session)
33+
authorize_url({ authorize_url: auth_path })
34+
end
35+
36+
# tries to login the user from access token
37+
def process_callback(params, session)
38+
args = {}.tap do |a|
39+
a[:code] = params[:code] if params[:code]
40+
end
41+
42+
get_access_token(args, token_url: token_url, token_method: :post)
43+
end
44+
end
45+
end
46+
end

sorcery.gemspec

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,3 @@ Gem::Specification.new do |s|
3434
s.add_development_dependency "rspec-rails", "~> 3.1.0"
3535
s.add_development_dependency "test-unit", "~> 3.1.0"
3636
end
37-

spec/controllers/controller_oauth2_spec.rb

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@
152152
expect(flash[:notice]).to eq "Success!"
153153
end
154154

155-
[:github, :google, :liveid, :vk, :salesforce, :paypal].each do |provider|
155+
[:github, :google, :liveid, :vk, :salesforce, :paypal, :slack].each do |provider|
156156

157157
describe "with #{provider}" do
158158

@@ -205,7 +205,7 @@
205205
end
206206

207207
sorcery_reload!([:user_activation,:external], :user_activation_mailer => ::SorceryMailer)
208-
sorcery_controller_property_set(:external_providers, [:facebook, :github, :google, :liveid, :vk, :salesforce, :paypal])
208+
sorcery_controller_property_set(:external_providers, [:facebook, :github, :google, :liveid, :vk, :salesforce, :paypal, :slack])
209209

210210
sorcery_controller_external_property_set(:facebook, :key, "eYVNBjBDi33aa9GkA3w")
211211
sorcery_controller_external_property_set(:facebook, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
@@ -228,8 +228,13 @@
228228
sorcery_controller_external_property_set(:paypal, :key, "eYVNBjBDi33aa9GkA3w")
229229
sorcery_controller_external_property_set(:paypal, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
230230
sorcery_controller_external_property_set(:paypal, :callback_url, "http://blabla.com")
231+
sorcery_controller_external_property_set(:slack, :key, "eYVNBjBDi33aa9GkA3w")
232+
sorcery_controller_external_property_set(:slack, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
233+
sorcery_controller_external_property_set(:slack, :callback_url, "http://blabla.com")
231234
end
232235

236+
237+
233238
after(:all) do
234239
if SORCERY_ORM == :active_record
235240
ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/activation")
@@ -287,7 +292,7 @@
287292
end
288293
end
289294

290-
%w(facebook github google liveid vk salesforce).each do |provider|
295+
%w(facebook github google liveid vk salesforce slack).each do |provider|
291296
context "when #{provider}" do
292297
before(:each) do
293298
sorcery_controller_property_set(:register_login_time, true)
@@ -327,7 +332,7 @@
327332

328333
let(:user) { double('user', id: 42) }
329334

330-
%w(facebook github google liveid vk salesforce).each do |provider|
335+
%w(facebook github google liveid vk salesforce slack).each do |provider|
331336
context "when #{provider}" do
332337
before(:each) do
333338
sorcery_model_property_set(:authentications_class, Authentication)
@@ -389,7 +394,13 @@ def stub_all_oauth2_requests!
389394
"first_name"=>"Noam",
390395
"last_name"=>"Ben Ari"
391396
}
392-
]}.to_json }
397+
],
398+
"user"=> {
399+
"name"=>"Sonny Whether",
400+
"id"=>"123",
401+
"email"=>"bobby@example.com"
402+
}
403+
}.to_json }
393404
allow(access_token).to receive(:get) { response }
394405
allow(access_token).to receive(:token) { "187041a618229fdaf16613e96e1caabc1e86e46bbfad228de41520e63fe45873684c365a14417289599f3" }
395406
# access_token params for VK auth
@@ -398,7 +409,7 @@ def stub_all_oauth2_requests!
398409
end
399410

400411
def set_external_property
401-
sorcery_controller_property_set(:external_providers, [:facebook, :github, :google, :liveid, :vk, :salesforce, :paypal])
412+
sorcery_controller_property_set(:external_providers, [:facebook, :github, :google, :liveid, :vk, :salesforce, :paypal, :slack])
402413
sorcery_controller_external_property_set(:facebook, :key, "eYVNBjBDi33aa9GkA3w")
403414
sorcery_controller_external_property_set(:facebook, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
404415
sorcery_controller_external_property_set(:facebook, :callback_url, "http://blabla.com")
@@ -420,6 +431,9 @@ def set_external_property
420431
sorcery_controller_external_property_set(:paypal, :key, "eYVNBjBDi33aa9GkA3w")
421432
sorcery_controller_external_property_set(:paypal, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
422433
sorcery_controller_external_property_set(:paypal, :callback_url, "http://blabla.com")
434+
sorcery_controller_external_property_set(:slack, :key, "eYVNBjBDi33aa9GkA3w")
435+
sorcery_controller_external_property_set(:slack, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8")
436+
sorcery_controller_external_property_set(:slack, :callback_url, "http://blabla.com")
423437
end
424438

425439
def provider_url(provider)
@@ -429,7 +443,8 @@ def provider_url(provider)
429443
google: "https://accounts.google.com/o/oauth2/auth?client_id=#{::Sorcery::Controller::Config.google.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&state",
430444
liveid: "https://oauth.live.com/authorize?client_id=#{::Sorcery::Controller::Config.liveid.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=wl.basic+wl.emails+wl.offline_access&state",
431445
vk: "https://oauth.vk.com/authorize?client_id=#{::Sorcery::Controller::Config.vk.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=#{::Sorcery::Controller::Config.vk.scope}&state",
432-
salesforce: "https://login.salesforce.com/services/oauth2/authorize?client_id=#{::Sorcery::Controller::Config.salesforce.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope#{'=' + ::Sorcery::Controller::Config.salesforce.scope unless ::Sorcery::Controller::Config.salesforce.scope.nil?}&state"
446+
salesforce: "https://login.salesforce.com/services/oauth2/authorize?client_id=#{::Sorcery::Controller::Config.salesforce.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope#{'=' + ::Sorcery::Controller::Config.salesforce.scope unless ::Sorcery::Controller::Config.salesforce.scope.nil?}&state",
447+
slack: "https://slack.com/oauth/authorize?client_id=#{::Sorcery::Controller::Config.slack.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=identity.basic%2C+identity.email&state"
433448
}[provider]
434449
end
435450
end

spec/rails_app/app/controllers/sorcery_controller.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ def login_at_test_salesforce
121121
login_at(:salesforce)
122122
end
123123

124+
def login_at_test_slack
125+
login_at(:slack)
126+
end
127+
124128
def login_at_test_with_state
125129
login_at(:facebook, {state: 'bla'})
126130
end
@@ -199,6 +203,14 @@ def test_login_from_salesforce
199203
end
200204
end
201205

206+
def test_login_from_slack
207+
if @user = login_from(:slack)
208+
redirect_to 'bla', notice: 'Success!'
209+
else
210+
redirect_to 'blu', alert: 'Failed!'
211+
end
212+
end
213+
202214
def test_return_to_with_external_twitter
203215
if @user = login_from(:twitter)
204216
redirect_back_or_to 'bla', notice: 'Success!'
@@ -273,6 +285,14 @@ def test_return_to_with_external_salesforce
273285
end
274286
end
275287

288+
def test_return_to_with_external_slack
289+
if @user = login_from(:slack)
290+
redirect_back_or_to 'bla', notice: 'Success!'
291+
else
292+
redirect_to 'blu', alert: 'Failed!'
293+
end
294+
end
295+
276296
def test_create_from_provider
277297
provider = params[:provider]
278298
login_from(provider)

spec/rails_app/config/routes.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
get :test_login_from_vk
2727
get :test_login_from_jira
2828
get :test_login_from_salesforce
29+
get :test_login_from_slack
2930
get :login_at_test
3031
get :login_at_test_twitter
3132
get :login_at_test_facebook
@@ -36,6 +37,7 @@
3637
get :login_at_test_vk
3738
get :login_at_test_jira
3839
get :login_at_test_salesforce
40+
get :login_at_test_slack
3941
get :test_return_to_with_external
4042
get :test_return_to_with_external_twitter
4143
get :test_return_to_with_external_facebook
@@ -46,6 +48,7 @@
4648
get :test_return_to_with_external_vk
4749
get :test_return_to_with_external_jira
4850
get :test_return_to_with_external_salesforce
51+
get :test_return_to_with_external_slack
4952
get :test_http_basic_auth
5053
get :some_action_making_a_non_persisted_change_to_the_user
5154
post :test_login_with_remember

spec/shared_examples/user_shared_examples.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,11 +262,11 @@ class Admin2 < User; end
262262
let(:user_with_pass) { create_new_user({:username => 'foo_bar', :email => "foo@bar.com", :password => 'foobar'})}
263263

264264
specify { expect(user_with_pass).to respond_to :valid_password? }
265-
265+
266266
it "returns true if password is correct" do
267267
expect(user_with_pass.valid_password?("foobar")).to be true
268268
end
269-
269+
270270
it "returns false if password is incorrect" do
271271
expect(user_with_pass.valid_password?("foobug")).to be false
272272
end
@@ -541,7 +541,7 @@ def self.matches?(crypted,*tokens)
541541
User.sorcery_adapter.delete_all
542542
end
543543

544-
[:facebook, :github, :google, :liveid].each do |provider|
544+
[:facebook, :github, :google, :liveid, :slack].each do |provider|
545545

546546
it "does not send activation email to external users" do
547547
old_size = ActionMailer::Base.deliveries.size

0 commit comments

Comments
 (0)