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

Base work for auto config MM slash commands

parent dd385c7c
No related branches found
No related tags found
No related merge requests found
Showing with 259 additions and 147 deletions
Loading
Loading
@@ -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
 
Loading
Loading
@@ -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
Loading
Loading
@@ -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])
 
Loading
Loading
Loading
Loading
@@ -54,6 +54,10 @@ class Service < ActiveRecord::Base
template
end
 
def auto_config?
false
end
def category
read_attribute(:category).to_sym
end
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
@@ -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
Loading
Loading
@@ -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:
Loading
Loading
Loading
Loading
@@ -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
 
Loading
Loading
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
Loading
Loading
@@ -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
Loading
Loading
@@ -31,6 +32,8 @@ module Mattermost
destroy
 
result
rescue Errno::ECONNREFUSED
raise NoSessionError
end
 
# Next methods are needed for Doorkeeper
Loading
Loading
@@ -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']
Loading
Loading
@@ -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
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