Commit 69c5cdd9 authored by Vasilii Iakliushin's avatar Vasilii Iakliushin Committed by James Lopez

Add validations and errors handling for SSE

Contributes to https://gitlab.com/gitlab-org/gitlab/-/issues/212558

* Add permissions check for user role
* Add validations
* Expose `is_supported_content` boolean field to frontend.

`is_supported_content` shows if there are no validation errors
detected by backend.

Validation error messages are not used for now. Frontend will show a
general error message for all validation failures.
parent 848b77fd
...@@ -2,10 +2,13 @@ ...@@ -2,10 +2,13 @@
class Projects::StaticSiteEditorController < Projects::ApplicationController class Projects::StaticSiteEditorController < Projects::ApplicationController
include ExtractsPath include ExtractsPath
include CreatesCommit
layout 'fullscreen' layout 'fullscreen'
prepend_before_action :authenticate_user!, only: [:show] prepend_before_action :authenticate_user!, only: [:show]
before_action :assign_ref_and_path, only: [:show] before_action :assign_ref_and_path, only: [:show]
before_action :authorize_edit_tree!, only: [:show]
def show def show
@config = Gitlab::StaticSiteEditor::Config.new(@repository, @ref, @path, params[:return_url]) @config = Gitlab::StaticSiteEditor::Config.new(@repository, @ref, @path, params[:return_url])
......
...@@ -3,33 +3,49 @@ ...@@ -3,33 +3,49 @@
module Gitlab module Gitlab
module StaticSiteEditor module StaticSiteEditor
class Config class Config
SUPPORTED_EXTENSIONS = %w[.md].freeze
def initialize(repository, ref, file_path, return_url) def initialize(repository, ref, file_path, return_url)
@repository = repository @repository = repository
@ref = ref @ref = ref
@file_path = file_path @file_path = file_path
@return_url = return_url @return_url = return_url
@commit_id = repository.commit(ref)&.id if ref
end end
def payload def payload
{ {
branch: ref, branch: ref,
path: file_path, path: file_path,
commit: commit.id, commit_id: commit_id,
project_id: project.id, project_id: project.id,
project: project.path, project: project.path,
namespace: project.namespace.path, namespace: project.namespace.path,
return_url: return_url return_url: return_url,
is_supported_content: supported_content?
} }
end end
private private
attr_reader :repository, :ref, :file_path, :return_url attr_reader :repository, :ref, :file_path, :return_url, :commit_id
delegate :project, to: :repository delegate :project, to: :repository
def commit def supported_content?
repository.commit(ref) master_branch? && extension_supported? && file_exists?
end
def master_branch?
ref == 'master'
end
def extension_supported?
File.extname(file_path).in?(SUPPORTED_EXTENSIONS)
end
def file_exists?
commit_id.present? && repository.blob_at(commit_id, file_path).present?
end end
end end
end end
......
...@@ -26,7 +26,21 @@ describe Projects::StaticSiteEditorController do ...@@ -26,7 +26,21 @@ describe Projects::StaticSiteEditorController do
end end
end end
%w[guest developer maintainer].each do |role| context 'as guest' do
let(:user) { create(:user) }
before do
project.add_guest(user)
sign_in(user)
get :show, params: default_params
end
it 'responds with 404 page' do
expect(response).to have_gitlab_http_status(:not_found)
end
end
%w[developer maintainer].each do |role|
context "as #{role}" do context "as #{role}" do
let(:user) { create(:user) } let(:user) { create(:user) }
......
...@@ -18,13 +18,44 @@ describe Gitlab::StaticSiteEditor::Config do ...@@ -18,13 +18,44 @@ describe Gitlab::StaticSiteEditor::Config do
it 'returns data for the frontend component' do it 'returns data for the frontend component' do
is_expected.to eq( is_expected.to eq(
branch: 'master', branch: 'master',
commit: repository.commit.id, commit_id: repository.commit.id,
namespace: 'namespace', namespace: 'namespace',
path: 'README.md', path: 'README.md',
project: 'project', project: 'project',
project_id: project.id, project_id: project.id,
return_url: 'http://example.com' return_url: 'http://example.com',
is_supported_content: true
) )
end end
context 'when branch is not master' do
let(:ref) { 'my-branch' }
it { is_expected.to include(is_supported_content: false) }
end
context 'when file does not have a markdown extension' do
let(:file_path) { 'README.txt' }
it { is_expected.to include(is_supported_content: false) }
end
context 'when file does not have an extension' do
let(:file_path) { 'README' }
it { is_expected.to include(is_supported_content: false) }
end
context 'when file does not exist' do
let(:file_path) { 'UNKNOWN.md' }
it { is_expected.to include(is_supported_content: false) }
end
context 'when repository is empty' do
let(:project) { create(:project_empty_repo) }
it { is_expected.to include(is_supported_content: false) }
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