summaryrefslogtreecommitdiff
path: root/app/controllers/concerns/snippets_url.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/controllers/concerns/snippets_url.rb')
-rw-r--r--app/controllers/concerns/snippets_url.rb64
1 files changed, 64 insertions, 0 deletions
diff --git a/app/controllers/concerns/snippets_url.rb b/app/controllers/concerns/snippets_url.rb
new file mode 100644
index 00000000000..09e07b6db4c
--- /dev/null
+++ b/app/controllers/concerns/snippets_url.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+module SnippetsUrl
+ extend ActiveSupport::Concern
+
+ SNIPPETS_SECRET_KEYWORD = 'secret'
+
+ private
+
+ attr_reader :snippet
+
+ def authorize_secret_snippet!
+ if snippet_is_secret?
+ return if secrets_match?(params[SNIPPETS_SECRET_KEYWORD])
+
+ return render_404
+ end
+
+ current_user ? render_404 : authenticate_user!
+ end
+
+ def snippet_is_secret?
+ snippet&.secret?
+ end
+
+ def secrets_match?(secret)
+ ActiveSupport::SecurityUtils.secure_compare(secret.to_s, snippet.secret)
+ end
+
+ def ensure_complete_url
+ redirect_to(complete_full_path.to_s) if redirect_to_complete_full_path?
+ end
+
+ def redirect_to_complete_full_path?
+ return unless snippet_is_secret?
+
+ complete_full_path != current_full_path
+ end
+
+ def complete_full_path
+ @complete_full_path ||= begin
+ path = current_full_path.clone
+ secret_query = { SNIPPETS_SECRET_KEYWORD => snippet.secret }
+ path.query = current_url_query_hash.merge(secret_query).to_query
+ path
+ end
+ end
+
+ def current_full_path
+ @current_full_path ||= begin
+ path = URI.parse(current_url.path.chomp('/'))
+ path.query = current_url_query_hash.to_query unless current_url_query_hash.empty?
+ path
+ end
+ end
+
+ def current_url
+ @current_url ||= URI.parse(request.original_url)
+ end
+
+ def current_url_query_hash
+ @current_url_query_hash ||= Rack::Utils.parse_nested_query(current_url.query)
+ end
+end