added async background token and domain checking

This commit is contained in:
Chris
2025-10-10 01:57:30 +01:00
parent 94cec0e2f7
commit 5dcc5dc635
13 changed files with 74 additions and 39 deletions

View File

@@ -71,8 +71,8 @@ module Projects
steps << Projects::ValidateNamespaceAvailability
steps << Projects::Save
# Only register webhook in non-local mode
if !Rails.application.config.local_mode && provider.git?
# Only register webhook in cloud mode
if Rails.application.config.cloud_mode && provider.git?
steps << Projects::RegisterGitWebhook
end

View File

@@ -10,6 +10,8 @@ module Accounts
head :not_found
end
# If the user is not having an email domain end in the
# portainer stack url, don't log them out, just return a different unauthorized.
if stack_manager.stack.client.authenticated?
head :ok
else
@@ -107,7 +109,12 @@ module Accounts
private
def stack_manager_params
params.require(:stack_manager).permit(:provider_url, :stack_manager_type)
params.require(:stack_manager).permit(
:provider_url,
:stack_manager_type,
:access_token,
:enable_role_based_access_control
)
end
def set_stack

View File

@@ -22,7 +22,7 @@ class Projects::BuildJob < ApplicationJob
Builders::BuildCloud.new(
build,
K8::BuildCloudManager.new(
K8::Connection.new(project, user),
K8::Connection.new(project, user, allow_anonymous: true),
project.build_configuration.build_cloud
)
)

View File

@@ -2,13 +2,14 @@
#
# Table name: stack_managers
#
# id :bigint not null, primary key
# access_token :string
# provider_url :string not null
# stack_manager_type :integer default("portainer"), not null
# created_at :datetime not null
# updated_at :datetime not null
# account_id :bigint not null
# id :bigint not null, primary key
# access_token :string
# enable_role_based_access_control :boolean default(TRUE)
# provider_url :string not null
# stack_manager_type :integer default("portainer"), not null
# created_at :datetime not null
# updated_at :datetime not null
# account_id :bigint not null
#
# Indexes
#
@@ -40,6 +41,14 @@ class StackManager < ApplicationRecord
end
end
def domain_host
URI.parse(provider_url).host
end
def is_user?(user)
user.email.ends_with?("@#{domain_host}")
end
private
def strip_trailing_slash_from_provider_url

View File

@@ -1,8 +1,9 @@
class K8::Connection
attr_reader :clusterable, :user
def initialize(clusterable, user)
attr_reader :clusterable, :user, :allow_anonymous
def initialize(clusterable, user, allow_anonymous: false)
@clusterable = clusterable
@user = user
@allow_anonymous = allow_anonymous
end
def cluster
@@ -24,7 +25,7 @@ class K8::Connection
cluster.kubeconfig
else
raise StandardError.new("No stack manager found") if stack_manager.blank?
stack = stack_manager.stack.connect(user)
stack = stack_manager.stack.connect(user, allow_anonymous: allow_anonymous)
stack.fetch_kubeconfig(cluster)
end
end

View File

@@ -20,9 +20,19 @@
<span class="label-text">Access Token</span>
<% end %>
<%= form.text_field :access_token, class: "input input-bordered w-full" %>
<label class="label">
<span class="label-text-alt">The access token is only used for asynchronous operations to a cluster, like auto-deploy.</span>
</label>
</div>
<% end %>
<div class="form-control">
<%= form.label :enable_role_based_access_control, class: "label cursor-pointer justify-start gap-2" do %>
<%= form.check_box :enable_role_based_access_control, class: "checkbox" %>
<span class="label-text">Enable Role-Based Access Control</span>
<% end %>
</div>
<div class="mt-4">
<div class="alert alert-warning">
<iconify-icon icon="lucide:alert-triangle" height="20"></iconify-icon>

View File

@@ -93,13 +93,11 @@
</div>
<% end %>
<% unless Rails.application.config.local_mode %>
<%= render(FormFieldComponent.new(
label: "Autodeploy",
description: "Automatically deploy the project when the branch is pushed to."
)) do %>
<%= form.check_box :autodeploy, class: "checkbox" %>
<% end %>
<%= render(FormFieldComponent.new(
label: "Autodeploy",
description: "Automatically deploy the project when the branch is pushed to."
)) do %>
<%= form.check_box :autodeploy, class: "checkbox" %>
<% end %>
<%= render(FormFieldComponent.new(

View File

@@ -0,0 +1,5 @@
class EnableRoleBasedAccessControlToStackManagers < ActiveRecord::Migration[7.2]
def change
add_column :stack_managers, :enable_role_based_access_control, :boolean, default: true
end
end

3
db/schema.rb generated
View File

@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.2].define(version: 2025_10_02_214647) do
ActiveRecord::Schema[7.2].define(version: 2025_10_09_003742) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -451,6 +451,7 @@ ActiveRecord::Schema[7.2].define(version: 2025_10_02_214647) do
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "access_token"
t.boolean "enable_role_based_access_control", default: true
t.index ["account_id"], name: "index_stack_managers_on_account_id", unique: true
end

View File

@@ -6,7 +6,7 @@ class Portainer::Login
executed do |context|
provider_url = context.account.stack_manager.provider_url
hostname = URI.parse(provider_url).host
hostname = context.account.stack_manager.domain_host
context.user = User.find_or_initialize_by(
email: context.username + "@#{hostname}",
)

View File

@@ -11,8 +11,10 @@ class Portainer::Stack
self
end
def connect(user)
access_token = if stack_manager.access_token.present?
def connect(user, allow_anonymous: false)
access_token = if stack_manager.access_token.present? && !enable_role_based_access_control
stack_manager.access_token
elsif stack_manager.access_token.present? && allow_anonymous
stack_manager.access_token
else
user.portainer_jwt

View File

@@ -2,13 +2,14 @@
#
# Table name: stack_managers
#
# id :bigint not null, primary key
# access_token :string
# provider_url :string not null
# stack_manager_type :integer default("portainer"), not null
# created_at :datetime not null
# updated_at :datetime not null
# account_id :bigint not null
# id :bigint not null, primary key
# access_token :string
# enable_role_based_access_control :boolean default(TRUE)
# provider_url :string not null
# stack_manager_type :integer default("portainer"), not null
# created_at :datetime not null
# updated_at :datetime not null
# account_id :bigint not null
#
# Indexes
#

View File

@@ -2,13 +2,14 @@
#
# Table name: stack_managers
#
# id :bigint not null, primary key
# access_token :string
# provider_url :string not null
# stack_manager_type :integer default("portainer"), not null
# created_at :datetime not null
# updated_at :datetime not null
# account_id :bigint not null
# id :bigint not null, primary key
# access_token :string
# enable_role_based_access_control :boolean default(TRUE)
# provider_url :string not null
# stack_manager_type :integer default("portainer"), not null
# created_at :datetime not null
# updated_at :datetime not null
# account_id :bigint not null
#
# Indexes
#