summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/stylesheets/pages/projects.scss20
-rw-r--r--app/controllers/projects/mattermost_controller.rb39
-rw-r--r--app/helpers/application_helper.rb4
-rw-r--r--app/helpers/projects_helper.rb9
-rw-r--r--app/models/project_services/mattermost_slash_commands_service.rb42
-rw-r--r--app/views/projects/mattermost/_no_teams.html.haml12
-rw-r--r--app/views/projects/mattermost/_team_selection.html.haml41
-rw-r--r--app/views/projects/mattermost/new.html.haml8
-rw-r--r--app/views/projects/services/_form.html.haml1
-rw-r--r--app/views/projects/services/mattermost_slash_commands/_detailed_help.html.haml91
-rw-r--r--app/views/projects/services/mattermost_slash_commands/_help.html.haml93
-rw-r--r--app/views/projects/services/mattermost_slash_commands/_installation_info.html.haml22
-rw-r--r--app/views/shared/icons/_mattermost_logo.svg.erb1
-rw-r--r--config/gitlab.yml.example2
-rw-r--r--config/routes/project.rb2
-rwxr-xr-xcopy.sh11
-rw-r--r--lib/mattermost/command.rb13
-rw-r--r--lib/mattermost/session.rb2
-rw-r--r--lib/mattermost/team.rb11
-rw-r--r--spec/features/projects/services/mattermost_slash_command_spec.rb67
-rw-r--r--spec/lib/mattermost/command_spec.rb19
-rw-r--r--spec/lib/mattermost/team_spec.rb41
-rw-r--r--spec/models/project_services/mattermost_slash_commands_service_spec.rb36
23 files changed, 481 insertions, 106 deletions
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index 3b1b375133d..2e2532580b6 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -882,3 +882,23 @@ pre.light-well {
width: 30%;
}
}
+
+.services-installation-info .row {
+ margin-bottom: 10px;
+}
+
+.service-installation {
+ padding: 32px;
+ margin: 32px;
+ border-radius: 3px;
+ background-color: $white-light;
+
+ h3 {
+ margin-top: 0;
+ }
+
+ hr {
+ margin: 32px 0;
+ border-color: $border-color;
+ }
+}
diff --git a/app/controllers/projects/mattermost_controller.rb b/app/controllers/projects/mattermost_controller.rb
new file mode 100644
index 00000000000..a0eaec262ee
--- /dev/null
+++ b/app/controllers/projects/mattermost_controller.rb
@@ -0,0 +1,39 @@
+class Projects::MattermostController < Projects::ApplicationController
+ layout 'project_settings'
+ before_action :authorize_admin_project!
+ before_action :service
+ before_action :teams, only: [:new]
+
+ def new
+ end
+
+ def create
+ message = @service.configure(current_user, configure_params)
+ notice = message.is_a?(String) ? message : 'This service is now configured'
+
+ redirect_to(
+ new_namespace_project_mattermost_path(@project.namespace, @project),
+ notice: notice
+ )
+ rescue NoSessionError
+ redirect_to(
+ new_namespace_project_mattermost_path(@project.namespace, @project),
+ alert: 'No session could be set up, is Mattermost configured with Single Sign on?'
+ )
+ end
+
+ private
+
+ def configure_params
+ params.permit(:trigger, :team_id).
+ merge(url: service_trigger_url(@service), icon_url: asset_url('gitlab_logo.png'))
+ end
+
+ def service
+ @service ||= @project.find_or_initialize_service('mattermost_slash_commands')
+ end
+
+ def teams
+ @teams = @service.list_teams(current_user)
+ end
+end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index c816b616631..adb5eeee3e4 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -294,4 +294,8 @@ module ApplicationHelper
def page_class
"issue-boards-page" if current_controller?(:boards)
end
+
+ def pretty_url(url)
+ url.gsub(/\A.*?:\/\//, '')
+ end
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index d2177f683a1..963e72ce96e 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -148,6 +148,15 @@ module ProjectsHelper
).html_safe
end
+ def mattermost_teams_options(teams)
+ teams_options = teams.map do |team|
+ return nil unless team['display_name'] && team['id']
+ [team['display_name'], team['id']]
+ end.compact
+ teams_options.unshift(['Select team...', '0']) unless teams_options.one?
+ teams_options
+ end
+
private
def repo_children_classes(field)
diff --git a/app/models/project_services/mattermost_slash_commands_service.rb b/app/models/project_services/mattermost_slash_commands_service.rb
index 33431f41dc2..5000f96e350 100644
--- a/app/models/project_services/mattermost_slash_commands_service.rb
+++ b/app/models/project_services/mattermost_slash_commands_service.rb
@@ -25,6 +25,31 @@ class MattermostSlashCommandsService < ChatService
]
end
+ def configure(current_user, params)
+ result = Mattermost::Session.new(current_user).with_session do |session|
+ Mattermost::Command.create(session, params[:team_id], command)
+ end
+
+ if result.has_key?('message')
+ result['message']
+ else
+ update!(token: result['token'], active: true)
+ end
+ end
+
+ def list_teams
+ begin
+ response = Mattermost::Session.new(current_user).with_session do |session|
+ Mattermost::Team.all(session)
+ end
+
+ # We ignore the error message as we can't display it
+ response.has_key?('message') ? [] : response
+ rescue Mattermost::NoSessionError
+ []
+ end
+ end
+
def trigger(params)
return nil unless valid_token?(params[:token])
@@ -39,6 +64,23 @@ class MattermostSlashCommandsService < ChatService
private
+ def command(trigger:, url:, icon_url:)
+ pretty_project_name = project.name_with_namespace
+
+ {
+ auto_complete: true,
+ auto_complete_desc: "Perform common operations on: #{pretty_project_name}",
+ auto_complete_hint: '[help]',
+ description: "Perform common operations on: #{pretty_project_name}",
+ display_name: "GitLab / #{pretty_project_name}",
+ method: 'P',
+ user_name: 'GitLab',
+ trigger: trigger,
+ url: url,
+ icon_url: icon_url
+ }
+ end
+
def find_chat_user(params)
ChatNames::FindUserService.new(self, params).execute
end
diff --git a/app/views/projects/mattermost/_no_teams.html.haml b/app/views/projects/mattermost/_no_teams.html.haml
new file mode 100644
index 00000000000..605c7f61dee
--- /dev/null
+++ b/app/views/projects/mattermost/_no_teams.html.haml
@@ -0,0 +1,12 @@
+%p
+ You aren’t a member of any team on the Mattermost instance at
+ %strong= Gitlab.config.mattermost.host
+%p
+ To install this service,
+ = link_to "#{Gitlab.config.mattermost.host}/select_team", target: '__blank' do
+ join a team
+ = icon('external-link')
+ and try again.
+%hr
+.clearfix
+ = link_to 'Go back', edit_namespace_project_service_path(@project.namespace, @project, @service), class: 'btn btn-lg pull-right'
diff --git a/app/views/projects/mattermost/_team_selection.html.haml b/app/views/projects/mattermost/_team_selection.html.haml
new file mode 100644
index 00000000000..e0ab63dbc5d
--- /dev/null
+++ b/app/views/projects/mattermost/_team_selection.html.haml
@@ -0,0 +1,41 @@
+%p
+ This service will be installed on the Mattermost instance at
+ %strong= Gitlab.config.mattermost.host
+%hr
+= form_for(:create, method: :post, url: configure_namespace_project_mattermost_index_path(@project.namespace, @project)) do |f|
+ %h4 Team
+ %p Select or create the team where the slash commands will be used in
+ - options = mattermost_teams_options(@teams)
+ = f.select(:team_id, options, {}, { class: 'form-control', selected: "#{options.first[1] if options.count.one?}", disabled: options.count.one? })
+ .help-block
+ - if options.count.one?
+ This is the only team where you are an administrator.
+ - else
+ The list shows teams where you are administrator
+ To create a team, ask your Mattermost system administrator.
+ To create a team,
+ = link_to "#{Gitlab.config.mattermost.host}/create_team" do
+ use Mattermost's interface
+ = icon('external-link')
+ %hr
+ %h4 Command trigger word
+ %p Choose the word that will trigger commands
+ = f.text_field(:trigger, value: @project.path, class: 'form-control')
+ .help-block
+ %p Trigger word must be unique, and cannot begin with a slash or contain any spaces. Use the word that works best for your team.
+ %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
+ %p
+ Reserved:
+ = link_to 'https://docs.mattermost.com/help/messaging/executing-commands.html#built-in-commands', target: '__blank' do
+ see list of built-in slash commands
+ = icon('external-link')
+ %hr
+ .clearfix
+ .pull-right
+ = link_to 'Cancel', edit_namespace_project_service_path(@project.namespace, @project, @service), class: 'btn btn-lg'
+ = f.submit 'Install', class: 'btn btn-save btn-lg'
diff --git a/app/views/projects/mattermost/new.html.haml b/app/views/projects/mattermost/new.html.haml
new file mode 100644
index 00000000000..96b1d2aee61
--- /dev/null
+++ b/app/views/projects/mattermost/new.html.haml
@@ -0,0 +1,8 @@
+.service-installation
+ .inline.pull-right
+ = custom_icon('mattermost_logo', size: 48)
+ %h3 Install Mattermost Command
+ - if @teams.empty?
+ = render 'no_teams'
+ - else
+ = render 'team_selection'
diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml
index db51c4f8a4e..fc338dcf887 100644
--- a/app/views/projects/services/_form.html.haml
+++ b/app/views/projects/services/_form.html.haml
@@ -8,7 +8,6 @@
.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
-
.footer-block.row-content-block
= form.submit 'Save changes', class: 'btn btn-save'
&nbsp;
diff --git a/app/views/projects/services/mattermost_slash_commands/_detailed_help.html.haml b/app/views/projects/services/mattermost_slash_commands/_detailed_help.html.haml
new file mode 100644
index 00000000000..8ca4c51a064
--- /dev/null
+++ b/app/views/projects/services/mattermost_slash_commands/_detailed_help.html.haml
@@ -0,0 +1,91 @@
+- run_actions_text = "Perform common operations on this project: #{@project.name_with_namespace}"
+
+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 / #{@project.name_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/projects/services/mattermost_slash_commands/_help.html.haml b/app/views/projects/services/mattermost_slash_commands/_help.html.haml
index 01a77a952d1..7ed291e09db 100644
--- a/app/views/projects/services/mattermost_slash_commands/_help.html.haml
+++ b/app/views/projects/services/mattermost_slash_commands/_help.html.haml
@@ -1,4 +1,4 @@
-- run_actions_text = "Perform common operations on this project: #{@project.name_with_namespace}"
+- enabled = Gitlab.config.mattermost.enabled
.well
This service allows GitLab users to perform common operations on this
@@ -7,93 +7,6 @@
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 / #{@project.name_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
+ = render 'projects/services/mattermost_slash_commands/detailed_help', subject: @service unless enabled
- %ul.list-unstyled
- %li
- 3. After adding the slash command, paste the
- %strong token
- into the field below
+= render 'projects/services/mattermost_slash_commands/installation_info' if enabled
diff --git a/app/views/projects/services/mattermost_slash_commands/_installation_info.html.haml b/app/views/projects/services/mattermost_slash_commands/_installation_info.html.haml
new file mode 100644
index 00000000000..abc68e955e7
--- /dev/null
+++ b/app/views/projects/services/mattermost_slash_commands/_installation_info.html.haml
@@ -0,0 +1,22 @@
+.services-installation-info
+ .row
+ %strong.col-sm-3.text-right Status
+ .col-sm-9= @service.activated? ? 'Installed' : 'Not installed'
+ .row
+ %strong.col-sm-3.text-right Mattermost
+ = link_to pretty_url(Gitlab.config.mattermost.host), Gitlab.config.mattermost.host, class: 'col-sm-9', target: '__blank'
+ .row
+ %strong.col-sm-3.text-right Installation
+ .col-sm-9
+ - if @service.activated?
+ To edit or uninstall this service, press
+ %strong Edit in Mattermost
+ - else
+ To install this service, press
+ %strong Add to Mattermost
+ and follow the instructions
+ .row
+ .col-sm-9.col-sm-offset-3
+ = link_to new_namespace_project_mattermost_path(@project.namespace, @project), class: 'btn btn-lg' do
+ = custom_icon('mattermost_logo', size: 15)
+ = @service.activated? ? 'Edit in Mattermost' : 'Add to Mattermost'
diff --git a/app/views/shared/icons/_mattermost_logo.svg.erb b/app/views/shared/icons/_mattermost_logo.svg.erb
new file mode 100644
index 00000000000..83fbd1a407d
--- /dev/null
+++ b/app/views/shared/icons/_mattermost_logo.svg.erb
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="<%= size %>" height="<%= size %>" version="1" viewBox="0 0 501 501"><path d="M236 .7C137.7 7.5 54 68.2 18.2 158.5c-32 81-19.6 172.8 33 242.5 39.8 53 97.2 87 164.3 97 16.5 2.7 48 3.2 63.5 1.2 48.7-6.3 92.2-24.6 129-54.2 13-10.5 33-31.2 42.2-43.7 26.4-35.5 42.8-75.8 49-120.3 1.6-12.3 1.6-48.7 0-61-4-28.3-12-54.8-24.2-79.5-12.8-26-26.5-45.3-46.8-65.8C417.8 64 400.2 49 398.4 49c-.6 0-.4 10.5.3 26l1.3 26 7 8.7c19 23.7 32.8 53.5 38.2 83 2.5 14 3 43 1 55.8-4.5 27.8-15.2 54-31 76.5-8.6 12.2-28 31.6-40.2 40.2-24 17-50 27.6-80 33-10 1.8-49 1.8-59 0-43-7.7-78.8-26-107.2-54.8-29.3-29.7-46.5-64-52.4-104.4-2-14-1.5-42 1-55C90 121.4 132 72 192 49.7c8-3 18.4-5.8 29.5-8.2 1.7-.4 34.4-38 35.3-40.6.3-1-10.2-1-20.8-.4z"/><path d="M322.2 24.6c-1.3.8-8.4 9.3-16 18.7-7.4 9.5-22.4 28-33.2 41.2-51 62.2-66 81.6-70.6 91-6 12-8.4 21-9 33-1.2 19.8 5 36 19 50C222 268 230 273 243 277.2c9 3 10.4 3.2 24 3.2 13.8 0 15 0 22.6-3 23.2-9 39-28.4 45-55.7 2-8.2 2-28.7.4-79.7l-2-72c-1-36.8-1.4-41.8-3-44-2-3-4.8-3.6-7.8-1.4z"/></svg>
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index b8b41a0d86c..f53a3d066df 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -576,4 +576,4 @@ test:
admin_group: ''
staging:
- <<: *base
+ <<: *base \ No newline at end of file
diff --git a/config/routes/project.rb b/config/routes/project.rb
index e17d6bae10c..b42c5e5211c 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -76,6 +76,8 @@ constraints(ProjectUrlConstrainer.new) do
end
end
+ resources :mattermost, only: [:new, :create]
+
resources :deploy_keys, constraints: { id: /\d+/ }, only: [:index, :new, :create] do
member do
put :enable
diff --git a/copy.sh b/copy.sh
new file mode 100755
index 00000000000..2cdc593ef6d
--- /dev/null
+++ b/copy.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+set -xe
+
+# rsync --delete -av config/{routes.rb,routes,initializers,application.rb} zj-gitlab:/opt/gitlab/embedded/service/gitlab-rails/config/
+rsync --delete -av lib/mattermost zj-gitlab:/opt/gitlab/embedded/service/gitlab-rails/lib
+# rsync --delete -av vendor/{assets,gitignore,gitlab-ci-yml} zj-gitlab:/opt/gitlab/embedded/service/gitlab-rails/vendor/
+# rsync --delete -av ../gitlab-shell/{bin,lib,spec,hooks} zj-gitlab:/opt/gitlab/embedded/service/gitlab-shell
+#ssh gitlab-test 'cd /opt/gitlab/embedded/service/gitlab-rails && /opt/gitlab/embedded/bin/bundle install --deployment'
+#ssh gitlab-test 'export NO_PRIVILEGE_DROP=true; export USE_DB=false; gitlab-rake assets:precompile'
+ssh zj-gitlab gitlab-ctl restart
diff --git a/lib/mattermost/command.rb b/lib/mattermost/command.rb
new file mode 100644
index 00000000000..afbf2ce3349
--- /dev/null
+++ b/lib/mattermost/command.rb
@@ -0,0 +1,13 @@
+module Mattermost
+ class Command
+ def self.create(session, team_id, command)
+ response = session.post("/api/v3/teams/#{team_id}/commands/create", body: command.to_json).parsed_response
+
+ if response.has_key?('message')
+ response
+ else
+ response['token']
+ end
+ end
+ end
+end
diff --git a/lib/mattermost/session.rb b/lib/mattermost/session.rb
index fb8d7d97f8a..670f83bb6bc 100644
--- a/lib/mattermost/session.rb
+++ b/lib/mattermost/session.rb
@@ -30,6 +30,8 @@ module Mattermost
begin
yield self
+ rescue Errno::ECONNREFUSED
+ raise NoSessionError
ensure
destroy
end
diff --git a/lib/mattermost/team.rb b/lib/mattermost/team.rb
new file mode 100644
index 00000000000..ea5cfd2cb0b
--- /dev/null
+++ b/lib/mattermost/team.rb
@@ -0,0 +1,11 @@
+module Mattermost
+ class Team
+ def self.all(session)
+ retreive_teams(session)
+ end
+
+ def self.retreive_teams(session)
+ session.get('/api/v3/teams/all').parsed_response
+ end
+ end
+end
diff --git a/spec/features/projects/services/mattermost_slash_command_spec.rb b/spec/features/projects/services/mattermost_slash_command_spec.rb
index f474e7e891b..4c08d1e6e65 100644
--- a/spec/features/projects/services/mattermost_slash_command_spec.rb
+++ b/spec/features/projects/services/mattermost_slash_command_spec.rb
@@ -10,23 +10,18 @@ feature 'Setup Mattermost slash commands', feature: true do
before do
project.team << [user, :master]
login_as(user)
+ visit edit_namespace_project_service_path(project.namespace, project, service)
end
- describe 'user visites the mattermost slash command config page', js: true do
+ describe 'user visits the mattermost slash command config page', js: true do
it 'shows a help message' do
- visit edit_namespace_project_service_path(project.namespace, project, service)
-
wait_for_ajax
expect(page).to have_content("This service allows GitLab users to perform common")
end
- end
-
- describe 'saving a token' do
- let(:token) { ('a'..'z').to_a.join }
it 'shows the token after saving' do
- visit edit_namespace_project_service_path(project.namespace, project, service)
+ token = ('a'..'z').to_a.join
fill_in 'service_token', with: token
click_on 'Save'
@@ -35,14 +30,58 @@ feature 'Setup Mattermost slash commands', feature: true do
expect(value).to eq(token)
end
- end
- describe 'the trigger url' do
- it 'shows the correct url' do
- visit edit_namespace_project_service_path(project.namespace, project, service)
+ describe 'mattermost service is enabled' do
+ let(:info) { find('.services-installation-info') }
+
+ before do
+ Gitlab.config.mattermost.enabled = true
+ end
+
+ it 'shows the correct mattermost url' do
+ expect(page).to have_content Gitlab.config.mattermost.host
+ end
+
+ describe 'mattermost service is active' do
+ before do
+ service.active = true
+ end
+
+ it 'shows that mattermost is active' do
+ expect(info).to have_content 'Installed'
+ expect(info).not_to have_content 'Not installed'
+ end
+
+ it 'shows the edit mattermost button' do
+ expect(info).to have_button 'Edit Mattermost'
+ end
+ end
+
+ describe 'mattermost service is not active' do
+ before do
+ service.active = false
+ end
+
+ it 'shows that mattermost is not active' do
+ expect(info).to have_content 'Not installed'
+ end
+
+ it 'shows the add to mattermost button' do
+ expect(info).to have_button 'Add to Mattermost'
+ end
+ end
+ end
+
+ describe 'mattermost service is not enabled' do
+ before do
+ Gitlab.config.mattermost.enabled = false
+ end
+
+ it 'shows the correct trigger url' do
+ value = find_field('request_url').value
- value = find_field('request_url').value
- expect(value).to match("api/v3/projects/#{project.id}/services/mattermost_slash_commands/trigger")
+ expect(value).to match("api/v3/projects/#{project.id}/services/mattermost_slash_commands/trigger")
+ end
end
end
end
diff --git a/spec/lib/mattermost/command_spec.rb b/spec/lib/mattermost/command_spec.rb
new file mode 100644
index 00000000000..f38bb273e7d
--- /dev/null
+++ b/spec/lib/mattermost/command_spec.rb
@@ -0,0 +1,19 @@
+require 'spec_helper'
+
+describe Mattermost::Command do
+ let(:session) { double("session") }
+ let(:hash) { { 'token' => 'token' } }
+
+ describe '.create' do
+ before do
+ allow(session).to receive(:post).and_return(hash)
+ allow(hash).to receive(:parsed_response).and_return(hash)
+ end
+
+ it 'gets the teams' do
+ expect(session).to receive(:post)
+
+ described_class.create(session, 'abc', url: 'http://trigger.com')
+ end
+ end
+end
diff --git a/spec/lib/mattermost/team_spec.rb b/spec/lib/mattermost/team_spec.rb
new file mode 100644
index 00000000000..d4fe63fcd8b
--- /dev/null
+++ b/spec/lib/mattermost/team_spec.rb
@@ -0,0 +1,41 @@
+require 'spec_helper'
+
+describe Mattermost::Team do
+ describe '.team_admin' do
+ let(:session) { double("session") }
+
+ let(:response) do
+ [{
+ "id"=>"xiyro8huptfhdndadpz8r3wnbo",
+ "create_at"=>1482174222155,
+ "update_at"=>1482174222155,
+ "delete_at"=>0,
+ "display_name"=>"chatops",
+ "name"=>"chatops",
+ "email"=>"admin@example.com",
+ "type"=>"O",
+ "company_name"=>"",
+ "allowed_domains"=>"",
+ "invite_id"=>"o4utakb9jtb7imctdfzbf9r5ro",
+ "allow_open_invite"=>false}]
+ end
+
+ let(:json) { nil }
+
+ before do
+ allow(session).to receive(:get).with('/api/v3/teams/all').
+ and_return(json)
+ allow(json).to receive(:parsed_response).and_return(response)
+ end
+
+ it 'gets the teams' do
+ expect(described_class.all(session).count).to be(1)
+ end
+
+ it 'filters on being team admin' do
+ ids = described_class.all(session).map { |team| team['id'] }
+
+ expect(ids).to include("xiyro8huptfhdndadpz8r3wnbo")
+ end
+ end
+end
diff --git a/spec/models/project_services/mattermost_slash_commands_service_spec.rb b/spec/models/project_services/mattermost_slash_commands_service_spec.rb
index 4a1037e950b..00018624d96 100644
--- a/spec/models/project_services/mattermost_slash_commands_service_spec.rb
+++ b/spec/models/project_services/mattermost_slash_commands_service_spec.rb
@@ -96,4 +96,40 @@ describe MattermostSlashCommandsService, models: true do
end
end
end
+
+ describe '#configure' do
+ let(:project) { create(:empty_project) }
+ let(:service) { project.build_mattermost_slash_commands_service }
+
+ subject do
+ service.configure('http://localhost:8065', team_id: 'abc', trigger: 'gitlab', url: 'http://trigger.url', icon_url: 'http://icon.url/icon.png')
+ end
+
+ context 'the requests succeeds' do
+ before do
+ allow_any_instance_of(Mattermost::Session).to receive(:with_session).
+ and_return('token' => 'mynewtoken')
+ end
+
+ it 'saves the service' do
+ expect_any_instance_of(Mattermost::Session).to receive(:with_session)
+ expect { subject }.to change { project.services.count }.by(1)
+ end
+
+ it 'saves the token' do
+ subject
+
+ expect(service.reload.token).to eq('mynewtoken')
+ end
+ end
+
+ context 'an error is received' do
+ it 'shows error messages' do
+ allow_any_instance_of(Mattermost::Session).to receive(:with_session).
+ and_return('token' => 'mynewtoken', 'message' => "Error")
+
+ expect(subject).to eq("Error")
+ end
+ end
+ end
end