Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Jérome Perrin
gitlab-ce
Commits
87d16063
Commit
87d16063
authored
Dec 13, 2016
by
Z.J. van de Weg
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Base work for auto config MM slash commands
parent
dd385c7c
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
259 additions
and
147 deletions
+259
-147
app/controllers/projects/services_controller.rb
app/controllers/projects/services_controller.rb
+27
-1
app/helpers/mattermost_helper.rb
app/helpers/mattermost_helper.rb
+13
-0
app/models/project_services/mattermost_slash_commands_service.rb
...els/project_services/mattermost_slash_commands_service.rb
+15
-0
app/models/service.rb
app/models/service.rb
+4
-0
app/views/projects/services/_form.html.haml
app/views/projects/services/_form.html.haml
+8
-12
app/views/projects/services/mattermost_slash_commands/_form.html.haml
...ojects/services/mattermost_slash_commands/_form.html.haml
+3
-0
app/views/projects/services/mattermost_slash_commands/_help.html.haml
...ojects/services/mattermost_slash_commands/_help.html.haml
+98
-97
app/views/shared/_service_settings.html.haml
app/views/shared/_service_settings.html.haml
+38
-35
config/gitlab.yml.example
config/gitlab.yml.example
+5
-0
config/routes/project.rb
config/routes/project.rb
+1
-0
lib/mattermost/command.rb
lib/mattermost/command.rb
+26
-0
lib/mattermost/session.rb
lib/mattermost/session.rb
+11
-2
lib/mattermost/team.rb
lib/mattermost/team.rb
+10
-0
No files found.
app/controllers/projects/services_controller.rb
View file @
87d16063
...
...
@@ -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
app/helpers/mattermost_helper.rb
0 → 100644
View file @
87d16063
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
app/models/project_services/mattermost_slash_commands_service.rb
View file @
87d16063
...
...
@@ -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
])
...
...
app/models/service.rb
View file @
87d16063
...
...
@@ -54,6 +54,10 @@ class Service < ActiveRecord::Base
template
end
def
auto_config?
false
end
def
category
read_attribute
(
:category
).
to_sym
end
...
...
app/views/projects/services/_form.html.haml
View file @
87d16063
...
...
@@ -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'
-
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"
app/views/projects/services/mattermost_slash_commands/_form.html.haml
0 → 100644
View file @
87d16063
-
teams
=
Mattermost
::
Mattermost
.
new
(
Gitlab
.
config
.
mattermost
.
host
,
current_user
).
with_session
do
Mattermost::Mattermost::Team.all
end
app/views/projects/services/mattermost_slash_commands/_help.html.haml
View file @
87d16063
-
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
/
<
command_trigger_word
>
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
/
<
command_trigger_word
>
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
app/views/shared/_service_settings.html.haml
View file @
87d16063
...
...
@@ -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
config/gitlab.yml.example
View file @
87d16063
...
...
@@ -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:
...
...
config/routes/project.rb
View file @
87d16063
...
...
@@ -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
...
...
lib/mattermost/command.rb
0 → 100644
View file @
87d16063
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
lib/mattermost/session.rb
View file @
87d16063
...
...
@@ -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
lib/mattermost/team.rb
0 → 100644
View file @
87d16063
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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment