Commit 3f02e805 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab-ce master

parents c26c8622 5d9e00aa
...@@ -2,19 +2,30 @@ ...@@ -2,19 +2,30 @@
module ErrorTracking module ErrorTracking
class ProjectErrorTrackingSetting < ActiveRecord::Base class ProjectErrorTrackingSetting < ActiveRecord::Base
include Gitlab::Utils::StrongMemoize
include ReactiveCaching include ReactiveCaching
API_URL_PATH_REGEXP = %r{
\A
(?<prefix>/api/0/projects/+)
(?:
(?<organization>[^/]+)/+
(?<project>[^/]+)/*
)?
\z
}x
self.reactive_cache_key = ->(setting) { [setting.class.model_name.singular, setting.project_id] } self.reactive_cache_key = ->(setting) { [setting.class.model_name.singular, setting.project_id] }
belongs_to :project belongs_to :project
validates :api_url, length: { maximum: 255 }, public_url: true, url: { enforce_sanitization: true, ascii_only: true }, allow_nil: true validates :api_url, length: { maximum: 255 }, public_url: true, url: { enforce_sanitization: true, ascii_only: true }, allow_nil: true
validates :api_url, presence: true, if: :enabled validates :api_url, presence: { message: 'is a required field' }, if: :enabled
validate :validate_api_url_path, if: :enabled validate :validate_api_url_path, if: :enabled
validates :token, presence: true, if: :enabled validates :token, presence: { message: 'is a required field' }, if: :enabled
attr_encrypted :token, attr_encrypted :token,
mode: :per_attribute_iv, mode: :per_attribute_iv,
...@@ -23,6 +34,11 @@ module ErrorTracking ...@@ -23,6 +34,11 @@ module ErrorTracking
after_save :clear_reactive_cache! after_save :clear_reactive_cache!
def api_url=(value)
super
clear_memoization(:api_url_slugs)
end
def project_name def project_name
super || project_name_from_slug super || project_name_from_slug
end end
...@@ -102,34 +118,39 @@ module ErrorTracking ...@@ -102,34 +118,39 @@ module ErrorTracking
end end
def project_slug_from_api_url def project_slug_from_api_url
extract_slug(:project) api_url_slug(:project)
end end
def organization_slug_from_api_url def organization_slug_from_api_url
extract_slug(:organization) api_url_slug(:organization)
end
def api_url_slug(capture)
slugs = strong_memoize(:api_url_slugs) { extract_api_url_slugs || {} }
slugs[capture]
end end
def extract_slug(capture) def extract_api_url_slugs
return if api_url.blank? return if api_url.blank?
begin begin
url = Addressable::URI.parse(api_url) url = Addressable::URI.parse(api_url)
rescue Addressable::URI::InvalidURIError rescue Addressable::URI::InvalidURIError
return nil return
end end
@slug_match ||= url.path.match(%r{^/api/0/projects/+(?<organization>[^/]+)/+(?<project>[^/|$]+)}) || {} url.path.match(API_URL_PATH_REGEXP)
@slug_match[capture]
end end
def validate_api_url_path def validate_api_url_path
return if api_url.blank? return if api_url.blank?
begin unless api_url_slug(:prefix)
unless Addressable::URI.parse(api_url).path.starts_with?('/api/0/projects') return errors.add(:api_url, 'is invalid')
errors.add(:api_url, 'path needs to start with /api/0/projects')
end end
rescue Addressable::URI::InvalidURIError
unless api_url_slug(:organization)
errors.add(:project, 'is a required field')
end end
end end
end end
......
...@@ -28,8 +28,8 @@ module ErrorTracking ...@@ -28,8 +28,8 @@ module ErrorTracking
(project.error_tracking_setting || project.build_error_tracking_setting).tap do |setting| (project.error_tracking_setting || project.build_error_tracking_setting).tap do |setting|
setting.api_url = ErrorTracking::ProjectErrorTrackingSetting.build_api_url_from( setting.api_url = ErrorTracking::ProjectErrorTrackingSetting.build_api_url_from(
api_host: params[:api_host], api_host: params[:api_host],
organization_slug: nil, organization_slug: 'org',
project_slug: nil project_slug: 'proj'
) )
setting.token = params[:token] setting.token = params[:token]
......
---
title: Moves EE util into the CE file
merge_request: 25680
author:
type: other
...@@ -10,6 +10,10 @@ en: ...@@ -10,6 +10,10 @@ en:
target: Target issue target: Target issue
group: group:
path: Group URL path: Group URL
project/error_tracking_setting:
token: "Auth Token"
project: "Project"
api_url: "Sentry API URL"
errors: errors:
messages: messages:
label_already_exists_at_group_level: "already exists at group level for %{group}. Please choose another one." label_already_exists_at_group_level: "already exists at group level for %{group}. Please choose another one."
......
...@@ -62,11 +62,32 @@ describe ErrorTracking::ProjectErrorTrackingSetting do ...@@ -62,11 +62,32 @@ describe ErrorTracking::ProjectErrorTrackingSetting do
end end
context 'URL path' do context 'URL path' do
it 'fails validation with wrong path' do it 'fails validation without api/0/projects' do
subject.api_url = 'http://gitlab.com/project1/something' subject.api_url = 'http://gitlab.com/project1/something'
expect(subject).not_to be_valid expect(subject).not_to be_valid
expect(subject.errors.messages[:api_url]).to include('path needs to start with /api/0/projects') expect(subject.errors.messages[:api_url]).to include('is invalid')
end
it 'fails validation without org and project slugs' do
subject.api_url = 'http://gitlab.com/api/0/projects/'
expect(subject).not_to be_valid
expect(subject.errors.messages[:project]).to include('is a required field')
end
it 'fails validation when api_url has extra parts' do
subject.api_url = 'http://gitlab.com/api/0/projects/org/proj/something'
expect(subject).not_to be_valid
expect(subject.errors.messages[:api_url]).to include("is invalid")
end
it 'fails validation when api_url has less parts' do
subject.api_url = 'http://gitlab.com/api/0/projects/org'
expect(subject).not_to be_valid
expect(subject.errors.messages[:api_url]).to include("is invalid")
end end
it 'passes validation with correct path' do it 'passes validation with correct path' do
......
...@@ -32,7 +32,7 @@ describe ErrorTracking::ListProjectsService do ...@@ -32,7 +32,7 @@ describe ErrorTracking::ListProjectsService do
end end
context 'set model attributes to new values' do context 'set model attributes to new values' do
let(:new_api_url) { new_api_host + 'api/0/projects/' } let(:new_api_url) { new_api_host + 'api/0/projects/org/proj/' }
before do before do
expect(error_tracking_setting).to receive(:list_sentry_projects) expect(error_tracking_setting).to receive(:list_sentry_projects)
...@@ -121,7 +121,7 @@ describe ErrorTracking::ListProjectsService do ...@@ -121,7 +121,7 @@ describe ErrorTracking::ListProjectsService do
context 'error_tracking_setting is nil' do context 'error_tracking_setting is nil' do
let(:error_tracking_setting) { build(:project_error_tracking_setting) } let(:error_tracking_setting) { build(:project_error_tracking_setting) }
let(:new_api_url) { new_api_host + 'api/0/projects/' } let(:new_api_url) { new_api_host + 'api/0/projects/org/proj/' }
before do before do
expect(project).to receive(:build_error_tracking_setting).once expect(project).to receive(:build_error_tracking_setting).once
......
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