Merge branch 'master' into dev

This commit is contained in:
End 2026-03-14 11:17:25 -07:00 committed by GitHub
commit 91cc8b703a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 34 additions and 17 deletions

View file

@ -18,7 +18,10 @@ module Admin
end
def search_uploads(query)
Upload.search(query).includes(:blob, :user).order(created_at: :desc).limit(50)
by_search = Upload.search(query)
by_url = Upload.where("original_url ILIKE ?", "%#{Upload.sanitize_sql_like(query)}%")
Upload.where(id: by_search.select(:id)).or(Upload.where(id: by_url.select(:id)))
.includes(:blob, :user).order(created_at: :desc).limit(50)
end
end
end

View file

@ -2,6 +2,7 @@
class ExternalUploadsController < ApplicationController
skip_before_action :require_authentication!
before_action :set_cors_headers
def show
upload = Upload.includes(:blob).find(params[:id])
@ -31,6 +32,8 @@ class ExternalUploadsController < ApplicationController
private
def set_cors_headers = response.set_header("Access-Control-Allow-Origin", "*")
def render_not_found_response(url)
if url.match?(/\.(png|jpe?g)$/i)
render_error_image

View file

@ -25,24 +25,31 @@ class User < ApplicationRecord
raise "Missing HCA user ID from authentication" if hca_id.blank?
user = find_by(hca_id:)
user ||= find_by(slack_id:) if slack_id.present?
if slack_id.present?
slack_user = find_by(slack_id:)
if slack_user && user && slack_user.id != user.id
# same person, two records — merge into the slack user
user.uploads.update_all(user_id: slack_user.id)
user.destroy!
user = slack_user
elsif slack_user
user = slack_user
end
end
attrs = {
hca_id:,
email: auth.info.email,
name: auth.info.name,
hca_access_token: auth.credentials.token
}
attrs[:slack_id] = slack_id if slack_id.present?
if user
user.update(
hca_id:,
slack_id:,
email: auth.info.email,
name: auth.info.name,
hca_access_token: auth.credentials.token
)
user.update!(attrs)
else
user = create!(
hca_id:,
slack_id:,
email: auth.info.email,
name: auth.info.name,
hca_access_token: auth.credentials.token
)
user = create!(attrs)
end
user

View file

@ -34,6 +34,10 @@ Requests are 301 redirected to the underlying storage bucket.
![](https://cdn.hackclub.com/019505e2-e7f3-7d40-a156-9c4e8b2d1f03/screenshot.png)
```
## Security
Upload IDs contain 74 bits of cryptographic randomness (UUID v7, via the OS CSPRNG). There's no file listing or directory index. URLs are safe to use for unreleased programs.
## Hotlinking
Supported. URLs can be embedded in GitHub, Notion, Discord, Slack, etc.

View file

@ -10,7 +10,7 @@ namespace :import do
ActiveStorage::Current.url_options = { host: ENV.fetch("CDN_HOST", "cdn.hackclub.com"), protocol: "https" }
csv_path = ENV.fetch("CSV_PATH", "files_with_slack_url.csv")
slack_token = ENV.fetch("SLACK_TOKEN") { raise "SLACK_TOKEN (xoxp-...) is required" }
thread_count = ENV.fetch("THREADS", 10).to_i
thread_count = ENV.fetch("THREADS", 67).to_i
dry_run = ENV["DRY_RUN"] == "true"
unless File.exist?(csv_path)