Commit 4621fa2b authored by Sean McGivern's avatar Sean McGivern Committed by Lin Jen-Shin

Merge branch 'snippets_visibility' into 'security'

Fix snippets visibility for show action - external users can not see internal snippets

See merge request !2087
parent ecbd9da8
......@@ -90,20 +90,20 @@ class SnippetsController < ApplicationController
protected
def snippet
@snippet ||= if current_user
PersonalSnippet.where("author_id = ? OR visibility_level IN (?)",
current_user.id,
[Snippet::PUBLIC, Snippet::INTERNAL]).
find(params[:id])
else
PersonalSnippet.find(params[:id])
end
@snippet ||= PersonalSnippet.find_by(id: params[:id])
end
alias_method :awardable, :snippet
alias_method :spammable, :snippet
def authorize_read_snippet!
authenticate_user! unless can?(current_user, :read_personal_snippet, @snippet)
return if can?(current_user, :read_personal_snippet, @snippet)
if current_user
render_404
else
authenticate_user!
end
end
def authorize_update_snippet!
......
---
title: Fix snippets visibility for show action - external users can not see internal snippets
merge_request:
author:
......@@ -25,119 +25,6 @@ describe SnippetsController do
end
end
describe 'GET #show' do
context 'when the personal snippet is private' do
let(:personal_snippet) { create(:personal_snippet, :private, author: user) }
context 'when signed in' do
before do
sign_in(user)
end
context 'when signed in user is not the author' do
let(:other_author) { create(:author) }
let(:other_personal_snippet) { create(:personal_snippet, :private, author: other_author) }
it 'responds with status 404' do
get :show, id: other_personal_snippet.to_param
expect(response).to have_http_status(404)
end
end
context 'when signed in user is the author' do
it 'renders the snippet' do
get :show, id: personal_snippet.to_param
expect(assigns(:snippet)).to eq(personal_snippet)
expect(response).to have_http_status(200)
end
end
end
context 'when not signed in' do
it 'redirects to the sign in page' do
get :show, id: personal_snippet.to_param
expect(response).to redirect_to(new_user_session_path)
end
end
end
context 'when the personal snippet is internal' do
let(:personal_snippet) { create(:personal_snippet, :internal, author: user) }
context 'when signed in' do
before do
sign_in(user)
end
it 'renders the snippet' do
get :show, id: personal_snippet.to_param
expect(assigns(:snippet)).to eq(personal_snippet)
expect(response).to have_http_status(200)
end
end
context 'when not signed in' do
it 'redirects to the sign in page' do
get :show, id: personal_snippet.to_param
expect(response).to redirect_to(new_user_session_path)
end
end
end
context 'when the personal snippet is public' do
let(:personal_snippet) { create(:personal_snippet, :public, author: user) }
context 'when signed in' do
before do
sign_in(user)
end
it 'renders the snippet' do
get :show, id: personal_snippet.to_param
expect(assigns(:snippet)).to eq(personal_snippet)
expect(response).to have_http_status(200)
end
end
context 'when not signed in' do
it 'renders the snippet' do
get :show, id: personal_snippet.to_param
expect(assigns(:snippet)).to eq(personal_snippet)
expect(response).to have_http_status(200)
end
end
end
context 'when the personal snippet does not exist' do
context 'when signed in' do
before do
sign_in(user)
end
it 'responds with status 404' do
get :show, id: 'doesntexist'
expect(response).to have_http_status(404)
end
end
context 'when not signed in' do
it 'responds with status 404' do
get :show, id: 'doesntexist'
expect(response).to have_http_status(404)
end
end
end
end
describe 'POST #create' do
def create_snippet(snippet_params = {}, additional_params = {})
sign_in(user)
......@@ -350,131 +237,181 @@ describe SnippetsController do
end
end
%w(raw download).each do |action|
describe "GET #{action}" do
context 'when the personal snippet is private' do
let(:personal_snippet) { create(:personal_snippet, :private, author: user) }
shared_examples "line endings" do |action|
context 'CRLF line ending' do
let(:personal_snippet) do
create(:personal_snippet, :public, author: user, content: "first line\r\nsecond line\r\nthird line")
end
context 'when signed in' do
before do
sign_in(user)
end
it 'returns LF line endings by default' do
get action, id: personal_snippet.to_param
context 'when signed in user is not the author' do
let(:other_author) { create(:author) }
let(:other_personal_snippet) { create(:personal_snippet, :private, author: other_author) }
expect(response.body).to eq("first line\nsecond line\nthird line")
end
it 'responds with status 404' do
get action, id: other_personal_snippet.to_param
it 'does not convert line endings when parameter present' do
get action, id: personal_snippet.to_param, line_ending: :raw
expect(response).to have_http_status(404)
end
expect(response.body).to eq("first line\r\nsecond line\r\nthird line")
end
end
end
shared_examples 'snippet response' do |action|
context 'when the personal snippet is private' do
let(:personal_snippet) { create(:personal_snippet, :private, author: user) }
context 'when signed in' do
before do
sign_in(user)
end
context 'when signed in user is not the author' do
let(:other_author) { create(:author) }
let(:other_personal_snippet) { create(:personal_snippet, :private, author: other_author) }
it 'responds with status 404' do
get action, id: other_personal_snippet.to_param
expect(response).to have_http_status(404)
end
end
context 'when signed in user is the author' do
before { get action, id: personal_snippet.to_param }
context 'when signed in user is the author' do
before { get action, id: personal_snippet.to_param }
it 'responds with status 200' do
expect(assigns(:snippet)).to eq(personal_snippet)
expect(response).to have_http_status(200)
end
it 'responds with status 200' do
expect(assigns(:snippet)).to eq(personal_snippet)
expect(response).to have_http_status(200)
end
it 'has expected headers' do
it 'has expected headers' do
if action == :show
expect(response.header['Content-Type']).to eq('text/html; charset=utf-8')
else
expect(response.header['Content-Type']).to eq('text/plain; charset=utf-8')
end
if action == :download
expect(response.header['Content-Disposition']).to match(/attachment/)
elsif action == :raw
expect(response.header['Content-Disposition']).to match(/inline/)
end
if action == :download
expect(response.header['Content-Disposition']).to match(/attachment/)
elsif action == :raw
expect(response.header['Content-Disposition']).to match(/inline/)
end
end
end
end
context 'when not signed in' do
it 'redirects to the sign in page' do
get action, id: personal_snippet.to_param
context 'when not signed in' do
it 'redirects to the sign in page' do
get action, id: personal_snippet.to_param
expect(response).to redirect_to(new_user_session_path)
end
expect(response).to redirect_to(new_user_session_path)
end
end
end
context 'when the personal snippet is internal' do
let(:personal_snippet) { create(:personal_snippet, :internal, author: user) }
context 'when the personal snippet is internal' do
let(:personal_snippet) { create(:personal_snippet, :internal, author: user) }
context 'when signed in' do
before do
sign_in(user)
end
context 'when signed in' do
before do
sign_in(user)
end
it 'responds with status 200' do
get action, id: personal_snippet.to_param
it 'responds with status 200' do
get action, id: personal_snippet.to_param
expect(assigns(:snippet)).to eq(personal_snippet)
expect(response).to have_http_status(200)
end
expect(assigns(:snippet)).to eq(personal_snippet)
expect(response).to have_http_status(200)
end
end
context 'when not signed in' do
it 'redirects to the sign in page' do
get action, id: personal_snippet.to_param
context 'when not signed in' do
it 'redirects to the sign in page' do
get action, id: personal_snippet.to_param
expect(response).to redirect_to(new_user_session_path)
end
expect(response).to redirect_to(new_user_session_path)
end
end
context 'when the personal snippet is public' do
let(:personal_snippet) { create(:personal_snippet, :public, author: user) }
context 'when signed in as an external user' do
let(:external_user) { create(:user, external: true) }
context 'when signed in' do
before do
sign_in(user)
end
before do
sign_in(external_user)
end
it 'responds with status 200' do
get action, id: personal_snippet.to_param
it 'responds with status 404' do
get :show, id: personal_snippet.to_param
expect(assigns(:snippet)).to eq(personal_snippet)
expect(response).to have_http_status(200)
end
expect(response).to have_http_status(404)
end
end
end
context 'when not signed in' do
it 'responds with status 200' do
get action, id: personal_snippet.to_param
context 'when the personal snippet is public' do
let(:personal_snippet) { create(:personal_snippet, :public, author: user) }
expect(assigns(:snippet)).to eq(personal_snippet)
expect(response).to have_http_status(200)
end
context 'when signed in' do
before do
sign_in(user)
end
it 'responds with status 200' do
get action, id: personal_snippet.to_param
expect(assigns(:snippet)).to eq(personal_snippet)
expect(response).to have_http_status(200)
end
end
context 'when the personal snippet does not exist' do
context 'when signed in' do
before do
sign_in(user)
end
context 'when not signed in' do
it 'responds with status 200' do
get action, id: personal_snippet.to_param
it 'responds with status 404' do
get action, id: 'doesntexist'
expect(assigns(:snippet)).to eq(personal_snippet)
expect(response).to have_http_status(200)
end
end
end
expect(response).to have_http_status(404)
end
context 'when the personal snippet does not exist' do
context 'when signed in' do
before do
sign_in(user)
end
context 'when not signed in' do
it 'responds with status 404' do
get action, id: 'doesntexist'
it 'responds with status 404' do
get action, id: 'doesntexist'
expect(response).to have_http_status(404)
end
expect(response).to have_http_status(404)
end
end
context 'when not signed in' do
it 'redirects to the sign in page' do
get action, id: 'doesntexist'
expect(response).to redirect_to(new_user_session_path)
end
end
end
end
describe "GET #raw" do
include_examples 'line endings', :raw
include_examples 'snippet response', :raw
end
describe "GET #download" do
include_examples 'line endings', :download
include_examples 'snippet response', :download
end
describe "GET #show" do
include_examples 'snippet response', :show
end
context 'award emoji on snippets' do
let(:personal_snippet) { create(:personal_snippet, :public, author: user) }
let(:another_user) { create(:user) }
......
require 'rails_helper'
feature 'Internal Snippets', feature: true do
let(:internal_snippet) { create(:personal_snippet, :internal) }
describe 'normal user' do
before do
login_as :user
end
scenario 'sees internal snippets' do
visit snippet_path(internal_snippet)
expect(page).to have_content(internal_snippet.content)
end
scenario 'sees raw internal snippets' do
visit raw_snippet_path(internal_snippet)
expect(page).to have_content(internal_snippet.content)
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