Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3626,6 +3626,7 @@ en:
label_ical_access_key_generation_hint: "Automatically generated when subscribing to a calendar."
label_ical_access_key_latest: "latest"
label_ical_access_key_revoke: "Revoke"
label_integrations: "Integrations"
label_add_column: "Add column"
label_applied_status: "Applied status"
label_archive_project: "Archive project"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<%#-- copyright
OpenProject is an open source project management software.
Copyright (C) the OpenProject GmbH

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 3.

OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
Copyright (C) 2006-2013 Jean-Philippe Lang
Copyright (C) 2010-2013 the ChiliProject Team

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

See COPYRIGHT and LICENSE files for more details.

++#%>

<%=
render(Primer::OpenProject::PageHeader.new) do |header|
header.with_title { t(:label_github_integration) }
header.with_breadcrumbs(breadcrumb_items)
helpers.render_tab_header_nav(header, tabs)
end
%>
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# frozen_string_literal: true

#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++

module GithubIntegration
module Admin
class PageHeaderComponent < ApplicationComponent
def tabs
result = [
{
name: "settings",
path: github_integration_admin_settings_path,
label: t(:label_setting_plural)
}
]

if OpenProject::FeatureDecisions.deploy_targets_active?
result << {
name: "deploy_targets",
path: deploy_targets_path,
label: t(:label_deploy_target_plural)
}
end

result
end

def breadcrumb_items
[
{ href: admin_index_path, text: t("label_administration") },
t(:label_github_integration)
]
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# frozen_string_literal: true

#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++

module GithubIntegration
module Admin
class SettingsController < ApplicationController
layout "admin"

menu_item :admin_github_integration

before_action :require_admin

def show
settings = plugin_settings
user_id = settings[:github_user_id].presence
@github_comment_user = user_id ? User.find_by(id: user_id) : nil
@webhook_secret = settings[:webhook_secret]
end

def update
merged = plugin_settings.merge(permitted_params)
Setting.plugin_openproject_github_integration = merged
flash[:notice] = I18n.t(:notice_successful_update)
redirect_to github_integration_admin_settings_path
end

private

def permitted_params
params.permit(:github_user_id, :webhook_secret).to_h
end

def plugin_settings
Hash(Setting.plugin_openproject_github_integration).with_indifferent_access
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# frozen_string_literal: true

#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++

module GithubIntegration
module Admin
class SettingsForm < ApplicationForm
form do |f|
f.autocompleter(
name: :github_user_id,
label: I18n.t(:label_github_comment_user),
caption: I18n.t(:text_github_comment_user_info),
autocomplete_options: {
component: "opce-user-autocompleter",
allowEmpty: true,
defaultData: false,
model: @comment_user_model
}
)

f.text_field(
name: :webhook_secret,
label: I18n.t(:label_github_webhook_secret),
caption: I18n.t(:text_github_webhook_secret_info),
value: @webhook_secret,
input_width: :xxlarge
)

f.submit(
name: :submit,
label: I18n.t(:button_save),
scheme: :primary
)
end

def initialize(comment_user: nil, webhook_secret: nil)
super()
@comment_user_model = comment_user.present? ? { id: comment_user.id, name: comment_user.name } : nil
@webhook_secret = webhook_secret
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,7 @@ See COPYRIGHT and LICENSE files for more details.

<% html_title t(:label_administration), t(:label_github_integration), t(:label_deploy_target_plural) %>

<%=
render(Primer::OpenProject::PageHeader.new) do |header|
header.with_title { t(:label_github_integration) }
header.with_breadcrumbs(
[{ href: admin_index_path, text: t("label_administration") },
t(:label_github_integration)]
)
end
%>
<%= render(GithubIntegration::Admin::PageHeaderComponent.new) %>

<%=
render(Primer::OpenProject::SubHeader.new) do |subheader|
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<%#-- copyright
OpenProject is an open source project management software.
Copyright (C) the OpenProject GmbH

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 3.

OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
Copyright (C) 2006-2013 Jean-Philippe Lang
Copyright (C) 2010-2013 the ChiliProject Team

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

See COPYRIGHT and LICENSE files for more details.

++#%>
<% html_title t(:label_administration), t(:label_github_integration), t(:label_setting_plural) %>

<%= render(GithubIntegration::Admin::PageHeaderComponent.new) %>

<%= settings_primer_form_with(url: github_integration_admin_settings_path, method: :patch) do |f| %>
<% if @webhook_secret.blank? %>
<%= render(Primer::Alpha::Banner.new(scheme: :warning, icon: :alert, mb: 4)) do %>
<%= t(:text_github_webhook_secret_missing_warning) %>
<% end %>
<% end %>
<%= render GithubIntegration::Admin::SettingsForm.new(f,
comment_user: @github_comment_user,
webhook_secret: @webhook_secret) %>
<% end %>
15 changes: 15 additions & 0 deletions modules/github_integration/config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,21 @@ en:
label_github_integration: GitHub Integration
notice_deploy_target_created: Deploy target created
notice_deploy_target_destroyed: Deploy target deleted
label_github_comment_user: "GitHub actor"
label_github_webhook_secret: "Webhook secret"
text_github_comment_user_info: >
The OpenProject user whose API key must be used to authenticate incoming webhook requests.
When set, requests authenticated with any other user's credentials are rejected.
This user also posts automated deploy-status comments on work packages. Defaults to the system user when not set.
text_github_webhook_secret_missing_warning: >
No webhook secret is configured. Any request to the GitHub webhook endpoint will be accepted
without verification, which may allow unauthorized actors to forge events. It is strongly
recommended to set a secret.
text_github_webhook_secret_info: >
A secret token shared with GitHub when configuring the webhook.
When set, OpenProject verifies the X-Hub-Signature-256 header on every incoming request,
rejecting payloads that do not match. Leave blank to skip verification (not recommended).

plugin_openproject_github_integration:
name: "OpenProject GitHub Integration"
description: "Integrates OpenProject and GitHub for a better workflow"
Expand Down
6 changes: 6 additions & 0 deletions modules/github_integration/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,11 @@
#++

Rails.application.routes.draw do
namespace "github_integration" do
namespace "admin" do
resource :settings, only: %i[show update]
end
end

resources :deploy_targets, only: %i[index new create destroy]
end
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ class Engine < ::Rails::Engine
def self.settings
{
default: {
"github_user_id" => nil
"github_user_id" => nil,
"webhook_secret" => nil
}
}
end
Expand All @@ -54,10 +55,16 @@ def self.settings
settings:
) do
::Redmine::MenuManager.map(:admin_menu) do |menu|
menu.push :admin_integrations,
{ controller: "/github_integration/admin/settings", action: "show" },
if: ->(_) { User.current.admin? },
icon: :"git-compare",
caption: :label_integrations
Comment on lines +58 to +62
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels wrong to have the parent menu item being added here. We also give "preference" to GitHub by making it the link from the integrations page. Especially since the gitlab plugin also relies on this being there. Maybe we can add this to the menus.rb initializer and have the 2 integrations hook into them.

menu.push :admin_github_integration,
{ controller: "/deploy_targets", action: "index" },
if: ->(_) { OpenProject::FeatureDecisions.deploy_targets_active? && User.current.admin? },
caption: :label_github_integration,
{ controller: "/github_integration/admin/settings", action: "show" },
parent: :admin_integrations,
if: ->(_) { User.current.admin? },
caption: "GitHub",
icon: "mark-github"
end

Expand Down
Loading
Loading