A kódbázis kommentek nélkül marad
Kérésre: minden magyarázó komment kikerült a forrásfájlokból — 89 Ruby, 16 TypeScript, 14 Vue, plusz a CSS/JS/CJS. Nem soralapú kereséssel: a Ruby-t a Ripper tokenizálta, a JS/TS/CSS-t állapotgép járta végig, hogy az URL-ekben, reguláris kifejezésekben és heredocokban álló // és # jelek helyükön maradjanak. Három komment maradt, mert nélkülük nem indul a kód: az entrypoint.sh shebangja, a vite-env.d.ts hármas perjeles referenciája, és a sanitize teszt @vitest-environment direktívája (ez utóbbi a magyarázó része nélkül). Egy helyen kódot is kellett írni: a CommandBlock másolás-hibaágán a komment volt a catch egyetlen tartalma, és üres blokkot az eslint nem enged — a copied jelző visszaállítása került a helyére. A yaml, Dockerfile, Makefile, erb és markdown fájlokat nem érintettem. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,12 +6,9 @@ module WarpEngine
|
||||
|
||||
UPDATE_SCOPE = "update".freeze
|
||||
UPLOAD_SCOPE = "upload".freeze
|
||||
# A token held by a *client* rather than a publisher: it reads the catalog and
|
||||
# downloads artifacts, and it never publishes anything.
|
||||
|
||||
CATALOG_SCOPE = "catalog".freeze
|
||||
|
||||
# The generated token is only available in memory at creation time — the DB
|
||||
# stores nothing but the SHA256 digest and the non-secret prefix.
|
||||
attr_reader :plain_token
|
||||
|
||||
belongs_to :owner, polymorphic: true
|
||||
@@ -33,7 +30,6 @@ module WarpEngine
|
||||
Digest::SHA256.hexdigest(token)
|
||||
end
|
||||
|
||||
# The live (not deleted, not expired) token carrying the required scope, else nil.
|
||||
def self.authenticate(token, required_scope: nil)
|
||||
return nil if token.blank?
|
||||
|
||||
@@ -48,7 +44,6 @@ module WarpEngine
|
||||
expires_at.present? && expires_at <= Time.current
|
||||
end
|
||||
|
||||
# Revocation = soft delete, the audit trail stays.
|
||||
def revoke!
|
||||
update_column(:deleted_at, Time.current)
|
||||
end
|
||||
@@ -57,7 +52,6 @@ module WarpEngine
|
||||
update_column(:last_used_at, Time.current)
|
||||
end
|
||||
|
||||
# Admin form: comma separated scope list
|
||||
def scopes_string
|
||||
Array(scopes).join(", ")
|
||||
end
|
||||
@@ -70,7 +64,6 @@ module WarpEngine
|
||||
%w[created_at deleted_at expires_at id last_used_at name owner_id owner_type token_prefix unrestricted updated_at]
|
||||
end
|
||||
|
||||
# Ransack cannot filter on the polymorphic owner association.
|
||||
def self.ransackable_associations(auth_object = nil)
|
||||
[]
|
||||
end
|
||||
@@ -81,10 +74,6 @@ module WarpEngine
|
||||
self.owner_type = WarpEngine.config.application_token_owner_class if owner_type.blank?
|
||||
end
|
||||
|
||||
# Publishing tokens and client tokens share this table but not their owners: one
|
||||
# belongs to whoever ships software, the other to whoever buys it. Both classes are
|
||||
# the host's to name, and either is acceptable here — which of the two a given token
|
||||
# may do is decided by its scopes, not by its owner.
|
||||
def self.permitted_owner_types
|
||||
[ WarpEngine.config.application_token_owner_class,
|
||||
WarpEngine.config.access_token_owner_class ].compact_blank
|
||||
|
||||
@@ -1,19 +1,8 @@
|
||||
module WarpEngine
|
||||
# One pending sign-in from a client that has no browser of its own.
|
||||
#
|
||||
# The shape is RFC 8628's device authorization grant, and the reason for it is that a
|
||||
# desktop client cannot host a login form without asking a person to type a password
|
||||
# into a window that is not a browser. So the client asks for a pair of codes, sends
|
||||
# the person to the host's own page with the short one, and polls with the long one
|
||||
# until somebody approves it.
|
||||
#
|
||||
# Short-lived by design: this row exists for the minute or two between "the client
|
||||
# asked" and "the person answered". What survives it is the ApplicationToken.
|
||||
|
||||
class DeviceGrant < ApplicationRecord
|
||||
self.table_name = "device_grants"
|
||||
|
||||
# No I, O, 0 or 1: this alphabet is read off one screen and typed into another, and
|
||||
# those four are where that goes wrong.
|
||||
USER_CODE_ALPHABET = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789".freeze
|
||||
USER_CODE_LENGTH = 8
|
||||
|
||||
@@ -33,7 +22,6 @@ module WarpEngine
|
||||
pending.find_by(user_code: normalize_user_code(code))
|
||||
end
|
||||
|
||||
# Typed by a person, so it arrives with whatever case and separators they used.
|
||||
def self.normalize_user_code(code)
|
||||
code.to_s.upcase.gsub(/[^A-Z0-9]/, "")
|
||||
end
|
||||
@@ -42,8 +30,6 @@ module WarpEngine
|
||||
def approved? = approved_at.present?
|
||||
def denied? = denied_at.present?
|
||||
|
||||
# What the polling client is told. Order matters: a denied grant is denied even
|
||||
# after it expires, because "somebody said no" is the more useful answer.
|
||||
def state
|
||||
return :denied if denied?
|
||||
return :approved if approved?
|
||||
@@ -52,13 +38,10 @@ module WarpEngine
|
||||
:pending
|
||||
end
|
||||
|
||||
# Grouped for reading aloud and for typing: WARP-K7M2.
|
||||
def formatted_user_code
|
||||
user_code.to_s.scan(/.{1,4}/).join("-")
|
||||
end
|
||||
|
||||
# Housekeeping for a host that wants it: an expired grant has nothing left to give,
|
||||
# and its issued_token would be a live secret nobody is waiting for.
|
||||
def self.sweep_expired!
|
||||
where(expires_at: ...Time.current).where.not(issued_token: nil).update_all(issued_token: nil)
|
||||
end
|
||||
@@ -79,8 +62,7 @@ module WarpEngine
|
||||
end
|
||||
|
||||
def self.generate_user_code
|
||||
# Retried rather than trusted: the alphabet is small enough that a collision is
|
||||
# a real, if rare, event, and a unique index would turn it into a 500.
|
||||
|
||||
10.times do
|
||||
candidate = Array.new(USER_CODE_LENGTH) { USER_CODE_ALPHABET.chars.sample }.join
|
||||
return candidate unless exists?(user_code: candidate)
|
||||
|
||||
@@ -2,29 +2,14 @@ module WarpEngine
|
||||
class Pipeline < ApplicationRecord
|
||||
self.table_name = "pipelines"
|
||||
|
||||
# Repos synced from Woodpecker without a matching Software land here
|
||||
# until a platform is assigned by hand.
|
||||
UNKNOWN_PLATFORM = "unknown".freeze
|
||||
|
||||
belongs_to :software, class_name: "WarpEngine::Software", optional: true
|
||||
|
||||
# Pipelines this record took the software from during the last save, by full name.
|
||||
# The admin says so out loud: a silent reassignment is what made the old behaviour
|
||||
# confusing in the first place.
|
||||
attr_reader :software_taken_from
|
||||
|
||||
default_scope { where(deleted_at: nil) }
|
||||
|
||||
# One pipeline per software, and the newest assignment wins.
|
||||
#
|
||||
# `Software#pipeline` is a `has_one`, so two pipelines pointing at the same software
|
||||
# is not an error — it is worse than one: the software keeps showing whichever row
|
||||
# comes first, and assigning it elsewhere looks like it did nothing. Rather than
|
||||
# refusing the assignment, the link moves: whoever held that software lets go of it.
|
||||
#
|
||||
# Deliberately a callback and not a unique index. Rows here are soft-deleted, and a
|
||||
# unique index counts deleted rows too, so a pipeline someone removed last year would
|
||||
# block the software from ever being linked again.
|
||||
before_save :claim_software_from_other_pipelines, if: :will_save_change_to_software_id?
|
||||
|
||||
validates :woodpecker_repo_id, presence: true, uniqueness: true
|
||||
@@ -57,10 +42,6 @@ module WarpEngine
|
||||
@software_taken_from = others.map(&:full_name)
|
||||
return if @software_taken_from.empty?
|
||||
|
||||
# Logged rather than flashed. The first attempt at this put a message on screen by
|
||||
# overriding the admin's `update` action, which bypassed the permitted-params path
|
||||
# and made every pipeline edit fail with ForbiddenAttributesError. A silent
|
||||
# reassignment is a small problem; an admin page that cannot save is a large one.
|
||||
Rails.logger.info(
|
||||
"[WarpEngine::Pipeline] #{full_name} took software #{software_id} from " \
|
||||
"#{@software_taken_from.join(', ')}"
|
||||
|
||||
@@ -2,8 +2,6 @@ module WarpEngine
|
||||
class Software < ApplicationRecord
|
||||
self.table_name = "softwares"
|
||||
|
||||
# Owner of the publishing token (e.g. AdminUser) — for 3rd-party isolation,
|
||||
# see enforce_software_ownership. nil = internal / pre-backfill software.
|
||||
belongs_to :owner, polymorphic: true, optional: true
|
||||
|
||||
has_many :software_images, foreign_key: :software_id, dependent: :destroy
|
||||
|
||||
Reference in New Issue
Block a user