From dd385c7c3d3046da18c6c251bce25afab1129662 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Thu, 15 Dec 2016 14:32:50 +0100 Subject: Improve session tests --- lib/mattermost/mattermost.rb | 102 ------------------------------------------ lib/mattermost/session.rb | 104 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 102 deletions(-) delete mode 100644 lib/mattermost/mattermost.rb create mode 100644 lib/mattermost/session.rb (limited to 'lib/mattermost') diff --git a/lib/mattermost/mattermost.rb b/lib/mattermost/mattermost.rb deleted file mode 100644 index 84d016bb197..00000000000 --- a/lib/mattermost/mattermost.rb +++ /dev/null @@ -1,102 +0,0 @@ -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 diff --git a/lib/mattermost/session.rb b/lib/mattermost/session.rb new file mode 100644 index 00000000000..81964666757 --- /dev/null +++ b/lib/mattermost/session.rb @@ -0,0 +1,104 @@ +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 Session + 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 + result = yield + destroy + + result + 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 ||= begin + 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 -- cgit v1.2.3