Translate code comments and admin strings to English
This commit is contained in:
@@ -39,29 +39,29 @@ ActiveAdmin.register WarpEngine::ApplicationToken, as: "Application Token" do
|
|||||||
include_blank: false
|
include_blank: false
|
||||||
else
|
else
|
||||||
f.template.concat(f.template.content_tag(:li,
|
f.template.concat(f.template.content_tag(:li,
|
||||||
"application_token_owner_class nincs beállítva — token nem hozható létre.",
|
"application_token_owner_class is not configured — tokens cannot be created.",
|
||||||
class: "flash flash_error"))
|
class: "flash flash_error"))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
f.input :name
|
f.input :name
|
||||||
f.input :scopes_string, label: "Scopes (comma separated)",
|
f.input :scopes_string, label: "Scopes (comma separated)",
|
||||||
hint: %(A /build/publish (és a legacy /update) végponthoz az "update", a /build/upload-hoz az "upload" scope kell.)
|
hint: %(The "update" scope is required for /build/publish, the "upload" scope for /build/upload.)
|
||||||
f.input :unrestricted, hint: "Belső token: az owner-izoláció (enforce_software_ownership) nem vonatkozik rá."
|
f.input :unrestricted, hint: "Internal token: exempt from owner isolation (enforce_software_ownership)."
|
||||||
f.input :expires_at, hint: "Üresen hagyva sosem jár le."
|
f.input :expires_at, hint: "Leave empty for a token that never expires."
|
||||||
end
|
end
|
||||||
f.actions
|
f.actions
|
||||||
end
|
end
|
||||||
|
|
||||||
show do
|
show do
|
||||||
if (plain = controller.instance_variable_get(:@plain_token))
|
if (plain = controller.instance_variable_get(:@plain_token))
|
||||||
panel "⚠️ Token — csak most látható, másold ki!" do
|
panel "⚠️ Token — shown only once, copy it now!" do
|
||||||
pre plain, style: "font-family:monospace;font-size:14px;padding:8px;background:#fff3cd;user-select:all;"
|
pre plain, style: "font-family:monospace;font-size:14px;padding:8px;background:#fff3cd;user-select:all;"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
attributes_table do
|
attributes_table do
|
||||||
row :id
|
row :id
|
||||||
row :name
|
row :name
|
||||||
row("Token") { |t| code "#{t.token_prefix}… (SHA256 digest tárolva)" }
|
row("Token") { |t| code "#{t.token_prefix}… (SHA256 digest stored)" }
|
||||||
row("Owner") { |t| "#{t.owner_type} ##{t.owner_id} — #{t.owner.try(:email) || t.owner.try(:name)}" }
|
row("Owner") { |t| "#{t.owner_type} ##{t.owner_id} — #{t.owner.try(:email) || t.owner.try(:name)}" }
|
||||||
row("Scopes") { |t| t.scopes_string }
|
row("Scopes") { |t| t.scopes_string }
|
||||||
row :unrestricted
|
row :unrestricted
|
||||||
@@ -73,9 +73,9 @@ ActiveAdmin.register WarpEngine::ApplicationToken, as: "Application Token" do
|
|||||||
end
|
end
|
||||||
|
|
||||||
controller do
|
controller do
|
||||||
# A plain token csak közvetlenül a létrehozás után létezik; a session-ön át
|
# The plain token only exists right after creation; it travels via the
|
||||||
# jut el az egyszeri megjelenítésig (a flash nem jó: az AA layout minden
|
# session to its one-time display (flash is unsuitable: the AA layout
|
||||||
# flash kulcsot üzenetsávként renderel).
|
# renders every flash key as a message bar).
|
||||||
def create
|
def create
|
||||||
create! do |success, _failure|
|
create! do |success, _failure|
|
||||||
success.html do
|
success.html do
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
module WarpEngine
|
module WarpEngine
|
||||||
# Token-hitelesítés a publikáló (/build/*) endpointokhoz.
|
# Token authentication for the publishing (/build/*) endpoints.
|
||||||
# A hitelesítési forrás kizárólagos: :database módban a shared secret nem
|
# The auth source is exclusive: in :database mode the shared secret is not
|
||||||
# érvényes, :env módban a DB-tokenek nem.
|
# accepted, in :env mode DB tokens are not.
|
||||||
module UpdateAuthentication
|
module UpdateAuthentication
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
@@ -9,8 +9,8 @@ module WarpEngine
|
|||||||
|
|
||||||
attr_reader :current_application_token
|
attr_reader :current_application_token
|
||||||
|
|
||||||
# A token kizárólag az X-Update-Secret headerből jöhet — URL-ben a secret
|
# The token is accepted from the X-Update-Secret header only — in the URL
|
||||||
# proxy- és access-logokba szivárogna.
|
# it would leak into proxy and access logs.
|
||||||
def update_authorized?(required_scope:)
|
def update_authorized?(required_scope:)
|
||||||
token = request.headers["X-Update-Secret"].presence
|
token = request.headers["X-Update-Secret"].presence
|
||||||
return false if token.blank?
|
return false if token.blank?
|
||||||
@@ -23,13 +23,13 @@ module WarpEngine
|
|||||||
|
|
||||||
def env_secret_authorized?(token)
|
def env_secret_authorized?(token)
|
||||||
expected = WarpEngine.config.update_secret
|
expected = WarpEngine.config.update_secret
|
||||||
# Konfigurálatlan secret esetén az endpoint zárva marad.
|
# With no secret configured the endpoint stays closed.
|
||||||
expected.present? && ActiveSupport::SecurityUtils.secure_compare(token, expected)
|
expected.present? && ActiveSupport::SecurityUtils.secure_compare(token, expected)
|
||||||
end
|
end
|
||||||
|
|
||||||
def database_token_authorized?(token, required_scope)
|
def database_token_authorized?(token, required_scope)
|
||||||
if WarpEngine.config.application_token_owner_class.blank?
|
if WarpEngine.config.application_token_owner_class.blank?
|
||||||
Rails.logger.error("[#{self.class.name}] application_token_source=:database, de application_token_owner_class nincs beállítva — minden kérés elutasítva")
|
Rails.logger.error("[#{self.class.name}] application_token_source=:database but application_token_owner_class is not set — rejecting every request")
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -41,9 +41,9 @@ module WarpEngine
|
|||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
# Owner-kényszer: csak :database módban (van token) és bekapcsolt
|
# Ownership enforcement applies only in :database mode (there is a token)
|
||||||
# enforce_software_ownership mellett szűr. Owner nélküli software a
|
# with enforce_software_ownership on. An ownerless software is up for grabs
|
||||||
# backfillig szabad préda — a kényszer bekapcsolása előtt kell backfillelni.
|
# until the backfill — backfill before enabling the enforcement.
|
||||||
def software_ownership_authorized?(name)
|
def software_ownership_authorized?(name)
|
||||||
return true unless WarpEngine.config.enforce_software_ownership
|
return true unless WarpEngine.config.enforce_software_ownership
|
||||||
|
|
||||||
@@ -56,8 +56,8 @@ module WarpEngine
|
|||||||
software.owner_type == token.owner_type && software.owner_id == token.owner_id
|
software.owner_type == token.owner_type && software.owner_id == token.owner_id
|
||||||
end
|
end
|
||||||
|
|
||||||
# Az először publikált (vagy backfill előtti, gazdátlan) software a beküldő
|
# A first-published (or pre-backfill, ownerless) software gets the
|
||||||
# token ownerét kapja. Unrestricted (belső) token nem foglal ownert.
|
# submitting token's owner. Unrestricted (internal) tokens claim nothing.
|
||||||
def claim_software_ownership(name)
|
def claim_software_ownership(name)
|
||||||
token = current_application_token
|
token = current_application_token
|
||||||
return if token.nil? || token.unrestricted?
|
return if token.nil? || token.unrestricted?
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
module WarpEngine
|
module WarpEngine
|
||||||
module Build
|
module Build
|
||||||
# Woodpecker configuration-extension endpoint: a CI-szerver pipeline-indításkor
|
# Woodpecker configuration-extension endpoint: on every pipeline start the
|
||||||
# POST-olja a repo marker-fájlját, és a platformhoz tartozó teljes pipeline
|
# CI server POSTs the repo's marker file and receives the platform's full
|
||||||
# YAML-t kapja vissza. A GET ugyanazt rendereli previewként.
|
# pipeline YAML. GET renders the same thing as a preview.
|
||||||
class ConfigsController < ApiController
|
class ConfigsController < ApiController
|
||||||
resource_description do
|
resource_description do
|
||||||
short "Woodpecker CI pipeline configs"
|
short "Woodpecker CI pipeline configs"
|
||||||
@@ -58,9 +58,9 @@ module WarpEngine
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Az első beküldött config, ami markernek parse-olható (Hash `platform` kulccsal).
|
# The first submitted config that parses as a marker (Hash with a `platform`
|
||||||
# A doksi szerint a kulcs "configuration", az example-config-service "configs"-ot
|
# key). The docs call the key "configuration", the example-config-service
|
||||||
# használ — mindkettőt elfogadjuk.
|
# uses "configs" — accept both.
|
||||||
def find_marker
|
def find_marker
|
||||||
configs = params[:configuration].presence || params[:configs].presence || []
|
configs = params[:configuration].presence || params[:configs].presence || []
|
||||||
configs.each do |config|
|
configs.each do |config|
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ module WarpEngine
|
|||||||
short "Build artifact upload"
|
short "Build artifact upload"
|
||||||
end
|
end
|
||||||
|
|
||||||
# A release-fájlnevek kötött konvenciója: <name>-<version>.<ext> vagy
|
# Release file naming convention: <name>-<version>.<ext> or
|
||||||
# <name>-<version>-<target>.zip — az updater is ezeket keresi.
|
# <name>-<version>-<target>.zip — the updater looks for these too.
|
||||||
NAME_FORMAT = /\A[A-Za-z0-9._-]+\z/
|
NAME_FORMAT = /\A[A-Za-z0-9._-]+\z/
|
||||||
|
|
||||||
api :POST, "/build/upload", "Upload a build artifact into the artifact directory"
|
api :POST, "/build/upload", "Upload a build artifact into the artifact directory"
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ module WarpEngine
|
|||||||
UPDATE_SCOPE = "update".freeze
|
UPDATE_SCOPE = "update".freeze
|
||||||
UPLOAD_SCOPE = "upload".freeze
|
UPLOAD_SCOPE = "upload".freeze
|
||||||
|
|
||||||
# A generált token csak létrehozáskor, memóriában érhető el — a DB-ben
|
# The generated token is only available in memory at creation time — the DB
|
||||||
# kizárólag a SHA256 digest és a nem-titkos prefix tárolódik.
|
# stores nothing but the SHA256 digest and the non-secret prefix.
|
||||||
attr_reader :plain_token
|
attr_reader :plain_token
|
||||||
|
|
||||||
belongs_to :owner, polymorphic: true
|
belongs_to :owner, polymorphic: true
|
||||||
@@ -30,7 +30,7 @@ module WarpEngine
|
|||||||
Digest::SHA256.hexdigest(token)
|
Digest::SHA256.hexdigest(token)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Az élő (nem törölt, nem lejárt), a kért scope-pal rendelkező token, különben nil.
|
# The live (not deleted, not expired) token carrying the required scope, else nil.
|
||||||
def self.authenticate(token, required_scope: nil)
|
def self.authenticate(token, required_scope: nil)
|
||||||
return nil if token.blank?
|
return nil if token.blank?
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ module WarpEngine
|
|||||||
expires_at.present? && expires_at <= Time.current
|
expires_at.present? && expires_at <= Time.current
|
||||||
end
|
end
|
||||||
|
|
||||||
# Visszavonás = soft delete, az audit-nyom megmarad.
|
# Revocation = soft delete, the audit trail stays.
|
||||||
def revoke!
|
def revoke!
|
||||||
update_column(:deleted_at, Time.current)
|
update_column(:deleted_at, Time.current)
|
||||||
end
|
end
|
||||||
@@ -54,7 +54,7 @@ module WarpEngine
|
|||||||
update_column(:last_used_at, Time.current)
|
update_column(:last_used_at, Time.current)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Admin form: vesszővel elválasztott scope-lista
|
# Admin form: comma separated scope list
|
||||||
def scopes_string
|
def scopes_string
|
||||||
Array(scopes).join(", ")
|
Array(scopes).join(", ")
|
||||||
end
|
end
|
||||||
@@ -67,7 +67,7 @@ module WarpEngine
|
|||||||
%w[created_at deleted_at expires_at id last_used_at name owner_id owner_type token_prefix unrestricted updated_at]
|
%w[created_at deleted_at expires_at id last_used_at name owner_id owner_type token_prefix unrestricted updated_at]
|
||||||
end
|
end
|
||||||
|
|
||||||
# A polimorf owner asszociációra a Ransack nem tud szűrni.
|
# Ransack cannot filter on the polymorphic owner association.
|
||||||
def self.ransackable_associations(auth_object = nil)
|
def self.ransackable_associations(auth_object = nil)
|
||||||
[]
|
[]
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ module WarpEngine
|
|||||||
class Software < ApplicationRecord
|
class Software < ApplicationRecord
|
||||||
self.table_name = "softwares"
|
self.table_name = "softwares"
|
||||||
|
|
||||||
# A publikáló token ownere (pl. AdminUser) — 3rd party izolációhoz, ld.
|
# Owner of the publishing token (e.g. AdminUser) — for 3rd-party isolation,
|
||||||
# enforce_software_ownership. nil = belső / backfill előtti software.
|
# see enforce_software_ownership. nil = internal / pre-backfill software.
|
||||||
belongs_to :owner, polymorphic: true, optional: true
|
belongs_to :owner, polymorphic: true, optional: true
|
||||||
|
|
||||||
has_many :software_images, foreign_key: :software_id, dependent: :destroy
|
has_many :software_images, foreign_key: :software_id, dependent: :destroy
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ module WarpEngine
|
|||||||
field(:license) { |sw| sw.license.to_s }
|
field(:license) { |sw| sw.license.to_s }
|
||||||
field :platform
|
field :platform
|
||||||
field :status
|
field :status
|
||||||
# Publikus owner-azonosító — az /api/software?owner_id= szűrőhöz.
|
# Public owner id — for the /api/software?owner_id= filter.
|
||||||
field(:ownerId) { |sw| sw.owner_id }
|
field(:ownerId) { |sw| sw.owner_id }
|
||||||
field(:highlighted) { |sw| sw.highlighted ? true : false }
|
field(:highlighted) { |sw| sw.highlighted ? true : false }
|
||||||
field(:externalLinks) { |sw| ExternalLinkSerializer.render_as_hash(sw.external_links) }
|
field(:externalLinks) { |sw| ExternalLinkSerializer.render_as_hash(sw.external_links) }
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
require "erb"
|
require "erb"
|
||||||
|
|
||||||
module WarpEngine
|
module WarpEngine
|
||||||
# A /build/config platform-template-jeinek renderelése: a pipeline-logika
|
# Renders the /build/config platform templates: the pipeline logic lives in
|
||||||
# a lib/warp_engine/ci_templates/<platform>.yaml.erb fájlokban él, a
|
# lib/warp_engine/ci_templates/<platform>.yaml.erb, the per-platform builder
|
||||||
# platformonkénti builder image-eket a WarpEngine.config.ci_platforms adja.
|
# images come from WarpEngine.config.ci_platforms.
|
||||||
class CiConfigService
|
class CiConfigService
|
||||||
PLATFORM_FORMAT = /\A[a-z0-9_-]+\z/
|
PLATFORM_FORMAT = /\A[a-z0-9_-]+\z/
|
||||||
|
|
||||||
# A renderelt pipeline YAML, vagy nil, ha a platform nem kiszolgált.
|
# The rendered pipeline YAML, or nil when the platform is not served.
|
||||||
def render(platform:, name:, update_server:)
|
def render(platform:, name:, update_server:)
|
||||||
platform = platform.to_s
|
platform = platform.to_s
|
||||||
return nil unless platform.match?(PLATFORM_FORMAT)
|
return nil unless platform.match?(PLATFORM_FORMAT)
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ require "base64"
|
|||||||
require "net/http"
|
require "net/http"
|
||||||
|
|
||||||
module WarpEngine
|
module WarpEngine
|
||||||
# A Woodpecker configuration-extension kéréseinek httpsig-ellenőrzése
|
# Verifies the httpsig signature of Woodpecker configuration-extension
|
||||||
# (draft-cavage http-signatures, ed25519). A szerver az aláírt headerek
|
# requests (draft-cavage http-signatures, ed25519). The server sends the
|
||||||
# listáját a Signature headerben küldi — tipikusan "(request-target) date".
|
# signed header list in the Signature header — typically "(request-target) date".
|
||||||
class CiSignatureVerifier
|
class CiSignatureVerifier
|
||||||
SIGNATURE_PARAM = /(\w+)="([^"]*)"/
|
SIGNATURE_PARAM = /(\w+)="([^"]*)"/
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ module WarpEngine
|
|||||||
@key_mutex = Mutex.new
|
@key_mutex = Mutex.new
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
# A letöltött kulcs process-szinten cache-elt (URL-enként).
|
# The downloaded key is cached process-wide (per URL).
|
||||||
def fetch_public_key(url)
|
def fetch_public_key(url)
|
||||||
@key_mutex.synchronize do
|
@key_mutex.synchronize do
|
||||||
@key_cache[url] ||= Net::HTTP.get(URI.parse(url))
|
@key_cache[url] ||= Net::HTTP.get(URI.parse(url))
|
||||||
@@ -32,7 +32,7 @@ module WarpEngine
|
|||||||
def valid?
|
def valid?
|
||||||
pem = public_key_pem
|
pem = public_key_pem
|
||||||
if pem.blank?
|
if pem.blank?
|
||||||
Rails.logger.error("[CiSignatureVerifier] nincs ci_extension_public_key(_url) konfigurálva — kérés elutasítva")
|
Rails.logger.error("[CiSignatureVerifier] no ci_extension_public_key(_url) configured — rejecting request")
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -58,11 +58,11 @@ module WarpEngine
|
|||||||
|
|
||||||
self.class.fetch_public_key(config.ci_extension_public_key_url)
|
self.class.fetch_public_key(config.ci_extension_public_key_url)
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
Rails.logger.error("[CiSignatureVerifier] kulcs-letöltés sikertelen: #{e.class}: #{e.message}")
|
Rails.logger.error("[CiSignatureVerifier] public key fetch failed: #{e.class}: #{e.message}")
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
# A Signature header (vagy az "Authorization: Signature ..." forma) paraméterei.
|
# Parameters of the Signature header (or the "Authorization: Signature ..." form).
|
||||||
def signature_params
|
def signature_params
|
||||||
header = @request.headers["Signature"].presence
|
header = @request.headers["Signature"].presence
|
||||||
if header.nil?
|
if header.nil?
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ class CreateApplicationTokens < ActiveRecord::Migration[8.1]
|
|||||||
create_table :application_tokens, id: { type: :bigint, unsigned: true },
|
create_table :application_tokens, id: { type: :bigint, unsigned: true },
|
||||||
charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci" do |t|
|
charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci" do |t|
|
||||||
t.string :name, limit: 128, null: false
|
t.string :name, limit: 128, null: false
|
||||||
# Az owner osztályát a host adja (WarpEngine.config.application_token_owner_class),
|
# The owner class comes from the host (WarpEngine.config.application_token_owner_class),
|
||||||
# ezért nem lehet FK.
|
# so no FK.
|
||||||
t.string :owner_type, limit: 128, null: false
|
t.string :owner_type, limit: 128, null: false
|
||||||
t.bigint :owner_id, null: false, unsigned: true
|
t.bigint :owner_id, null: false, unsigned: true
|
||||||
t.string :token_digest, limit: 64, null: false
|
t.string :token_digest, limit: 64, null: false
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
class AddBuildOwnership < ActiveRecord::Migration[8.1]
|
class AddBuildOwnership < ActiveRecord::Migration[8.1]
|
||||||
def change
|
def change
|
||||||
# A publikáló token ownere; nil = belső / backfill előtti software.
|
# Owner of the publishing token; nil = internal / pre-backfill software.
|
||||||
# Az owner osztályát a host adja (application_token_owner_class), ezért nem lehet FK.
|
# The owner class comes from the host (application_token_owner_class), so no FK.
|
||||||
add_column :softwares, :owner_type, :string, limit: 128
|
add_column :softwares, :owner_type, :string, limit: 128
|
||||||
add_column :softwares, :owner_id, :bigint, unsigned: true
|
add_column :softwares, :owner_id, :bigint, unsigned: true
|
||||||
add_index :softwares, [ :owner_type, :owner_id ], name: "idx_softwares_owner"
|
add_index :softwares, [ :owner_type, :owner_id ], name: "idx_softwares_owner"
|
||||||
|
|
||||||
# unrestricted = belső token: az enforce_software_ownership nem vonatkozik rá.
|
# unrestricted = internal token: exempt from enforce_software_ownership.
|
||||||
add_column :application_tokens, :unrestricted, :boolean, default: false, null: false
|
add_column :application_tokens, :unrestricted, :boolean, default: false, null: false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ Rails.application.config.to_prepare do
|
|||||||
c.file_container_path = ENV.fetch("FILE_CONTAINER_PATH", "/softwares")
|
c.file_container_path = ENV.fetch("FILE_CONTAINER_PATH", "/softwares")
|
||||||
c.image_container_path = ENV.fetch("IMAGE_CONTAINER_PATH", "/images")
|
c.image_container_path = ENV.fetch("IMAGE_CONTAINER_PATH", "/images")
|
||||||
|
|
||||||
# Beállítatlan secret esetén a /build/* endpointok minden kérést elutasítanak.
|
# With no secret configured the /build/* endpoints reject every request.
|
||||||
c.update_secret = ENV["UPDATE_SECRET"]
|
c.update_secret = ENV["UPDATE_SECRET"]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ class CreateWarpEngineTables < ActiveRecord::Migration[8.0]
|
|||||||
t.string :site
|
t.string :site
|
||||||
t.string :status, limit: 20, default: "development"
|
t.string :status, limit: 20, default: "development"
|
||||||
t.boolean :highlighted, default: false
|
t.boolean :highlighted, default: false
|
||||||
# A publikáló token ownere (enforce_software_ownership) — nem lehet FK,
|
# Owner of the publishing token (enforce_software_ownership) — no FK,
|
||||||
# az owner osztályát a host adja.
|
# the owner class comes from the host.
|
||||||
t.string :owner_type, limit: 128
|
t.string :owner_type, limit: 128
|
||||||
t.bigint :owner_id
|
t.bigint :owner_id
|
||||||
t.datetime :deleted_at, precision: 3
|
t.datetime :deleted_at, precision: 3
|
||||||
@@ -87,7 +87,7 @@ class CreateWarpEngineTables < ActiveRecord::Migration[8.0]
|
|||||||
t.string :token_digest, limit: 64, null: false
|
t.string :token_digest, limit: 64, null: false
|
||||||
t.string :token_prefix, limit: 12, null: false
|
t.string :token_prefix, limit: 12, null: false
|
||||||
t.json :scopes
|
t.json :scopes
|
||||||
# Belső token: az enforce_software_ownership nem vonatkozik rá.
|
# Internal token: exempt from enforce_software_ownership.
|
||||||
t.boolean :unrestricted, default: false, null: false
|
t.boolean :unrestricted, default: false, null: false
|
||||||
t.datetime :expires_at, precision: 3
|
t.datetime :expires_at, precision: 3
|
||||||
t.datetime :last_used_at, precision: 3
|
t.datetime :last_used_at, precision: 3
|
||||||
|
|||||||
@@ -1,43 +1,44 @@
|
|||||||
Rails.application.config.to_prepare do
|
Rails.application.config.to_prepare do
|
||||||
WarpEngine.configure do |c|
|
WarpEngine.configure do |c|
|
||||||
# A build-artifactok és képek tárolási helye (defaultok az env-ből:
|
# Storage locations for build artifacts and images (defaults from ENV:
|
||||||
# FILE_CONTAINER_PATH ill. IMAGE_CONTAINER_PATH).
|
# FILE_CONTAINER_PATH and IMAGE_CONTAINER_PATH).
|
||||||
# c.file_container_path = "/softwares"
|
# c.file_container_path = "/softwares"
|
||||||
# c.image_container_path = "/images"
|
# c.image_container_path = "/images"
|
||||||
|
|
||||||
# A /build/* endpointok shared secretje (default: ENV["UPDATE_SECRET"]).
|
# Shared secret of the /build/* endpoints (default: ENV["UPDATE_SECRET"]).
|
||||||
# Beállítatlan secret esetén az endpointok minden kérést elutasítanak.
|
# With no secret configured the endpoints reject every request.
|
||||||
# c.update_secret = ENV["UPDATE_SECRET"]
|
# c.update_secret = ENV["UPDATE_SECRET"]
|
||||||
|
|
||||||
# A /build/* hitelesítési forrása — kizárólagos választás:
|
# Auth source of the /build/* endpoints — an exclusive choice:
|
||||||
# :env — a fenti shared secret érvényes (default)
|
# :env — the shared secret above is accepted (default)
|
||||||
# :database — csak DB-tárolt WarpEngine::ApplicationToken érvényes
|
# :database — only DB-stored WarpEngine::ApplicationToken records are
|
||||||
# ("update" scope-pal); a shared secret ilyenkor NEM működik.
|
# accepted (with the "update" scope); the shared secret
|
||||||
# A :database módhoz kötelező a tokenek tulajdonos-osztálya is:
|
# stops working the moment you switch.
|
||||||
|
# :database mode also requires the owner class every token belongs to:
|
||||||
# c.application_token_source = :database
|
# c.application_token_source = :database
|
||||||
# c.application_token_owner_class = "AdminUser"
|
# c.application_token_owner_class = "AdminUser"
|
||||||
|
|
||||||
# Woodpecker configuration extension (/build/config): a kiszolgált
|
# Woodpecker configuration extension (/build/config): builder images of
|
||||||
# platformok builder image-ei és a CI-szerver aláíró kulcsa. Üres
|
# the served platforms and the CI server's signing key. An empty
|
||||||
# ci_platforms (default) = a feature inaktív.
|
# ci_platforms (default) keeps the feature inactive.
|
||||||
# c.ci_platforms = {
|
# c.ci_platforms = {
|
||||||
# "godot" => { builder: "registry.example/godot-builder:4.6" },
|
# "godot" => { builder: "registry.example/godot-builder:4.6" },
|
||||||
# "tic80" => { builder: "registry.example/tic80-builder:1.0",
|
# "tic80" => { builder: "registry.example/tic80-builder:1.0",
|
||||||
# exporter: "registry.example/tic80pro:1.0" }
|
# exporter: "registry.example/tic80pro:1.0" }
|
||||||
# }
|
# }
|
||||||
# c.ci_extension_public_key_url = "https://ci.example.org/api/signature/public-key"
|
# c.ci_extension_public_key_url = "https://ci.example.org/api/signature/public-key"
|
||||||
# c.ci_update_server = nil # nil: a kérés base_url-je
|
# c.ci_update_server = nil # nil: the request base_url
|
||||||
|
|
||||||
# A /build/upload (és az admin file manager) méretplafonja bájtban (default: 500MB).
|
# Size cap in bytes for /build/upload (and the admin file manager, default: 500MB).
|
||||||
# c.max_upload_size = 500 * 1024 * 1024
|
# c.max_upload_size = 500 * 1024 * 1024
|
||||||
|
|
||||||
# Owner-izoláció: DB-token csak a saját ownerének szoftvereit
|
# Owner isolation: a DB token may only upload/publish its own owner's
|
||||||
# uploadolhatja/publisholhatja (unrestricted token kivétel). Csak azután
|
# softwares (unrestricted tokens are exempt). Enable only after existing
|
||||||
# kapcsold be, hogy a meglévő szoftverek ownert kaptak (backfill)!
|
# softwares got an owner (backfill)!
|
||||||
# c.enforce_software_ownership = true
|
# c.enforce_software_ownership = true
|
||||||
|
|
||||||
# Ha a host modelljei is hivatkoznak katalógus-képekre, regisztráld őket,
|
# If host models also reference catalog images, register them so the
|
||||||
# hogy az admin Images oldal orphan-detektálása figyelembe vegye:
|
# admin Images page's orphan detection takes them into account:
|
||||||
# c.image_owners = [
|
# c.image_owners = [
|
||||||
# {
|
# {
|
||||||
# label: "member",
|
# label: "member",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Generált pipeline — WarpEngine /build/config (platform: bevy, name: <%= name %>)
|
# Generated pipeline — WarpEngine /build/config (platform: bevy, name: <%= name %>)
|
||||||
steps:
|
steps:
|
||||||
- name: version
|
- name: version
|
||||||
image: alpine
|
image: alpine
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Generált pipeline — WarpEngine /build/config (platform: c64, name: <%= name %>)
|
# Generated pipeline — WarpEngine /build/config (platform: c64, name: <%= name %>)
|
||||||
steps:
|
steps:
|
||||||
- name: version
|
- name: version
|
||||||
image: alpine
|
image: alpine
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Generált pipeline — WarpEngine /build/config (platform: ebitengine, name: <%= name %>)
|
# Generated pipeline — WarpEngine /build/config (platform: ebitengine, name: <%= name %>)
|
||||||
steps:
|
steps:
|
||||||
- name: version
|
- name: version
|
||||||
image: alpine
|
image: alpine
|
||||||
@@ -41,8 +41,8 @@ steps:
|
|||||||
VERSION=$(cat .version)
|
VERSION=$(cat .version)
|
||||||
# win-x86 / win-x64: pure Go cross-compile (Windowson nem kell cgo)
|
# win-x86 / win-x64: pure Go cross-compile (Windowson nem kell cgo)
|
||||||
# linux-x64: cgo build, linux/amd64 hoston fut (builder image, X11/GL dev libekkel)
|
# linux-x64: cgo build, linux/amd64 hoston fut (builder image, X11/GL dev libekkel)
|
||||||
# belső helper: egy target buildje + zip egyetlen gyökérmappával
|
# helper: builds one target + zips it with a single root folder
|
||||||
# (a zipet unixos zip készíti, így a végrehajtási bit megmarad)
|
# (unix zip keeps the executable bit)
|
||||||
binary_build() {
|
binary_build() {
|
||||||
B_GOOS="$1"; B_GOARCH="$2"; B_CGO="$3"; B_EXT="$4"; B_TARGET="$5"
|
B_GOOS="$1"; B_GOARCH="$2"; B_CGO="$3"; B_EXT="$4"; B_TARGET="$5"
|
||||||
PKG_DIR="<%= name %>-$VERSION-$B_TARGET"
|
PKG_DIR="<%= name %>-$VERSION-$B_TARGET"
|
||||||
@@ -56,7 +56,7 @@ steps:
|
|||||||
rm -rf "$PKG_DIR"
|
rm -rf "$PKG_DIR"
|
||||||
echo "==> $PKG_DIR.zip kesz"
|
echo "==> $PKG_DIR.zip kesz"
|
||||||
}
|
}
|
||||||
# a CI (linux builder) ezt a hármat építi:
|
# CI (linux builder) builds these three:
|
||||||
binary_build "windows" "386" "0" ".exe" "win-x86"
|
binary_build "windows" "386" "0" ".exe" "win-x86"
|
||||||
binary_build "windows" "amd64" "0" ".exe" "win-x64"
|
binary_build "windows" "amd64" "0" ".exe" "win-x64"
|
||||||
binary_build "linux" "amd64" "1" "" "linux-x64"
|
binary_build "linux" "amd64" "1" "" "linux-x64"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Generált pipeline — WarpEngine /build/config (platform: godot, name: <%= name %>)
|
# Generated pipeline — WarpEngine /build/config (platform: godot, name: <%= name %>)
|
||||||
steps:
|
steps:
|
||||||
- name: version
|
- name: version
|
||||||
image: alpine
|
image: alpine
|
||||||
@@ -32,8 +32,8 @@ steps:
|
|||||||
rm -rf dist/web
|
rm -rf dist/web
|
||||||
- |
|
- |
|
||||||
VERSION=$(cat .version)
|
VERSION=$(cat .version)
|
||||||
# win/linux target exportja + zip egyetlen gyökérmappával (embed_pck
|
# exports a win/linux target + zips it with a single root folder
|
||||||
# miatt az export egyetlen futtatható fájl)
|
# (embed_pck makes the export a single executable)
|
||||||
binary_build() {
|
binary_build() {
|
||||||
B_PRESET="$1"; B_EXT="$2"; B_TARGET="$3"
|
B_PRESET="$1"; B_EXT="$2"; B_TARGET="$3"
|
||||||
PKG_DIR="<%= name %>-$VERSION-$B_TARGET"
|
PKG_DIR="<%= name %>-$VERSION-$B_TARGET"
|
||||||
@@ -47,9 +47,9 @@ steps:
|
|||||||
rm -rf "$PKG_DIR"
|
rm -rf "$PKG_DIR"
|
||||||
echo "==> $PKG_DIR.zip kesz"
|
echo "==> $PKG_DIR.zip kesz"
|
||||||
}
|
}
|
||||||
# mac: a Godot linuxról csak .zip-be tud macOS-t exportálni (benne a
|
# mac: from linux Godot can only export macOS into a .zip (holding the
|
||||||
# .app), átcsomagoljuk a gyökérmappás konvencióra (zip -ry: exec bitek
|
# .app); repackage it to the root-folder convention (zip -ry keeps
|
||||||
# és symlinkek megmaradnak)
|
# exec bits and symlinks)
|
||||||
binary_build_mac() {
|
binary_build_mac() {
|
||||||
B_PRESET="$1"; B_TARGET="$2"
|
B_PRESET="$1"; B_TARGET="$2"
|
||||||
PKG_DIR="<%= name %>-$VERSION-$B_TARGET"
|
PKG_DIR="<%= name %>-$VERSION-$B_TARGET"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Generált pipeline — WarpEngine /build/config (platform: love, name: <%= name %>)
|
# Generated pipeline — WarpEngine /build/config (platform: love, name: <%= name %>)
|
||||||
steps:
|
steps:
|
||||||
- name: version
|
- name: version
|
||||||
image: alpine
|
image: alpine
|
||||||
@@ -34,8 +34,8 @@ steps:
|
|||||||
--exclude "metadata.json" \
|
--exclude "metadata.json" \
|
||||||
--exclude "*.zip"
|
--exclude "*.zip"
|
||||||
mkdir -p dist/web
|
mkdir -p dist/web
|
||||||
# A love-builder CI image ide előre letölti a love.js-t; lokális
|
# The love-builder CI image pre-fetches love.js here; local builds
|
||||||
# buildnél GitHubról jön.
|
# fall back to GitHub.
|
||||||
if [ -f /opt/lovejs.zip ]; then
|
if [ -f /opt/lovejs.zip ]; then
|
||||||
echo "==> Using cached love.js (/opt/lovejs.zip)"
|
echo "==> Using cached love.js (/opt/lovejs.zip)"
|
||||||
cp /opt/lovejs.zip dist/lovejs.zip
|
cp /opt/lovejs.zip dist/lovejs.zip
|
||||||
@@ -68,8 +68,8 @@ steps:
|
|||||||
commands:
|
commands:
|
||||||
- |
|
- |
|
||||||
VERSION=$(cat .version)
|
VERSION=$(cat .version)
|
||||||
# Az export step törölte a .love-ot, itt újraépítjük (make-ben a
|
# The export step deleted the .love, rebuild it here (in make the
|
||||||
# binary-* targetek love-prerequisite-je tette ugyanezt).
|
# binary-* targets' love prerequisite did the same).
|
||||||
mkdir -p dist
|
mkdir -p dist
|
||||||
zip -r dist/<%= name %>.love . \
|
zip -r dist/<%= name %>.love . \
|
||||||
--exclude "*.git*" \
|
--exclude "*.git*" \
|
||||||
@@ -79,8 +79,8 @@ steps:
|
|||||||
--exclude ".version" \
|
--exclude ".version" \
|
||||||
--exclude "metadata.json" \
|
--exclude "metadata.json" \
|
||||||
--exclude "*.zip"
|
--exclude "*.zip"
|
||||||
# A love-builder CI image a dist-fájlokat /opt/love-dist alá előre
|
# The love-builder CI image pre-fetches the dist files to
|
||||||
# letölti; lokális buildnél GitHubról jönnek.
|
# /opt/love-dist; local builds fall back to GitHub.
|
||||||
fetch_love() {
|
fetch_love() {
|
||||||
if [ -f "/opt/love-dist/$1" ]; then
|
if [ -f "/opt/love-dist/$1" ]; then
|
||||||
echo "==> Using cached $1"
|
echo "==> Using cached $1"
|
||||||
@@ -117,10 +117,10 @@ steps:
|
|||||||
zip -qry "$PKG_DIR.zip" "$PKG_DIR"
|
zip -qry "$PKG_DIR.zip" "$PKG_DIR"
|
||||||
rm -rf "$PKG_DIR" dist/macos
|
rm -rf "$PKG_DIR" dist/macos
|
||||||
echo "==> $PKG_DIR.zip kesz"
|
echo "==> $PKG_DIR.zip kesz"
|
||||||
# Az AppImage runtime glibc-dinamikus, alpine (musl) alatt nem
|
# The AppImage runtime is glibc-dynamic and cannot run on alpine
|
||||||
# futtatható, ezért nem a runtime-ot futtatjuk: az offsetet readelf-ből
|
# (musl), so we do not run the runtime: the offset is computed from
|
||||||
# számoljuk (shoff + shentsize*shnum), a squashfs-t unsquashfs -o
|
# readelf (shoff + shentsize*shnum) and the squashfs is extracted
|
||||||
# bontja ki.
|
# with unsquashfs -o.
|
||||||
echo "==> Fusing linux AppImage"
|
echo "==> Fusing linux AppImage"
|
||||||
fetch_love love-11.5-x86_64.AppImage
|
fetch_love love-11.5-x86_64.AppImage
|
||||||
PKG_DIR="<%= name %>-$VERSION-linux-x64"
|
PKG_DIR="<%= name %>-$VERSION-linux-x64"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Generált pipeline — WarpEngine /build/config (platform: phaser, name: <%= name %>)
|
# Generated pipeline — WarpEngine /build/config (platform: phaser, name: <%= name %>)
|
||||||
steps:
|
steps:
|
||||||
- name: version
|
- name: version
|
||||||
image: alpine
|
image: alpine
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Generált pipeline — WarpEngine /build/config (platform: tic80, name: <%= name %>)
|
# Generated pipeline — WarpEngine /build/config (platform: tic80, name: <%= name %>)
|
||||||
# A verzió a forrásból jön (inc/meta/meta.header.lua "-- version:" komment) — a
|
# The version comes from the source (inc/meta/meta.header.lua "-- version:"
|
||||||
# WarpEngine is a Lua headerből parsolja a tic80-metadatát, ezért nincs metadata.json.
|
# comment) — WarpEngine parses tic80 metadata from the Lua header too, hence
|
||||||
|
# no metadata.json.
|
||||||
steps:
|
steps:
|
||||||
- name: version
|
- name: version
|
||||||
image: alpine
|
image: alpine
|
||||||
@@ -136,7 +137,7 @@ steps:
|
|||||||
echo "==> Exporting native players for version $VERSION"
|
echo "==> Exporting native players for version $VERSION"
|
||||||
tic80 --cli --skip --fs=. \
|
tic80 --cli --skip --fs=. \
|
||||||
--cmd="load <%= name %>.lua & export win <%= name %>-win & export linux <%= name %>-linux & export mac <%= name %>-mac & exit"
|
--cmd="load <%= name %>.lua & export win <%= name %>-win & export linux <%= name %>-linux & export mac <%= name %>-mac & exit"
|
||||||
# unixos zip őrzi a végrehajtási bitet
|
# unix zip preserves the executable bit
|
||||||
pack_binary() {
|
pack_binary() {
|
||||||
SLUG="$1"; SRC_FILE="$2"; DST_FILE="$3"
|
SLUG="$1"; SRC_FILE="$2"; DST_FILE="$3"
|
||||||
PKG_DIR="<%= name %>-$VERSION-$SLUG"
|
PKG_DIR="<%= name %>-$VERSION-$SLUG"
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
module WarpEngine
|
module WarpEngine
|
||||||
class Configuration
|
class Configuration
|
||||||
# Owner kontraktus az image_owners elemeire:
|
# Owner contract for image_owners elements:
|
||||||
# label: String
|
# label: String
|
||||||
# image_ids: -> { Array<Integer> } — az owner által használt image id-k
|
# image_ids: -> { Array<Integer> } — image ids used by the owner
|
||||||
# usage_label: ->(image) { String vagy nil } — megjelenítendő címke, ha használja
|
# usage_label: ->(image) { String or nil } — label to display when in use
|
||||||
# application_token_source: a /build/* endpointok hitelesítési forrása, kizárólagos.
|
# application_token_source: auth source of the /build/* endpoints, exclusive.
|
||||||
# :env — a shared secret (update_secret) érvényes, a DB-tokenek nem
|
# :env — the shared secret (update_secret) is accepted, DB tokens are not
|
||||||
# :database — csak WarpEngine::ApplicationToken érvényes, a shared secret nem
|
# :database — only WarpEngine::ApplicationToken is accepted, the shared secret is not
|
||||||
# application_token_owner_class: a tokenek kötelező tulajdonosának osztályneve
|
# application_token_owner_class: class name of the mandatory token owner
|
||||||
# (pl. "AdminUser"); nil esetén a :database mód minden kérést elutasít.
|
# (e.g. "AdminUser"); nil makes :database mode reject every request.
|
||||||
# max_upload_size: a /build/upload (és az admin file manager) fájlméret-plafonja bájtban.
|
# max_upload_size: file size cap in bytes for /build/upload (and the admin file manager).
|
||||||
# enforce_software_ownership: ha true, egy DB-token csak a saját ownerének
|
# enforce_software_ownership: when true, a DB token may only upload/publish
|
||||||
# szoftvereit uploadolhatja/publisholhatja (unrestricted token kivétel).
|
# its own owner's softwares (unrestricted tokens are exempt).
|
||||||
# Bekapcsolás CSAK backfill után: gazdátlan software-t bármely token elvihet.
|
# Enable ONLY after the backfill: any token can claim an ownerless software.
|
||||||
# ci_platforms: a /build/config által kiszolgált platformok:
|
# ci_platforms: platforms served by /build/config:
|
||||||
# { "godot" => { builder: "<image>" }, "tic80" => { builder: ..., exporter: ... } }
|
# { "godot" => { builder: "<image>" }, "tic80" => { builder: ..., exporter: ... } }
|
||||||
# Üres map = a feature inaktív (POST → 204, GET → 404).
|
# Empty map = the feature is inactive (POST → 204, GET → 404).
|
||||||
# ci_extension_public_key(_url): a Woodpecker httpsig ed25519 publikus kulcsa
|
# ci_extension_public_key(_url): the Woodpecker httpsig ed25519 public key as
|
||||||
# PEM-ben, vagy URL, ahonnan letölthető (pl. https://ci.../api/signature/public-key).
|
# PEM, or a URL to fetch it from (e.g. https://ci.../api/signature/public-key).
|
||||||
# Egyik sincs beállítva → a POST /build/config minden kérést elutasít.
|
# With neither set, POST /build/config rejects every request.
|
||||||
# ci_update_server: az upload/publish stepekbe írt szerver-URL; nil → a kérés base_url-je.
|
# ci_update_server: server URL written into the upload/publish steps; nil → the request's base_url.
|
||||||
attr_accessor :file_container_path,
|
attr_accessor :file_container_path,
|
||||||
:image_container_path,
|
:image_container_path,
|
||||||
:update_secret,
|
:update_secret,
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
# Csak a dummy app tesztjeihez: az ApplicationToken owner szerepét tölti be.
|
# Test-only: plays the ApplicationToken owner role in the dummy app.
|
||||||
class TestOwner < ActiveRecord::Base
|
class TestOwner < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Csak a tesztekhez: az ApplicationToken owner-e (a hostban ez pl. AdminUser).
|
# Test-only: plays the ApplicationToken owner role (AdminUser in the host).
|
||||||
class CreateTestOwners < ActiveRecord::Migration[8.1]
|
class CreateTestOwners < ActiveRecord::Migration[8.1]
|
||||||
def change
|
def change
|
||||||
create_table :test_owners, id: { type: :bigint, unsigned: true },
|
create_table :test_owners, id: { type: :bigint, unsigned: true },
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# A TestOwner csak a dummy appban létezik — host-oldali használatnál az owner-t
|
# TestOwner exists only in the dummy app — host-side usage must override the
|
||||||
# felül kell írni (pl. owner: create(:admin_user)).
|
# owner (e.g. owner: create(:admin_user)).
|
||||||
FactoryBot.define do
|
FactoryBot.define do
|
||||||
factory :test_owner, class: "TestOwner" do
|
factory :test_owner, class: "TestOwner" do
|
||||||
name { "test owner" }
|
name { "test owner" }
|
||||||
|
|||||||
Reference in New Issue
Block a user