Skip to content
Snippets Groups Projects
Commit 429c9220 authored by Z.J. van de Weg's avatar Z.J. van de Weg
Browse files

Setup mattermost session

parent db9e1635
No related branches found
No related tags found
No related merge requests found
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
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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment