Commit 87d16063 authored by Z.J. van de Weg's avatar Z.J. van de Weg

Base work for auto config MM slash commands

parent dd385c7c
...@@ -3,7 +3,7 @@ class Projects::ServicesController < Projects::ApplicationController ...@@ -3,7 +3,7 @@ class Projects::ServicesController < Projects::ApplicationController
# Authorize # Authorize
before_action :authorize_admin_project! before_action :authorize_admin_project!
before_action :service, only: [:edit, :update, :test] before_action :service, only: [:edit, :update, :test, :configure]
respond_to :html respond_to :html
...@@ -44,9 +44,35 @@ class Projects::ServicesController < Projects::ApplicationController ...@@ -44,9 +44,35 @@ class Projects::ServicesController < Projects::ApplicationController
redirect_back_or_default(options: message) redirect_back_or_default(options: message)
end end
def configure
host = Gitlab.config.mattermost.host
if @service.auto_config? && host
@service.configure(host, current_user, params)
redirect_to(
edit_namespace_project_service_path(@project.namespace, @project, @service.to_param),
notice: 'This service is now configured.'
)
else
redirect_to(
edit_namespace_project_service_path(@project.namespace, @project, @service.to_param),
alert: 'This service can not be automatticly configured.'
)
end
rescue Mattermost::NoSessionError
redirect_to(
edit_namespace_project_service_path(@project.namespace, @project, @service.to_param),
alert: 'An error occurred, is Mattermost configured with Single Sign on?'
)
end
private private
def service def service
@service ||= @project.find_or_initialize_service(params[:id]) @service ||= @project.find_or_initialize_service(params[:id])
end end
def configure_params
params.require(:auto_configure).permit(:trigger, :team_id)
end
end end
module MattermostHelper
def mattermost_teams_for(current_user)
return unless Gitlab.config.mattermost.enabled
# Hack to make frontend work better
return [{"id"=>"qz8gdr1fopncueb8n9on8ohk3h", "create_at"=>1479992105904, "update_at"=>1479992105904, "delete_at"=>0, "display_name"=>"chatops", "name"=>"chatops", "email"=>"admin@example.com", "type"=>"O", "company_name"=>"", "allowed_domains"=>"", "invite_id"=>"gthxi47gj7rxtcx6zama63zd1w", "allow_open_invite"=>false}]
host = Gitlab.config.mattermost.host
Mattermost::Mattermost.new(host, current_user).with_session do
Mattermost::Team.all
end
end
end
...@@ -25,6 +25,21 @@ class MattermostSlashCommandsService < ChatService ...@@ -25,6 +25,21 @@ class MattermostSlashCommandsService < ChatService
] ]
end end
def auto_config?
Gitlab.config.mattermost.enabled
end
def configure(host, current_user, params)
token = Mattermost::Mattermost.new(host, current_user).with_session do
Mattermost::Commands.create(params[:team_id],
trigger: params[:trigger] || @service.project.path,
url: service_trigger_url(@service),
icon_url: asset_url('gitlab_logo.png'))
end
update_attributes(token: token)
end
def trigger(params) def trigger(params)
return nil unless valid_token?(params[:token]) return nil unless valid_token?(params[:token])
......
...@@ -54,6 +54,10 @@ class Service < ActiveRecord::Base ...@@ -54,6 +54,10 @@ class Service < ActiveRecord::Base
template template
end end
def auto_config?
false
end
def category def category
read_attribute(:category).to_sym read_attribute(:category).to_sym
end end
......
...@@ -6,16 +6,12 @@ ...@@ -6,16 +6,12 @@
%p= @service.description %p= @service.description
.col-lg-9 .col-lg-9
= form_for(@service, as: :service, url: namespace_project_service_path(@project.namespace, @project, @service.to_param), method: :put, html: { class: 'form-horizontal' }) do |form| - # This returns an array of hashes, could you make a fancy dropdown :D
= render 'shared/service_settings', form: form, subject: @service - # Also, this is mocked for now, checkout the MattermostHelper to edit the data
= mattermost_teams_for(current_user)
= form_for(:auto_configure, method: :post, url: configure_namespace_project_service_path(@project.namespace, @project, @service.to_param)) do |f|
= "Team ID"
= f.text_field(:team_id)
= "Team ID"
= f.submit 'Save changes', class: 'btn btn-save'
.footer-block.row-content-block
= form.submit 'Save changes', class: 'btn btn-save'
&nbsp;
- if @service.valid? && @service.activated?
- unless @service.can_test?
- disabled_class = 'disabled'
- disabled_title = @service.disabled_title
= link_to 'Test settings', test_namespace_project_service_path(@project.namespace, @project, @service), class: "btn #{disabled_class}", title: disabled_title
= link_to "Cancel", namespace_project_services_path(@project.namespace, @project), class: "btn btn-cancel"
- teams = Mattermost::Mattermost.new(Gitlab.config.mattermost.host, current_user).with_session do
Mattermost::Mattermost::Team.all
end
- pretty_path_with_namespace = "#{@project ? @project.namespace.name : 'namespace'} / #{@project ? @project.name : 'name'}" - pretty_path_with_namespace = "#{@project ? @project.namespace.name : 'namespace'} / #{@project ? @project.name : 'name'}"
- run_actions_text = "Perform common operations on this project: #{pretty_path_with_namespace}" - run_actions_text = "Perform common operations on this project: #{pretty_path_with_namespace}"
.well - unless GitLab.config.mattermost.enabled
.well
This service allows GitLab users to perform common operations on this This service allows GitLab users to perform common operations on this
project by entering slash commands in Mattermost. project by entering slash commands in Mattermost.
%br %br
......
...@@ -13,6 +13,9 @@ ...@@ -13,6 +13,9 @@
.col-sm-10 .col-sm-10
= form.check_box :active = form.check_box :active
- if @service.auto_config?
- else
- if @service.supported_events.present? - if @service.supported_events.present?
.form-group .form-group
= form.label :url, "Trigger", class: 'control-label' = form.label :url, "Trigger", class: 'control-label'
......
...@@ -153,6 +153,11 @@ production: &base ...@@ -153,6 +153,11 @@ production: &base
# The location where LFS objects are stored (default: shared/lfs-objects). # The location where LFS objects are stored (default: shared/lfs-objects).
# storage_path: shared/lfs-objects # storage_path: shared/lfs-objects
# For executing commands from GitLab on Mattermost
mattermost:
enabled: false
host: 'http://locahost:8065'
## Gravatar ## Gravatar
## For Libravatar see: http://doc.gitlab.com/ce/customization/libravatar.html ## For Libravatar see: http://doc.gitlab.com/ce/customization/libravatar.html
gravatar: gravatar:
......
...@@ -61,6 +61,7 @@ constraints(ProjectUrlConstrainer.new) do ...@@ -61,6 +61,7 @@ constraints(ProjectUrlConstrainer.new) do
resources :services, constraints: { id: /[^\/]+/ }, only: [:index, :edit, :update] do resources :services, constraints: { id: /[^\/]+/ }, only: [:index, :edit, :update] do
member do member do
get :test get :test
post :configure
end end
end end
......
module Mattermost
class Command
def self.all(team_id)
Mattermost::Mattermost.get("/teams/#{team_id}/commands/list_team_commands")
end
# params should be a hash, which supplies _at least_:
# - trigger => The slash command, no spaces, cannot start with a /
# - url => What is the URL to trigger here?
# - icon_url => Supply a link to the icon
def self.create(team_id, params)
params = {
auto_complete: true,
auto_complete_desc: 'List all available commands',
auto_complete_hint: '[help]',
description: 'Perform common operations on GitLab',
display_name: 'GitLab',
method: 'P',
user_name: 'GitLab'
}..merge(params)
Mattermost::Mattermost.post( "/teams/#{team_id}/commands/create", params.to_json).
parsed_response['token']
end
end
end
...@@ -20,6 +20,7 @@ module Mattermost ...@@ -20,6 +20,7 @@ module Mattermost
attr_accessor :current_resource_owner attr_accessor :current_resource_owner
def initialize(uri, current_user) def initialize(uri, current_user)
uri = normalize_uri(uri)
self.class.base_uri(uri) self.class.base_uri(uri)
@current_resource_owner = current_user @current_resource_owner = current_user
...@@ -31,6 +32,8 @@ module Mattermost ...@@ -31,6 +32,8 @@ module Mattermost
destroy destroy
result result
rescue Errno::ECONNREFUSED
raise NoSessionError
end end
# Next methods are needed for Doorkeeper # Next methods are needed for Doorkeeper
...@@ -67,11 +70,11 @@ module Mattermost ...@@ -67,11 +70,11 @@ module Mattermost
end end
def destroy def destroy
post('/api/v3/users/logout') post('/users/logout')
end end
def oauth_uri def oauth_uri
response = get("/api/v3/oauth/gitlab/login", follow_redirects: false) response = get("/oauth/gitlab/login", follow_redirects: false)
return unless 300 <= response.code && response.code < 400 return unless 300 <= response.code && response.code < 400
redirect_uri = response.headers['location'] redirect_uri = response.headers['location']
...@@ -100,5 +103,11 @@ module Mattermost ...@@ -100,5 +103,11 @@ module Mattermost
def post(path, options = {}) def post(path, options = {})
self.class.post(path, options) self.class.post(path, options)
end end
def normalize_uri(uri)
uri << '/' unless uri.end_with?('/')
uri << 'api/v3'
end
end end
end end
module Mattermost
class Team < Mattermost
# After normalization this returns an array of hashes
#
# [{"id"=>"paf573pj9t81urupw3fanozeda", "display_name"=>"my team", <snip>}]
def self.all
@all_teams ||= get('/teams/all').parsed_response.values
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment