Setup mattermost session
This commit is contained in:
parent
db9e1635d0
commit
429c9220f0
2 changed files with 144 additions and 0 deletions
102
lib/mattermost/mattermost.rb
Normal file
102
lib/mattermost/mattermost.rb
Normal file
|
@ -0,0 +1,102 @@
|
|||
module Mattermost
|
||||
class NoSessionError < StandardError; end
|
||||
# This class' prime objective is to obtain a session token on a Mattermost
|
||||
# instance with SSO configured where this GitLab instance is the provider.
|
||||
#
|
||||
# The process depends on OAuth, but skips a step in the authentication cycle.
|
||||
# For example, usually a user would click the 'login in GitLab' button on
|
||||
# Mattermost, which would yield a 302 status code and redirects you to GitLab
|
||||
# to approve the use of your account on Mattermost. Which would trigger a
|
||||
# callback so Mattermost knows this request is approved and gets the required
|
||||
# data to create the user account etc.
|
||||
#
|
||||
# This class however skips the button click, and also the approval phase to
|
||||
# speed up the process and keep it without manual action and get a session
|
||||
# going.
|
||||
class Mattermost
|
||||
include Doorkeeper::Helpers::Controller
|
||||
include HTTParty
|
||||
|
||||
attr_accessor :current_resource_owner
|
||||
|
||||
def initialize(uri, current_user)
|
||||
self.class.base_uri(uri)
|
||||
|
||||
@current_resource_owner = current_user
|
||||
end
|
||||
|
||||
def with_session
|
||||
raise NoSessionError unless create
|
||||
yield
|
||||
destroy
|
||||
end
|
||||
|
||||
# Next methods are needed for Doorkeeper
|
||||
def pre_auth
|
||||
@pre_auth ||= Doorkeeper::OAuth::PreAuthorization.new(
|
||||
Doorkeeper.configuration, server.client_via_uid, params)
|
||||
end
|
||||
|
||||
def authorization
|
||||
@authorization ||= strategy.request
|
||||
end
|
||||
|
||||
def strategy
|
||||
@strategy ||= server.authorization_request(pre_auth.response_type)
|
||||
end
|
||||
|
||||
def request
|
||||
@request ||= OpenStruct.new(parameters: params)
|
||||
end
|
||||
|
||||
def params
|
||||
Rack::Utils.parse_query(@oauth_uri.query).symbolize_keys
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create
|
||||
return unless oauth_uri
|
||||
return unless token_uri
|
||||
|
||||
self.class.headers("Cookie" => "MMAUTHTOKEN=#{request_token}")
|
||||
|
||||
request_token
|
||||
end
|
||||
|
||||
def destroy
|
||||
post('/api/v3/users/logout')
|
||||
end
|
||||
|
||||
def oauth_uri
|
||||
response = get("/api/v3/oauth/gitlab/login", follow_redirects: false)
|
||||
return unless 300 <= response.code && response.code < 400
|
||||
|
||||
redirect_uri = response.headers['location']
|
||||
return unless redirect_uri
|
||||
|
||||
@oauth_uri ||= URI.parse(redirect_uri)
|
||||
end
|
||||
|
||||
def token_uri
|
||||
@token_uri ||= if @oauth_uri
|
||||
authorization.authorize.redirect_uri if pre_auth.authorizable?
|
||||
end
|
||||
end
|
||||
|
||||
def request_token
|
||||
@request_token ||= if @token_uri
|
||||
response = get(@token_uri, follow_redirects: false)
|
||||
response.headers['token'] if 200 <= response.code && response.code < 400
|
||||
end
|
||||
end
|
||||
|
||||
def get(path, options = {})
|
||||
self.class.get(path, options)
|
||||
end
|
||||
|
||||
def post(path, options = {})
|
||||
self.class.post(path, options)
|
||||
end
|
||||
end
|
||||
end
|
42
spec/lib/mattermost/mattermost_spec.rb
Normal file
42
spec/lib/mattermost/mattermost_spec.rb
Normal file
|
@ -0,0 +1,42 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Mattermost::Mattermost do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
subject { described_class.new('http://localhost:8065', user) }
|
||||
|
||||
# Needed for doorman to function
|
||||
it { is_expected.to respond_to(:current_resource_owner) }
|
||||
it { is_expected.to respond_to(:request) }
|
||||
it { is_expected.to respond_to(:authorization) }
|
||||
it { is_expected.to respond_to(:strategy) }
|
||||
|
||||
describe '#with session' do
|
||||
let!(:stub) do
|
||||
WebMock.stub_request(:get, 'http://localhost:8065/api/v3/oauth/gitlab/login').
|
||||
to_return(headers: { 'location' => 'http://mylocation.com' }, status: 307)
|
||||
end
|
||||
|
||||
context 'without oauth uri' do
|
||||
it 'makes a request to the oauth uri' do
|
||||
expect { subject.with_session }.to raise_error(Mattermost::NoSessionError)
|
||||
end
|
||||
|
||||
context 'with oauth_uri' do
|
||||
let!(:doorkeeper) do
|
||||
Doorkeeper::Application.create(name: "GitLab Mattermost",
|
||||
redirect_uri: "http://localhost:8065/signup/gitlab/complete\nhttp://localhost:8065/login/gitlab/complete",
|
||||
scopes: "")
|
||||
end
|
||||
|
||||
context 'without token_uri' do
|
||||
it 'can not create a session' do
|
||||
expect do
|
||||
subject.with_session
|
||||
end.to raise_error(Mattermost::NoSessionError)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue