Commit 8f461ef7 authored by John Jarvis's avatar John Jarvis

Merge branch 'security-48259-private-snippet' into 'master'

[master] Prevent private snippet from being embeddable

See merge request gitlab/gitlabhq!2692
parents c684dd63 ed0d691e
...@@ -75,7 +75,14 @@ class Projects::SnippetsController < Projects::ApplicationController ...@@ -75,7 +75,14 @@ class Projects::SnippetsController < Projects::ApplicationController
format.json do format.json do
render_blob_json(blob) render_blob_json(blob)
end end
format.js { render 'shared/snippets/show'}
format.js do
if @snippet.embeddable?
render 'shared/snippets/show'
else
head :not_found
end
end
end end
end end
......
...@@ -80,7 +80,13 @@ class SnippetsController < ApplicationController ...@@ -80,7 +80,13 @@ class SnippetsController < ApplicationController
render_blob_json(blob) render_blob_json(blob)
end end
format.js { render 'shared/snippets/show' } format.js do
if @snippet.embeddable?
render 'shared/snippets/show'
else
head :not_found
end
end
end end
end end
......
...@@ -130,12 +130,4 @@ module SnippetsHelper ...@@ -130,12 +130,4 @@ module SnippetsHelper
link_to external_snippet_icon('download'), download_url, class: 'btn', target: '_blank', title: 'Download', rel: 'noopener noreferrer' link_to external_snippet_icon('download'), download_url, class: 'btn', target: '_blank', title: 'Download', rel: 'noopener noreferrer'
end end
def public_snippet?
if @snippet.project_id?
can?(nil, :read_project_snippet, @snippet)
else
can?(nil, :read_personal_snippet, @snippet)
end
end
end end
...@@ -175,6 +175,12 @@ class Snippet < ActiveRecord::Base ...@@ -175,6 +175,12 @@ class Snippet < ActiveRecord::Base
:visibility_level :visibility_level
end end
def embeddable?
ability = project_id? ? :read_project_snippet : :read_personal_snippet
Ability.allowed?(nil, ability, self)
end
def notes_with_associations def notes_with_associations
notes.includes(:author) notes.includes(:author)
end end
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
- if @snippet.updated_at != @snippet.created_at - if @snippet.updated_at != @snippet.created_at
= edited_time_ago_with_tooltip(@snippet, placement: 'bottom', html_class: 'snippet-edited-ago', exclude_author: true) = edited_time_ago_with_tooltip(@snippet, placement: 'bottom', html_class: 'snippet-edited-ago', exclude_author: true)
- if public_snippet? - if @snippet.embeddable?
.embed-snippet .embed-snippet
.input-group .input-group
.input-group-prepend .input-group-prepend
......
---
title: Prevent private snippets from being embeddable
merge_request:
author:
type: security
...@@ -379,6 +379,46 @@ describe Projects::SnippetsController do ...@@ -379,6 +379,46 @@ describe Projects::SnippetsController do
end end
end end
describe "GET #show for embeddable content" do
let(:project_snippet) { create(:project_snippet, snippet_permission, project: project, author: user) }
before do
sign_in(user)
get :show, namespace_id: project.namespace, project_id: project, id: project_snippet.to_param, format: :js
end
context 'when snippet is private' do
let(:snippet_permission) { :private }
it 'responds with status 404' do
expect(response).to have_gitlab_http_status(404)
end
end
context 'when snippet is public' do
let(:snippet_permission) { :public }
it 'responds with status 200' do
expect(assigns(:snippet)).to eq(project_snippet)
expect(response).to have_gitlab_http_status(200)
end
end
context 'when the project is private' do
let(:project) { create(:project_empty_repo, :private) }
context 'when snippet is public' do
let(:project_snippet) { create(:project_snippet, :public, project: project, author: user) }
it 'responds with status 404' do
expect(assigns(:snippet)).to eq(project_snippet)
expect(response).to have_gitlab_http_status(404)
end
end
end
end
describe 'GET #raw' do describe 'GET #raw' do
let(:project_snippet) do let(:project_snippet) do
create( create(
......
...@@ -80,6 +80,12 @@ describe SnippetsController do ...@@ -80,6 +80,12 @@ describe SnippetsController do
expect(assigns(:snippet)).to eq(personal_snippet) expect(assigns(:snippet)).to eq(personal_snippet)
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
end end
it 'responds with status 404 when embeddable content is requested' do
get :show, id: personal_snippet.to_param, format: :js
expect(response).to have_gitlab_http_status(404)
end
end end
end end
...@@ -106,6 +112,12 @@ describe SnippetsController do ...@@ -106,6 +112,12 @@ describe SnippetsController do
expect(assigns(:snippet)).to eq(personal_snippet) expect(assigns(:snippet)).to eq(personal_snippet)
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
end end
it 'responds with status 404 when embeddable content is requested' do
get :show, id: personal_snippet.to_param, format: :js
expect(response).to have_gitlab_http_status(404)
end
end end
context 'when not signed in' do context 'when not signed in' do
...@@ -131,6 +143,13 @@ describe SnippetsController do ...@@ -131,6 +143,13 @@ describe SnippetsController do
expect(assigns(:snippet)).to eq(personal_snippet) expect(assigns(:snippet)).to eq(personal_snippet)
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
end end
it 'responds with status 200 when embeddable content is requested' do
get :show, id: personal_snippet.to_param, format: :js
expect(assigns(:snippet)).to eq(personal_snippet)
expect(response).to have_gitlab_http_status(200)
end
end end
context 'when not signed in' do context 'when not signed in' do
......
...@@ -423,4 +423,41 @@ describe Snippet do ...@@ -423,4 +423,41 @@ describe Snippet do
expect(blob.data).to eq(snippet.content) expect(blob.data).to eq(snippet.content)
end end
end end
describe '#embeddable?' do
context 'project snippet' do
[
{ project: :public, snippet: :public, embeddable: true },
{ project: :internal, snippet: :public, embeddable: false },
{ project: :private, snippet: :public, embeddable: false },
{ project: :public, snippet: :internal, embeddable: false },
{ project: :internal, snippet: :internal, embeddable: false },
{ project: :private, snippet: :internal, embeddable: false },
{ project: :public, snippet: :private, embeddable: false },
{ project: :internal, snippet: :private, embeddable: false },
{ project: :private, snippet: :private, embeddable: false }
].each do |combination|
it 'only returns true when both project and snippet are public' do
project = create(:project, combination[:project])
snippet = create(:project_snippet, combination[:snippet], project: project)
expect(snippet.embeddable?).to eq(combination[:embeddable])
end
end
end
context 'personal snippet' do
[
{ snippet: :public, embeddable: true },
{ snippet: :internal, embeddable: false },
{ snippet: :private, embeddable: false }
].each do |combination|
it 'only returns true when snippet is public' do
snippet = create(:personal_snippet, combination[:snippet])
expect(snippet.embeddable?).to eq(combination[:embeddable])
end
end
end
end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment