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
# Authorize
before_action :authorize_admin_project!
before_action :service, only: [:edit, :update, :test]
before_action :service, only: [:edit, :update, :test, :configure]
respond_to :html
......@@ -44,9 +44,35 @@ class Projects::ServicesController < Projects::ApplicationController
redirect_back_or_default(options: message)
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
def service
@service ||= @project.find_or_initialize_service(params[:id])
end
def configure_params
params.require(:auto_configure).permit(:trigger, :team_id)
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
]
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)
return nil unless valid_token?(params[:token])
......
......@@ -54,6 +54,10 @@ class Service < ActiveRecord::Base
template
end
def auto_config?
false
end
def category
read_attribute(:category).to_sym
end
......
......@@ -6,16 +6,12 @@
%p= @service.description
.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|
= render 'shared/service_settings', form: form, subject: @service
- # This returns an array of hashes, could you make a fancy dropdown :D
- # 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'}"
- run_actions_text = "Perform common operations on this project: #{pretty_path_with_namespace}"
.well
This service allows GitLab users to perform common operations on this
project by entering slash commands in Mattermost.
%br
See list of available commands in Mattermost after setting up this service,
by entering
%code /&lt;command_trigger_word&gt; help
%br
%br
To setup this service:
%ul.list-unstyled
%li
1.
= link_to 'Enable custom slash commands', 'https://docs.mattermost.com/developer/slash-commands.html#enabling-custom-commands'
on your Mattermost installation
%li
2.
= link_to 'Add a slash command', 'https://docs.mattermost.com/developer/slash-commands.html#set-up-a-custom-command'
in Mattermost with these options:
%hr
.help-form
.form-group
= label_tag :display_name, 'Display name', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.input-group
= text_field_tag :display_name, "GitLab / #{pretty_path_with_namespace}", class: 'form-control input-sm', readonly: 'readonly'
.input-group-btn
= clipboard_button(clipboard_target: '#display_name')
.form-group
= label_tag :description, 'Description', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.input-group
= text_field_tag :description, run_actions_text, class: 'form-control input-sm', readonly: 'readonly'
.input-group-btn
= clipboard_button(clipboard_target: '#description')
.form-group
= label_tag nil, 'Command trigger word', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.text-block
%p Fill in the word that works best for your team.
%p
Suggestions:
%code= 'gitlab'
%code= @project.path # Path contains no spaces, but dashes
%code= @project.path_with_namespace
.form-group
= label_tag :request_url, 'Request URL', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.input-group
= text_field_tag :request_url, service_trigger_url(subject), class: 'form-control input-sm', readonly: 'readonly'
.input-group-btn
= clipboard_button(clipboard_target: '#request_url')
.form-group
= label_tag nil, 'Request method', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.text-block POST
.form-group
= label_tag :response_username, 'Response username', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.input-group
= text_field_tag :response_username, 'GitLab', class: 'form-control input-sm', readonly: 'readonly'
.input-group-btn
= clipboard_button(clipboard_target: '#response_username')
.form-group
= label_tag :response_icon, 'Response icon', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.input-group
= text_field_tag :response_icon, asset_url('gitlab_logo.png'), class: 'form-control input-sm', readonly: 'readonly'
.input-group-btn
= clipboard_button(clipboard_target: '#response_icon')
.form-group
= label_tag nil, 'Autocomplete', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.text-block Yes
.form-group
= label_tag :autocomplete_hint, 'Autocomplete hint', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.input-group
= text_field_tag :autocomplete_hint, '[help]', class: 'form-control input-sm', readonly: 'readonly'
.input-group-btn
= clipboard_button(clipboard_target: '#autocomplete_hint')
.form-group
= label_tag :autocomplete_description, 'Autocomplete description', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.input-group
= text_field_tag :autocomplete_description, run_actions_text, class: 'form-control input-sm', readonly: 'readonly'
.input-group-btn
= clipboard_button(clipboard_target: '#autocomplete_description')
%hr
%ul.list-unstyled
%li
3. After adding the slash command, paste the
%strong token
into the field below
- unless GitLab.config.mattermost.enabled
.well
This service allows GitLab users to perform common operations on this
project by entering slash commands in Mattermost.
%br
See list of available commands in Mattermost after setting up this service,
by entering
%code /&lt;command_trigger_word&gt; help
%br
%br
To setup this service:
%ul.list-unstyled
%li
1.
= link_to 'Enable custom slash commands', 'https://docs.mattermost.com/developer/slash-commands.html#enabling-custom-commands'
on your Mattermost installation
%li
2.
= link_to 'Add a slash command', 'https://docs.mattermost.com/developer/slash-commands.html#set-up-a-custom-command'
in Mattermost with these options:
%hr
.help-form
.form-group
= label_tag :display_name, 'Display name', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.input-group
= text_field_tag :display_name, "GitLab / #{pretty_path_with_namespace}", class: 'form-control input-sm', readonly: 'readonly'
.input-group-btn
= clipboard_button(clipboard_target: '#display_name')
.form-group
= label_tag :description, 'Description', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.input-group
= text_field_tag :description, run_actions_text, class: 'form-control input-sm', readonly: 'readonly'
.input-group-btn
= clipboard_button(clipboard_target: '#description')
.form-group
= label_tag nil, 'Command trigger word', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.text-block
%p Fill in the word that works best for your team.
%p
Suggestions:
%code= 'gitlab'
%code= @project.path # Path contains no spaces, but dashes
%code= @project.path_with_namespace
.form-group
= label_tag :request_url, 'Request URL', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.input-group
= text_field_tag :request_url, service_trigger_url(subject), class: 'form-control input-sm', readonly: 'readonly'
.input-group-btn
= clipboard_button(clipboard_target: '#request_url')
.form-group
= label_tag nil, 'Request method', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.text-block POST
.form-group
= label_tag :response_username, 'Response username', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.input-group
= text_field_tag :response_username, 'GitLab', class: 'form-control input-sm', readonly: 'readonly'
.input-group-btn
= clipboard_button(clipboard_target: '#response_username')
.form-group
= label_tag :response_icon, 'Response icon', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.input-group
= text_field_tag :response_icon, asset_url('gitlab_logo.png'), class: 'form-control input-sm', readonly: 'readonly'
.input-group-btn
= clipboard_button(clipboard_target: '#response_icon')
.form-group
= label_tag nil, 'Autocomplete', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.text-block Yes
.form-group
= label_tag :autocomplete_hint, 'Autocomplete hint', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.input-group
= text_field_tag :autocomplete_hint, '[help]', class: 'form-control input-sm', readonly: 'readonly'
.input-group-btn
= clipboard_button(clipboard_target: '#autocomplete_hint')
.form-group
= label_tag :autocomplete_description, 'Autocomplete description', class: 'col-sm-2 col-xs-12 control-label'
.col-sm-10.col-xs-12.input-group
= text_field_tag :autocomplete_description, run_actions_text, class: 'form-control input-sm', readonly: 'readonly'
.input-group-btn
= clipboard_button(clipboard_target: '#autocomplete_description')
%hr
%ul.list-unstyled
%li
3. After adding the slash command, paste the
%strong token
into the field below
......@@ -13,38 +13,41 @@
.col-sm-10
= form.check_box :active
- if @service.supported_events.present?
.form-group
= form.label :url, "Trigger", class: 'control-label'
.col-sm-10
- @service.supported_events.each do |event|
%div
= form.check_box service_event_field_name(event), class: 'pull-left'
.prepend-left-20
= form.label service_event_field_name(event), class: 'list-label' do
%strong
= event.humanize
- field = @service.event_field(event)
- if field
%p
= form.text_field field[:name], class: "form-control", placeholder: field[:placeholder]
%p.light
= service_event_description(event)
- @service.global_fields.each do |field|
- type = field[:type]
- if type == 'fieldset'
- fields = field[:fields]
- legend = field[:legend]
%fieldset
%legend= legend
- fields.each do |subfield|
= render 'shared/field', form: form, field: subfield
- else
= render 'shared/field', form: form, field: field
- if @service.auto_config?
- else
- if @service.supported_events.present?
.form-group
= form.label :url, "Trigger", class: 'control-label'
.col-sm-10
- @service.supported_events.each do |event|
%div
= form.check_box service_event_field_name(event), class: 'pull-left'
.prepend-left-20
= form.label service_event_field_name(event), class: 'list-label' do
%strong
= event.humanize
- field = @service.event_field(event)
- if field
%p
= form.text_field field[:name], class: "form-control", placeholder: field[:placeholder]
%p.light
= service_event_description(event)
- @service.global_fields.each do |field|
- type = field[:type]
- if type == 'fieldset'
- fields = field[:fields]
- legend = field[:legend]
%fieldset
%legend= legend
- fields.each do |subfield|
= render 'shared/field', form: form, field: subfield
- else
= render 'shared/field', form: form, field: field
......@@ -153,6 +153,11 @@ production: &base
# The location where LFS objects are stored (default: shared/lfs-objects).
# storage_path: shared/lfs-objects
# For executing commands from GitLab on Mattermost
mattermost:
enabled: false
host: 'http://locahost:8065'
## Gravatar
## For Libravatar see: http://doc.gitlab.com/ce/customization/libravatar.html
gravatar:
......
......@@ -61,6 +61,7 @@ constraints(ProjectUrlConstrainer.new) do
resources :services, constraints: { id: /[^\/]+/ }, only: [:index, :edit, :update] do
member do
get :test
post :configure
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
attr_accessor :current_resource_owner
def initialize(uri, current_user)
uri = normalize_uri(uri)
self.class.base_uri(uri)
@current_resource_owner = current_user
......@@ -31,6 +32,8 @@ module Mattermost
destroy
result
rescue Errno::ECONNREFUSED
raise NoSessionError
end
# Next methods are needed for Doorkeeper
......@@ -67,11 +70,11 @@ module Mattermost
end
def destroy
post('/api/v3/users/logout')
post('/users/logout')
end
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
redirect_uri = response.headers['location']
......@@ -100,5 +103,11 @@ module Mattermost
def post(path, options = {})
self.class.post(path, options)
end
def normalize_uri(uri)
uri << '/' unless uri.end_with?('/')
uri << 'api/v3'
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