gitlab-org--gitlab-foss/lib/mattermost/session.rb

116 lines
2.9 KiB
Ruby
Raw Normal View History

2016-12-12 03:31:48 -05:00
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.
2016-12-15 08:32:50 -05:00
class Session
2016-12-12 03:31:48 -05:00
include Doorkeeper::Helpers::Controller
include HTTParty
2016-12-16 06:20:42 -05:00
base_uri Settings.mattermost.host
2016-12-12 03:31:48 -05:00
2016-12-16 06:20:42 -05:00
attr_accessor :current_resource_owner, :token
2016-12-12 03:31:48 -05:00
2016-12-16 06:20:42 -05:00
def initialize(current_user)
2016-12-12 03:31:48 -05:00
@current_resource_owner = current_user
end
def with_session
raise NoSessionError unless create
2016-12-15 08:32:50 -05:00
2016-12-15 15:06:17 -05:00
begin
2016-12-16 06:20:42 -05:00
yield self
2016-12-15 15:06:17 -05:00
ensure
destroy
end
2016-12-12 03:31:48 -05:00
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
2016-12-16 07:43:01 -05:00
Rack::Utils.parse_query(oauth_uri.query).symbolize_keys
end
def get(path, options = {})
self.class.get(path, options.merge(headers: @headers))
end
def post(path, options = {})
self.class.post(path, options.merge(headers: @headers))
2016-12-12 03:31:48 -05:00
end
private
def create
return unless oauth_uri
return unless token_uri
2016-12-16 07:43:01 -05:00
@token = request_token
2016-12-16 06:20:42 -05:00
@headers = {
2016-12-16 07:43:01 -05:00
Authorization: "Bearer #{@token}"
2016-12-16 06:20:42 -05:00
}
2016-12-16 07:43:01 -05:00
@token
2016-12-12 03:31:48 -05:00
end
def destroy
post('/api/v3/users/logout')
end
def oauth_uri
2016-12-16 07:43:01 -05:00
return @oauth_uri if defined?(@oauth_uri)
@oauth_uri = nil
2016-12-12 03:31:48 -05:00
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
2016-12-16 07:43:01 -05:00
@oauth_uri = URI.parse(redirect_uri)
2016-12-12 03:31:48 -05:00
end
def token_uri
2016-12-16 05:31:26 -05:00
@token_uri ||=
2016-12-16 07:43:01 -05:00
if oauth_uri
2016-12-16 05:31:26 -05:00
authorization.authorize.redirect_uri if pre_auth.authorizable?
end
2016-12-12 03:31:48 -05:00
end
def request_token
2016-12-16 07:43:01 -05:00
response = get(token_uri, follow_redirects: false)
2016-12-16 05:31:26 -05:00
if 200 <= response.code && response.code < 400
response.headers['token']
end
2016-12-12 03:31:48 -05:00
end
end
end