diff --git a/app/models/group.rb b/app/models/group.rb index 240a17f1dc181bb693cb432cc93bc6a3fcfb4d89..27dc4e8f3193d3614d92aec80bb26badba9fcf30 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -21,6 +21,7 @@ class Group < Namespace has_many :shared_projects, through: :project_group_links, source: :project has_many :notification_settings, dependent: :destroy, as: :source has_many :labels, class_name: 'GroupLabel' + has_one :chat_team, dependent: :destroy validate :avatar_type, if: ->(user) { user.avatar.present? && user.avatar_changed? } validate :visibility_level_allowed_by_projects diff --git a/app/services/groups/create_service.rb b/app/services/groups/create_service.rb index febeb661fb5f3bb5622a5c06591e19d223dde4df..209fd15f4814c7933cd43e2ee8645c35fc536529 100644 --- a/app/services/groups/create_service.rb +++ b/app/services/groups/create_service.rb @@ -22,6 +22,11 @@ module Groups @group.name ||= @group.path.dup @group.save @group.add_owner(current_user) + + if params[:create_chat_team] && Gitlab.config.mattermost.enabled + Mattermost::CreateTeamWorker.perform_async(@group.id, current_user.id) + end + @group end end diff --git a/app/views/groups/new.html.haml b/app/views/groups/new.html.haml index 38d63fd9acc64be3e3e7d7bb607cfdff2136c54b..8e1513b151b2ead2ee0bb3d6b20b9d2e0dc4b84b 100644 --- a/app/views/groups/new.html.haml +++ b/app/views/groups/new.html.haml @@ -16,6 +16,11 @@ = render 'shared/visibility_level', f: f, visibility_level: default_group_visibility, can_change_visibility_level: true, form_model: @group + .form-group + = f.label :create_chat_team, "Create Mattermost Team", class: 'control-label' + .col-sm-10 + = f.check_box :chat_team + .form-group .col-sm-offset-2.col-sm-10 = render 'shared/group_tips' diff --git a/app/workers/mattermost/create_team_worker.rb b/app/workers/mattermost/create_team_worker.rb new file mode 100644 index 0000000000000000000000000000000000000000..69486569cbffd7d766fe8536861dd7aa876f066c --- /dev/null +++ b/app/workers/mattermost/create_team_worker.rb @@ -0,0 +1,28 @@ +module Mattermost + class CreateTeamWorker + include Sidekiq::Worker + include DedicatedSidekiqQueue + + def perform(group_id, current_user_id, options = {}) + @group = Group.find(group_id) + current_user = User.find(current_user_id) + + options = team_params.merge(options) + + # The user that creates the team will be Team Admin + response = Mattermost::Team.new(current_user).create(options) + + ChatTeam.create!(namespace: @group, name: response['name'], team_id: response['id']) + end + + private + + def team_params + { + name: @group.path[0..59], + display_name: @group.name[0..59], + type: @group.public? ? 'O' : 'I' # Open vs Invite-only + } + end + end +end diff --git a/db/migrate/20170120131253_create_chat_teams.rb b/db/migrate/20170120131253_create_chat_teams.rb new file mode 100644 index 0000000000000000000000000000000000000000..6476c23915288682d4016e6a73443cd4f04130df --- /dev/null +++ b/db/migrate/20170120131253_create_chat_teams.rb @@ -0,0 +1,17 @@ +class CreateChatTeams < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def change + create_table :chat_teams do |t| + t.integer :namespace_id, index: true + t.string :team_id + t.string :name + + t.timestamps null: false + end + + add_foreign_key :chat_teams, :namespaces, on_delete: :cascade + end +end diff --git a/db/schema.rb b/db/schema.rb index 52672406ec643bb62e98b591b66412594516a358..0ae208fb5e4ebbd9ad80ea484d589b7b0189b159 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -171,6 +171,16 @@ ActiveRecord::Schema.define(version: 20170214111112) do add_index "chat_names", ["service_id", "team_id", "chat_id"], name: "index_chat_names_on_service_id_and_team_id_and_chat_id", unique: true, using: :btree add_index "chat_names", ["user_id", "service_id"], name: "index_chat_names_on_user_id_and_service_id", unique: true, using: :btree + create_table "chat_teams", force: :cascade do |t| + t.integer "namespace_id" + t.string "team_id" + t.string "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "chat_teams", ["namespace_id"], name: "index_chat_teams_on_namespace_id", using: :btree + create_table "ci_application_settings", force: :cascade do |t| t.boolean "all_broken_builds" t.boolean "add_pusher" @@ -1330,6 +1340,7 @@ ActiveRecord::Schema.define(version: 20170214111112) do add_index "web_hooks", ["project_id"], name: "index_web_hooks_on_project_id", using: :btree add_foreign_key "boards", "projects" + add_foreign_key "chat_teams", "namespaces", on_delete: :cascade add_foreign_key "issue_metrics", "issues", on_delete: :cascade add_foreign_key "label_priorities", "labels", on_delete: :cascade add_foreign_key "label_priorities", "projects", on_delete: :cascade diff --git a/lib/mattermost/session.rb b/lib/mattermost/session.rb index 377cb7b10211f4b8101d923d6fb99c0f0500cb32..d4b4ba97f8ce4ddf8ab63b029767f3f7b315689a 100644 --- a/lib/mattermost/session.rb +++ b/lib/mattermost/session.rb @@ -153,7 +153,7 @@ module Mattermost yield rescue HTTParty::Error => e raise Mattermost::ConnectionError.new(e.message) - rescue Errno::ECONNREFUSED + rescue Errno::ECONNREFUSED => e raise Mattermost::ConnectionError.new(e.message) end end diff --git a/lib/mattermost/team.rb b/lib/mattermost/team.rb index 09dfd082b3a5e4fb211219a13a7445de1105310f..9e80f7f8571eae64836a460633e5ddd207dc724d 100644 --- a/lib/mattermost/team.rb +++ b/lib/mattermost/team.rb @@ -1,7 +1,12 @@ module Mattermost class Team < Client + # Returns **all** teams for an admin def all session_get('/api/v3/teams/all') end + + def create(params) + session_post('/api/v3/teams/create', body: params.to_json) + end end end diff --git a/spec/models/chat_team_spec.rb b/spec/models/chat_team_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..37a22f5cd6d501cc56dad34641c97cc819529645 --- /dev/null +++ b/spec/models/chat_team_spec.rb @@ -0,0 +1,10 @@ +require 'spec_helper' + +describe ChatTeam, type: :model do + # Associations + it { is_expected.to belong_to(:group) } + + # Fields + it { is_expected.to respond_to(:name) } + it { is_expected.to respond_to(:team_id) } +end diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index a4e6eb4e3a6e3f0181a1263b73bfbba47b638aa8..8cfc208545808453b633243a7902679c18624dfc 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -13,6 +13,7 @@ describe Group, models: true do it { is_expected.to have_many(:shared_projects).through(:project_group_links) } it { is_expected.to have_many(:notification_settings).dependent(:destroy) } it { is_expected.to have_many(:labels).class_name('GroupLabel') } + it { is_expected.to have_one(:chat_team) } describe '#members & #requesters' do let(:requester) { create(:user) } diff --git a/spec/workers/mattermost/create_team_worker_spec.rb b/spec/workers/mattermost/create_team_worker_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..a6b87967ca29e5b7e92dff84dcab4c918613beba --- /dev/null +++ b/spec/workers/mattermost/create_team_worker_spec.rb @@ -0,0 +1,21 @@ +require 'spec_helper' + +describe Mattermost::CreateTeamWorker do + let(:group) { create(:group, path: 'path', name: 'name') } + let(:admin) { create(:admin) } + + describe '.perform' do + subject { described_class.new.perform(group.id, admin.id) } + + before do + allow_any_instance_of(Mattermost::Team). + to receive(:create). + with(name: "path", display_name: "name", type: "O"). + and_return('name' => 'my team', 'id' => 'sjfkdlwkdjfwlkfjwf') + end + + it 'creates a new chat team' do + expect { subject }.to change { ChatTeam.count }.from(0).to(1) + end + end +end