From 4d2f36118a3b21b6bb4ee702b98d032967ba463a Mon Sep 17 00:00:00 2001 From: Joel Koglin Date: Tue, 21 Jul 2015 14:03:26 -0700 Subject: Issue #993: Fixed login failure when extern_uid changes --- lib/gitlab/ldap/user.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/ldap/user.rb b/lib/gitlab/ldap/user.rb index f7f3ba9ad7d..2ffb1241966 100644 --- a/lib/gitlab/ldap/user.rb +++ b/lib/gitlab/ldap/user.rb @@ -44,9 +44,13 @@ module Gitlab gl_user.skip_reconfirmation! gl_user.email = auth_hash.email - # Build new identity only if we dont have have same one - gl_user.identities.find_or_initialize_by(provider: auth_hash.provider, - extern_uid: auth_hash.uid) + # If we don't have an identity for this provider yet, create one + if gl_user.identities.find_by(provider: auth_hash.provider).nil? + gl_user.identities.new(extern_uid: auth_hash.uid, provider: auth_hash.provider) + else # Update the UID attribute for this provider in case it has changed + identity = gl_user.identities.select { |identity| identity.provider == auth_hash.provider } + identity.first.extern_uid = auth_hash.uid + end gl_user end -- cgit v1.2.1 From 4344b8d2d4367b19c6849c3cab0d02d17ddf2304 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Tue, 25 Aug 2015 14:31:33 -0700 Subject: Add Gitlab::ColorSchemes module Very similar to Gitlab::Theme, this contains all of the definitions for our syntax highlighting schemes. --- lib/gitlab/color_schemes.rb | 62 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 lib/gitlab/color_schemes.rb (limited to 'lib') diff --git a/lib/gitlab/color_schemes.rb b/lib/gitlab/color_schemes.rb new file mode 100644 index 00000000000..763853ab1cb --- /dev/null +++ b/lib/gitlab/color_schemes.rb @@ -0,0 +1,62 @@ +module Gitlab + # Module containing GitLab's syntax color scheme definitions and helper + # methods for accessing them. + module ColorSchemes + # Struct class representing a single Scheme + Scheme = Struct.new(:id, :name, :css_class) + + SCHEMES = [ + Scheme.new(1, 'White', 'white'), + Scheme.new(2, 'Dark', 'dark'), + Scheme.new(3, 'Solarized Light', 'solarized-light'), + Scheme.new(4, 'Solarized Dark', 'solarized-dark'), + Scheme.new(5, 'Monokai', 'monokai') + ].freeze + + # Convenience method to get a space-separated String of all the color scheme + # classes that might be applied to a code block. + # + # Returns a String + def self.body_classes + SCHEMES.collect(&:css_class).uniq.join(' ') + end + + # Get a Scheme by its ID + # + # If the ID is invalid, returns the default Scheme. + # + # id - Integer ID + # + # Returns a Scheme + def self.by_id(id) + SCHEMES.detect { |s| s.id == id } || default + end + + # Get the default Scheme + # + # Returns a Scheme + def self.default + by_id(1) + end + + # Iterate through each Scheme + # + # Yields the Scheme object + def self.each(&block) + SCHEMES.each(&block) + end + + # Get the Scheme for the specified user, or the default + # + # user - User record + # + # Returns a Scheme + def self.for_user(user) + if user + by_id(user.color_scheme_id) + else + default + end + end + end +end -- cgit v1.2.1 From 2c3e42e4a44e2f40e521cbafc8144e5d7c366b76 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Tue, 25 Aug 2015 15:24:53 -0700 Subject: Remove user_color_scheme_class Instead of rendering this value server-side, we use Javascript and Gon to apply the user's color scheme (or the default) to any syntax highlighted code blocks. This will make it easier to cache these blocks in the future because they're no longer state-dependent. --- lib/redcarpet/render/gitlab_html.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/redcarpet/render/gitlab_html.rb b/lib/redcarpet/render/gitlab_html.rb index f57b56cbdf0..9cb8e91d6e3 100644 --- a/lib/redcarpet/render/gitlab_html.rb +++ b/lib/redcarpet/render/gitlab_html.rb @@ -4,9 +4,8 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML attr_reader :template alias_method :h, :template - def initialize(template, color_scheme, options = {}) + def initialize(template, options = {}) @template = template - @color_scheme = color_scheme @options = options.dup @options.reverse_merge!( @@ -35,7 +34,7 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML end formatter = Rouge::Formatters::HTMLGitlab.new( - cssclass: "code highlight #{@color_scheme} #{lexer.tag}" + cssclass: "code highlight js-syntax-highlight #{lexer.tag}" ) formatter.format(lexer.lex(code)) end -- cgit v1.2.1 From 6d43308b5a5ff7663e1782fd6f5493f48c0f7e2a Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Wed, 26 Aug 2015 11:30:11 -0700 Subject: Add `Gitlab::Themes.for_user` --- lib/gitlab/themes.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'lib') diff --git a/lib/gitlab/themes.rb b/lib/gitlab/themes.rb index 5209df92795..37a36b9599b 100644 --- a/lib/gitlab/themes.rb +++ b/lib/gitlab/themes.rb @@ -51,6 +51,19 @@ module Gitlab THEMES.each(&block) end + # Get the Theme for the specified user, or the default + # + # user - User record + # + # Returns a Theme + def self.for_user(user) + if user + by_id(user.theme_id) + else + default + end + end + private def self.default_id -- cgit v1.2.1 From 2d72efcd9fb63f4bb0c6aed5a472a2eca2d6abac Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Wed, 26 Aug 2015 11:30:38 -0700 Subject: Add `count` to Themes and ColorSchemes --- lib/gitlab/color_schemes.rb | 5 +++++ lib/gitlab/themes.rb | 5 +++++ 2 files changed, 10 insertions(+) (limited to 'lib') diff --git a/lib/gitlab/color_schemes.rb b/lib/gitlab/color_schemes.rb index 763853ab1cb..9c4664df903 100644 --- a/lib/gitlab/color_schemes.rb +++ b/lib/gitlab/color_schemes.rb @@ -32,6 +32,11 @@ module Gitlab SCHEMES.detect { |s| s.id == id } || default end + # Returns the number of defined Schemes + def self.count + SCHEMES.size + end + # Get the default Scheme # # Returns a Scheme diff --git a/lib/gitlab/themes.rb b/lib/gitlab/themes.rb index 37a36b9599b..83f91de810c 100644 --- a/lib/gitlab/themes.rb +++ b/lib/gitlab/themes.rb @@ -37,6 +37,11 @@ module Gitlab THEMES.detect { |t| t.id == id } || default end + # Returns the number of defined Themes + def self.count + THEMES.size + end + # Get the default Theme # # Returns a Theme -- cgit v1.2.1 From 4340dd3eeb6fdda83b729c16cba29239b8ed9f43 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 27 Aug 2015 13:09:01 -0700 Subject: Decouple Gitlab::Markdown from the GitlabMarkdownHelper This module is now the sole source of knowledge for *how* we render Markdown (and GFM). --- lib/gitlab/markdown.rb | 62 ++++++++++++++++++++++---- lib/gitlab/markdown/syntax_highlight_filter.rb | 38 ++++++++++++++++ lib/gitlab/reference_extractor.rb | 8 +--- lib/redcarpet/render/gitlab_html.rb | 45 ------------------- 4 files changed, 94 insertions(+), 59 deletions(-) create mode 100644 lib/gitlab/markdown/syntax_highlight_filter.rb delete mode 100644 lib/redcarpet/render/gitlab_html.rb (limited to 'lib') diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb index 9f6e19a09fd..de1da31a390 100644 --- a/lib/gitlab/markdown.rb +++ b/lib/gitlab/markdown.rb @@ -5,6 +5,44 @@ module Gitlab # # See the files in `lib/gitlab/markdown/` for specific processing information. module Markdown + # https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use + REDCARPET_OPTIONS = { + no_intra_emphasis: true, + tables: true, + fenced_code_blocks: true, + strikethrough: true, + lax_spacing: true, + space_after_headers: true, + superscript: true, + footnotes: true + }.freeze + + # Convert a Markdown String into an HTML-safe String of HTML + # + # markdown - Markdown String + # context - Hash of context options passed to our HTML Pipeline + # + # Returns an HTML-safe String + def self.render(markdown, context = {}) + html = renderer.render(markdown) + html = gfm(html, context) + + html.html_safe + end + + # Convert a Markdown String into HTML without going through the HTML + # Pipeline. + # + # Note that because the pipeline is skipped, SanitizationFilter is as well. + # Do not output the result of this method to the user. + # + # markdown - Markdown String + # + # Returns a String + def self.render_without_gfm(markdown) + self.renderer.render(markdown) + end + # Provide autoload paths for filters to prevent a circular dependency error autoload :AutolinkFilter, 'gitlab/markdown/autolink_filter' autoload :CommitRangeReferenceFilter, 'gitlab/markdown/commit_range_reference_filter' @@ -18,6 +56,7 @@ module Gitlab autoload :RelativeLinkFilter, 'gitlab/markdown/relative_link_filter' autoload :SanitizationFilter, 'gitlab/markdown/sanitization_filter' autoload :SnippetReferenceFilter, 'gitlab/markdown/snippet_reference_filter' + autoload :SyntaxHighlightFilter, 'gitlab/markdown/syntax_highlight_filter' autoload :TableOfContentsFilter, 'gitlab/markdown/table_of_contents_filter' autoload :TaskListFilter, 'gitlab/markdown/task_list_filter' autoload :UserReferenceFilter, 'gitlab/markdown/user_reference_filter' @@ -29,7 +68,7 @@ module Gitlab # :xhtml - output XHTML instead of HTML # :reference_only_path - Use relative path for reference links # html_options - extra options for the reference links as given to link_to - def gfm(text, options = {}, html_options = {}) + def self.gfm(text, options = {}) return text if text.nil? # Duplicate the string so we don't alter the original, then call to_str @@ -40,8 +79,8 @@ module Gitlab options.reverse_merge!( xhtml: false, reference_only_path: true, - project: @project, - current_user: current_user + project: options[:project], + current_user: options[:current_user] ) @pipeline ||= HTML::Pipeline.new(filters) @@ -61,12 +100,11 @@ module Gitlab current_user: options[:current_user], only_path: options[:reference_only_path], project: options[:project], - reference_class: html_options[:class], # RelativeLinkFilter - ref: @ref, - requested_path: @path, - project_wiki: @project_wiki + ref: options[:ref], + requested_path: options[:path], + project_wiki: options[:project_wiki] } result = @pipeline.call(text, context) @@ -83,14 +121,22 @@ module Gitlab private + def self.renderer + @markdown ||= begin + renderer = Redcarpet::Render::HTML.new + Redcarpet::Markdown.new(renderer, REDCARPET_OPTIONS) + end + end + # Filters used in our pipeline # # SanitizationFilter should come first so that all generated reference HTML # goes through untouched. # # See https://github.com/jch/html-pipeline#filters for more filters. - def filters + def self.filters [ + Gitlab::Markdown::SyntaxHighlightFilter, Gitlab::Markdown::SanitizationFilter, Gitlab::Markdown::RelativeLinkFilter, diff --git a/lib/gitlab/markdown/syntax_highlight_filter.rb b/lib/gitlab/markdown/syntax_highlight_filter.rb new file mode 100644 index 00000000000..9f468f98aeb --- /dev/null +++ b/lib/gitlab/markdown/syntax_highlight_filter.rb @@ -0,0 +1,38 @@ +require 'html/pipeline/filter' +require 'rouge/plugins/redcarpet' + +module Gitlab + module Markdown + # HTML Filter to highlight fenced code blocks + # + class SyntaxHighlightFilter < HTML::Pipeline::Filter + include Rouge::Plugins::Redcarpet + + def call + doc.search('pre > code').each do |node| + highlight_node(node) + end + + doc + end + + def highlight_node(node) + language = node.attr('class') + code = node.text + + highlighted = block_code(code, language) + + # Replace the parent `pre` element with the entire highlighted block + node.parent.replace(highlighted) + end + + private + + # Override Rouge::Plugins::Redcarpet#rouge_formatter + def rouge_formatter(lexer) + Rouge::Formatters::HTMLGitlab.new( + cssclass: "code highlight js-syntax-highlight #{lexer.tag}") + end + end + end +end diff --git a/lib/gitlab/reference_extractor.rb b/lib/gitlab/reference_extractor.rb index e836b05ff25..20f4098057c 100644 --- a/lib/gitlab/reference_extractor.rb +++ b/lib/gitlab/reference_extractor.rb @@ -10,7 +10,7 @@ module Gitlab def analyze(text) references.clear - @text = markdown.render(text.dup) + @text = Gitlab::Markdown.render_without_gfm(text) end %i(user label issue merge_request snippet commit commit_range).each do |type| @@ -21,10 +21,6 @@ module Gitlab private - def markdown - @markdown ||= Redcarpet::Markdown.new(Redcarpet::Render::HTML, GitlabMarkdownHelper::MARKDOWN_OPTIONS) - end - def references @references ||= Hash.new do |references, type| type = type.to_sym @@ -42,7 +38,7 @@ module Gitlab # Returns the results Array for the requested filter type def pipeline_result(filter_type) klass = filter_type.to_s.camelize + 'ReferenceFilter' - filter = "Gitlab::Markdown::#{klass}".constantize + filter = Gitlab::Markdown.const_get(klass) context = { project: project, diff --git a/lib/redcarpet/render/gitlab_html.rb b/lib/redcarpet/render/gitlab_html.rb deleted file mode 100644 index 9cb8e91d6e3..00000000000 --- a/lib/redcarpet/render/gitlab_html.rb +++ /dev/null @@ -1,45 +0,0 @@ -require 'active_support/core_ext/string/output_safety' - -class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML - attr_reader :template - alias_method :h, :template - - def initialize(template, options = {}) - @template = template - @options = options.dup - - @options.reverse_merge!( - # Handled further down the line by Gitlab::Markdown::SanitizationFilter - escape_html: false, - project: @template.instance_variable_get("@project") - ) - - super(options) - end - - def normal_text(text) - ERB::Util.html_escape_once(text) - end - - # Stolen from Rouge::Plugins::Redcarpet as this module is not required - # from Rouge's gem root. - def block_code(code, language) - lexer = Rouge::Lexer.find_fancy(language, code) || Rouge::Lexers::PlainText - - # XXX HACK: Redcarpet strips hard tabs out of code blocks, - # so we assume you're not using leading spaces that aren't tabs, - # and just replace them here. - if lexer.tag == 'make' - code.gsub!(/^ /, "\t") - end - - formatter = Rouge::Formatters::HTMLGitlab.new( - cssclass: "code highlight js-syntax-highlight #{lexer.tag}" - ) - formatter.format(lexer.lex(code)) - end - - def postprocess(full_document) - h.gfm(full_document, @options) - end -end -- cgit v1.2.1 From 8e7111f79de43ea5c8471f3e0bf6ac0c76dd3117 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 27 Aug 2015 15:36:26 -0700 Subject: Reference filters no longer take a custom class context option --- lib/gitlab/markdown.rb | 1 - lib/gitlab/markdown/reference_filter.rb | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb index de1da31a390..7efcbaf3252 100644 --- a/lib/gitlab/markdown.rb +++ b/lib/gitlab/markdown.rb @@ -67,7 +67,6 @@ module Gitlab # options - A Hash of options used to customize output (default: {}): # :xhtml - output XHTML instead of HTML # :reference_only_path - Use relative path for reference links - # html_options - extra options for the reference links as given to link_to def self.gfm(text, options = {}) return text if text.nil? diff --git a/lib/gitlab/markdown/reference_filter.rb b/lib/gitlab/markdown/reference_filter.rb index 47ee1d99da3..3b1dbb3004c 100644 --- a/lib/gitlab/markdown/reference_filter.rb +++ b/lib/gitlab/markdown/reference_filter.rb @@ -9,7 +9,6 @@ module Gitlab # # Context options: # :project (required) - Current project, ignored if reference is cross-project. - # :reference_class - Custom CSS class added to reference links. # :only_path - Generate path-only links. # # Results: @@ -70,7 +69,7 @@ module Gitlab end def reference_class(type) - "gfm gfm-#{type} #{context[:reference_class]}".strip + "gfm gfm-#{type}".strip end # Iterate through the document's text nodes, yielding the current node's -- cgit v1.2.1 From 9bb06ae9effab7bc2ae813539f1253038cb6c221 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 27 Aug 2015 16:02:49 -0700 Subject: Make sure the main Gitlab::Markdown module gets loaded before filters --- lib/gitlab/markdown/autolink_filter.rb | 1 + lib/gitlab/markdown/commit_range_reference_filter.rb | 2 ++ lib/gitlab/markdown/commit_reference_filter.rb | 2 ++ lib/gitlab/markdown/cross_project_reference.rb | 2 ++ lib/gitlab/markdown/emoji_filter.rb | 3 ++- lib/gitlab/markdown/external_issue_reference_filter.rb | 2 ++ lib/gitlab/markdown/external_link_filter.rb | 1 + lib/gitlab/markdown/issue_reference_filter.rb | 2 ++ lib/gitlab/markdown/label_reference_filter.rb | 2 ++ lib/gitlab/markdown/merge_request_reference_filter.rb | 2 ++ lib/gitlab/markdown/reference_filter.rb | 1 + lib/gitlab/markdown/relative_link_filter.rb | 1 + lib/gitlab/markdown/sanitization_filter.rb | 1 + lib/gitlab/markdown/snippet_reference_filter.rb | 2 ++ lib/gitlab/markdown/syntax_highlight_filter.rb | 1 + lib/gitlab/markdown/table_of_contents_filter.rb | 1 + lib/gitlab/markdown/task_list_filter.rb | 1 + lib/gitlab/markdown/user_reference_filter.rb | 2 ++ 18 files changed, 28 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/gitlab/markdown/autolink_filter.rb b/lib/gitlab/markdown/autolink_filter.rb index 541f1d88ffc..c37c3bc55bf 100644 --- a/lib/gitlab/markdown/autolink_filter.rb +++ b/lib/gitlab/markdown/autolink_filter.rb @@ -1,3 +1,4 @@ +require 'gitlab/markdown' require 'html/pipeline/filter' require 'uri' diff --git a/lib/gitlab/markdown/commit_range_reference_filter.rb b/lib/gitlab/markdown/commit_range_reference_filter.rb index a9f1ee9c161..8613150894b 100644 --- a/lib/gitlab/markdown/commit_range_reference_filter.rb +++ b/lib/gitlab/markdown/commit_range_reference_filter.rb @@ -1,3 +1,5 @@ +require 'gitlab/markdown' + module Gitlab module Markdown # HTML filter that replaces commit range references with links. diff --git a/lib/gitlab/markdown/commit_reference_filter.rb b/lib/gitlab/markdown/commit_reference_filter.rb index eacdf8a6d37..5696b4fa585 100644 --- a/lib/gitlab/markdown/commit_reference_filter.rb +++ b/lib/gitlab/markdown/commit_reference_filter.rb @@ -1,3 +1,5 @@ +require 'gitlab/markdown' + module Gitlab module Markdown # HTML filter that replaces commit references with links. diff --git a/lib/gitlab/markdown/cross_project_reference.rb b/lib/gitlab/markdown/cross_project_reference.rb index 66c256c5104..855748fdccc 100644 --- a/lib/gitlab/markdown/cross_project_reference.rb +++ b/lib/gitlab/markdown/cross_project_reference.rb @@ -1,3 +1,5 @@ +require 'gitlab/markdown' + module Gitlab module Markdown # Common methods for ReferenceFilters that support an optional cross-project diff --git a/lib/gitlab/markdown/emoji_filter.rb b/lib/gitlab/markdown/emoji_filter.rb index 6794ab9c897..da10e4d3760 100644 --- a/lib/gitlab/markdown/emoji_filter.rb +++ b/lib/gitlab/markdown/emoji_filter.rb @@ -1,6 +1,7 @@ +require 'action_controller' +require 'gitlab/markdown' require 'gitlab_emoji' require 'html/pipeline/filter' -require 'action_controller' module Gitlab module Markdown diff --git a/lib/gitlab/markdown/external_issue_reference_filter.rb b/lib/gitlab/markdown/external_issue_reference_filter.rb index afd28dd8cf3..f7c43e1ca89 100644 --- a/lib/gitlab/markdown/external_issue_reference_filter.rb +++ b/lib/gitlab/markdown/external_issue_reference_filter.rb @@ -1,3 +1,5 @@ +require 'gitlab/markdown' + module Gitlab module Markdown # HTML filter that replaces external issue tracker references with links. diff --git a/lib/gitlab/markdown/external_link_filter.rb b/lib/gitlab/markdown/external_link_filter.rb index c539e0fb823..29e51b6ade6 100644 --- a/lib/gitlab/markdown/external_link_filter.rb +++ b/lib/gitlab/markdown/external_link_filter.rb @@ -1,3 +1,4 @@ +require 'gitlab/markdown' require 'html/pipeline/filter' module Gitlab diff --git a/lib/gitlab/markdown/issue_reference_filter.rb b/lib/gitlab/markdown/issue_reference_filter.rb index ab6f6bc1cf7..01320f80796 100644 --- a/lib/gitlab/markdown/issue_reference_filter.rb +++ b/lib/gitlab/markdown/issue_reference_filter.rb @@ -1,3 +1,5 @@ +require 'gitlab/markdown' + module Gitlab module Markdown # HTML filter that replaces issue references with links. References to diff --git a/lib/gitlab/markdown/label_reference_filter.rb b/lib/gitlab/markdown/label_reference_filter.rb index 2186f36f854..3d7445a27f1 100644 --- a/lib/gitlab/markdown/label_reference_filter.rb +++ b/lib/gitlab/markdown/label_reference_filter.rb @@ -1,3 +1,5 @@ +require 'gitlab/markdown' + module Gitlab module Markdown # HTML filter that replaces label references with links. diff --git a/lib/gitlab/markdown/merge_request_reference_filter.rb b/lib/gitlab/markdown/merge_request_reference_filter.rb index 884f60f9d53..48248f5219d 100644 --- a/lib/gitlab/markdown/merge_request_reference_filter.rb +++ b/lib/gitlab/markdown/merge_request_reference_filter.rb @@ -1,3 +1,5 @@ +require 'gitlab/markdown' + module Gitlab module Markdown # HTML filter that replaces merge request references with links. References diff --git a/lib/gitlab/markdown/reference_filter.rb b/lib/gitlab/markdown/reference_filter.rb index 3b1dbb3004c..4e936d7cd51 100644 --- a/lib/gitlab/markdown/reference_filter.rb +++ b/lib/gitlab/markdown/reference_filter.rb @@ -1,4 +1,5 @@ require 'active_support/core_ext/string/output_safety' +require 'gitlab/markdown' require 'html/pipeline/filter' module Gitlab diff --git a/lib/gitlab/markdown/relative_link_filter.rb b/lib/gitlab/markdown/relative_link_filter.rb index 30f50b82996..8c5cf51bfe1 100644 --- a/lib/gitlab/markdown/relative_link_filter.rb +++ b/lib/gitlab/markdown/relative_link_filter.rb @@ -1,3 +1,4 @@ +require 'gitlab/markdown' require 'html/pipeline/filter' require 'uri' diff --git a/lib/gitlab/markdown/sanitization_filter.rb b/lib/gitlab/markdown/sanitization_filter.rb index 74b3a8d274f..68ed57f6257 100644 --- a/lib/gitlab/markdown/sanitization_filter.rb +++ b/lib/gitlab/markdown/sanitization_filter.rb @@ -1,3 +1,4 @@ +require 'gitlab/markdown' require 'html/pipeline/filter' require 'html/pipeline/sanitization_filter' diff --git a/lib/gitlab/markdown/snippet_reference_filter.rb b/lib/gitlab/markdown/snippet_reference_filter.rb index 92979a356dc..9e1aab936cb 100644 --- a/lib/gitlab/markdown/snippet_reference_filter.rb +++ b/lib/gitlab/markdown/snippet_reference_filter.rb @@ -1,3 +1,5 @@ +require 'gitlab/markdown' + module Gitlab module Markdown # HTML filter that replaces snippet references with links. References to diff --git a/lib/gitlab/markdown/syntax_highlight_filter.rb b/lib/gitlab/markdown/syntax_highlight_filter.rb index 9f468f98aeb..86f4385753a 100644 --- a/lib/gitlab/markdown/syntax_highlight_filter.rb +++ b/lib/gitlab/markdown/syntax_highlight_filter.rb @@ -1,3 +1,4 @@ +require 'gitlab/markdown' require 'html/pipeline/filter' require 'rouge/plugins/redcarpet' diff --git a/lib/gitlab/markdown/table_of_contents_filter.rb b/lib/gitlab/markdown/table_of_contents_filter.rb index 38887c9778c..bbb3bf7fc8b 100644 --- a/lib/gitlab/markdown/table_of_contents_filter.rb +++ b/lib/gitlab/markdown/table_of_contents_filter.rb @@ -1,3 +1,4 @@ +require 'gitlab/markdown' require 'html/pipeline/filter' module Gitlab diff --git a/lib/gitlab/markdown/task_list_filter.rb b/lib/gitlab/markdown/task_list_filter.rb index c6eb2e2bf6d..2f133ae8500 100644 --- a/lib/gitlab/markdown/task_list_filter.rb +++ b/lib/gitlab/markdown/task_list_filter.rb @@ -1,3 +1,4 @@ +require 'gitlab/markdown' require 'task_list/filter' module Gitlab diff --git a/lib/gitlab/markdown/user_reference_filter.rb b/lib/gitlab/markdown/user_reference_filter.rb index a4aec7a05d1..1871e52df0e 100644 --- a/lib/gitlab/markdown/user_reference_filter.rb +++ b/lib/gitlab/markdown/user_reference_filter.rb @@ -1,3 +1,5 @@ +require 'gitlab/markdown' + module Gitlab module Markdown # HTML filter that replaces user or group references with links. -- cgit v1.2.1 From 23aee0ca8ad3de5697f770696f3e55fbfdba2be8 Mon Sep 17 00:00:00 2001 From: Eric Maziade Date: Wed, 26 Aug 2015 22:28:24 -0400 Subject: fixed connection detection so settings can be read from the database --- lib/gitlab/current_settings.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/gitlab/current_settings.rb b/lib/gitlab/current_settings.rb index 1a2a50a14d0..7ad3ed8728f 100644 --- a/lib/gitlab/current_settings.rb +++ b/lib/gitlab/current_settings.rb @@ -4,7 +4,7 @@ module Gitlab key = :current_application_settings RequestStore.store[key] ||= begin - if ActiveRecord::Base.connected? && ActiveRecord::Base.connection.table_exists?('application_settings') + if ActiveRecord::Base.connection.active? && ActiveRecord::Base.connection.table_exists?('application_settings') ApplicationSetting.current || ApplicationSetting.create_from_defaults else fake_application_settings -- cgit v1.2.1 From d92f428024b2878682bb23b6b03bc671636b5afe Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 7 Aug 2015 16:09:48 +0200 Subject: Minor refactor --- lib/gitlab/ldap/user.rb | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/ldap/user.rb b/lib/gitlab/ldap/user.rb index 2ffb1241966..04a22237478 100644 --- a/lib/gitlab/ldap/user.rb +++ b/lib/gitlab/ldap/user.rb @@ -44,13 +44,14 @@ module Gitlab gl_user.skip_reconfirmation! gl_user.email = auth_hash.email - # If we don't have an identity for this provider yet, create one - if gl_user.identities.find_by(provider: auth_hash.provider).nil? - gl_user.identities.new(extern_uid: auth_hash.uid, provider: auth_hash.provider) - else # Update the UID attribute for this provider in case it has changed - identity = gl_user.identities.select { |identity| identity.provider == auth_hash.provider } - identity.first.extern_uid = auth_hash.uid - end + # find_or_initialize_by doesn't update `gl_user.identities`, and isn't autosaved. + identity = gl_user.identities.find { |identity| identity.provider == auth_hash.provider } + identity ||= gl_user.identities.build(provider: auth_hash.provider) + + # For a new user set extern_uid to the LDAP DN + # For an existing user with matching email but changed DN, update the DN. + # For an existing user with no change in DN, this line changes nothing. + identity.extern_uid = auth_hash.uid gl_user end -- cgit v1.2.1 From 4027a26e7b5a1a2a54dd57e480507095c91af26b Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Mon, 31 Aug 2015 15:30:15 +0200 Subject: Replace grack with gitlab-git-http-server --- lib/gitlab/backend/grack_auth.rb | 16 +++---- lib/support/init.d/gitlab | 74 +++++++++++++++++++++++-------- lib/support/init.d/gitlab.default.example | 10 +++++ lib/support/nginx/gitlab | 44 +++++++++--------- lib/support/nginx/gitlab-ssl | 44 +++++++++--------- 5 files changed, 115 insertions(+), 73 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb index 12292f614e9..dc87aa52a3e 100644 --- a/lib/gitlab/backend/grack_auth.rb +++ b/lib/gitlab/backend/grack_auth.rb @@ -26,12 +26,8 @@ module Grack auth! if project && authorized_request? - if ENV['GITLAB_GRACK_AUTH_ONLY'] == '1' - # Tell gitlab-git-http-server the request is OK, and what the GL_ID is - render_grack_auth_ok - else - @app.call(env) - end + # Tell gitlab-git-http-server the request is OK, and what the GL_ID is + render_grack_auth_ok elsif @user.nil? && !@gitlab_ci unauthorized else @@ -132,7 +128,9 @@ module Grack case git_cmd when *Gitlab::GitAccess::DOWNLOAD_COMMANDS - if user + if !Gitlab.config.gitlab_shell.upload_pack + false + elsif user Gitlab::GitAccess.new(user, project).download_access_check.allowed? elsif project.public? # Allow clone/fetch for public projects @@ -141,7 +139,9 @@ module Grack false end when *Gitlab::GitAccess::PUSH_COMMANDS - if user + if !Gitlab.config.gitlab_shell.receive_pack + false + elsif user # Skip user authorization on upload request. # It will be done by the pre-receive hook in the repository. true diff --git a/lib/support/init.d/gitlab b/lib/support/init.d/gitlab index 457bd31e23b..f2923314d48 100755 --- a/lib/support/init.d/gitlab +++ b/lib/support/init.d/gitlab @@ -37,6 +37,10 @@ web_server_pid_path="$pid_path/unicorn.pid" sidekiq_pid_path="$pid_path/sidekiq.pid" mail_room_enabled=false mail_room_pid_path="$pid_path/mail_room.pid" +gitlab_git_http_server_pid_path="$pid_path/gitlab-git-http-server.pid" +gitlab_git_http_server_options="-listenUmask 0 -listenNetwork unix -listenAddr $socket_path/gitlab-git-http-server.socket -authBackend http://127.0.0.1:8080" +gitlab_git_http_server_repo_root='/home/git/repositories' +gitlab_git_http_server_log="$app_root/log/gitlab-git-http-server.log" shell_path="/bin/bash" # Read configuration variable file if it is present @@ -72,6 +76,11 @@ check_pids(){ else spid=0 fi + if [ -f "$gitlab_git_http_server_pid_path" ]; then + hpid=$(cat "$gitlab_git_http_server_pid_path") + else + hpid=0 + fi if [ "$mail_room_enabled" = true ]; then if [ -f "$mail_room_pid_path" ]; then mpid=$(cat "$mail_room_pid_path") @@ -85,7 +94,7 @@ check_pids(){ wait_for_pids(){ # We are sleeping a bit here mostly because sidekiq is slow at writing it's pid i=0; - while [ ! -f $web_server_pid_path ] || [ ! -f $sidekiq_pid_path ] || { [ "$mail_room_enabled" = true ] && [ ! -f $mail_room_pid_path ]; }; do + while [ ! -f $web_server_pid_path ] || [ ! -f $sidekiq_pid_path ] || [ ! -f $gitlab_git_http_server_pid_path ] || { [ "$mail_room_enabled" = true ] && [ ! -f $mail_room_pid_path ]; }; do sleep 0.1; i=$((i+1)) if [ $((i%10)) = 0 ]; then @@ -120,6 +129,12 @@ check_status(){ else sidekiq_status="-1" fi + if [ $hpid -ne 0 ]; then + kill -0 "$hpid" 2>/dev/null + gitlab_git_http_server_status="$?" + else + gitlab_git_http_server_status="-1" + fi if [ "$mail_room_enabled" = true ]; then if [ $mpid -ne 0 ]; then kill -0 "$mpid" 2>/dev/null @@ -128,7 +143,7 @@ check_status(){ mail_room_status="-1" fi fi - if [ $web_status = 0 ] && [ $sidekiq_status = 0 ] && { [ "$mail_room_enabled" != true ] || [ $mail_room_status = 0 ]; }; then + if [ $web_status = 0 ] && [ $sidekiq_status = 0 ] && [ $gitlab_git_http_server_status = 0 ] && { [ "$mail_room_enabled" != true ] || [ $mail_room_status = 0 ]; }; then gitlab_status=0 else # http://refspecs.linuxbase.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html @@ -156,6 +171,13 @@ check_stale_pids(){ exit 1 fi fi + if [ "$hpid" != "0" ] && [ "$gitlab_git_http_server_status" != "0" ]; then + echo "Removing stale gitlab-git-http-server pid. This is most likely caused by gitlab-git-http-server crashing the last time it ran." + if ! rm "$gitlab_git_http_server_pid_path"; then + echo "Unable to remove stale pid, exiting" + exit 1 + fi + fi if [ "$mail_room_enabled" = true ] && [ "$mpid" != "0" ] && [ "$mail_room_status" != "0" ]; then echo "Removing stale MailRoom job dispatcher pid. This is most likely caused by MailRoom crashing the last time it ran." if ! rm "$mail_room_pid_path"; then @@ -168,7 +190,7 @@ check_stale_pids(){ ## If no parts of the service is running, bail out. exit_if_not_running(){ check_stale_pids - if [ "$web_status" != "0" ] && [ "$sidekiq_status" != "0" ] && { [ "$mail_room_enabled" != true ] || [ "$mail_room_status" != "0" ]; }; then + if [ "$web_status" != "0" ] && [ "$sidekiq_status" != "0" ] && [ "$gitlab_git_http_server_status" != "0" ] && { [ "$mail_room_enabled" != true ] || [ "$mail_room_status" != "0" ]; }; then echo "GitLab is not running." exit fi @@ -184,6 +206,9 @@ start_gitlab() { if [ "$sidekiq_status" != "0" ]; then echo "Starting GitLab Sidekiq" fi + if [ "$gitlab_git_http_server_status" != "0" ]; then + echo "Starting gitlab-git-http-server" + fi if [ "$mail_room_enabled" = true ] && [ "$mail_room_status" != "0" ]; then echo "Starting GitLab MailRoom" fi @@ -205,6 +230,17 @@ start_gitlab() { RAILS_ENV=$RAILS_ENV bin/background_jobs start & fi + if [ "$gitlab_git_http_server_status" = "0" ]; then + echo "The gitlab-git-http-server is already running with pid $spid, not restarting" + else + # No need to remove a socket, gitlab-git-http-server does this itself + $app_root/bin/daemon_with_pidfile $gitlab_git_http_server_pid_path \ + $app_root/../gitlab-git-http-server/gitlab-git-http-server \ + $gitlab_git_http_server_options \ + $gitlab_git_http_server_repo_root \ + >> $gitlab_git_http_server_log 2>&1 & + fi + if [ "$mail_room_enabled" = true ]; then # If MailRoom is already running, don't start it again. if [ "$mail_room_status" = "0" ]; then @@ -226,33 +262,27 @@ stop_gitlab() { if [ "$web_status" = "0" ]; then echo "Shutting down GitLab Unicorn" + RAILS_ENV=$RAILS_ENV bin/web stop fi if [ "$sidekiq_status" = "0" ]; then echo "Shutting down GitLab Sidekiq" - fi - if [ "$mail_room_enabled" = true ] && [ "$mail_room_status" = "0" ]; then - echo "Shutting down GitLab MailRoom" - fi - - # If the Unicorn web server is running, tell it to stop; - if [ "$web_status" = "0" ]; then - RAILS_ENV=$RAILS_ENV bin/web stop - fi - # And do the same thing for the Sidekiq. - if [ "$sidekiq_status" = "0" ]; then RAILS_ENV=$RAILS_ENV bin/background_jobs stop fi - # And do the same thing for the MailRoom. + if [ "$gitlab_git_http_server_status" = "0" ]; then + echo "Shutting down gitlab-git-http-server" + kill $(cat $gitlab_git_http_server_pid_path) + fi if [ "$mail_room_enabled" = true ] && [ "$mail_room_status" = "0" ]; then + echo "Shutting down GitLab MailRoom" RAILS_ENV=$RAILS_ENV bin/mail_room stop fi # If something needs to be stopped, lets wait for it to stop. Never use SIGKILL in a script. - while [ "$web_status" = "0" ] || [ "$sidekiq_status" = "0" ] || { [ "$mail_room_enabled" = true ] && [ "$mail_room_status" = "0" ]; }; do + while [ "$web_status" = "0" ] || [ "$sidekiq_status" = "0" ] || [ "$gitlab_git_http_server_status" = "0" ] || { [ "$mail_room_enabled" = true ] && [ "$mail_room_status" = "0" ]; }; do sleep 1 check_status printf "." - if [ "$web_status" != "0" ] && [ "$sidekiq_status" != "0" ] && { [ "$mail_room_enabled" != true ] || [ "$mail_room_status" != "0" ]; }; then + if [ "$web_status" != "0" ] && [ "$sidekiq_status" != "0" ] && [ "$gitlab_git_http_server_status" != "0" ] && { [ "$mail_room_enabled" != true ] || [ "$mail_room_status" != "0" ]; }; then printf "\n" break fi @@ -262,6 +292,7 @@ stop_gitlab() { # Cleaning up unused pids rm "$web_server_pid_path" 2>/dev/null # rm "$sidekiq_pid_path" 2>/dev/null # Sidekiq seems to be cleaning up it's own pid. + rm -f "$gitlab_git_http_server_pid_path" if [ "$mail_room_enabled" = true ]; then rm "$mail_room_pid_path" 2>/dev/null fi @@ -272,7 +303,7 @@ stop_gitlab() { ## Prints the status of GitLab and it's components. print_status() { check_status - if [ "$web_status" != "0" ] && [ "$sidekiq_status" != "0" ] && { [ "$mail_room_enabled" != true ] || [ "$mail_room_status" != "0" ]; }; then + if [ "$web_status" != "0" ] && [ "$sidekiq_status" != "0" ] && [ "$gitlab_git_http_server_status" != "0" ] && { [ "$mail_room_enabled" != true ] || [ "$mail_room_status" != "0" ]; }; then echo "GitLab is not running." return fi @@ -286,6 +317,11 @@ print_status() { else printf "The GitLab Sidekiq job dispatcher is \033[31mnot running\033[0m.\n" fi + if [ "$gitlab_git_http_server_status" = "0" ]; then + echo "The gitlab-git-http-server with pid $hpid is running." + else + printf "The gitlab-git-http-server is \033[31mnot running\033[0m.\n" + fi if [ "$mail_room_enabled" = true ]; then if [ "$mail_room_status" = "0" ]; then echo "The GitLab MailRoom email processor with pid $mpid is running." @@ -324,7 +360,7 @@ reload_gitlab(){ ## Restarts Sidekiq and Unicorn. restart_gitlab(){ check_status - if [ "$web_status" = "0" ] || [ "$sidekiq_status" = "0" ] || { [ "$mail_room_enabled" = true ] && [ "$mail_room_status" = "0" ]; }; then + if [ "$web_status" = "0" ] || [ "$sidekiq_status" = "0" ] || [ "$gitlab_git_http_server" = "0" ] || { [ "$mail_room_enabled" = true ] && [ "$mail_room_status" = "0" ]; }; then stop_gitlab fi start_gitlab diff --git a/lib/support/init.d/gitlab.default.example b/lib/support/init.d/gitlab.default.example index fd70cb7cc74..aab5acaa72c 100755 --- a/lib/support/init.d/gitlab.default.example +++ b/lib/support/init.d/gitlab.default.example @@ -30,6 +30,16 @@ web_server_pid_path="$pid_path/unicorn.pid" # The default is "$pid_path/sidekiq.pid" sidekiq_pid_path="$pid_path/sidekiq.pid" +gitlab_git_http_server_pid_path="$pid_path/gitlab-git-http-server.pid" +# The -listenXxx settings determine where gitlab-git-http-server +# listens for connections from NGINX. To listen on localhost:8181, write +# '-listenNetwork tcp -listenAddr localhost:8181'. +# The -authBackend setting tells gitlab-git-http-server where it can reach +# Unicorn. +gitlab_git_http_server_options="-listenUmask 0 -listenNetwork unix -listenAddr $socket_path/gitlab-git-http-server.socket -authBackend http://127.0.0.1:8080" +gitlab_git_http_server_repo_root="/home/git/repositories" +gitlab_git_http_server_log="$app_root/log/gitlab-git-http-server.log" + # mail_room_enabled specifies whether mail_room, which is used to process incoming email, is enabled. # This is required for the Reply by email feature. # The default is "false" diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab index efa0898900f..17f89c8beb6 100644 --- a/lib/support/nginx/gitlab +++ b/lib/support/nginx/gitlab @@ -38,10 +38,9 @@ upstream gitlab { server unix:/home/git/gitlab/tmp/sockets/gitlab.socket fail_timeout=0; } -## Experimental: gitlab-git-http-server -# upstream gitlab-git-http-server { -# server localhost:8181; -# } +upstream gitlab-git-http-server { + server unix:/home/git/gitlab/tmp/sockets/gitlab-git-http-server.socket fail_timeout=0; +} ## Normal HTTP host server { @@ -114,25 +113,24 @@ server { proxy_pass http://gitlab; } - ## Experimental: send Git HTTP traffic to gitlab-git-http-server instead of Unicorn - # location ~ [-\/\w\.]+\.git\/ { - # ## If you use HTTPS make sure you disable gzip compression - # ## to be safe against BREACH attack. - # # gzip off; - - # ## https://github.com/gitlabhq/gitlabhq/issues/694 - # ## Some requests take more than 30 seconds. - # proxy_read_timeout 300; - # proxy_connect_timeout 300; - # proxy_redirect off; - - # proxy_set_header Host $http_host; - # proxy_set_header X-Real-IP $remote_addr; - # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # proxy_set_header X-Forwarded-Proto $scheme; - - # proxy_pass http://gitlab-git-http-server; - # } + location ~ [-\/\w\.]+\.git\/ { + ## If you use HTTPS make sure you disable gzip compression + ## to be safe against BREACH attack. + # gzip off; + + ## https://github.com/gitlabhq/gitlabhq/issues/694 + ## Some requests take more than 30 seconds. + proxy_read_timeout 300; + proxy_connect_timeout 300; + proxy_redirect off; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_pass http://gitlab-git-http-server; + } ## Enable gzip compression as per rails guide: ## http://guides.rubyonrails.org/asset_pipeline.html#gzip-compression diff --git a/lib/support/nginx/gitlab-ssl b/lib/support/nginx/gitlab-ssl index 314525518f1..5ba39fc41a4 100644 --- a/lib/support/nginx/gitlab-ssl +++ b/lib/support/nginx/gitlab-ssl @@ -42,10 +42,9 @@ upstream gitlab { server unix:/home/git/gitlab/tmp/sockets/gitlab.socket fail_timeout=0; } -## Experimental: gitlab-git-http-server -# upstream gitlab-git-http-server { -# server localhost:8181; -# } +upstream gitlab-git-http-server { + server unix:/home/git/gitlab/tmp/sockets/gitlab-git-http-server.socket fail_timeout=0; +} ## Redirects all HTTP traffic to the HTTPS host server { @@ -161,25 +160,24 @@ server { proxy_pass http://gitlab; } - ## Experimental: send Git HTTP traffic to gitlab-git-http-server instead of Unicorn - # location ~ [-\/\w\.]+\.git\/ { - # ## If you use HTTPS make sure you disable gzip compression - # ## to be safe against BREACH attack. - # gzip off; - - # ## https://github.com/gitlabhq/gitlabhq/issues/694 - # ## Some requests take more than 30 seconds. - # proxy_read_timeout 300; - # proxy_connect_timeout 300; - # proxy_redirect off; - - # proxy_set_header Host $http_host; - # proxy_set_header X-Real-IP $remote_addr; - # proxy_set_header X-Forwarded-Ssl on; - # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # proxy_set_header X-Forwarded-Proto $scheme; - # proxy_pass http://gitlab-git-http-server; - # } + location ~ [-\/\w\.]+\.git\/ { + ## If you use HTTPS make sure you disable gzip compression + ## to be safe against BREACH attack. + gzip off; + + ## https://github.com/gitlabhq/gitlabhq/issues/694 + ## Some requests take more than 30 seconds. + proxy_read_timeout 300; + proxy_connect_timeout 300; + proxy_redirect off; + + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Ssl on; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass http://gitlab-git-http-server; + } ## Enable gzip compression as per rails guide: ## http://guides.rubyonrails.org/asset_pipeline.html#gzip-compression -- cgit v1.2.1 From 780bac1026f96d68d8c658ead605c61a5b018f62 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Mon, 31 Aug 2015 16:15:41 +0200 Subject: Be more defensive when running 'kill' --- lib/support/init.d/gitlab | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/support/init.d/gitlab b/lib/support/init.d/gitlab index f2923314d48..a80e7e77430 100755 --- a/lib/support/init.d/gitlab +++ b/lib/support/init.d/gitlab @@ -270,7 +270,7 @@ stop_gitlab() { fi if [ "$gitlab_git_http_server_status" = "0" ]; then echo "Shutting down gitlab-git-http-server" - kill $(cat $gitlab_git_http_server_pid_path) + kill -- $(cat $gitlab_git_http_server_pid_path) fi if [ "$mail_room_enabled" = true ] && [ "$mail_room_status" = "0" ]; then echo "Shutting down GitLab MailRoom" -- cgit v1.2.1 From 08ca9411865a9dff5354f0e7ec214fba6af4e9d9 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Mon, 31 Aug 2015 16:22:34 -0400 Subject: Move REDCARPET_OPTIONS to a private method There wasn't really a reason to have them as a constant, and we were getting "already defined" warnings which are always annoying. --- lib/gitlab/markdown.rb | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb index 7efcbaf3252..097caf67a65 100644 --- a/lib/gitlab/markdown.rb +++ b/lib/gitlab/markdown.rb @@ -5,18 +5,6 @@ module Gitlab # # See the files in `lib/gitlab/markdown/` for specific processing information. module Markdown - # https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use - REDCARPET_OPTIONS = { - no_intra_emphasis: true, - tables: true, - fenced_code_blocks: true, - strikethrough: true, - lax_spacing: true, - space_after_headers: true, - superscript: true, - footnotes: true - }.freeze - # Convert a Markdown String into an HTML-safe String of HTML # # markdown - Markdown String @@ -40,7 +28,7 @@ module Gitlab # # Returns a String def self.render_without_gfm(markdown) - self.renderer.render(markdown) + renderer.render(markdown) end # Provide autoload paths for filters to prevent a circular dependency error @@ -123,10 +111,24 @@ module Gitlab def self.renderer @markdown ||= begin renderer = Redcarpet::Render::HTML.new - Redcarpet::Markdown.new(renderer, REDCARPET_OPTIONS) + Redcarpet::Markdown.new(renderer, redcarpet_options) end end + def self.redcarpet_options + # https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use + @redcarpet_options ||= { + fenced_code_blocks: true, + footnotes: true, + lax_spacing: true, + no_intra_emphasis: true, + space_after_headers: true, + strikethrough: true, + superscript: true, + tables: true + }.freeze + end + # Filters used in our pipeline # # SanitizationFilter should come first so that all generated reference HTML -- cgit v1.2.1 From c104f4d590b16d4784d029c953be90fda130e8b4 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Mon, 31 Aug 2015 16:23:46 -0400 Subject: Remove unnecessary `strip` from `reference_class` method --- lib/gitlab/markdown/reference_filter.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/gitlab/markdown/reference_filter.rb b/lib/gitlab/markdown/reference_filter.rb index 4e936d7cd51..9b293c957d6 100644 --- a/lib/gitlab/markdown/reference_filter.rb +++ b/lib/gitlab/markdown/reference_filter.rb @@ -70,7 +70,7 @@ module Gitlab end def reference_class(type) - "gfm gfm-#{type}".strip + "gfm gfm-#{type}" end # Iterate through the document's text nodes, yielding the current node's -- cgit v1.2.1 From 31e4654b1f77ab48e5705f8feb8d628c66d4f962 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sun, 30 Aug 2015 17:47:11 -0700 Subject: Sort issues by creation date in Bitbucket importer API reference here: https://bitbucket.org/site/master/issues/3571/api-issues-sorting-bb-3518 Closes https://github.com/gitlabhq/gitlabhq/issues/9519 --- lib/gitlab/bitbucket_import/client.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/gitlab/bitbucket_import/client.rb b/lib/gitlab/bitbucket_import/client.rb index aec44b8c87b..bb8bf7e3a98 100644 --- a/lib/gitlab/bitbucket_import/client.rb +++ b/lib/gitlab/bitbucket_import/client.rb @@ -52,7 +52,7 @@ module Gitlab end def issues(project_identifier) - JSON.parse(get("/api/1.0/repositories/#{project_identifier}/issues").body) + JSON.parse(get("/api/1.0/repositories/#{project_identifier}/issues?sort=utc_created_on").body) end def issue_comments(project_identifier, issue_id) -- cgit v1.2.1 From 3a8773fb2f86757ce0a061ef6476b7d91bcb6259 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Tue, 1 Sep 2015 12:45:14 +0200 Subject: Added USE_DB env var to allow loading fake settings without db running. --- lib/gitlab/current_settings.rb | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/gitlab/current_settings.rb b/lib/gitlab/current_settings.rb index 7ad3ed8728f..0ea1b6a2f6f 100644 --- a/lib/gitlab/current_settings.rb +++ b/lib/gitlab/current_settings.rb @@ -4,7 +4,7 @@ module Gitlab key = :current_application_settings RequestStore.store[key] ||= begin - if ActiveRecord::Base.connection.active? && ActiveRecord::Base.connection.table_exists?('application_settings') + if connect_to_db? ApplicationSetting.current || ApplicationSetting.create_from_defaults else fake_application_settings @@ -26,5 +26,17 @@ module Gitlab import_sources: Settings.gitlab['import_sources'] ) end + + private + + def connect_to_db? + use_db = if ENV['USE_DB'] == "false" + false + else + true + end + + use_db && ActiveRecord::Base.connection.active? && ActiveRecord::Base.connection.table_exists?('application_settings') + end end end -- cgit v1.2.1 From 2e9c922dd17d13e2cb20b214f00eb875c673dfdf Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Mon, 31 Aug 2015 17:03:09 -0700 Subject: Fix bug where only the first 15 Bitbucket issues would be imported. Also fix a number of issues where author/reporter names were not available. --- lib/gitlab/bitbucket_import/client.rb | 23 ++++++++++++++++++++-- lib/gitlab/bitbucket_import/importer.rb | 34 ++++++++++++++++++++++++++------- lib/gitlab/github_import/importer.rb | 3 ++- lib/gitlab/gitlab_import/importer.rb | 3 ++- lib/gitlab/import_formatter.rb | 4 ++-- 5 files changed, 54 insertions(+), 13 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/bitbucket_import/client.rb b/lib/gitlab/bitbucket_import/client.rb index bb8bf7e3a98..d88a6eaac6b 100644 --- a/lib/gitlab/bitbucket_import/client.rb +++ b/lib/gitlab/bitbucket_import/client.rb @@ -52,11 +52,26 @@ module Gitlab end def issues(project_identifier) - JSON.parse(get("/api/1.0/repositories/#{project_identifier}/issues?sort=utc_created_on").body) + all_issues = [] + offset = 0 + per_page = 50 # Maximum number allowed by Bitbucket + index = 0 + + begin + issues = JSON.parse(get(issue_api_endpoint(project_identifier, per_page, offset)).body) + # Find out how many total issues are present + total = issues["count"] if index == 0 + all_issues.concat(issues["issues"]) + offset += issues["issues"].count + index += 1 + end while all_issues.count < total + + all_issues end def issue_comments(project_identifier, issue_id) - JSON.parse(get("/api/1.0/repositories/#{project_identifier}/issues/#{issue_id}/comments").body) + comments = JSON.parse(get("/api/1.0/repositories/#{project_identifier}/issues/#{issue_id}/comments").body) + comments.sort_by { |comment| comment["utc_created_on"] } end def project(project_identifier) @@ -100,6 +115,10 @@ module Gitlab response end + def issue_api_endpoint(project_identifier, per_page, offset) + "/api/1.0/repositories/#{project_identifier}/issues?sort=utc_created_on&limit=#{per_page}&start=#{offset}" + end + def config Gitlab.config.omniauth.providers.find { |provider| provider.name == "bitbucket"} end diff --git a/lib/gitlab/bitbucket_import/importer.rb b/lib/gitlab/bitbucket_import/importer.rb index d8a7d29f1bf..2355b3c6ddc 100644 --- a/lib/gitlab/bitbucket_import/importer.rb +++ b/lib/gitlab/bitbucket_import/importer.rb @@ -20,8 +20,18 @@ module Gitlab #Issues && Comments issues = client.issues(project_identifier) - issues["issues"].each do |issue| - body = @formatter.author_line(issue["reported_by"]["username"], issue["content"]) + issues.each do |issue| + body = '' + reporter = nil + author = 'Anonymous' + + if issue["reported_by"] && issue["reported_by"]["username"] + reporter = issue["reported_by"]["username"] + author = reporter + end + + body = @formatter.author_line(author) + body += issue["content"] comments = client.issue_comments(project_identifier, issue["local_id"]) @@ -30,14 +40,20 @@ module Gitlab end comments.each do |comment| - body += @formatter.comment(comment["author_info"]["username"], comment["utc_created_on"], comment["content"]) + author = 'Anonymous' + + if comment["author_info"] && comment["author_info"]["username"] + author = comment["author_info"]["username"] + end + + body += @formatter.comment(author, comment["utc_created_on"], comment["content"]) end project.issues.create!( description: body, title: issue["title"], state: %w(resolved invalid duplicate wontfix).include?(issue["status"]) ? 'closed' : 'opened', - author_id: gl_user_id(project, issue["reported_by"]["username"]) + author_id: gl_user_id(project, reporter) ) end @@ -47,9 +63,13 @@ module Gitlab private def gl_user_id(project, bitbucket_id) - user = User.joins(:identities).find_by("identities.extern_uid = ? AND identities.provider = 'bitbucket'", bitbucket_id.to_s) - (user && user.id) || project.creator_id - end + if bitbucket_id + user = User.joins(:identities).find_by("identities.extern_uid = ? AND identities.provider = 'bitbucket'", bitbucket_id.to_s) + (user && user.id) || project.creator_id + else + project.creator_id + end + end end end end diff --git a/lib/gitlab/github_import/importer.rb b/lib/gitlab/github_import/importer.rb index 8c106a61735..bd7340a80f1 100644 --- a/lib/gitlab/github_import/importer.rb +++ b/lib/gitlab/github_import/importer.rb @@ -18,7 +18,8 @@ module Gitlab direction: :asc).each do |issue| if issue.pull_request.nil? - body = @formatter.author_line(issue.user.login, issue.body) + body = @formatter.author_line(issue.user.login) + body += issue.body if issue.comments > 0 body += @formatter.comments_header diff --git a/lib/gitlab/gitlab_import/importer.rb b/lib/gitlab/gitlab_import/importer.rb index 50594d2b24f..e24b94d6159 100644 --- a/lib/gitlab/gitlab_import/importer.rb +++ b/lib/gitlab/gitlab_import/importer.rb @@ -18,7 +18,8 @@ module Gitlab issues = client.issues(project_identifier) issues.each do |issue| - body = @formatter.author_line(issue["author"]["name"], issue["description"]) + body = @formatter.author_line(issue["author"]["name"]) + body += issue["description"] comments = client.issue_comments(project_identifier, issue["id"]) diff --git a/lib/gitlab/import_formatter.rb b/lib/gitlab/import_formatter.rb index 72e041a90b1..3e54456e936 100644 --- a/lib/gitlab/import_formatter.rb +++ b/lib/gitlab/import_formatter.rb @@ -8,8 +8,8 @@ module Gitlab "\n\n\n**Imported comments:**\n" end - def author_line(author, body) - "*Created by: #{author}*\n\n#{body}" + def author_line(author) + "*Created by: #{author}*\n\n" end end end -- cgit v1.2.1 From f43e48a1ce0a5568e352049b3a8a844b0ded6332 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Tue, 1 Sep 2015 13:28:19 -0400 Subject: Require gitlab/markdown in ReferenceExtractor --- lib/gitlab/reference_extractor.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib') diff --git a/lib/gitlab/reference_extractor.rb b/lib/gitlab/reference_extractor.rb index 20f4098057c..0961bd80421 100644 --- a/lib/gitlab/reference_extractor.rb +++ b/lib/gitlab/reference_extractor.rb @@ -1,3 +1,5 @@ +require 'gitlab/markdown' + module Gitlab # Extract possible GFM references from an arbitrary String for further processing. class ReferenceExtractor -- cgit v1.2.1 From 263abda3fd7ddfb826cd17ae88fb47d0e1d67fae Mon Sep 17 00:00:00 2001 From: Kirilll Zaitsev Date: Thu, 27 Aug 2015 02:58:49 +0300 Subject: Drone CI service --- lib/api/helpers.rb | 26 ++++++++++++ lib/api/services.rb | 86 ++++++++++++++------------------------ lib/gitlab/backend/grack_auth.rb | 25 ++++++----- lib/tasks/services.rake | 89 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 161 insertions(+), 65 deletions(-) create mode 100644 lib/tasks/services.rake (limited to 'lib') diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 1ebf9a1f022..76c9cc2e3a4 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -55,6 +55,32 @@ module API end end + def project_service + @project_service ||= begin + underscored_service = params[:service_slug].underscore + + if Service.available_services_names.include?(underscored_service) + user_project.build_missing_services + + service_method = "#{underscored_service}_service" + + send_service(service_method) + end + end + + @project_service || not_found!("Service") + end + + def send_service(service_method) + user_project.send(service_method) + end + + def service_attributes + @service_attributes ||= project_service.fields.inject([]) do |arr, hash| + arr << hash[:name].to_sym + end + end + def find_group(id) begin group = Group.find(id) diff --git a/lib/api/services.rb b/lib/api/services.rb index 3ad59cf3adf..73645cedea4 100644 --- a/lib/api/services.rb +++ b/lib/api/services.rb @@ -4,73 +4,49 @@ module API before { authenticate! } before { authorize_admin_project } + resource :projects do - # Set GitLab CI service for project - # - # Parameters: - # token (required) - CI project token - # project_url (required) - CI project url + # Set service for project # # Example Request: + # # PUT /projects/:id/services/gitlab-ci - put ":id/services/gitlab-ci" do - required_attributes! [:token, :project_url] - attrs = attributes_for_keys [:token, :project_url] - user_project.build_missing_services - - if user_project.gitlab_ci_service.update_attributes(attrs.merge(active: true)) - true - else - not_found! - end - end - - # Delete GitLab CI service settings # - # Example Request: - # DELETE /projects/:id/services/gitlab-ci - delete ":id/services/gitlab-ci" do - if user_project.gitlab_ci_service - user_project.gitlab_ci_service.update_attributes( - active: false, - token: nil, - project_url: nil - ) - end - end + put ':id/services/:service_slug' do + if project_service + validators = project_service.class.validators.select do |s| + s.class == ActiveRecord::Validations::PresenceValidator && + s.attributes != [:project_id] + end - # Set Hipchat service for project - # - # Parameters: - # token (required) - Hipchat token - # room (required) - Hipchat room name - # - # Example Request: - # PUT /projects/:id/services/hipchat - put ':id/services/hipchat' do - required_attributes! [:token, :room] - attrs = attributes_for_keys [:token, :room] - user_project.build_missing_services + required_attributes! validators.map(&:attributes).flatten.uniq + attrs = attributes_for_keys service_attributes - if user_project.hipchat_service.update_attributes( - attrs.merge(active: true)) - true - else - not_found! + if project_service.update_attributes(attrs.merge(active: true)) + true + else + not_found! + end end end - # Delete Hipchat service settings + # Delete service for project # # Example Request: - # DELETE /projects/:id/services/hipchat - delete ':id/services/hipchat' do - if user_project.hipchat_service - user_project.hipchat_service.update_attributes( - active: false, - token: nil, - room: nil - ) + # + # DELETE /project/:id/services/gitlab-ci + # + delete ':id/services/:service_slug' do + if project_service + attrs = service_attributes.inject({}) do |hash, key| + hash.merge!(key => nil) + end + + if project_service.update_attributes(attrs.merge(active: false)) + true + else + not_found! + end end end end diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb index dc87aa52a3e..aa46c9a6d49 100644 --- a/lib/gitlab/backend/grack_auth.rb +++ b/lib/gitlab/backend/grack_auth.rb @@ -10,7 +10,7 @@ module Grack @request = Rack::Request.new(env) @auth = Request.new(env) - @gitlab_ci = false + @ci = false # Need this patch due to the rails mount # Need this if under RELATIVE_URL_ROOT @@ -28,7 +28,7 @@ module Grack if project && authorized_request? # Tell gitlab-git-http-server the request is OK, and what the GL_ID is render_grack_auth_ok - elsif @user.nil? && !@gitlab_ci + elsif @user.nil? && !@ci unauthorized else render_not_found @@ -47,8 +47,8 @@ module Grack # Allow authentication for GitLab CI service # if valid token passed - if gitlab_ci_request?(login, password) - @gitlab_ci = true + if ci_request?(login, password) + @ci = true return end @@ -60,12 +60,17 @@ module Grack end end - def gitlab_ci_request?(login, password) - if login == "gitlab-ci-token" && project && project.gitlab_ci? - token = project.gitlab_ci_service.token + def ci_request?(login, password) + matched_login = /(?^[a-zA-Z]*-ci)-token$/.match(login) - if token.present? && token == password && git_cmd == 'git-upload-pack' - return true + if project && matched_login.present? && git_cmd == 'git-upload-pack' + underscored_service = matched_login['s'].underscore + + if Service.available_services_names.include?(underscored_service) + service_method = "#{underscored_service}_service" + service = project.send(service_method) + + return service && service.activated? && service.valid_token?(password) end end @@ -124,7 +129,7 @@ module Grack end def authorized_request? - return true if @gitlab_ci + return true if @ci case git_cmd when *Gitlab::GitAccess::DOWNLOAD_COMMANDS diff --git a/lib/tasks/services.rake b/lib/tasks/services.rake new file mode 100644 index 00000000000..53d912d2a7c --- /dev/null +++ b/lib/tasks/services.rake @@ -0,0 +1,89 @@ +services_template = <<-ERB +# Services + +<% services.each do |service| %> +## <%= service[:title] %> + + +<% unless service[:description].blank? %> +<%= service[:description] %> +<% end %> + + +### Create/Edit <%= service[:title] %> service + +Set <%= service[:title] %> service for a project. +<% unless service[:help].blank? %> + +> <%= service[:help].gsub("\n", ' ') %> + +<% end %> + +``` +PUT /projects/:id/services/<%= service[:dashed_name] %> + +``` + +Parameters: + +<% service[:params].each do |param| %> +- `<%= param[:name] %>` <%= param[:required] ? "(**required**)" : "(optional)" %><%= [" -", param[:description]].join(" ").gsub("\n", '') unless param[:description].blank? %> + +<% end %> + +### Delete <%= service[:title] %> service + +Delete <%= service[:title] %> service for a project. + +``` +DELETE /projects/:id/services/<%= service[:dashed_name] %> + +``` + +<% end %> +ERB + +namespace :services do + task :doc do + services = Service.available_services_names.map do |s| + service_start = Time.now + klass = "#{s}_service".classify.constantize + + service = klass.new + + service_hash = {} + + service_hash[:title] = service.title + service_hash[:dashed_name] = s.dasherize + service_hash[:description] = service.description + service_hash[:help] = service.help + service_hash[:params] = service.fields.map do |p| + param_hash = {} + + param_hash[:name] = p[:name] + param_hash[:description] = p[:placeholder] || p[:title] + param_hash[:required] = klass.validators_on(p[:name].to_sym).any? do |v| + v.class == ActiveRecord::Validations::PresenceValidator + end + + param_hash + end.sort_by { |p| p[:required] ? 0 : 1 } + + puts "Collected data for: #{service.title}, #{Time.now-service_start}" + service_hash + end + + doc_start = Time.now + doc_path = File.join(Rails.root, 'doc', 'api', 'services.md') + + result = ERB.new(services_template, 0 , '>') + .result(OpenStruct.new(services: services).instance_eval { binding }) + + File.open(doc_path, 'w') do |f| + f.write result + end + + puts "write a new service.md to: #{doc_path.to_s}, #{Time.now-doc_start}" + + end +end -- cgit v1.2.1 From 30bf2b9cc370da5936f70b827db4f53dc33d8f1f Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Wed, 2 Sep 2015 18:47:56 +0200 Subject: Avoid instance variable re-use trouble This is the quickest/dumbest/safest way I could think of to prevent the instance variable reuse problems we have on dev.gitlab.org now. --- lib/gitlab/backend/grack_auth.rb | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'lib') diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb index dc87aa52a3e..7ffc3226913 100644 --- a/lib/gitlab/backend/grack_auth.rb +++ b/lib/gitlab/backend/grack_auth.rb @@ -1,6 +1,14 @@ require_relative 'shell_env' module Grack + class AuthSpawner + def self.call(env) + # Avoid issues with instance variables in Grack::Auth persisting across + # requests by creating a new instance for each request. + Auth.new({}).call(env) + end + end + class Auth < Rack::Auth::Basic attr_accessor :user, :project, :env -- cgit v1.2.1 From 8ec59bd18bcacf13c012a34b3e37c2c9167bcc65 Mon Sep 17 00:00:00 2001 From: "Artem V. Navrotskiy" Date: Sat, 29 Aug 2015 12:52:21 +0300 Subject: Add API method for get user by ID of an SSH key --- lib/api/api.rb | 1 + lib/api/entities.rb | 4 ++++ lib/api/keys.rb | 20 ++++++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 lib/api/keys.rb (limited to 'lib') diff --git a/lib/api/api.rb b/lib/api/api.rb index eebd44ea5b6..c09488d3547 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -50,5 +50,6 @@ module API mount Branches mount Labels mount Settings + mount Keys end end diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 1f9dd6bc152..8dddcd7ccc3 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -199,6 +199,10 @@ module API expose :id, :title, :key, :created_at end + class SSHKeyWithUser < SSHKey + expose :user, using: Entities::UserFull + end + class Note < Grape::Entity expose :id expose :note, as: :body diff --git a/lib/api/keys.rb b/lib/api/keys.rb new file mode 100644 index 00000000000..2b723b79504 --- /dev/null +++ b/lib/api/keys.rb @@ -0,0 +1,20 @@ +module API + # Keys API + class Keys < Grape::API + before { authenticate! } + + resource :keys do + # Get single ssh key by id. Only available to admin users. + # + # Example Request: + # GET /keys/:id + get ":id" do + authenticated_as_admin! + + key = Key.find(params[:id]) + + present key, with: Entities::SSHKeyWithUser + end + end + end +end -- cgit v1.2.1 From a73044320f806c660a21992fdbf63deb161c615e Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Thu, 3 Sep 2015 20:49:13 +0000 Subject: Fix `rake services:doc` generation [ci skip] --- lib/tasks/services.rake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/tasks/services.rake b/lib/tasks/services.rake index 53d912d2a7c..3f276a5e12e 100644 --- a/lib/tasks/services.rake +++ b/lib/tasks/services.rake @@ -44,11 +44,11 @@ DELETE /projects/:id/services/<%= service[:dashed_name] %> ERB namespace :services do - task :doc do + task doc: :environment do services = Service.available_services_names.map do |s| service_start = Time.now klass = "#{s}_service".classify.constantize - + service = klass.new service_hash = {} @@ -62,7 +62,7 @@ namespace :services do param_hash[:name] = p[:name] param_hash[:description] = p[:placeholder] || p[:title] - param_hash[:required] = klass.validators_on(p[:name].to_sym).any? do |v| + param_hash[:required] = klass.validators_on(p[:name].to_sym).any? do |v| v.class == ActiveRecord::Validations::PresenceValidator end -- cgit v1.2.1 From a5314e79f26f7f0de43388a0fde142d91f3ddd96 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Fri, 4 Sep 2015 16:24:01 -0700 Subject: Fix URL construction for merge requests, issues, notes, and commits for relative URL config Closes https://github.com/gitlabhq/gitlabhq/issues/9605 --- lib/gitlab/url_builder.rb | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/url_builder.rb b/lib/gitlab/url_builder.rb index 11b0d44f340..779819bc2bf 100644 --- a/lib/gitlab/url_builder.rb +++ b/lib/gitlab/url_builder.rb @@ -23,12 +23,12 @@ module Gitlab def build_issue_url(id) issue = Issue.find(id) - issue_url(issue, host: Gitlab.config.gitlab['url']) + issue_url(issue) end def build_merge_request_url(id) merge_request = MergeRequest.find(id) - merge_request_url(merge_request, host: Gitlab.config.gitlab['url']) + merge_request_url(merge_request) end def build_note_url(id) @@ -37,22 +37,18 @@ module Gitlab namespace_project_commit_url(namespace_id: note.project.namespace, id: note.commit_id, project_id: note.project, - host: Gitlab.config.gitlab['url'], anchor: "note_#{note.id}") elsif note.for_issue? issue = Issue.find(note.noteable_id) issue_url(issue, - host: Gitlab.config.gitlab['url'], anchor: "note_#{note.id}") elsif note.for_merge_request? merge_request = MergeRequest.find(note.noteable_id) merge_request_url(merge_request, - host: Gitlab.config.gitlab['url'], anchor: "note_#{note.id}") elsif note.for_project_snippet? snippet = Snippet.find(note.noteable_id) project_snippet_url(snippet, - host: Gitlab.config.gitlab['url'], anchor: "note_#{note.id}") end end -- cgit v1.2.1 From 30039dae6326e7b1ae7e3e2d321def122cda3e36 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sun, 6 Sep 2015 00:29:41 -0700 Subject: Upgrade Redis requirement check to 2.4.0 per https://github.com/mperham/sidekiq/pull/957 Closes #2222 Closes #2445 --- lib/tasks/gitlab/check.rake | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index 2b9688c1b40..7999fe0b0e1 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -278,7 +278,7 @@ namespace :gitlab do fix_and_rerun end end - + def check_uploads print "Uploads directory setup correctly? ... " @@ -331,15 +331,18 @@ namespace :gitlab do end def check_redis_version - print "Redis version >= 2.0.0? ... " + min_redis_version = "2.4.0" + print "Redis version >= #{min_redis_version}? ... " redis_version = run(%W(redis-cli --version)) - if redis_version.try(:match, /redis-cli 2.\d.\d/) || redis_version.try(:match, /redis-cli 3.\d.\d/) + redis_version = redis_version.try(:match, /redis-cli (.*)/) + if redis_version && + (Gem::Version.new(redis_version[1]) > Gem::Version.new(min_redis_version)) puts "yes".green else puts "no".red try_fixing_it( - "Update your redis server to a version >= 2.0.0" + "Update your redis server to a version >= #{min_redis_version}" ) for_more_information( "gitlab-public-wiki/wiki/Trouble-Shooting-Guide in section sidekiq" -- cgit v1.2.1 From fd6eba34eba76ea348b8e1d65f2c1ccb901095f9 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sun, 6 Sep 2015 07:41:23 -0700 Subject: Use File.join to prevent extra slash in help message from appearing. Before: ``` Try fixing it: sudo -u git -H /opt/gitlab/embedded/service/gitlab-shell//bin/create-hooks ``` --- lib/tasks/gitlab/check.rake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index 2b9688c1b40..504823f3e12 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -278,7 +278,7 @@ namespace :gitlab do fix_and_rerun end end - + def check_uploads print "Uploads directory setup correctly? ... " @@ -488,7 +488,7 @@ namespace :gitlab do else puts "wrong or missing hooks".red try_fixing_it( - sudo_gitlab("#{gitlab_shell_path}/bin/create-hooks"), + sudo_gitlab("#{File.join(gitlab_shell_path, 'bin/create-hooks')}"), 'Check the hooks_path in config/gitlab.yml', 'Check your gitlab-shell installation' ) -- cgit v1.2.1 From 8d59b1ac456575496e0bceb6812c59545b1e9b50 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Mon, 7 Sep 2015 13:05:29 +0200 Subject: Do not let NGINX buffer Git HTTP requests Before this change NGINX would convert a chunked HTTP POST (e.g. git push) into a HTTP 1.0 single large POST. This creates an unnecessary delay, and it creates unnecessary memory pressure on gitlab-git-http-server. For the response ('proxy_buffering') I am less sure that NGINX 's buffering behavior is harmful, but it still makes more sense to me not to interfere with gitlab-git-http-server (and the Golang net/http server). --- lib/support/nginx/gitlab | 7 +++++++ lib/support/nginx/gitlab-ssl | 7 +++++++ 2 files changed, 14 insertions(+) (limited to 'lib') diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab index 17f89c8beb6..1cd81ea769f 100644 --- a/lib/support/nginx/gitlab +++ b/lib/support/nginx/gitlab @@ -124,6 +124,13 @@ server { proxy_connect_timeout 300; proxy_redirect off; + # Do not buffer Git HTTP responses + proxy_buffering off; + + # Pass chunked request bodies to gitlab-git-http-server as-is + proxy_request_buffering off; + proxy_http_version 1.1; + proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; diff --git a/lib/support/nginx/gitlab-ssl b/lib/support/nginx/gitlab-ssl index 5ba39fc41a4..83aad321aab 100644 --- a/lib/support/nginx/gitlab-ssl +++ b/lib/support/nginx/gitlab-ssl @@ -171,6 +171,13 @@ server { proxy_connect_timeout 300; proxy_redirect off; + # Do not buffer Git HTTP responses + proxy_buffering off; + + # Pass chunked request bodies to gitlab-git-http-server as-is + proxy_request_buffering off; + proxy_http_version 1.1; + proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Ssl on; -- cgit v1.2.1 From 783791fd08e8144a2ab97307a12df9d2a40e0421 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Mon, 7 Sep 2015 14:59:32 +0200 Subject: The good stuff needs NGINX 1.7.11 --- lib/support/nginx/gitlab | 8 +++++--- lib/support/nginx/gitlab-ssl | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab index 1cd81ea769f..7218a4d2f20 100644 --- a/lib/support/nginx/gitlab +++ b/lib/support/nginx/gitlab @@ -127,9 +127,11 @@ server { # Do not buffer Git HTTP responses proxy_buffering off; - # Pass chunked request bodies to gitlab-git-http-server as-is - proxy_request_buffering off; - proxy_http_version 1.1; + # The following settings only work with NGINX 1.7.11 or newer + # + # # Pass chunked request bodies to gitlab-git-http-server as-is + # proxy_request_buffering off; + # proxy_http_version 1.1; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; diff --git a/lib/support/nginx/gitlab-ssl b/lib/support/nginx/gitlab-ssl index 83aad321aab..7dabfba87e2 100644 --- a/lib/support/nginx/gitlab-ssl +++ b/lib/support/nginx/gitlab-ssl @@ -174,9 +174,11 @@ server { # Do not buffer Git HTTP responses proxy_buffering off; - # Pass chunked request bodies to gitlab-git-http-server as-is - proxy_request_buffering off; - proxy_http_version 1.1; + # The following settings only work with NGINX 1.7.11 or newer + # + # # Pass chunked request bodies to gitlab-git-http-server as-is + # proxy_request_buffering off; + # proxy_http_version 1.1; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; -- cgit v1.2.1 From e156f42079ebf8247b6a39fa6314d4d5c6b73d12 Mon Sep 17 00:00:00 2001 From: Jared Szechy Date: Tue, 4 Aug 2015 18:21:12 -0400 Subject: FogBugz project import --- lib/gitlab/fogbugz_import/client.rb | 56 +++++ lib/gitlab/fogbugz_import/importer.rb | 298 +++++++++++++++++++++++++++ lib/gitlab/fogbugz_import/project_creator.rb | 38 ++++ lib/gitlab/fogbugz_import/repository.rb | 31 +++ lib/gitlab/import_sources.rb | 1 + 5 files changed, 424 insertions(+) create mode 100644 lib/gitlab/fogbugz_import/client.rb create mode 100644 lib/gitlab/fogbugz_import/importer.rb create mode 100644 lib/gitlab/fogbugz_import/project_creator.rb create mode 100644 lib/gitlab/fogbugz_import/repository.rb (limited to 'lib') diff --git a/lib/gitlab/fogbugz_import/client.rb b/lib/gitlab/fogbugz_import/client.rb new file mode 100644 index 00000000000..431d50882fd --- /dev/null +++ b/lib/gitlab/fogbugz_import/client.rb @@ -0,0 +1,56 @@ +require 'fogbugz' + +module Gitlab + module FogbugzImport + class Client + attr_reader :api + + def initialize(options = {}) + if options[:uri] && options[:token] + @api = ::Fogbugz::Interface.new(options) + elsif options[:uri] && options[:email] && options[:password] + @api = ::Fogbugz::Interface.new(options) + @api.authenticate + @api + end + end + + def get_token + @api.token + end + + def valid? + !get_token.blank? + end + + def user_map + users = {} + res = @api.command(:listPeople) + res['people']['person'].each do |user| + users[user['ixPerson']] = { name: user['sFullName'], email: user['sEmail'] } + end + users + end + + def repos + res = @api.command(:listProjects) + @repos ||= res['projects']['project'].map { |proj| FogbugzImport::Repository.new(proj) } + end + + def repo(id) + repos.find { |r| r.id.to_s == id.to_s } + end + + def cases(project_id) + project_name = repo(project_id).name + res = @api.command(:search, q: "project:'#{project_name}'", cols: 'ixPersonAssignedTo,ixPersonOpenedBy,ixPersonClosedBy,sStatus,sPriority,sCategory,fOpen,sTitle,sLatestTextSummary,dtOpened,dtClosed,dtResolved,dtLastUpdated,events') + return [] unless res['cases']['count'].to_i > 0 + res['cases']['case'] + end + + def categories + @api.command(:listCategories) + end + end + end +end diff --git a/lib/gitlab/fogbugz_import/importer.rb b/lib/gitlab/fogbugz_import/importer.rb new file mode 100644 index 00000000000..61e08b23543 --- /dev/null +++ b/lib/gitlab/fogbugz_import/importer.rb @@ -0,0 +1,298 @@ +module Gitlab + module FogbugzImport + class Importer + attr_reader :project, :repo + + def initialize(project) + @project = project + + import_data = project.import_data.try(:data) + repo_data = import_data['repo'] if import_data + @repo = FogbugzImport::Repository.new(repo_data) + + @known_labels = Set.new + end + + def execute + return true unless repo.valid? + + data = project.import_data.try(:data) + + client = Gitlab::FogbugzImport::Client.new(token: data['fb_session']['token'], uri: data['fb_session']['uri']) + + @cases = client.cases(@repo.id.to_i) + @categories = client.categories + + import_cases + + true + end + + private + + def user_map + @user_map ||= begin + user_map = Hash.new + import_data = project.import_data.try(:data) + stored_user_map = import_data['user_map'] if import_data + user_map.update(stored_user_map) if stored_user_map + + user_map + end + end + + def import_labels + @categories['categories']['category'].each do |label| + create_label(label['sCategory']) + @known_labels << name + end + end + + def nice_label_color(name) + case name + when 'Blocker' + '#ff0000' + when 'Crash' + '#ffcfcf' + when 'Major' + '#deffcf' + when 'Minor' + '#cfe9ff' + when 'Bug' + '#d9534f' + when 'Feature' + '#44ad8e' + when 'Technical Task' + '#4b6dd0' + else + '#e2e2e2' + end + end + + def create_label(name) + color = nice_label_color(name) + Label.create!(project_id: project.id, title: name, color: color) + end + + def user_info(person_id) + user_hash = user_map[person_id.to_s] + + user_name = '' + gitlab_id = nil + + unless user_hash.nil? + user_name = user_hash['name'] + if user = User.find_by(id: user_hash['gitlab_user']) + user_name = "@#{user.username}" + gitlab_id = user.id + end + end + + { name: user_name, gitlab_id: gitlab_id } + end + + def import_cases + return unless @cases + + while bug = @cases.shift + author = user_info(bug['ixPersonOpenedBy'])[:name] + date = DateTime.parse(bug['dtOpened']) + + comments = bug['events']['event'] + + content = format_content(opened_content(comments)) + body = format_issue_body(author, date, content) + + labels = [] + [bug['sCategory'], bug['sPriority']].each do |label| + unless label.blank? + labels << label + unless @known_labels.include?(label) + create_label(label) + @known_labels << label + end + end + end + + assignee_id = user_info(bug['ixPersonAssignedTo'])[:gitlab_id] + author_id = user_info(bug['ixPersonOpenedBy'])[:gitlab_id] || project.creator_id + + issue = Issue.create!( + project_id: project.id, + title: bug['sTitle'], + description: body, + author_id: author_id, + assignee_id: assignee_id, + state: bug['fOpen'] == 'true' ? 'opened' : 'closed' + ) + issue.add_labels_by_names(labels) + + if issue.iid != bug['ixBug'] + issue.update_attribute(:iid, bug['ixBug']) + end + + import_issue_comments(issue, comments) + + issue.update_attribute(:created_at, date) + + last_update = DateTime.parse(bug['dtLastUpdated']) + issue.update_attribute(:updated_at, last_update) + end + end + + def opened_content(comments) + while comment = comments.shift + if comment['sVerb'] == 'Opened' + return comment['s'] + end + end + '' + end + + def import_issue_comments(issue, comments) + Note.transaction do + while comment = comments.shift + verb = comment['sVerb'] + + next if verb == 'Opened' || verb === 'Closed' + + content = format_content(comment['s']) + attachments = format_attachments(comment['rgAttachments']) + updates = format_updates(comment) + + next if content.blank? && attachments.empty? && updates.empty? + + author = user_info(comment['ixPerson'])[:name] + author_id = user_info(comment['ixPerson'])[:gitlab_id] || project.creator_id + date = DateTime.parse(comment['dt']) + + body = format_issue_comment_body( + comment['ixBugEvent'], + author, + date, + content, + attachments, + updates + ) + + note = Note.create!( + project_id: project.id, + noteable_type: "Issue", + noteable_id: issue.id, + author_id: author_id, + note: body + ) + + note.update_attribute(:created_at, date) + note.update_attribute(:updated_at, date) + end + end + end + + def linkify_issues(s) + s = s.gsub(/([Ii]ssue) ([0-9]+)/, '\1 #\2') + s = s.gsub(/([Cc]ase) ([0-9]+)/, '\1 #\2') + s + end + + def escape_for_markdown(s) + s = s.gsub(/^#/, "\\#") + s = s.gsub(/^-/, "\\-") + s = s.gsub("`", "\\~") + s = s.gsub("\r", "") + s = s.gsub("\n", " \n") + s + end + + def format_content(raw_content) + return raw_content if raw_content.nil? + linkify_issues(escape_for_markdown(raw_content)) + end + + def format_attachments(raw_attachments) + return [] unless raw_attachments + + attachments = case raw_attachments['attachment'] + when Array + raw_attachments['attachment'] + when Hash + [raw_attachments['attachment']] + else + [] + end + + attachments.map! { |a| format_attachment(a) } + attachments.compact + end + + def format_attachment(attachment) + link = build_attachment_url(attachment['sURL']) + + res = ::Projects::DownloadService.new(project, link).execute + + return nil if res.nil? + + text = "[#{res['alt']}](#{res['url']})" + text = "!#{text}" if res['is_image'] + text + end + + def build_attachment_url(rel_url) + data = project.import_data.try(:data) + uri = data['fb_session']['uri'] + token = data['fb_session']['token'] + "#{uri}/#{rel_url}&token=#{token}" + end + + def format_updates(comment) + updates = [] + + if comment['sChanges'] + updates << "*Changes: #{linkify_issues(comment['sChanges'].chomp)}*" + end + + if comment['evtDescription'] + updates << "*#{comment['evtDescription']}*" + end + + updates + end + + def format_issue_body(author, date, content) + body = [] + body << "*By #{author} on #{date} (imported from FogBugz)*" + body << '---' + + if content.blank? + content = '*(No description has been entered for this issue)*' + end + body << content + + body.join("\n\n") + end + + def format_issue_comment_body(id, author, date, content, attachments, updates) + body = [] + body << "*By #{author} on #{date} (imported from FogBugz)*" + body << '---' + + if content.blank? + content = "*(No comment has been entered for this change)*" + end + body << content + + if updates.any? + body << '---' + body += updates + end + + if attachments.any? + body << '---' + body += attachments + end + + body.join("\n\n") + end + end + end +end diff --git a/lib/gitlab/fogbugz_import/project_creator.rb b/lib/gitlab/fogbugz_import/project_creator.rb new file mode 100644 index 00000000000..f02ea43910f --- /dev/null +++ b/lib/gitlab/fogbugz_import/project_creator.rb @@ -0,0 +1,38 @@ +module Gitlab + module FogbugzImport + class ProjectCreator + attr_reader :repo, :fb_session, :namespace, :current_user, :user_map + + def initialize(repo, fb_session, namespace, current_user, user_map = nil) + @repo = repo + @fb_session = fb_session + @namespace = namespace + @current_user = current_user + @user_map = user_map + end + + def execute + project = ::Projects::CreateService.new(current_user, + name: repo.safe_name, + path: repo.path, + namespace: namespace, + creator: current_user, + visibility_level: Gitlab::VisibilityLevel::INTERNAL, + import_type: 'fogbugz', + import_source: repo.name, + import_url: Project::UNKNOWN_IMPORT_URL + ).execute + + import_data = project.create_import_data( + data: { + 'repo' => repo.raw_data, + 'user_map' => user_map, + 'fb_session' => fb_session + } + ) + + project + end + end + end +end diff --git a/lib/gitlab/fogbugz_import/repository.rb b/lib/gitlab/fogbugz_import/repository.rb new file mode 100644 index 00000000000..d1dc63db2b2 --- /dev/null +++ b/lib/gitlab/fogbugz_import/repository.rb @@ -0,0 +1,31 @@ +module Gitlab + module FogbugzImport + class Repository + attr_accessor :raw_data + + def initialize(raw_data) + @raw_data = raw_data + end + + def valid? + raw_data.is_a?(Hash) + end + + def id + raw_data['ixProject'] + end + + def name + raw_data['sProject'] + end + + def safe_name + name.gsub(/[^\s\w.-]/, '') + end + + def path + safe_name.gsub(/[\s]/, '_') + end + end + end +end diff --git a/lib/gitlab/import_sources.rb b/lib/gitlab/import_sources.rb index 991b70aab6a..ccfdfbe73e8 100644 --- a/lib/gitlab/import_sources.rb +++ b/lib/gitlab/import_sources.rb @@ -19,6 +19,7 @@ module Gitlab 'GitLab.com' => 'gitlab', 'Gitorious.org' => 'gitorious', 'Google Code' => 'google_code', + 'FogBugz' => 'fogbugz', 'Any repo by URL' => 'git', } end -- cgit v1.2.1