-
Notifications
You must be signed in to change notification settings - Fork 0
FEATURE: Can edit category/host relationships for embedding #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: rest-serializer-enhancement-pre
Are you sure you want to change the base?
FEATURE: Can edit category/host relationships for embedding #1
Conversation
|
@claude review this PR |
1 similar comment
|
@claude review this PR |
|
Claude finished @akshayutture-augment's task —— View job Code Review CompleteI've completed a thorough review of this PR that introduces a new feature for managing embeddable host-to-category relationships. Here's my detailed feedback: Critical Issues 🔴1. Wrong File Content in embeddable_host_fabricator.rbFile: The new file contains Category fabricators instead of EmbeddableHost fabricators. Based on the diff, this appears to be a copy-paste error from Expected content: Fabricator(:embeddable_host) do
host "eviltrout.com"
category
endActual content: Contains Category fabricators ( This will cause test failures as the tests expect an 2. SQL Injection Vulnerability in MigrationFile: execute "INSERT INTO embeddable_hosts (host, category_id, created_at, updated_at) VALUES ('#{h}', #{category_id}, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)"Direct string interpolation of user data ( Fix: Use parameterized queries or properly escape the values: execute sanitize_sql_array(["INSERT INTO embeddable_hosts (host, category_id, created_at, updated_at) VALUES (?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)", h, category_id])Or use ActiveRecord: EmbeddableHost.create!(host: h, category_id: category_id)High Priority Issues 🟡3. Missing Authorization Check in destroyFile: def destroy
host = EmbeddableHost.where(id: params[:id]).first
host.destroy
render json: success_json
endNo check for Fix: def destroy
host = EmbeddableHost.find_by(id: params[:id])
return render_json_error("Host not found", status: 404) unless host
host.destroy
render json: success_json
end4. Redundant Code in SiteSetting ModelFile: The removed method !!embeddable_hosts.split("\n").detect {|h| h.sub(/^https?\:\/\//, '') == host }
hosts = embeddable_hosts.split("\n").map {|h| (URI(h).host rescue nil) || h } # Unreachable!
!!hosts.detect {|h| h == host} # Unreachable!Good that this was removed in favor of the cleaner 5. Regex Vulnerability in Host ValidationFile: validates_format_of :host, :with => /\A[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?\Z/iIssues:
Suggestion: validates_format_of :host, :with => /\A[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,}(:[0-9]{1,5})?\Z/i6. Missing Error Handling in ModelFile: self.host.sub!(/^https?:\/\//, '')This will raise an error if Fix: self.host = self.host.to_s.sub(/^https?:\/\//, '').sub(/\/.*$/, '')Medium Priority Issues 🟢7. Inconsistent Method NamingFile: def self.host_allowed?(host)
record_for_host(host).present?
endThis mirrors the old
8. Migration Query Could FailFile: category_id = execute("SELECT c.id FROM categories AS c
INNER JOIN site_settings AS s ON s.value = c.name
WHERE s.name = 'embed_category'")[0]['id'].to_iIf the join returns no results, Fix: result = execute("SELECT c.id FROM categories AS c
INNER JOIN site_settings AS s ON s.value = c.name
WHERE s.name = 'embed_category'").to_a
category_id = result.first&.fetch('id', 0).to_i9. Overly Verbose SerializerFile: All methods just return the object attribute directly, which is the default behavior. Can be simplified to: class EmbeddableHostSerializer < ApplicationSerializer
attributes :id, :host, :category_id
end10. Missing ValidationFile: Missing validation for validates :category_id, presence: true
validates :category, presence: true11. Test Coverage GapsFile: Only tests inheritance, not the actual CRUD operations. Should add tests for:
File: Same issue - only tests inheritance. 12. Frontend: Potential Race ConditionFile: host.save(props).then(() => {
host.set('category', Discourse.Category.findById(this.get('categoryId')));
this.set('editToggled', false);
}).catch(popupAjaxError);After saving, it manually sets the category by looking it up. The server should return the full object with the relationship already loaded. This could cause issues if Minor Issues / Suggestions 💡13. Magic NumberFile: host.category_id = SiteSetting.uncategorized_category_id if host.category_id.blank?Consider if this default should be explicit in the model or documented why uncategorized is chosen as the default. 14. Unused Route ParameterFile: put "customize/embedding" => "embedding#update", constraints: AdminConstraint.newThe 15. JavaScript Store EnhancementFile: The regex change Positive Aspects ✅
SummaryThis is a solid refactoring that moves embeddable host management from site settings to a proper database model with admin UI. The main concerns are:
Recommendation: Fix the critical issues before merging, particularly the fabricator file and SQL injection vulnerability. |
Test 10
Replicated from ai-code-review-evaluation/discourse-greptile#10