Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZ.J. van de Weg <git@zjvandeweg.nl>2016-12-13 21:52:41 +0300
committerZ.J. van de Weg <git@zjvandeweg.nl>2016-12-16 14:21:09 +0300
commit87d160634dfdaacd0dc382c26932786382d1be34 (patch)
tree3eb381dd13f1ebd0acdf6c5364f9c2639e057b26
parentdd385c7c3d3046da18c6c251bce25afab1129662 (diff)
Base work for auto config MM slash commands
-rw-r--r--app/controllers/projects/services_controller.rb28
-rw-r--r--app/helpers/mattermost_helper.rb13
-rw-r--r--app/models/project_services/mattermost_slash_commands_service.rb15
-rw-r--r--app/models/service.rb4
-rw-r--r--app/views/projects/services/_form.html.haml20
-rw-r--r--app/views/projects/services/mattermost_slash_commands/_form.html.haml3
-rw-r--r--app/views/projects/services/mattermost_slash_commands/_help.html.haml195
-rw-r--r--app/views/shared/_service_settings.html.haml73
-rw-r--r--config/gitlab.yml.example5
-rw-r--r--config/routes/project.rb1
-rw-r--r--lib/mattermost/command.rb26
-rw-r--r--lib/mattermost/session.rb13
-rw-r--r--lib/mattermost/team.rb10
13 files changed, 259 insertions, 147 deletions
diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb
index 30c2a5d9982..94ea36bbdd9 100644
--- a/app/controllers/projects/services_controller.rb
+++ b/app/controllers/projects/services_controller.rb
@@ -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
diff --git a/app/helpers/mattermost_helper.rb b/app/helpers/mattermost_helper.rb
new file mode 100644
index 00000000000..83434c20c2b
--- /dev/null
+++ b/app/helpers/mattermost_helper.rb
@@ -0,0 +1,13 @@
+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
diff --git a/app/models/project_services/mattermost_slash_commands_service.rb b/app/models/project_services/mattermost_slash_commands_service.rb
index 33431f41dc2..c0e8e1a9324 100644
--- a/app/models/project_services/mattermost_slash_commands_service.rb
+++ b/app/models/project_services/mattermost_slash_commands_service.rb
@@ -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])
diff --git a/app/models/service.rb b/app/models/service.rb
index e49a8fa2904..9004d9caa19 100644
--- a/app/models/service.rb
+++ b/app/models/service.rb
@@ -54,6 +54,10 @@ class Service < ActiveRecord::Base
template
end
+ def auto_config?
+ false
+ end
+
def category
read_attribute(:category).to_sym
end
diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml
index db51c4f8a4e..0160a366aaa 100644
--- a/app/views/projects/services/_form.html.haml
+++ b/app/views/projects/services/_form.html.haml
@@ -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"
diff --git a/app/views/projects/services/mattermost_slash_commands/_form.html.haml b/app/views/projects/services/mattermost_slash_commands/_form.html.haml
new file mode 100644
index 00000000000..9d9c877e791
--- /dev/null
+++ b/app/views/projects/services/mattermost_slash_commands/_form.html.haml
@@ -0,0 +1,3 @@
+- teams = Mattermost::Mattermost.new(Gitlab.config.mattermost.host, current_user).with_session do
+ Mattermost::Mattermost::Team.all
+ end
diff --git a/app/views/projects/services/mattermost_slash_commands/_help.html.haml b/app/views/projects/services/mattermost_slash_commands/_help.html.haml
index a676c0290a0..70f2ef52135 100644
--- a/app/views/projects/services/mattermost_slash_commands/_help.html.haml
+++ b/app/views/projects/services/mattermost_slash_commands/_help.html.haml
@@ -1,100 +1,101 @@
- 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
diff --git a/app/views/shared/_service_settings.html.haml b/app/views/shared/_service_settings.html.haml
index 9c5053dace5..e8ab1b2ed46 100644
--- a/app/views/shared/_service_settings.html.haml
+++ b/app/views/shared/_service_settings.html.haml
@@ -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
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index 327e4a7937c..e1e76e8bf73 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -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:
diff --git a/config/routes/project.rb b/config/routes/project.rb
index 0754f0ec3b0..6f480b9e1a0 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -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
diff --git a/lib/mattermost/command.rb b/lib/mattermost/command.rb
new file mode 100644
index 00000000000..e159458a788
--- /dev/null
+++ b/lib/mattermost/command.rb
@@ -0,0 +1,26 @@
+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
diff --git a/lib/mattermost/session.rb b/lib/mattermost/session.rb
index 81964666757..cc4cb1f4f12 100644
--- a/lib/mattermost/session.rb
+++ b/lib/mattermost/session.rb
@@ -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
diff --git a/lib/mattermost/team.rb b/lib/mattermost/team.rb
new file mode 100644
index 00000000000..76e238a866e
--- /dev/null
+++ b/lib/mattermost/team.rb
@@ -0,0 +1,10 @@
+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