GitLab wurde aktualisiert. Dank regelmäßiger Updates bleibt das THM GitLab sicher und Sie profitieren von den neuesten Funktionen. Vielen Dank für Ihre Geduld.

Commit 928fc94c authored by Vinnie Okada's avatar Vinnie Okada
Browse files

Enforce restricted visibilities for snippets

Add new service classes to create and update project and personal
snippets.  These classes are responsible for enforcing restricted
visibility settings for non-admin users.
parent 285c5341
......@@ -28,26 +28,22 @@ def new
end
def create
@snippet = @project.snippets.build(snippet_params)
@snippet.author = current_user
if @snippet.save
redirect_to namespace_project_snippet_path(@project.namespace, @project,
@snippet)
else
respond_with(@snippet)
end
@snippet = CreateSnippetService.new(@project, current_user,
snippet_params).execute
respond_with(@snippet,
location: namespace_project_snippet_path(@project.namespace,
@project, @snippet))
end
def edit
end
def update
if @snippet.update_attributes(snippet_params)
redirect_to namespace_project_snippet_path(@project.namespace, @project, @snippet)
else
respond_with(@snippet)
end
UpdateSnippetService.new(project, current_user, @snippet,
snippet_params).execute
respond_with(@snippet,
location: namespace_project_snippet_path(@project.namespace,
@project, @snippet))
end
def show
......
......@@ -42,25 +42,19 @@ def new
end
def create
@snippet = PersonalSnippet.new(snippet_params)
@snippet.author = current_user
@snippet = CreateSnippetService.new(nil, current_user,
snippet_params).execute
if @snippet.save
redirect_to snippet_path(@snippet)
else
respond_with @snippet
end
respond_with @snippet.becomes(Snippet)
end
def edit
end
def update
if @snippet.update_attributes(snippet_params)
redirect_to snippet_path(@snippet)
else
respond_with @snippet
end
UpdateSnippetService.new(nil, current_user, @snippet,
snippet_params).execute
respond_with @snippet.becomes(Snippet)
end
def show
......
......@@ -45,7 +45,8 @@ def merge_request_url(entity, *args)
namespace_project_merge_request_url(entity.project.namespace, entity.project, entity, *args)
end
def snippet_url(entity, *args)
def project_snippet_url(entity, *args)
namespace_project_snippet_url(entity.project.namespace, entity.project, entity, *args)
end
end
......@@ -31,6 +31,21 @@ def system_hook_service
SystemHooksService.new
end
# Add an error to the specified model for restricted visibility levels
def deny_visibility_level(model, denied_visibility_level = nil)
denied_visibility_level ||= model.visibility_level
level_name = 'Unknown'
Gitlab::VisibilityLevel.options.each do |name, level|
level_name = name if level == denied_visibility_level
end
model.errors.add(
:visibility_level,
"#{level_name} visibility has been restricted by your GitLab administrator"
)
end
private
def error(message, http_status = nil)
......
class CreateSnippetService < BaseService
def execute
if project.nil?
snippet = PersonalSnippet.new(params)
else
snippet = project.snippets.build(params)
end
unless Gitlab::VisibilityLevel.allowed_for?(current_user,
params[:visibility_level])
deny_visibility_level(snippet)
return snippet
end
snippet.author = current_user
snippet.save
snippet
end
end
module Projects
class BaseService < ::BaseService
# Add an error to the project for restricted visibility levels
def deny_visibility_level(project, denied_visibility_level = nil)
denied_visibility_level ||= project.visibility_level
level_name = 'Unknown'
Gitlab::VisibilityLevel.options.each do |name, level|
level_name = name if level == denied_visibility_level
end
project.errors.add(
:visibility_level,
"#{level_name} visibility has been restricted by your GitLab administrator"
)
end
end
end
module Projects
class CreateService < Projects::BaseService
class CreateService < BaseService
def initialize(user, params)
@current_user, @params = user, params.dup
end
......
module Projects
class UpdateService < Projects::BaseService
class UpdateService < BaseService
def execute
# check that user is allowed to set specified visibility_level
new_visibility = params[:visibility_level]
......
class UpdateSnippetService < BaseService
attr_accessor :snippet
def initialize(project = nil, user, snippet, params = {})
def initialize(project, user, snippet, params)
super(project, user, params)
@snippet = snippet
end
......@@ -9,10 +9,10 @@ def initialize(project = nil, user, snippet, params = {})
def execute
# check that user is allowed to set specified visibility_level
new_visibility = params[:visibility_level]
if new_visibility && new_visibility != snippet.visibility_level
if new_visibility && new_visibility.to_i != snippet.visibility_level
unless can?(current_user, :change_visibility_level, snippet) &&
Gitlab::VisibilityLevel.allowed_for?(current_user, new_visibility)
deny_visibility_level(snippet, new_visibility_level)
deny_visibility_level(snippet, new_visibility)
return snippet
end
end
......
......@@ -42,18 +42,19 @@ def handle_project_member_errors(errors)
# title (required) - The title of a snippet
# file_name (required) - The name of a snippet file
# code (required) - The content of a snippet
# visibility_level (required) - The snippet's visibility
# Example Request:
# POST /projects/:id/snippets
post ":id/snippets" do
authorize! :write_project_snippet, user_project
required_attributes! [:title, :file_name, :code]
required_attributes! [:title, :file_name, :code, :visibility_level]
attrs = attributes_for_keys [:title, :file_name]
attrs = attributes_for_keys [:title, :file_name, :visibility_level]
attrs[:content] = params[:code] if params[:code].present?
@snippet = user_project.snippets.new attrs
@snippet.author = current_user
@snippet = CreateSnippetservice.new(user_project, current_user,
attrs).execute
if @snippet.save
if @snippet.saved?
present @snippet, with: Entities::ProjectSnippet
else
render_validation_error!(@snippet)
......@@ -68,19 +69,22 @@ def handle_project_member_errors(errors)
# title (optional) - The title of a snippet
# file_name (optional) - The name of a snippet file
# code (optional) - The content of a snippet
# visibility_level (optional) - The snippet's visibility
# Example Request:
# PUT /projects/:id/snippets/:snippet_id
put ":id/snippets/:snippet_id" do
@snippet = user_project.snippets.find(params[:snippet_id])
authorize! :modify_project_snippet, @snippet
attrs = attributes_for_keys [:title, :file_name]
attrs = attributes_for_keys [:title, :file_name, :visibility_level]
attrs[:content] = params[:code] if params[:code].present?
if @snippet.update_attributes attrs
present @snippet, with: Entities::ProjectSnippet
else
UpdateSnippetService.new(user_project, current_user, @snippet,
attrs).execute
if @snippet.errors.any?
render_validation_error!(@snippet)
else
present @snippet, with: Entities::ProjectSnippet
end
end
......
......@@ -51,9 +51,9 @@ def build_note_url(id)
anchor: "note_#{note.id}")
elsif note.for_project_snippet?
snippet = Snippet.find(note.noteable_id)
snippet_url(snippet,
host: Gitlab.config.gitlab['url'],
anchor: "note_#{note.id}")
project_snippet_url(snippet,
host: Gitlab.config.gitlab['url'],
anchor: "note_#{note.id}")
end
end
end
......
......@@ -425,7 +425,8 @@
describe 'POST /projects/:id/snippets' do
it 'should create a new project snippet' do
post api("/projects/#{project.id}/snippets", user),
title: 'api test', file_name: 'sample.rb', code: 'test'
title: 'api test', file_name: 'sample.rb', code: 'test',
visibility_level: '0'
expect(response.status).to eq(201)
expect(json_response['title']).to eq('api test')
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